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 !isOpenMPTaskLoopDirective(DVar.DKind)) || 971 isOpenMPTeamsDirective(DVar.DKind)) { 972 DVar.CKind = OMPC_shared; 973 return DVar; 974 } 975 976 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 977 // in a Construct, implicitly determined, p.4] 978 // In a task construct, if no default clause is present, a variable that in 979 // the enclosing context is determined to be shared by all implicit tasks 980 // bound to the current team is shared. 981 if (isOpenMPTaskingDirective(DVar.DKind)) { 982 DSAVarData DVarTemp; 983 const_iterator I = Iter, E = end(); 984 do { 985 ++I; 986 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 987 // Referenced in a Construct, implicitly determined, p.6] 988 // In a task construct, if no default clause is present, a variable 989 // whose data-sharing attribute is not determined by the rules above is 990 // firstprivate. 991 DVarTemp = getDSA(I, D); 992 if (DVarTemp.CKind != OMPC_shared) { 993 DVar.RefExpr = nullptr; 994 DVar.CKind = OMPC_firstprivate; 995 return DVar; 996 } 997 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 998 DVar.CKind = 999 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1000 return DVar; 1001 } 1002 } 1003 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1004 // in a Construct, implicitly determined, p.3] 1005 // For constructs other than task, if no default clause is present, these 1006 // variables inherit their data-sharing attributes from the enclosing 1007 // context. 1008 return getDSA(++Iter, D); 1009 } 1010 1011 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1012 const Expr *NewDE) { 1013 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1014 D = getCanonicalDecl(D); 1015 SharingMapTy &StackElem = getTopOfStack(); 1016 auto It = StackElem.AlignedMap.find(D); 1017 if (It == StackElem.AlignedMap.end()) { 1018 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1019 StackElem.AlignedMap[D] = NewDE; 1020 return nullptr; 1021 } 1022 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1023 return It->second; 1024 } 1025 1026 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1027 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1028 D = getCanonicalDecl(D); 1029 SharingMapTy &StackElem = getTopOfStack(); 1030 StackElem.LCVMap.try_emplace( 1031 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1032 } 1033 1034 const DSAStackTy::LCDeclInfo 1035 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1036 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1037 D = getCanonicalDecl(D); 1038 const SharingMapTy &StackElem = getTopOfStack(); 1039 auto It = StackElem.LCVMap.find(D); 1040 if (It != StackElem.LCVMap.end()) 1041 return It->second; 1042 return {0, nullptr}; 1043 } 1044 1045 const DSAStackTy::LCDeclInfo 1046 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1047 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1048 assert(Parent && "Data-sharing attributes stack is empty"); 1049 D = getCanonicalDecl(D); 1050 auto It = Parent->LCVMap.find(D); 1051 if (It != Parent->LCVMap.end()) 1052 return It->second; 1053 return {0, nullptr}; 1054 } 1055 1056 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1057 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1058 assert(Parent && "Data-sharing attributes stack is empty"); 1059 if (Parent->LCVMap.size() < I) 1060 return nullptr; 1061 for (const auto &Pair : Parent->LCVMap) 1062 if (Pair.second.first == I) 1063 return Pair.first; 1064 return nullptr; 1065 } 1066 1067 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1068 DeclRefExpr *PrivateCopy) { 1069 D = getCanonicalDecl(D); 1070 if (A == OMPC_threadprivate) { 1071 DSAInfo &Data = Threadprivates[D]; 1072 Data.Attributes = A; 1073 Data.RefExpr.setPointer(E); 1074 Data.PrivateCopy = nullptr; 1075 } else { 1076 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1077 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1078 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1079 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1080 (isLoopControlVariable(D).first && A == OMPC_private)); 1081 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1082 Data.RefExpr.setInt(/*IntVal=*/true); 1083 return; 1084 } 1085 const bool IsLastprivate = 1086 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1087 Data.Attributes = A; 1088 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1089 Data.PrivateCopy = PrivateCopy; 1090 if (PrivateCopy) { 1091 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1092 Data.Attributes = A; 1093 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1094 Data.PrivateCopy = nullptr; 1095 } 1096 } 1097 } 1098 1099 /// Build a variable declaration for OpenMP loop iteration variable. 1100 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1101 StringRef Name, const AttrVec *Attrs = nullptr, 1102 DeclRefExpr *OrigRef = nullptr) { 1103 DeclContext *DC = SemaRef.CurContext; 1104 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1105 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1106 auto *Decl = 1107 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1108 if (Attrs) { 1109 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1110 I != E; ++I) 1111 Decl->addAttr(*I); 1112 } 1113 Decl->setImplicit(); 1114 if (OrigRef) { 1115 Decl->addAttr( 1116 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1117 } 1118 return Decl; 1119 } 1120 1121 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1122 SourceLocation Loc, 1123 bool RefersToCapture = false) { 1124 D->setReferenced(); 1125 D->markUsed(S.Context); 1126 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1127 SourceLocation(), D, RefersToCapture, Loc, Ty, 1128 VK_LValue); 1129 } 1130 1131 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1132 BinaryOperatorKind BOK) { 1133 D = getCanonicalDecl(D); 1134 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1135 assert( 1136 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1137 "Additional reduction info may be specified only for reduction items."); 1138 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1139 assert(ReductionData.ReductionRange.isInvalid() && 1140 getTopOfStack().Directive == OMPD_taskgroup && 1141 "Additional reduction info may be specified only once for reduction " 1142 "items."); 1143 ReductionData.set(BOK, SR); 1144 Expr *&TaskgroupReductionRef = 1145 getTopOfStack().TaskgroupReductionRef; 1146 if (!TaskgroupReductionRef) { 1147 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1148 SemaRef.Context.VoidPtrTy, ".task_red."); 1149 TaskgroupReductionRef = 1150 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1151 } 1152 } 1153 1154 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1155 const Expr *ReductionRef) { 1156 D = getCanonicalDecl(D); 1157 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1158 assert( 1159 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1160 "Additional reduction info may be specified only for reduction items."); 1161 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1162 assert(ReductionData.ReductionRange.isInvalid() && 1163 getTopOfStack().Directive == OMPD_taskgroup && 1164 "Additional reduction info may be specified only once for reduction " 1165 "items."); 1166 ReductionData.set(ReductionRef, SR); 1167 Expr *&TaskgroupReductionRef = 1168 getTopOfStack().TaskgroupReductionRef; 1169 if (!TaskgroupReductionRef) { 1170 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1171 SemaRef.Context.VoidPtrTy, ".task_red."); 1172 TaskgroupReductionRef = 1173 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1174 } 1175 } 1176 1177 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1178 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1179 Expr *&TaskgroupDescriptor) const { 1180 D = getCanonicalDecl(D); 1181 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1182 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1183 const DSAInfo &Data = I->SharingMap.lookup(D); 1184 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1185 continue; 1186 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1187 if (!ReductionData.ReductionOp || 1188 ReductionData.ReductionOp.is<const Expr *>()) 1189 return DSAVarData(); 1190 SR = ReductionData.ReductionRange; 1191 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1192 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1193 "expression for the descriptor is not " 1194 "set."); 1195 TaskgroupDescriptor = I->TaskgroupReductionRef; 1196 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1197 Data.PrivateCopy, I->DefaultAttrLoc); 1198 } 1199 return DSAVarData(); 1200 } 1201 1202 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1203 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1204 Expr *&TaskgroupDescriptor) const { 1205 D = getCanonicalDecl(D); 1206 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1207 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1208 const DSAInfo &Data = I->SharingMap.lookup(D); 1209 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1210 continue; 1211 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1212 if (!ReductionData.ReductionOp || 1213 !ReductionData.ReductionOp.is<const Expr *>()) 1214 return DSAVarData(); 1215 SR = ReductionData.ReductionRange; 1216 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1217 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1218 "expression for the descriptor is not " 1219 "set."); 1220 TaskgroupDescriptor = I->TaskgroupReductionRef; 1221 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1222 Data.PrivateCopy, I->DefaultAttrLoc); 1223 } 1224 return DSAVarData(); 1225 } 1226 1227 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1228 D = D->getCanonicalDecl(); 1229 for (const_iterator E = end(); I != E; ++I) { 1230 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1231 isOpenMPTargetExecutionDirective(I->Directive)) { 1232 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1233 Scope *CurScope = getCurScope(); 1234 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1235 CurScope = CurScope->getParent(); 1236 return CurScope != TopScope; 1237 } 1238 } 1239 return false; 1240 } 1241 1242 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1243 bool AcceptIfMutable = true, 1244 bool *IsClassType = nullptr) { 1245 ASTContext &Context = SemaRef.getASTContext(); 1246 Type = Type.getNonReferenceType().getCanonicalType(); 1247 bool IsConstant = Type.isConstant(Context); 1248 Type = Context.getBaseElementType(Type); 1249 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1250 ? Type->getAsCXXRecordDecl() 1251 : nullptr; 1252 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1253 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1254 RD = CTD->getTemplatedDecl(); 1255 if (IsClassType) 1256 *IsClassType = RD; 1257 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1258 RD->hasDefinition() && RD->hasMutableFields()); 1259 } 1260 1261 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1262 QualType Type, OpenMPClauseKind CKind, 1263 SourceLocation ELoc, 1264 bool AcceptIfMutable = true, 1265 bool ListItemNotVar = false) { 1266 ASTContext &Context = SemaRef.getASTContext(); 1267 bool IsClassType; 1268 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1269 unsigned Diag = ListItemNotVar 1270 ? diag::err_omp_const_list_item 1271 : IsClassType ? diag::err_omp_const_not_mutable_variable 1272 : diag::err_omp_const_variable; 1273 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1274 if (!ListItemNotVar && D) { 1275 const VarDecl *VD = dyn_cast<VarDecl>(D); 1276 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1277 VarDecl::DeclarationOnly; 1278 SemaRef.Diag(D->getLocation(), 1279 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1280 << D; 1281 } 1282 return true; 1283 } 1284 return false; 1285 } 1286 1287 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1288 bool FromParent) { 1289 D = getCanonicalDecl(D); 1290 DSAVarData DVar; 1291 1292 auto *VD = dyn_cast<VarDecl>(D); 1293 auto TI = Threadprivates.find(D); 1294 if (TI != Threadprivates.end()) { 1295 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1296 DVar.CKind = OMPC_threadprivate; 1297 return DVar; 1298 } 1299 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1300 DVar.RefExpr = buildDeclRefExpr( 1301 SemaRef, VD, D->getType().getNonReferenceType(), 1302 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1303 DVar.CKind = OMPC_threadprivate; 1304 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1305 return DVar; 1306 } 1307 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1308 // in a Construct, C/C++, predetermined, p.1] 1309 // Variables appearing in threadprivate directives are threadprivate. 1310 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1311 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1312 SemaRef.getLangOpts().OpenMPUseTLS && 1313 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1314 (VD && VD->getStorageClass() == SC_Register && 1315 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1316 DVar.RefExpr = buildDeclRefExpr( 1317 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1318 DVar.CKind = OMPC_threadprivate; 1319 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1320 return DVar; 1321 } 1322 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1323 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1324 !isLoopControlVariable(D).first) { 1325 const_iterator IterTarget = 1326 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1327 return isOpenMPTargetExecutionDirective(Data.Directive); 1328 }); 1329 if (IterTarget != end()) { 1330 const_iterator ParentIterTarget = IterTarget + 1; 1331 for (const_iterator Iter = begin(); 1332 Iter != ParentIterTarget; ++Iter) { 1333 if (isOpenMPLocal(VD, Iter)) { 1334 DVar.RefExpr = 1335 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1336 D->getLocation()); 1337 DVar.CKind = OMPC_threadprivate; 1338 return DVar; 1339 } 1340 } 1341 if (!isClauseParsingMode() || IterTarget != begin()) { 1342 auto DSAIter = IterTarget->SharingMap.find(D); 1343 if (DSAIter != IterTarget->SharingMap.end() && 1344 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1345 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1346 DVar.CKind = OMPC_threadprivate; 1347 return DVar; 1348 } 1349 const_iterator End = end(); 1350 if (!SemaRef.isOpenMPCapturedByRef( 1351 D, std::distance(ParentIterTarget, End), 1352 /*OpenMPCaptureLevel=*/0)) { 1353 DVar.RefExpr = 1354 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1355 IterTarget->ConstructLoc); 1356 DVar.CKind = OMPC_threadprivate; 1357 return DVar; 1358 } 1359 } 1360 } 1361 } 1362 1363 if (isStackEmpty()) 1364 // Not in OpenMP execution region and top scope was already checked. 1365 return DVar; 1366 1367 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1368 // in a Construct, C/C++, predetermined, p.4] 1369 // Static data members are shared. 1370 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1371 // in a Construct, C/C++, predetermined, p.7] 1372 // Variables with static storage duration that are declared in a scope 1373 // inside the construct are shared. 1374 if (VD && VD->isStaticDataMember()) { 1375 // Check for explicitly specified attributes. 1376 const_iterator I = begin(); 1377 const_iterator EndI = end(); 1378 if (FromParent && I != EndI) 1379 ++I; 1380 auto It = I->SharingMap.find(D); 1381 if (It != I->SharingMap.end()) { 1382 const DSAInfo &Data = It->getSecond(); 1383 DVar.RefExpr = Data.RefExpr.getPointer(); 1384 DVar.PrivateCopy = Data.PrivateCopy; 1385 DVar.CKind = Data.Attributes; 1386 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1387 DVar.DKind = I->Directive; 1388 return DVar; 1389 } 1390 1391 DVar.CKind = OMPC_shared; 1392 return DVar; 1393 } 1394 1395 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1396 // The predetermined shared attribute for const-qualified types having no 1397 // mutable members was removed after OpenMP 3.1. 1398 if (SemaRef.LangOpts.OpenMP <= 31) { 1399 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1400 // in a Construct, C/C++, predetermined, p.6] 1401 // Variables with const qualified type having no mutable member are 1402 // shared. 1403 if (isConstNotMutableType(SemaRef, D->getType())) { 1404 // Variables with const-qualified type having no mutable member may be 1405 // listed in a firstprivate clause, even if they are static data members. 1406 DSAVarData DVarTemp = hasInnermostDSA( 1407 D, 1408 [](OpenMPClauseKind C) { 1409 return C == OMPC_firstprivate || C == OMPC_shared; 1410 }, 1411 MatchesAlways, FromParent); 1412 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1413 return DVarTemp; 1414 1415 DVar.CKind = OMPC_shared; 1416 return DVar; 1417 } 1418 } 1419 1420 // Explicitly specified attributes and local variables with predetermined 1421 // attributes. 1422 const_iterator I = begin(); 1423 const_iterator EndI = end(); 1424 if (FromParent && I != EndI) 1425 ++I; 1426 auto It = I->SharingMap.find(D); 1427 if (It != I->SharingMap.end()) { 1428 const DSAInfo &Data = It->getSecond(); 1429 DVar.RefExpr = Data.RefExpr.getPointer(); 1430 DVar.PrivateCopy = Data.PrivateCopy; 1431 DVar.CKind = Data.Attributes; 1432 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1433 DVar.DKind = I->Directive; 1434 } 1435 1436 return DVar; 1437 } 1438 1439 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1440 bool FromParent) const { 1441 if (isStackEmpty()) { 1442 const_iterator I; 1443 return getDSA(I, D); 1444 } 1445 D = getCanonicalDecl(D); 1446 const_iterator StartI = begin(); 1447 const_iterator EndI = end(); 1448 if (FromParent && StartI != EndI) 1449 ++StartI; 1450 return getDSA(StartI, D); 1451 } 1452 1453 const DSAStackTy::DSAVarData 1454 DSAStackTy::hasDSA(ValueDecl *D, 1455 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1456 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1457 bool FromParent) const { 1458 if (isStackEmpty()) 1459 return {}; 1460 D = getCanonicalDecl(D); 1461 const_iterator I = begin(); 1462 const_iterator EndI = end(); 1463 if (FromParent && I != EndI) 1464 ++I; 1465 for (; I != EndI; ++I) { 1466 if (!DPred(I->Directive) && 1467 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1468 continue; 1469 const_iterator NewI = I; 1470 DSAVarData DVar = getDSA(NewI, D); 1471 if (I == NewI && CPred(DVar.CKind)) 1472 return DVar; 1473 } 1474 return {}; 1475 } 1476 1477 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1478 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1479 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1480 bool FromParent) const { 1481 if (isStackEmpty()) 1482 return {}; 1483 D = getCanonicalDecl(D); 1484 const_iterator StartI = begin(); 1485 const_iterator EndI = end(); 1486 if (FromParent && StartI != EndI) 1487 ++StartI; 1488 if (StartI == EndI || !DPred(StartI->Directive)) 1489 return {}; 1490 const_iterator NewI = StartI; 1491 DSAVarData DVar = getDSA(NewI, D); 1492 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1493 } 1494 1495 bool DSAStackTy::hasExplicitDSA( 1496 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1497 unsigned Level, bool NotLastprivate) const { 1498 if (getStackSize() <= Level) 1499 return false; 1500 D = getCanonicalDecl(D); 1501 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1502 auto I = StackElem.SharingMap.find(D); 1503 if (I != StackElem.SharingMap.end() && 1504 I->getSecond().RefExpr.getPointer() && 1505 CPred(I->getSecond().Attributes) && 1506 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1507 return true; 1508 // Check predetermined rules for the loop control variables. 1509 auto LI = StackElem.LCVMap.find(D); 1510 if (LI != StackElem.LCVMap.end()) 1511 return CPred(OMPC_private); 1512 return false; 1513 } 1514 1515 bool DSAStackTy::hasExplicitDirective( 1516 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1517 unsigned Level) const { 1518 if (getStackSize() <= Level) 1519 return false; 1520 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1521 return DPred(StackElem.Directive); 1522 } 1523 1524 bool DSAStackTy::hasDirective( 1525 const llvm::function_ref<bool(OpenMPDirectiveKind, 1526 const DeclarationNameInfo &, SourceLocation)> 1527 DPred, 1528 bool FromParent) const { 1529 // We look only in the enclosing region. 1530 size_t Skip = FromParent ? 2 : 1; 1531 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1532 I != E; ++I) { 1533 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1534 return true; 1535 } 1536 return false; 1537 } 1538 1539 void Sema::InitDataSharingAttributesStack() { 1540 VarDataSharingAttributesStack = new DSAStackTy(*this); 1541 } 1542 1543 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1544 1545 void Sema::pushOpenMPFunctionRegion() { 1546 DSAStack->pushFunction(); 1547 } 1548 1549 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1550 DSAStack->popFunction(OldFSI); 1551 } 1552 1553 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1554 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1555 "Expected OpenMP device compilation."); 1556 return !S.isInOpenMPTargetExecutionDirective() && 1557 !S.isInOpenMPDeclareTargetContext(); 1558 } 1559 1560 namespace { 1561 /// Status of the function emission on the host/device. 1562 enum class FunctionEmissionStatus { 1563 Emitted, 1564 Discarded, 1565 Unknown, 1566 }; 1567 } // anonymous namespace 1568 1569 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1570 unsigned DiagID) { 1571 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1572 "Expected OpenMP device compilation."); 1573 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1574 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1575 switch (FES) { 1576 case FunctionEmissionStatus::Emitted: 1577 Kind = DeviceDiagBuilder::K_Immediate; 1578 break; 1579 case FunctionEmissionStatus::Unknown: 1580 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1581 : DeviceDiagBuilder::K_Immediate; 1582 break; 1583 case FunctionEmissionStatus::TemplateDiscarded: 1584 case FunctionEmissionStatus::OMPDiscarded: 1585 Kind = DeviceDiagBuilder::K_Nop; 1586 break; 1587 case FunctionEmissionStatus::CUDADiscarded: 1588 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1589 break; 1590 } 1591 1592 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1593 } 1594 1595 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1596 unsigned DiagID) { 1597 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1598 "Expected OpenMP host compilation."); 1599 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1600 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1601 switch (FES) { 1602 case FunctionEmissionStatus::Emitted: 1603 Kind = DeviceDiagBuilder::K_Immediate; 1604 break; 1605 case FunctionEmissionStatus::Unknown: 1606 Kind = DeviceDiagBuilder::K_Deferred; 1607 break; 1608 case FunctionEmissionStatus::TemplateDiscarded: 1609 case FunctionEmissionStatus::OMPDiscarded: 1610 case FunctionEmissionStatus::CUDADiscarded: 1611 Kind = DeviceDiagBuilder::K_Nop; 1612 break; 1613 } 1614 1615 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1616 } 1617 1618 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1619 bool CheckForDelayedContext) { 1620 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1621 "Expected OpenMP device compilation."); 1622 assert(Callee && "Callee may not be null."); 1623 Callee = Callee->getMostRecentDecl(); 1624 FunctionDecl *Caller = getCurFunctionDecl(); 1625 1626 // host only function are not available on the device. 1627 if (Caller) { 1628 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1629 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1630 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1631 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1632 "CUDADiscarded unexpected in OpenMP device function check"); 1633 if ((CallerS == FunctionEmissionStatus::Emitted || 1634 (!isOpenMPDeviceDelayedContext(*this) && 1635 CallerS == FunctionEmissionStatus::Unknown)) && 1636 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1637 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1638 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1639 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1640 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1641 diag::note_omp_marked_device_type_here) 1642 << HostDevTy; 1643 return; 1644 } 1645 } 1646 // If the caller is known-emitted, mark the callee as known-emitted. 1647 // Otherwise, mark the call in our call graph so we can traverse it later. 1648 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1649 (!Caller && !CheckForDelayedContext) || 1650 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1651 markKnownEmitted(*this, Caller, Callee, Loc, 1652 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1653 return CheckForDelayedContext && 1654 S.getEmissionStatus(FD) == 1655 FunctionEmissionStatus::Emitted; 1656 }); 1657 else if (Caller) 1658 DeviceCallGraph[Caller].insert({Callee, Loc}); 1659 } 1660 1661 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1662 bool CheckCaller) { 1663 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1664 "Expected OpenMP host compilation."); 1665 assert(Callee && "Callee may not be null."); 1666 Callee = Callee->getMostRecentDecl(); 1667 FunctionDecl *Caller = getCurFunctionDecl(); 1668 1669 // device only function are not available on the host. 1670 if (Caller) { 1671 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1672 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1673 assert( 1674 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1675 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1676 "CUDADiscarded unexpected in OpenMP host function check"); 1677 if (CallerS == FunctionEmissionStatus::Emitted && 1678 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1679 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1680 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1681 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1682 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1683 diag::note_omp_marked_device_type_here) 1684 << NoHostDevTy; 1685 return; 1686 } 1687 } 1688 // If the caller is known-emitted, mark the callee as known-emitted. 1689 // Otherwise, mark the call in our call graph so we can traverse it later. 1690 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1691 if ((!CheckCaller && !Caller) || 1692 (Caller && 1693 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1694 markKnownEmitted( 1695 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1696 return CheckCaller && 1697 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1698 }); 1699 else if (Caller) 1700 DeviceCallGraph[Caller].insert({Callee, Loc}); 1701 } 1702 } 1703 1704 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1705 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1706 "OpenMP device compilation mode is expected."); 1707 QualType Ty = E->getType(); 1708 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1709 ((Ty->isFloat128Type() || 1710 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1711 !Context.getTargetInfo().hasFloat128Type()) || 1712 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1713 !Context.getTargetInfo().hasInt128Type())) 1714 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1715 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1716 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1717 } 1718 1719 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1720 unsigned OpenMPCaptureLevel) const { 1721 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1722 1723 ASTContext &Ctx = getASTContext(); 1724 bool IsByRef = true; 1725 1726 // Find the directive that is associated with the provided scope. 1727 D = cast<ValueDecl>(D->getCanonicalDecl()); 1728 QualType Ty = D->getType(); 1729 1730 bool IsVariableUsedInMapClause = false; 1731 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1732 // This table summarizes how a given variable should be passed to the device 1733 // given its type and the clauses where it appears. This table is based on 1734 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1735 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1736 // 1737 // ========================================================================= 1738 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1739 // | |(tofrom:scalar)| | pvt | | | | 1740 // ========================================================================= 1741 // | scl | | | | - | | bycopy| 1742 // | scl | | - | x | - | - | bycopy| 1743 // | scl | | x | - | - | - | null | 1744 // | scl | x | | | - | | byref | 1745 // | scl | x | - | x | - | - | bycopy| 1746 // | scl | x | x | - | - | - | null | 1747 // | scl | | - | - | - | x | byref | 1748 // | scl | x | - | - | - | x | byref | 1749 // 1750 // | agg | n.a. | | | - | | byref | 1751 // | agg | n.a. | - | x | - | - | byref | 1752 // | agg | n.a. | x | - | - | - | null | 1753 // | agg | n.a. | - | - | - | x | byref | 1754 // | agg | n.a. | - | - | - | x[] | byref | 1755 // 1756 // | ptr | n.a. | | | - | | bycopy| 1757 // | ptr | n.a. | - | x | - | - | bycopy| 1758 // | ptr | n.a. | x | - | - | - | null | 1759 // | ptr | n.a. | - | - | - | x | byref | 1760 // | ptr | n.a. | - | - | - | x[] | bycopy| 1761 // | ptr | n.a. | - | - | x | | bycopy| 1762 // | ptr | n.a. | - | - | x | x | bycopy| 1763 // | ptr | n.a. | - | - | x | x[] | bycopy| 1764 // ========================================================================= 1765 // Legend: 1766 // scl - scalar 1767 // ptr - pointer 1768 // agg - aggregate 1769 // x - applies 1770 // - - invalid in this combination 1771 // [] - mapped with an array section 1772 // byref - should be mapped by reference 1773 // byval - should be mapped by value 1774 // null - initialize a local variable to null on the device 1775 // 1776 // Observations: 1777 // - All scalar declarations that show up in a map clause have to be passed 1778 // by reference, because they may have been mapped in the enclosing data 1779 // environment. 1780 // - If the scalar value does not fit the size of uintptr, it has to be 1781 // passed by reference, regardless the result in the table above. 1782 // - For pointers mapped by value that have either an implicit map or an 1783 // array section, the runtime library may pass the NULL value to the 1784 // device instead of the value passed to it by the compiler. 1785 1786 if (Ty->isReferenceType()) 1787 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1788 1789 // Locate map clauses and see if the variable being captured is referred to 1790 // in any of those clauses. Here we only care about variables, not fields, 1791 // because fields are part of aggregates. 1792 bool IsVariableAssociatedWithSection = false; 1793 1794 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1795 D, Level, 1796 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1797 OMPClauseMappableExprCommon::MappableExprComponentListRef 1798 MapExprComponents, 1799 OpenMPClauseKind WhereFoundClauseKind) { 1800 // Only the map clause information influences how a variable is 1801 // captured. E.g. is_device_ptr does not require changing the default 1802 // behavior. 1803 if (WhereFoundClauseKind != OMPC_map) 1804 return false; 1805 1806 auto EI = MapExprComponents.rbegin(); 1807 auto EE = MapExprComponents.rend(); 1808 1809 assert(EI != EE && "Invalid map expression!"); 1810 1811 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1812 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1813 1814 ++EI; 1815 if (EI == EE) 1816 return false; 1817 1818 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1819 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1820 isa<MemberExpr>(EI->getAssociatedExpression())) { 1821 IsVariableAssociatedWithSection = true; 1822 // There is nothing more we need to know about this variable. 1823 return true; 1824 } 1825 1826 // Keep looking for more map info. 1827 return false; 1828 }); 1829 1830 if (IsVariableUsedInMapClause) { 1831 // If variable is identified in a map clause it is always captured by 1832 // reference except if it is a pointer that is dereferenced somehow. 1833 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1834 } else { 1835 // By default, all the data that has a scalar type is mapped by copy 1836 // (except for reduction variables). 1837 IsByRef = 1838 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1839 !Ty->isAnyPointerType()) || 1840 !Ty->isScalarType() || 1841 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1842 DSAStack->hasExplicitDSA( 1843 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1844 } 1845 } 1846 1847 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1848 IsByRef = 1849 ((IsVariableUsedInMapClause && 1850 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1851 OMPD_target) || 1852 !DSAStack->hasExplicitDSA( 1853 D, 1854 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1855 Level, /*NotLastprivate=*/true)) && 1856 // If the variable is artificial and must be captured by value - try to 1857 // capture by value. 1858 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1859 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1860 } 1861 1862 // When passing data by copy, we need to make sure it fits the uintptr size 1863 // and alignment, because the runtime library only deals with uintptr types. 1864 // If it does not fit the uintptr size, we need to pass the data by reference 1865 // instead. 1866 if (!IsByRef && 1867 (Ctx.getTypeSizeInChars(Ty) > 1868 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1869 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1870 IsByRef = true; 1871 } 1872 1873 return IsByRef; 1874 } 1875 1876 unsigned Sema::getOpenMPNestingLevel() const { 1877 assert(getLangOpts().OpenMP); 1878 return DSAStack->getNestingLevel(); 1879 } 1880 1881 bool Sema::isInOpenMPTargetExecutionDirective() const { 1882 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1883 !DSAStack->isClauseParsingMode()) || 1884 DSAStack->hasDirective( 1885 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1886 SourceLocation) -> bool { 1887 return isOpenMPTargetExecutionDirective(K); 1888 }, 1889 false); 1890 } 1891 1892 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1893 unsigned StopAt) { 1894 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1895 D = getCanonicalDecl(D); 1896 1897 auto *VD = dyn_cast<VarDecl>(D); 1898 // Do not capture constexpr variables. 1899 if (VD && VD->isConstexpr()) 1900 return nullptr; 1901 1902 // If we want to determine whether the variable should be captured from the 1903 // perspective of the current capturing scope, and we've already left all the 1904 // capturing scopes of the top directive on the stack, check from the 1905 // perspective of its parent directive (if any) instead. 1906 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1907 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1908 1909 // If we are attempting to capture a global variable in a directive with 1910 // 'target' we return true so that this global is also mapped to the device. 1911 // 1912 if (VD && !VD->hasLocalStorage() && 1913 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1914 if (isInOpenMPDeclareTargetContext()) { 1915 // Try to mark variable as declare target if it is used in capturing 1916 // regions. 1917 if (LangOpts.OpenMP <= 45 && 1918 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1919 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1920 return nullptr; 1921 } else if (isInOpenMPTargetExecutionDirective()) { 1922 // If the declaration is enclosed in a 'declare target' directive, 1923 // then it should not be captured. 1924 // 1925 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1926 return nullptr; 1927 return VD; 1928 } 1929 } 1930 1931 if (CheckScopeInfo) { 1932 bool OpenMPFound = false; 1933 for (unsigned I = StopAt + 1; I > 0; --I) { 1934 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1935 if(!isa<CapturingScopeInfo>(FSI)) 1936 return nullptr; 1937 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1938 if (RSI->CapRegionKind == CR_OpenMP) { 1939 OpenMPFound = true; 1940 break; 1941 } 1942 } 1943 if (!OpenMPFound) 1944 return nullptr; 1945 } 1946 1947 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1948 (!DSAStack->isClauseParsingMode() || 1949 DSAStack->getParentDirective() != OMPD_unknown)) { 1950 auto &&Info = DSAStack->isLoopControlVariable(D); 1951 if (Info.first || 1952 (VD && VD->hasLocalStorage() && 1953 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1954 (VD && DSAStack->isForceVarCapturing())) 1955 return VD ? VD : Info.second; 1956 DSAStackTy::DSAVarData DVarPrivate = 1957 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1958 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1959 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1960 // Threadprivate variables must not be captured. 1961 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1962 return nullptr; 1963 // The variable is not private or it is the variable in the directive with 1964 // default(none) clause and not used in any clause. 1965 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1966 [](OpenMPDirectiveKind) { return true; }, 1967 DSAStack->isClauseParsingMode()); 1968 if (DVarPrivate.CKind != OMPC_unknown || 1969 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1970 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1971 } 1972 return nullptr; 1973 } 1974 1975 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1976 unsigned Level) const { 1977 SmallVector<OpenMPDirectiveKind, 4> Regions; 1978 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1979 FunctionScopesIndex -= Regions.size(); 1980 } 1981 1982 void Sema::startOpenMPLoop() { 1983 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1984 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1985 DSAStack->loopInit(); 1986 } 1987 1988 void Sema::startOpenMPCXXRangeFor() { 1989 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1990 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1991 DSAStack->resetPossibleLoopCounter(); 1992 DSAStack->loopStart(); 1993 } 1994 } 1995 1996 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1997 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1998 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1999 if (DSAStack->getAssociatedLoops() > 0 && 2000 !DSAStack->isLoopStarted()) { 2001 DSAStack->resetPossibleLoopCounter(D); 2002 DSAStack->loopStart(); 2003 return true; 2004 } 2005 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2006 DSAStack->isLoopControlVariable(D).first) && 2007 !DSAStack->hasExplicitDSA( 2008 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2009 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2010 return true; 2011 } 2012 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2013 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2014 DSAStack->isForceVarCapturing() && 2015 !DSAStack->hasExplicitDSA( 2016 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2017 return true; 2018 } 2019 return DSAStack->hasExplicitDSA( 2020 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2021 (DSAStack->isClauseParsingMode() && 2022 DSAStack->getClauseParsingMode() == OMPC_private) || 2023 // Consider taskgroup reduction descriptor variable a private to avoid 2024 // possible capture in the region. 2025 (DSAStack->hasExplicitDirective( 2026 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2027 Level) && 2028 DSAStack->isTaskgroupReductionRef(D, Level)); 2029 } 2030 2031 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2032 unsigned Level) { 2033 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2034 D = getCanonicalDecl(D); 2035 OpenMPClauseKind OMPC = OMPC_unknown; 2036 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2037 const unsigned NewLevel = I - 1; 2038 if (DSAStack->hasExplicitDSA(D, 2039 [&OMPC](const OpenMPClauseKind K) { 2040 if (isOpenMPPrivate(K)) { 2041 OMPC = K; 2042 return true; 2043 } 2044 return false; 2045 }, 2046 NewLevel)) 2047 break; 2048 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2049 D, NewLevel, 2050 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2051 OpenMPClauseKind) { return true; })) { 2052 OMPC = OMPC_map; 2053 break; 2054 } 2055 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2056 NewLevel)) { 2057 OMPC = OMPC_map; 2058 if (D->getType()->isScalarType() && 2059 DSAStack->getDefaultDMAAtLevel(NewLevel) != 2060 DefaultMapAttributes::DMA_tofrom_scalar) 2061 OMPC = OMPC_firstprivate; 2062 break; 2063 } 2064 } 2065 if (OMPC != OMPC_unknown) 2066 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2067 } 2068 2069 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2070 unsigned Level) const { 2071 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2072 // Return true if the current level is no longer enclosed in a target region. 2073 2074 const auto *VD = dyn_cast<VarDecl>(D); 2075 return VD && !VD->hasLocalStorage() && 2076 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2077 Level); 2078 } 2079 2080 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2081 2082 void Sema::finalizeOpenMPDelayedAnalysis() { 2083 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2084 // Diagnose implicit declare target functions and their callees. 2085 for (const auto &CallerCallees : DeviceCallGraph) { 2086 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2087 OMPDeclareTargetDeclAttr::getDeviceType( 2088 CallerCallees.getFirst()->getMostRecentDecl()); 2089 // Ignore host functions during device analyzis. 2090 if (LangOpts.OpenMPIsDevice && DevTy && 2091 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2092 continue; 2093 // Ignore nohost functions during host analyzis. 2094 if (!LangOpts.OpenMPIsDevice && DevTy && 2095 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2096 continue; 2097 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2098 &Callee : CallerCallees.getSecond()) { 2099 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2100 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2101 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2102 if (LangOpts.OpenMPIsDevice && DevTy && 2103 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2104 // Diagnose host function called during device codegen. 2105 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2106 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2107 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2108 << HostDevTy << 0; 2109 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2110 diag::note_omp_marked_device_type_here) 2111 << HostDevTy; 2112 continue; 2113 } 2114 if (!LangOpts.OpenMPIsDevice && DevTy && 2115 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2116 // Diagnose nohost function called during host codegen. 2117 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2118 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2119 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2120 << NoHostDevTy << 1; 2121 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2122 diag::note_omp_marked_device_type_here) 2123 << NoHostDevTy; 2124 continue; 2125 } 2126 } 2127 } 2128 } 2129 2130 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2131 const DeclarationNameInfo &DirName, 2132 Scope *CurScope, SourceLocation Loc) { 2133 DSAStack->push(DKind, DirName, CurScope, Loc); 2134 PushExpressionEvaluationContext( 2135 ExpressionEvaluationContext::PotentiallyEvaluated); 2136 } 2137 2138 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2139 DSAStack->setClauseParsingMode(K); 2140 } 2141 2142 void Sema::EndOpenMPClause() { 2143 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2144 } 2145 2146 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2147 ArrayRef<OMPClause *> Clauses); 2148 2149 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2150 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2151 // A variable of class type (or array thereof) that appears in a lastprivate 2152 // clause requires an accessible, unambiguous default constructor for the 2153 // class type, unless the list item is also specified in a firstprivate 2154 // clause. 2155 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2156 for (OMPClause *C : D->clauses()) { 2157 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2158 SmallVector<Expr *, 8> PrivateCopies; 2159 for (Expr *DE : Clause->varlists()) { 2160 if (DE->isValueDependent() || DE->isTypeDependent()) { 2161 PrivateCopies.push_back(nullptr); 2162 continue; 2163 } 2164 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2165 auto *VD = cast<VarDecl>(DRE->getDecl()); 2166 QualType Type = VD->getType().getNonReferenceType(); 2167 const DSAStackTy::DSAVarData DVar = 2168 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2169 if (DVar.CKind == OMPC_lastprivate) { 2170 // Generate helper private variable and initialize it with the 2171 // default value. The address of the original variable is replaced 2172 // by the address of the new private variable in CodeGen. This new 2173 // variable is not added to IdResolver, so the code in the OpenMP 2174 // region uses original variable for proper diagnostics. 2175 VarDecl *VDPrivate = buildVarDecl( 2176 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2177 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2178 ActOnUninitializedDecl(VDPrivate); 2179 if (VDPrivate->isInvalidDecl()) { 2180 PrivateCopies.push_back(nullptr); 2181 continue; 2182 } 2183 PrivateCopies.push_back(buildDeclRefExpr( 2184 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2185 } else { 2186 // The variable is also a firstprivate, so initialization sequence 2187 // for private copy is generated already. 2188 PrivateCopies.push_back(nullptr); 2189 } 2190 } 2191 Clause->setPrivateCopies(PrivateCopies); 2192 } 2193 } 2194 // Check allocate clauses. 2195 if (!CurContext->isDependentContext()) 2196 checkAllocateClauses(*this, DSAStack, D->clauses()); 2197 } 2198 2199 DSAStack->pop(); 2200 DiscardCleanupsInEvaluationContext(); 2201 PopExpressionEvaluationContext(); 2202 } 2203 2204 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2205 Expr *NumIterations, Sema &SemaRef, 2206 Scope *S, DSAStackTy *Stack); 2207 2208 namespace { 2209 2210 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2211 private: 2212 Sema &SemaRef; 2213 2214 public: 2215 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2216 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2217 NamedDecl *ND = Candidate.getCorrectionDecl(); 2218 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2219 return VD->hasGlobalStorage() && 2220 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2221 SemaRef.getCurScope()); 2222 } 2223 return false; 2224 } 2225 2226 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2227 return std::make_unique<VarDeclFilterCCC>(*this); 2228 } 2229 2230 }; 2231 2232 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2233 private: 2234 Sema &SemaRef; 2235 2236 public: 2237 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2238 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2239 NamedDecl *ND = Candidate.getCorrectionDecl(); 2240 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2241 isa<FunctionDecl>(ND))) { 2242 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2243 SemaRef.getCurScope()); 2244 } 2245 return false; 2246 } 2247 2248 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2249 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2250 } 2251 }; 2252 2253 } // namespace 2254 2255 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2256 CXXScopeSpec &ScopeSpec, 2257 const DeclarationNameInfo &Id, 2258 OpenMPDirectiveKind Kind) { 2259 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2260 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2261 2262 if (Lookup.isAmbiguous()) 2263 return ExprError(); 2264 2265 VarDecl *VD; 2266 if (!Lookup.isSingleResult()) { 2267 VarDeclFilterCCC CCC(*this); 2268 if (TypoCorrection Corrected = 2269 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2270 CTK_ErrorRecovery)) { 2271 diagnoseTypo(Corrected, 2272 PDiag(Lookup.empty() 2273 ? diag::err_undeclared_var_use_suggest 2274 : diag::err_omp_expected_var_arg_suggest) 2275 << Id.getName()); 2276 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2277 } else { 2278 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2279 : diag::err_omp_expected_var_arg) 2280 << Id.getName(); 2281 return ExprError(); 2282 } 2283 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2284 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2285 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2286 return ExprError(); 2287 } 2288 Lookup.suppressDiagnostics(); 2289 2290 // OpenMP [2.9.2, Syntax, C/C++] 2291 // Variables must be file-scope, namespace-scope, or static block-scope. 2292 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2293 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2294 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2295 bool IsDecl = 2296 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2297 Diag(VD->getLocation(), 2298 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2299 << VD; 2300 return ExprError(); 2301 } 2302 2303 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2304 NamedDecl *ND = CanonicalVD; 2305 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2306 // A threadprivate directive for file-scope variables must appear outside 2307 // any definition or declaration. 2308 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2309 !getCurLexicalContext()->isTranslationUnit()) { 2310 Diag(Id.getLoc(), diag::err_omp_var_scope) 2311 << getOpenMPDirectiveName(Kind) << VD; 2312 bool IsDecl = 2313 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2314 Diag(VD->getLocation(), 2315 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2316 << VD; 2317 return ExprError(); 2318 } 2319 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2320 // A threadprivate directive for static class member variables must appear 2321 // in the class definition, in the same scope in which the member 2322 // variables are declared. 2323 if (CanonicalVD->isStaticDataMember() && 2324 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2325 Diag(Id.getLoc(), diag::err_omp_var_scope) 2326 << getOpenMPDirectiveName(Kind) << VD; 2327 bool IsDecl = 2328 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2329 Diag(VD->getLocation(), 2330 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2331 << VD; 2332 return ExprError(); 2333 } 2334 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2335 // A threadprivate directive for namespace-scope variables must appear 2336 // outside any definition or declaration other than the namespace 2337 // definition itself. 2338 if (CanonicalVD->getDeclContext()->isNamespace() && 2339 (!getCurLexicalContext()->isFileContext() || 2340 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2341 Diag(Id.getLoc(), diag::err_omp_var_scope) 2342 << getOpenMPDirectiveName(Kind) << VD; 2343 bool IsDecl = 2344 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2345 Diag(VD->getLocation(), 2346 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2347 << VD; 2348 return ExprError(); 2349 } 2350 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2351 // A threadprivate directive for static block-scope variables must appear 2352 // in the scope of the variable and not in a nested scope. 2353 if (CanonicalVD->isLocalVarDecl() && CurScope && 2354 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2355 Diag(Id.getLoc(), diag::err_omp_var_scope) 2356 << getOpenMPDirectiveName(Kind) << VD; 2357 bool IsDecl = 2358 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2359 Diag(VD->getLocation(), 2360 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2361 << VD; 2362 return ExprError(); 2363 } 2364 2365 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2366 // A threadprivate directive must lexically precede all references to any 2367 // of the variables in its list. 2368 if (Kind == OMPD_threadprivate && VD->isUsed() && 2369 !DSAStack->isThreadPrivate(VD)) { 2370 Diag(Id.getLoc(), diag::err_omp_var_used) 2371 << getOpenMPDirectiveName(Kind) << VD; 2372 return ExprError(); 2373 } 2374 2375 QualType ExprType = VD->getType().getNonReferenceType(); 2376 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2377 SourceLocation(), VD, 2378 /*RefersToEnclosingVariableOrCapture=*/false, 2379 Id.getLoc(), ExprType, VK_LValue); 2380 } 2381 2382 Sema::DeclGroupPtrTy 2383 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2384 ArrayRef<Expr *> VarList) { 2385 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2386 CurContext->addDecl(D); 2387 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2388 } 2389 return nullptr; 2390 } 2391 2392 namespace { 2393 class LocalVarRefChecker final 2394 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2395 Sema &SemaRef; 2396 2397 public: 2398 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2399 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2400 if (VD->hasLocalStorage()) { 2401 SemaRef.Diag(E->getBeginLoc(), 2402 diag::err_omp_local_var_in_threadprivate_init) 2403 << E->getSourceRange(); 2404 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2405 << VD << VD->getSourceRange(); 2406 return true; 2407 } 2408 } 2409 return false; 2410 } 2411 bool VisitStmt(const Stmt *S) { 2412 for (const Stmt *Child : S->children()) { 2413 if (Child && Visit(Child)) 2414 return true; 2415 } 2416 return false; 2417 } 2418 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2419 }; 2420 } // namespace 2421 2422 OMPThreadPrivateDecl * 2423 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2424 SmallVector<Expr *, 8> Vars; 2425 for (Expr *RefExpr : VarList) { 2426 auto *DE = cast<DeclRefExpr>(RefExpr); 2427 auto *VD = cast<VarDecl>(DE->getDecl()); 2428 SourceLocation ILoc = DE->getExprLoc(); 2429 2430 // Mark variable as used. 2431 VD->setReferenced(); 2432 VD->markUsed(Context); 2433 2434 QualType QType = VD->getType(); 2435 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2436 // It will be analyzed later. 2437 Vars.push_back(DE); 2438 continue; 2439 } 2440 2441 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2442 // A threadprivate variable must not have an incomplete type. 2443 if (RequireCompleteType(ILoc, VD->getType(), 2444 diag::err_omp_threadprivate_incomplete_type)) { 2445 continue; 2446 } 2447 2448 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2449 // A threadprivate variable must not have a reference type. 2450 if (VD->getType()->isReferenceType()) { 2451 Diag(ILoc, diag::err_omp_ref_type_arg) 2452 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2453 bool IsDecl = 2454 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2455 Diag(VD->getLocation(), 2456 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2457 << VD; 2458 continue; 2459 } 2460 2461 // Check if this is a TLS variable. If TLS is not being supported, produce 2462 // the corresponding diagnostic. 2463 if ((VD->getTLSKind() != VarDecl::TLS_None && 2464 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2465 getLangOpts().OpenMPUseTLS && 2466 getASTContext().getTargetInfo().isTLSSupported())) || 2467 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2468 !VD->isLocalVarDecl())) { 2469 Diag(ILoc, diag::err_omp_var_thread_local) 2470 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2471 bool IsDecl = 2472 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2473 Diag(VD->getLocation(), 2474 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2475 << VD; 2476 continue; 2477 } 2478 2479 // Check if initial value of threadprivate variable reference variable with 2480 // local storage (it is not supported by runtime). 2481 if (const Expr *Init = VD->getAnyInitializer()) { 2482 LocalVarRefChecker Checker(*this); 2483 if (Checker.Visit(Init)) 2484 continue; 2485 } 2486 2487 Vars.push_back(RefExpr); 2488 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2489 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2490 Context, SourceRange(Loc, Loc))); 2491 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2492 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2493 } 2494 OMPThreadPrivateDecl *D = nullptr; 2495 if (!Vars.empty()) { 2496 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2497 Vars); 2498 D->setAccess(AS_public); 2499 } 2500 return D; 2501 } 2502 2503 static OMPAllocateDeclAttr::AllocatorTypeTy 2504 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2505 if (!Allocator) 2506 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2507 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2508 Allocator->isInstantiationDependent() || 2509 Allocator->containsUnexpandedParameterPack()) 2510 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2511 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2512 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2513 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2514 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2515 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2516 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2517 llvm::FoldingSetNodeID AEId, DAEId; 2518 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2519 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2520 if (AEId == DAEId) { 2521 AllocatorKindRes = AllocatorKind; 2522 break; 2523 } 2524 } 2525 return AllocatorKindRes; 2526 } 2527 2528 static bool checkPreviousOMPAllocateAttribute( 2529 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2530 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2531 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2532 return false; 2533 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2534 Expr *PrevAllocator = A->getAllocator(); 2535 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2536 getAllocatorKind(S, Stack, PrevAllocator); 2537 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2538 if (AllocatorsMatch && 2539 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2540 Allocator && PrevAllocator) { 2541 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2542 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2543 llvm::FoldingSetNodeID AEId, PAEId; 2544 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2545 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2546 AllocatorsMatch = AEId == PAEId; 2547 } 2548 if (!AllocatorsMatch) { 2549 SmallString<256> AllocatorBuffer; 2550 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2551 if (Allocator) 2552 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2553 SmallString<256> PrevAllocatorBuffer; 2554 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2555 if (PrevAllocator) 2556 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2557 S.getPrintingPolicy()); 2558 2559 SourceLocation AllocatorLoc = 2560 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2561 SourceRange AllocatorRange = 2562 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2563 SourceLocation PrevAllocatorLoc = 2564 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2565 SourceRange PrevAllocatorRange = 2566 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2567 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2568 << (Allocator ? 1 : 0) << AllocatorStream.str() 2569 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2570 << AllocatorRange; 2571 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2572 << PrevAllocatorRange; 2573 return true; 2574 } 2575 return false; 2576 } 2577 2578 static void 2579 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2580 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2581 Expr *Allocator, SourceRange SR) { 2582 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2583 return; 2584 if (Allocator && 2585 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2586 Allocator->isInstantiationDependent() || 2587 Allocator->containsUnexpandedParameterPack())) 2588 return; 2589 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2590 Allocator, SR); 2591 VD->addAttr(A); 2592 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2593 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2594 } 2595 2596 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2597 SourceLocation Loc, ArrayRef<Expr *> VarList, 2598 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2599 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2600 Expr *Allocator = nullptr; 2601 if (Clauses.empty()) { 2602 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2603 // allocate directives that appear in a target region must specify an 2604 // allocator clause unless a requires directive with the dynamic_allocators 2605 // clause is present in the same compilation unit. 2606 if (LangOpts.OpenMPIsDevice && 2607 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2608 targetDiag(Loc, diag::err_expected_allocator_clause); 2609 } else { 2610 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2611 } 2612 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2613 getAllocatorKind(*this, DSAStack, Allocator); 2614 SmallVector<Expr *, 8> Vars; 2615 for (Expr *RefExpr : VarList) { 2616 auto *DE = cast<DeclRefExpr>(RefExpr); 2617 auto *VD = cast<VarDecl>(DE->getDecl()); 2618 2619 // Check if this is a TLS variable or global register. 2620 if (VD->getTLSKind() != VarDecl::TLS_None || 2621 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2622 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2623 !VD->isLocalVarDecl())) 2624 continue; 2625 2626 // If the used several times in the allocate directive, the same allocator 2627 // must be used. 2628 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2629 AllocatorKind, Allocator)) 2630 continue; 2631 2632 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2633 // If a list item has a static storage type, the allocator expression in the 2634 // allocator clause must be a constant expression that evaluates to one of 2635 // the predefined memory allocator values. 2636 if (Allocator && VD->hasGlobalStorage()) { 2637 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2638 Diag(Allocator->getExprLoc(), 2639 diag::err_omp_expected_predefined_allocator) 2640 << Allocator->getSourceRange(); 2641 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2642 VarDecl::DeclarationOnly; 2643 Diag(VD->getLocation(), 2644 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2645 << VD; 2646 continue; 2647 } 2648 } 2649 2650 Vars.push_back(RefExpr); 2651 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2652 DE->getSourceRange()); 2653 } 2654 if (Vars.empty()) 2655 return nullptr; 2656 if (!Owner) 2657 Owner = getCurLexicalContext(); 2658 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2659 D->setAccess(AS_public); 2660 Owner->addDecl(D); 2661 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2662 } 2663 2664 Sema::DeclGroupPtrTy 2665 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2666 ArrayRef<OMPClause *> ClauseList) { 2667 OMPRequiresDecl *D = nullptr; 2668 if (!CurContext->isFileContext()) { 2669 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2670 } else { 2671 D = CheckOMPRequiresDecl(Loc, ClauseList); 2672 if (D) { 2673 CurContext->addDecl(D); 2674 DSAStack->addRequiresDecl(D); 2675 } 2676 } 2677 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2678 } 2679 2680 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2681 ArrayRef<OMPClause *> ClauseList) { 2682 /// For target specific clauses, the requires directive cannot be 2683 /// specified after the handling of any of the target regions in the 2684 /// current compilation unit. 2685 ArrayRef<SourceLocation> TargetLocations = 2686 DSAStack->getEncounteredTargetLocs(); 2687 if (!TargetLocations.empty()) { 2688 for (const OMPClause *CNew : ClauseList) { 2689 // Check if any of the requires clauses affect target regions. 2690 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2691 isa<OMPUnifiedAddressClause>(CNew) || 2692 isa<OMPReverseOffloadClause>(CNew) || 2693 isa<OMPDynamicAllocatorsClause>(CNew)) { 2694 Diag(Loc, diag::err_omp_target_before_requires) 2695 << getOpenMPClauseName(CNew->getClauseKind()); 2696 for (SourceLocation TargetLoc : TargetLocations) { 2697 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2698 } 2699 } 2700 } 2701 } 2702 2703 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2704 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2705 ClauseList); 2706 return nullptr; 2707 } 2708 2709 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2710 const ValueDecl *D, 2711 const DSAStackTy::DSAVarData &DVar, 2712 bool IsLoopIterVar = false) { 2713 if (DVar.RefExpr) { 2714 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2715 << getOpenMPClauseName(DVar.CKind); 2716 return; 2717 } 2718 enum { 2719 PDSA_StaticMemberShared, 2720 PDSA_StaticLocalVarShared, 2721 PDSA_LoopIterVarPrivate, 2722 PDSA_LoopIterVarLinear, 2723 PDSA_LoopIterVarLastprivate, 2724 PDSA_ConstVarShared, 2725 PDSA_GlobalVarShared, 2726 PDSA_TaskVarFirstprivate, 2727 PDSA_LocalVarPrivate, 2728 PDSA_Implicit 2729 } Reason = PDSA_Implicit; 2730 bool ReportHint = false; 2731 auto ReportLoc = D->getLocation(); 2732 auto *VD = dyn_cast<VarDecl>(D); 2733 if (IsLoopIterVar) { 2734 if (DVar.CKind == OMPC_private) 2735 Reason = PDSA_LoopIterVarPrivate; 2736 else if (DVar.CKind == OMPC_lastprivate) 2737 Reason = PDSA_LoopIterVarLastprivate; 2738 else 2739 Reason = PDSA_LoopIterVarLinear; 2740 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2741 DVar.CKind == OMPC_firstprivate) { 2742 Reason = PDSA_TaskVarFirstprivate; 2743 ReportLoc = DVar.ImplicitDSALoc; 2744 } else if (VD && VD->isStaticLocal()) 2745 Reason = PDSA_StaticLocalVarShared; 2746 else if (VD && VD->isStaticDataMember()) 2747 Reason = PDSA_StaticMemberShared; 2748 else if (VD && VD->isFileVarDecl()) 2749 Reason = PDSA_GlobalVarShared; 2750 else if (D->getType().isConstant(SemaRef.getASTContext())) 2751 Reason = PDSA_ConstVarShared; 2752 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2753 ReportHint = true; 2754 Reason = PDSA_LocalVarPrivate; 2755 } 2756 if (Reason != PDSA_Implicit) { 2757 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2758 << Reason << ReportHint 2759 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2760 } else if (DVar.ImplicitDSALoc.isValid()) { 2761 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2762 << getOpenMPClauseName(DVar.CKind); 2763 } 2764 } 2765 2766 namespace { 2767 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2768 DSAStackTy *Stack; 2769 Sema &SemaRef; 2770 bool ErrorFound = false; 2771 bool TryCaptureCXXThisMembers = false; 2772 CapturedStmt *CS = nullptr; 2773 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2774 llvm::SmallVector<Expr *, 4> ImplicitMap; 2775 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2776 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2777 2778 void VisitSubCaptures(OMPExecutableDirective *S) { 2779 // Check implicitly captured variables. 2780 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2781 return; 2782 visitSubCaptures(S->getInnermostCapturedStmt()); 2783 // Try to capture inner this->member references to generate correct mappings 2784 // and diagnostics. 2785 if (TryCaptureCXXThisMembers || 2786 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2787 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2788 [](const CapturedStmt::Capture &C) { 2789 return C.capturesThis(); 2790 }))) { 2791 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2792 TryCaptureCXXThisMembers = true; 2793 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2794 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2795 } 2796 } 2797 2798 public: 2799 void VisitDeclRefExpr(DeclRefExpr *E) { 2800 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 2801 E->isValueDependent() || E->containsUnexpandedParameterPack() || 2802 E->isInstantiationDependent()) 2803 return; 2804 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2805 // Check the datasharing rules for the expressions in the clauses. 2806 if (!CS) { 2807 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2808 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2809 Visit(CED->getInit()); 2810 return; 2811 } 2812 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2813 // Do not analyze internal variables and do not enclose them into 2814 // implicit clauses. 2815 return; 2816 VD = VD->getCanonicalDecl(); 2817 // Skip internally declared variables. 2818 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2819 return; 2820 2821 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2822 // Check if the variable has explicit DSA set and stop analysis if it so. 2823 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2824 return; 2825 2826 // Skip internally declared static variables. 2827 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2828 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2829 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2830 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2831 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2832 return; 2833 2834 SourceLocation ELoc = E->getExprLoc(); 2835 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2836 // The default(none) clause requires that each variable that is referenced 2837 // in the construct, and does not have a predetermined data-sharing 2838 // attribute, must have its data-sharing attribute explicitly determined 2839 // by being listed in a data-sharing attribute clause. 2840 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2841 isImplicitOrExplicitTaskingRegion(DKind) && 2842 VarsWithInheritedDSA.count(VD) == 0) { 2843 VarsWithInheritedDSA[VD] = E; 2844 return; 2845 } 2846 2847 if (isOpenMPTargetExecutionDirective(DKind) && 2848 !Stack->isLoopControlVariable(VD).first) { 2849 if (!Stack->checkMappableExprComponentListsForDecl( 2850 VD, /*CurrentRegionOnly=*/true, 2851 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2852 StackComponents, 2853 OpenMPClauseKind) { 2854 // Variable is used if it has been marked as an array, array 2855 // section or the variable iself. 2856 return StackComponents.size() == 1 || 2857 std::all_of( 2858 std::next(StackComponents.rbegin()), 2859 StackComponents.rend(), 2860 [](const OMPClauseMappableExprCommon:: 2861 MappableComponent &MC) { 2862 return MC.getAssociatedDeclaration() == 2863 nullptr && 2864 (isa<OMPArraySectionExpr>( 2865 MC.getAssociatedExpression()) || 2866 isa<ArraySubscriptExpr>( 2867 MC.getAssociatedExpression())); 2868 }); 2869 })) { 2870 bool IsFirstprivate = false; 2871 // By default lambdas are captured as firstprivates. 2872 if (const auto *RD = 2873 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2874 IsFirstprivate = RD->isLambda(); 2875 IsFirstprivate = 2876 IsFirstprivate || 2877 (VD->getType().getNonReferenceType()->isScalarType() && 2878 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2879 if (IsFirstprivate) 2880 ImplicitFirstprivate.emplace_back(E); 2881 else 2882 ImplicitMap.emplace_back(E); 2883 return; 2884 } 2885 } 2886 2887 // OpenMP [2.9.3.6, Restrictions, p.2] 2888 // A list item that appears in a reduction clause of the innermost 2889 // enclosing worksharing or parallel construct may not be accessed in an 2890 // explicit task. 2891 DVar = Stack->hasInnermostDSA( 2892 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2893 [](OpenMPDirectiveKind K) { 2894 return isOpenMPParallelDirective(K) || 2895 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2896 }, 2897 /*FromParent=*/true); 2898 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2899 ErrorFound = true; 2900 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2901 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2902 return; 2903 } 2904 2905 // Define implicit data-sharing attributes for task. 2906 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2907 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2908 !Stack->isLoopControlVariable(VD).first) { 2909 ImplicitFirstprivate.push_back(E); 2910 return; 2911 } 2912 2913 // Store implicitly used globals with declare target link for parent 2914 // target. 2915 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2916 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2917 Stack->addToParentTargetRegionLinkGlobals(E); 2918 return; 2919 } 2920 } 2921 } 2922 void VisitMemberExpr(MemberExpr *E) { 2923 if (E->isTypeDependent() || E->isValueDependent() || 2924 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2925 return; 2926 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2927 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2928 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2929 if (!FD) 2930 return; 2931 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2932 // Check if the variable has explicit DSA set and stop analysis if it 2933 // so. 2934 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2935 return; 2936 2937 if (isOpenMPTargetExecutionDirective(DKind) && 2938 !Stack->isLoopControlVariable(FD).first && 2939 !Stack->checkMappableExprComponentListsForDecl( 2940 FD, /*CurrentRegionOnly=*/true, 2941 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2942 StackComponents, 2943 OpenMPClauseKind) { 2944 return isa<CXXThisExpr>( 2945 cast<MemberExpr>( 2946 StackComponents.back().getAssociatedExpression()) 2947 ->getBase() 2948 ->IgnoreParens()); 2949 })) { 2950 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2951 // A bit-field cannot appear in a map clause. 2952 // 2953 if (FD->isBitField()) 2954 return; 2955 2956 // Check to see if the member expression is referencing a class that 2957 // has already been explicitly mapped 2958 if (Stack->isClassPreviouslyMapped(TE->getType())) 2959 return; 2960 2961 ImplicitMap.emplace_back(E); 2962 return; 2963 } 2964 2965 SourceLocation ELoc = E->getExprLoc(); 2966 // OpenMP [2.9.3.6, Restrictions, p.2] 2967 // A list item that appears in a reduction clause of the innermost 2968 // enclosing worksharing or parallel construct may not be accessed in 2969 // an explicit task. 2970 DVar = Stack->hasInnermostDSA( 2971 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2972 [](OpenMPDirectiveKind K) { 2973 return isOpenMPParallelDirective(K) || 2974 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2975 }, 2976 /*FromParent=*/true); 2977 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2978 ErrorFound = true; 2979 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2980 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2981 return; 2982 } 2983 2984 // Define implicit data-sharing attributes for task. 2985 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2986 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2987 !Stack->isLoopControlVariable(FD).first) { 2988 // Check if there is a captured expression for the current field in the 2989 // region. Do not mark it as firstprivate unless there is no captured 2990 // expression. 2991 // TODO: try to make it firstprivate. 2992 if (DVar.CKind != OMPC_unknown) 2993 ImplicitFirstprivate.push_back(E); 2994 } 2995 return; 2996 } 2997 if (isOpenMPTargetExecutionDirective(DKind)) { 2998 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2999 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3000 /*NoDiagnose=*/true)) 3001 return; 3002 const auto *VD = cast<ValueDecl>( 3003 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3004 if (!Stack->checkMappableExprComponentListsForDecl( 3005 VD, /*CurrentRegionOnly=*/true, 3006 [&CurComponents]( 3007 OMPClauseMappableExprCommon::MappableExprComponentListRef 3008 StackComponents, 3009 OpenMPClauseKind) { 3010 auto CCI = CurComponents.rbegin(); 3011 auto CCE = CurComponents.rend(); 3012 for (const auto &SC : llvm::reverse(StackComponents)) { 3013 // Do both expressions have the same kind? 3014 if (CCI->getAssociatedExpression()->getStmtClass() != 3015 SC.getAssociatedExpression()->getStmtClass()) 3016 if (!(isa<OMPArraySectionExpr>( 3017 SC.getAssociatedExpression()) && 3018 isa<ArraySubscriptExpr>( 3019 CCI->getAssociatedExpression()))) 3020 return false; 3021 3022 const Decl *CCD = CCI->getAssociatedDeclaration(); 3023 const Decl *SCD = SC.getAssociatedDeclaration(); 3024 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3025 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3026 if (SCD != CCD) 3027 return false; 3028 std::advance(CCI, 1); 3029 if (CCI == CCE) 3030 break; 3031 } 3032 return true; 3033 })) { 3034 Visit(E->getBase()); 3035 } 3036 } else if (!TryCaptureCXXThisMembers) { 3037 Visit(E->getBase()); 3038 } 3039 } 3040 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3041 for (OMPClause *C : S->clauses()) { 3042 // Skip analysis of arguments of implicitly defined firstprivate clause 3043 // for task|target directives. 3044 // Skip analysis of arguments of implicitly defined map clause for target 3045 // directives. 3046 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3047 C->isImplicit())) { 3048 for (Stmt *CC : C->children()) { 3049 if (CC) 3050 Visit(CC); 3051 } 3052 } 3053 } 3054 // Check implicitly captured variables. 3055 VisitSubCaptures(S); 3056 } 3057 void VisitStmt(Stmt *S) { 3058 for (Stmt *C : S->children()) { 3059 if (C) { 3060 // Check implicitly captured variables in the task-based directives to 3061 // check if they must be firstprivatized. 3062 Visit(C); 3063 } 3064 } 3065 } 3066 3067 void visitSubCaptures(CapturedStmt *S) { 3068 for (const CapturedStmt::Capture &Cap : S->captures()) { 3069 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3070 continue; 3071 VarDecl *VD = Cap.getCapturedVar(); 3072 // Do not try to map the variable if it or its sub-component was mapped 3073 // already. 3074 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3075 Stack->checkMappableExprComponentListsForDecl( 3076 VD, /*CurrentRegionOnly=*/true, 3077 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3078 OpenMPClauseKind) { return true; })) 3079 continue; 3080 DeclRefExpr *DRE = buildDeclRefExpr( 3081 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3082 Cap.getLocation(), /*RefersToCapture=*/true); 3083 Visit(DRE); 3084 } 3085 } 3086 bool isErrorFound() const { return ErrorFound; } 3087 ArrayRef<Expr *> getImplicitFirstprivate() const { 3088 return ImplicitFirstprivate; 3089 } 3090 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 3091 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3092 return VarsWithInheritedDSA; 3093 } 3094 3095 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3096 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3097 // Process declare target link variables for the target directives. 3098 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3099 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3100 Visit(E); 3101 } 3102 } 3103 }; 3104 } // namespace 3105 3106 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3107 switch (DKind) { 3108 case OMPD_parallel: 3109 case OMPD_parallel_for: 3110 case OMPD_parallel_for_simd: 3111 case OMPD_parallel_sections: 3112 case OMPD_teams: 3113 case OMPD_teams_distribute: 3114 case OMPD_teams_distribute_simd: { 3115 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3116 QualType KmpInt32PtrTy = 3117 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3118 Sema::CapturedParamNameType Params[] = { 3119 std::make_pair(".global_tid.", KmpInt32PtrTy), 3120 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3121 std::make_pair(StringRef(), QualType()) // __context with shared vars 3122 }; 3123 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3124 Params); 3125 break; 3126 } 3127 case OMPD_target_teams: 3128 case OMPD_target_parallel: 3129 case OMPD_target_parallel_for: 3130 case OMPD_target_parallel_for_simd: 3131 case OMPD_target_teams_distribute: 3132 case OMPD_target_teams_distribute_simd: { 3133 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3134 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3135 QualType KmpInt32PtrTy = 3136 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3137 QualType Args[] = {VoidPtrTy}; 3138 FunctionProtoType::ExtProtoInfo EPI; 3139 EPI.Variadic = true; 3140 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3141 Sema::CapturedParamNameType Params[] = { 3142 std::make_pair(".global_tid.", KmpInt32Ty), 3143 std::make_pair(".part_id.", KmpInt32PtrTy), 3144 std::make_pair(".privates.", VoidPtrTy), 3145 std::make_pair( 3146 ".copy_fn.", 3147 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3148 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3149 std::make_pair(StringRef(), QualType()) // __context with shared vars 3150 }; 3151 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3152 Params, /*OpenMPCaptureLevel=*/0); 3153 // Mark this captured region as inlined, because we don't use outlined 3154 // function directly. 3155 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3156 AlwaysInlineAttr::CreateImplicit( 3157 Context, {}, AttributeCommonInfo::AS_Keyword, 3158 AlwaysInlineAttr::Keyword_forceinline)); 3159 Sema::CapturedParamNameType ParamsTarget[] = { 3160 std::make_pair(StringRef(), QualType()) // __context with shared vars 3161 }; 3162 // Start a captured region for 'target' with no implicit parameters. 3163 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3164 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3165 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3166 std::make_pair(".global_tid.", KmpInt32PtrTy), 3167 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3168 std::make_pair(StringRef(), QualType()) // __context with shared vars 3169 }; 3170 // Start a captured region for 'teams' or 'parallel'. Both regions have 3171 // the same implicit parameters. 3172 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3173 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3174 break; 3175 } 3176 case OMPD_target: 3177 case OMPD_target_simd: { 3178 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3179 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3180 QualType KmpInt32PtrTy = 3181 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3182 QualType Args[] = {VoidPtrTy}; 3183 FunctionProtoType::ExtProtoInfo EPI; 3184 EPI.Variadic = true; 3185 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3186 Sema::CapturedParamNameType Params[] = { 3187 std::make_pair(".global_tid.", KmpInt32Ty), 3188 std::make_pair(".part_id.", KmpInt32PtrTy), 3189 std::make_pair(".privates.", VoidPtrTy), 3190 std::make_pair( 3191 ".copy_fn.", 3192 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3193 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3194 std::make_pair(StringRef(), QualType()) // __context with shared vars 3195 }; 3196 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3197 Params, /*OpenMPCaptureLevel=*/0); 3198 // Mark this captured region as inlined, because we don't use outlined 3199 // function directly. 3200 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3201 AlwaysInlineAttr::CreateImplicit( 3202 Context, {}, AttributeCommonInfo::AS_Keyword, 3203 AlwaysInlineAttr::Keyword_forceinline)); 3204 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3205 std::make_pair(StringRef(), QualType()), 3206 /*OpenMPCaptureLevel=*/1); 3207 break; 3208 } 3209 case OMPD_simd: 3210 case OMPD_for: 3211 case OMPD_for_simd: 3212 case OMPD_sections: 3213 case OMPD_section: 3214 case OMPD_single: 3215 case OMPD_master: 3216 case OMPD_critical: 3217 case OMPD_taskgroup: 3218 case OMPD_distribute: 3219 case OMPD_distribute_simd: 3220 case OMPD_ordered: 3221 case OMPD_atomic: 3222 case OMPD_target_data: { 3223 Sema::CapturedParamNameType Params[] = { 3224 std::make_pair(StringRef(), QualType()) // __context with shared vars 3225 }; 3226 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3227 Params); 3228 break; 3229 } 3230 case OMPD_task: { 3231 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3232 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3233 QualType KmpInt32PtrTy = 3234 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3235 QualType Args[] = {VoidPtrTy}; 3236 FunctionProtoType::ExtProtoInfo EPI; 3237 EPI.Variadic = true; 3238 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3239 Sema::CapturedParamNameType Params[] = { 3240 std::make_pair(".global_tid.", KmpInt32Ty), 3241 std::make_pair(".part_id.", KmpInt32PtrTy), 3242 std::make_pair(".privates.", VoidPtrTy), 3243 std::make_pair( 3244 ".copy_fn.", 3245 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3246 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3247 std::make_pair(StringRef(), QualType()) // __context with shared vars 3248 }; 3249 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3250 Params); 3251 // Mark this captured region as inlined, because we don't use outlined 3252 // function directly. 3253 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3254 AlwaysInlineAttr::CreateImplicit( 3255 Context, {}, AttributeCommonInfo::AS_Keyword, 3256 AlwaysInlineAttr::Keyword_forceinline)); 3257 break; 3258 } 3259 case OMPD_taskloop: 3260 case OMPD_taskloop_simd: 3261 case OMPD_master_taskloop: 3262 case OMPD_master_taskloop_simd: { 3263 QualType KmpInt32Ty = 3264 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3265 .withConst(); 3266 QualType KmpUInt64Ty = 3267 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3268 .withConst(); 3269 QualType KmpInt64Ty = 3270 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3271 .withConst(); 3272 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3273 QualType KmpInt32PtrTy = 3274 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3275 QualType Args[] = {VoidPtrTy}; 3276 FunctionProtoType::ExtProtoInfo EPI; 3277 EPI.Variadic = true; 3278 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3279 Sema::CapturedParamNameType Params[] = { 3280 std::make_pair(".global_tid.", KmpInt32Ty), 3281 std::make_pair(".part_id.", KmpInt32PtrTy), 3282 std::make_pair(".privates.", VoidPtrTy), 3283 std::make_pair( 3284 ".copy_fn.", 3285 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3286 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3287 std::make_pair(".lb.", KmpUInt64Ty), 3288 std::make_pair(".ub.", KmpUInt64Ty), 3289 std::make_pair(".st.", KmpInt64Ty), 3290 std::make_pair(".liter.", KmpInt32Ty), 3291 std::make_pair(".reductions.", VoidPtrTy), 3292 std::make_pair(StringRef(), QualType()) // __context with shared vars 3293 }; 3294 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3295 Params); 3296 // Mark this captured region as inlined, because we don't use outlined 3297 // function directly. 3298 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3299 AlwaysInlineAttr::CreateImplicit( 3300 Context, {}, AttributeCommonInfo::AS_Keyword, 3301 AlwaysInlineAttr::Keyword_forceinline)); 3302 break; 3303 } 3304 case OMPD_parallel_master_taskloop: 3305 case OMPD_parallel_master_taskloop_simd: { 3306 QualType KmpInt32Ty = 3307 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3308 .withConst(); 3309 QualType KmpUInt64Ty = 3310 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3311 .withConst(); 3312 QualType KmpInt64Ty = 3313 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3314 .withConst(); 3315 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3316 QualType KmpInt32PtrTy = 3317 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3318 Sema::CapturedParamNameType ParamsParallel[] = { 3319 std::make_pair(".global_tid.", KmpInt32PtrTy), 3320 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3321 std::make_pair(StringRef(), QualType()) // __context with shared vars 3322 }; 3323 // Start a captured region for 'parallel'. 3324 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3325 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3326 QualType Args[] = {VoidPtrTy}; 3327 FunctionProtoType::ExtProtoInfo EPI; 3328 EPI.Variadic = true; 3329 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3330 Sema::CapturedParamNameType Params[] = { 3331 std::make_pair(".global_tid.", KmpInt32Ty), 3332 std::make_pair(".part_id.", KmpInt32PtrTy), 3333 std::make_pair(".privates.", VoidPtrTy), 3334 std::make_pair( 3335 ".copy_fn.", 3336 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3337 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3338 std::make_pair(".lb.", KmpUInt64Ty), 3339 std::make_pair(".ub.", KmpUInt64Ty), 3340 std::make_pair(".st.", KmpInt64Ty), 3341 std::make_pair(".liter.", KmpInt32Ty), 3342 std::make_pair(".reductions.", VoidPtrTy), 3343 std::make_pair(StringRef(), QualType()) // __context with shared vars 3344 }; 3345 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3346 Params, /*OpenMPCaptureLevel=*/2); 3347 // Mark this captured region as inlined, because we don't use outlined 3348 // function directly. 3349 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3350 AlwaysInlineAttr::CreateImplicit( 3351 Context, {}, AttributeCommonInfo::AS_Keyword, 3352 AlwaysInlineAttr::Keyword_forceinline)); 3353 break; 3354 } 3355 case OMPD_distribute_parallel_for_simd: 3356 case OMPD_distribute_parallel_for: { 3357 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3358 QualType KmpInt32PtrTy = 3359 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3360 Sema::CapturedParamNameType Params[] = { 3361 std::make_pair(".global_tid.", KmpInt32PtrTy), 3362 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3363 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3364 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3365 std::make_pair(StringRef(), QualType()) // __context with shared vars 3366 }; 3367 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3368 Params); 3369 break; 3370 } 3371 case OMPD_target_teams_distribute_parallel_for: 3372 case OMPD_target_teams_distribute_parallel_for_simd: { 3373 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3374 QualType KmpInt32PtrTy = 3375 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3376 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3377 3378 QualType Args[] = {VoidPtrTy}; 3379 FunctionProtoType::ExtProtoInfo EPI; 3380 EPI.Variadic = true; 3381 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3382 Sema::CapturedParamNameType Params[] = { 3383 std::make_pair(".global_tid.", KmpInt32Ty), 3384 std::make_pair(".part_id.", KmpInt32PtrTy), 3385 std::make_pair(".privates.", VoidPtrTy), 3386 std::make_pair( 3387 ".copy_fn.", 3388 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3389 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3390 std::make_pair(StringRef(), QualType()) // __context with shared vars 3391 }; 3392 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3393 Params, /*OpenMPCaptureLevel=*/0); 3394 // Mark this captured region as inlined, because we don't use outlined 3395 // function directly. 3396 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3397 AlwaysInlineAttr::CreateImplicit( 3398 Context, {}, AttributeCommonInfo::AS_Keyword, 3399 AlwaysInlineAttr::Keyword_forceinline)); 3400 Sema::CapturedParamNameType ParamsTarget[] = { 3401 std::make_pair(StringRef(), QualType()) // __context with shared vars 3402 }; 3403 // Start a captured region for 'target' with no implicit parameters. 3404 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3405 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3406 3407 Sema::CapturedParamNameType ParamsTeams[] = { 3408 std::make_pair(".global_tid.", KmpInt32PtrTy), 3409 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3410 std::make_pair(StringRef(), QualType()) // __context with shared vars 3411 }; 3412 // Start a captured region for 'target' with no implicit parameters. 3413 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3414 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3415 3416 Sema::CapturedParamNameType ParamsParallel[] = { 3417 std::make_pair(".global_tid.", KmpInt32PtrTy), 3418 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3419 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3420 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3421 std::make_pair(StringRef(), QualType()) // __context with shared vars 3422 }; 3423 // Start a captured region for 'teams' or 'parallel'. Both regions have 3424 // the same implicit parameters. 3425 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3426 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3427 break; 3428 } 3429 3430 case OMPD_teams_distribute_parallel_for: 3431 case OMPD_teams_distribute_parallel_for_simd: { 3432 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3433 QualType KmpInt32PtrTy = 3434 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3435 3436 Sema::CapturedParamNameType ParamsTeams[] = { 3437 std::make_pair(".global_tid.", KmpInt32PtrTy), 3438 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3439 std::make_pair(StringRef(), QualType()) // __context with shared vars 3440 }; 3441 // Start a captured region for 'target' with no implicit parameters. 3442 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3443 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3444 3445 Sema::CapturedParamNameType ParamsParallel[] = { 3446 std::make_pair(".global_tid.", KmpInt32PtrTy), 3447 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3448 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3449 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3450 std::make_pair(StringRef(), QualType()) // __context with shared vars 3451 }; 3452 // Start a captured region for 'teams' or 'parallel'. Both regions have 3453 // the same implicit parameters. 3454 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3455 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3456 break; 3457 } 3458 case OMPD_target_update: 3459 case OMPD_target_enter_data: 3460 case OMPD_target_exit_data: { 3461 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3462 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3463 QualType KmpInt32PtrTy = 3464 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3465 QualType Args[] = {VoidPtrTy}; 3466 FunctionProtoType::ExtProtoInfo EPI; 3467 EPI.Variadic = true; 3468 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3469 Sema::CapturedParamNameType Params[] = { 3470 std::make_pair(".global_tid.", KmpInt32Ty), 3471 std::make_pair(".part_id.", KmpInt32PtrTy), 3472 std::make_pair(".privates.", VoidPtrTy), 3473 std::make_pair( 3474 ".copy_fn.", 3475 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3476 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3477 std::make_pair(StringRef(), QualType()) // __context with shared vars 3478 }; 3479 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3480 Params); 3481 // Mark this captured region as inlined, because we don't use outlined 3482 // function directly. 3483 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3484 AlwaysInlineAttr::CreateImplicit( 3485 Context, {}, AttributeCommonInfo::AS_Keyword, 3486 AlwaysInlineAttr::Keyword_forceinline)); 3487 break; 3488 } 3489 case OMPD_threadprivate: 3490 case OMPD_allocate: 3491 case OMPD_taskyield: 3492 case OMPD_barrier: 3493 case OMPD_taskwait: 3494 case OMPD_cancellation_point: 3495 case OMPD_cancel: 3496 case OMPD_flush: 3497 case OMPD_declare_reduction: 3498 case OMPD_declare_mapper: 3499 case OMPD_declare_simd: 3500 case OMPD_declare_target: 3501 case OMPD_end_declare_target: 3502 case OMPD_requires: 3503 case OMPD_declare_variant: 3504 llvm_unreachable("OpenMP Directive is not allowed"); 3505 case OMPD_unknown: 3506 llvm_unreachable("Unknown OpenMP directive"); 3507 } 3508 } 3509 3510 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3511 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3512 } 3513 3514 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3515 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3516 getOpenMPCaptureRegions(CaptureRegions, DKind); 3517 return CaptureRegions.size(); 3518 } 3519 3520 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3521 Expr *CaptureExpr, bool WithInit, 3522 bool AsExpression) { 3523 assert(CaptureExpr); 3524 ASTContext &C = S.getASTContext(); 3525 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3526 QualType Ty = Init->getType(); 3527 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3528 if (S.getLangOpts().CPlusPlus) { 3529 Ty = C.getLValueReferenceType(Ty); 3530 } else { 3531 Ty = C.getPointerType(Ty); 3532 ExprResult Res = 3533 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3534 if (!Res.isUsable()) 3535 return nullptr; 3536 Init = Res.get(); 3537 } 3538 WithInit = true; 3539 } 3540 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3541 CaptureExpr->getBeginLoc()); 3542 if (!WithInit) 3543 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3544 S.CurContext->addHiddenDecl(CED); 3545 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3546 return CED; 3547 } 3548 3549 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3550 bool WithInit) { 3551 OMPCapturedExprDecl *CD; 3552 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3553 CD = cast<OMPCapturedExprDecl>(VD); 3554 else 3555 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3556 /*AsExpression=*/false); 3557 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3558 CaptureExpr->getExprLoc()); 3559 } 3560 3561 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3562 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3563 if (!Ref) { 3564 OMPCapturedExprDecl *CD = buildCaptureDecl( 3565 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3566 /*WithInit=*/true, /*AsExpression=*/true); 3567 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3568 CaptureExpr->getExprLoc()); 3569 } 3570 ExprResult Res = Ref; 3571 if (!S.getLangOpts().CPlusPlus && 3572 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3573 Ref->getType()->isPointerType()) { 3574 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3575 if (!Res.isUsable()) 3576 return ExprError(); 3577 } 3578 return S.DefaultLvalueConversion(Res.get()); 3579 } 3580 3581 namespace { 3582 // OpenMP directives parsed in this section are represented as a 3583 // CapturedStatement with an associated statement. If a syntax error 3584 // is detected during the parsing of the associated statement, the 3585 // compiler must abort processing and close the CapturedStatement. 3586 // 3587 // Combined directives such as 'target parallel' have more than one 3588 // nested CapturedStatements. This RAII ensures that we unwind out 3589 // of all the nested CapturedStatements when an error is found. 3590 class CaptureRegionUnwinderRAII { 3591 private: 3592 Sema &S; 3593 bool &ErrorFound; 3594 OpenMPDirectiveKind DKind = OMPD_unknown; 3595 3596 public: 3597 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3598 OpenMPDirectiveKind DKind) 3599 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3600 ~CaptureRegionUnwinderRAII() { 3601 if (ErrorFound) { 3602 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3603 while (--ThisCaptureLevel >= 0) 3604 S.ActOnCapturedRegionError(); 3605 } 3606 } 3607 }; 3608 } // namespace 3609 3610 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3611 // Capture variables captured by reference in lambdas for target-based 3612 // directives. 3613 if (!CurContext->isDependentContext() && 3614 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3615 isOpenMPTargetDataManagementDirective( 3616 DSAStack->getCurrentDirective()))) { 3617 QualType Type = V->getType(); 3618 if (const auto *RD = Type.getCanonicalType() 3619 .getNonReferenceType() 3620 ->getAsCXXRecordDecl()) { 3621 bool SavedForceCaptureByReferenceInTargetExecutable = 3622 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3623 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3624 /*V=*/true); 3625 if (RD->isLambda()) { 3626 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3627 FieldDecl *ThisCapture; 3628 RD->getCaptureFields(Captures, ThisCapture); 3629 for (const LambdaCapture &LC : RD->captures()) { 3630 if (LC.getCaptureKind() == LCK_ByRef) { 3631 VarDecl *VD = LC.getCapturedVar(); 3632 DeclContext *VDC = VD->getDeclContext(); 3633 if (!VDC->Encloses(CurContext)) 3634 continue; 3635 MarkVariableReferenced(LC.getLocation(), VD); 3636 } else if (LC.getCaptureKind() == LCK_This) { 3637 QualType ThisTy = getCurrentThisType(); 3638 if (!ThisTy.isNull() && 3639 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3640 CheckCXXThisCapture(LC.getLocation()); 3641 } 3642 } 3643 } 3644 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3645 SavedForceCaptureByReferenceInTargetExecutable); 3646 } 3647 } 3648 } 3649 3650 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3651 ArrayRef<OMPClause *> Clauses) { 3652 bool ErrorFound = false; 3653 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3654 *this, ErrorFound, DSAStack->getCurrentDirective()); 3655 if (!S.isUsable()) { 3656 ErrorFound = true; 3657 return StmtError(); 3658 } 3659 3660 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3661 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3662 OMPOrderedClause *OC = nullptr; 3663 OMPScheduleClause *SC = nullptr; 3664 SmallVector<const OMPLinearClause *, 4> LCs; 3665 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3666 // This is required for proper codegen. 3667 for (OMPClause *Clause : Clauses) { 3668 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3669 Clause->getClauseKind() == OMPC_in_reduction) { 3670 // Capture taskgroup task_reduction descriptors inside the tasking regions 3671 // with the corresponding in_reduction items. 3672 auto *IRC = cast<OMPInReductionClause>(Clause); 3673 for (Expr *E : IRC->taskgroup_descriptors()) 3674 if (E) 3675 MarkDeclarationsReferencedInExpr(E); 3676 } 3677 if (isOpenMPPrivate(Clause->getClauseKind()) || 3678 Clause->getClauseKind() == OMPC_copyprivate || 3679 (getLangOpts().OpenMPUseTLS && 3680 getASTContext().getTargetInfo().isTLSSupported() && 3681 Clause->getClauseKind() == OMPC_copyin)) { 3682 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3683 // Mark all variables in private list clauses as used in inner region. 3684 for (Stmt *VarRef : Clause->children()) { 3685 if (auto *E = cast_or_null<Expr>(VarRef)) { 3686 MarkDeclarationsReferencedInExpr(E); 3687 } 3688 } 3689 DSAStack->setForceVarCapturing(/*V=*/false); 3690 } else if (CaptureRegions.size() > 1 || 3691 CaptureRegions.back() != OMPD_unknown) { 3692 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3693 PICs.push_back(C); 3694 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3695 if (Expr *E = C->getPostUpdateExpr()) 3696 MarkDeclarationsReferencedInExpr(E); 3697 } 3698 } 3699 if (Clause->getClauseKind() == OMPC_schedule) 3700 SC = cast<OMPScheduleClause>(Clause); 3701 else if (Clause->getClauseKind() == OMPC_ordered) 3702 OC = cast<OMPOrderedClause>(Clause); 3703 else if (Clause->getClauseKind() == OMPC_linear) 3704 LCs.push_back(cast<OMPLinearClause>(Clause)); 3705 } 3706 // OpenMP, 2.7.1 Loop Construct, Restrictions 3707 // The nonmonotonic modifier cannot be specified if an ordered clause is 3708 // specified. 3709 if (SC && 3710 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3711 SC->getSecondScheduleModifier() == 3712 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3713 OC) { 3714 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3715 ? SC->getFirstScheduleModifierLoc() 3716 : SC->getSecondScheduleModifierLoc(), 3717 diag::err_omp_schedule_nonmonotonic_ordered) 3718 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3719 ErrorFound = true; 3720 } 3721 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3722 for (const OMPLinearClause *C : LCs) { 3723 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3724 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3725 } 3726 ErrorFound = true; 3727 } 3728 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3729 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3730 OC->getNumForLoops()) { 3731 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3732 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3733 ErrorFound = true; 3734 } 3735 if (ErrorFound) { 3736 return StmtError(); 3737 } 3738 StmtResult SR = S; 3739 unsigned CompletedRegions = 0; 3740 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3741 // Mark all variables in private list clauses as used in inner region. 3742 // Required for proper codegen of combined directives. 3743 // TODO: add processing for other clauses. 3744 if (ThisCaptureRegion != OMPD_unknown) { 3745 for (const clang::OMPClauseWithPreInit *C : PICs) { 3746 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3747 // Find the particular capture region for the clause if the 3748 // directive is a combined one with multiple capture regions. 3749 // If the directive is not a combined one, the capture region 3750 // associated with the clause is OMPD_unknown and is generated 3751 // only once. 3752 if (CaptureRegion == ThisCaptureRegion || 3753 CaptureRegion == OMPD_unknown) { 3754 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3755 for (Decl *D : DS->decls()) 3756 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3757 } 3758 } 3759 } 3760 } 3761 if (++CompletedRegions == CaptureRegions.size()) 3762 DSAStack->setBodyComplete(); 3763 SR = ActOnCapturedRegionEnd(SR.get()); 3764 } 3765 return SR; 3766 } 3767 3768 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3769 OpenMPDirectiveKind CancelRegion, 3770 SourceLocation StartLoc) { 3771 // CancelRegion is only needed for cancel and cancellation_point. 3772 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3773 return false; 3774 3775 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3776 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3777 return false; 3778 3779 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3780 << getOpenMPDirectiveName(CancelRegion); 3781 return true; 3782 } 3783 3784 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3785 OpenMPDirectiveKind CurrentRegion, 3786 const DeclarationNameInfo &CurrentName, 3787 OpenMPDirectiveKind CancelRegion, 3788 SourceLocation StartLoc) { 3789 if (Stack->getCurScope()) { 3790 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3791 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3792 bool NestingProhibited = false; 3793 bool CloseNesting = true; 3794 bool OrphanSeen = false; 3795 enum { 3796 NoRecommend, 3797 ShouldBeInParallelRegion, 3798 ShouldBeInOrderedRegion, 3799 ShouldBeInTargetRegion, 3800 ShouldBeInTeamsRegion 3801 } Recommend = NoRecommend; 3802 if (isOpenMPSimdDirective(ParentRegion) && 3803 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 3804 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 3805 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { 3806 // OpenMP [2.16, Nesting of Regions] 3807 // OpenMP constructs may not be nested inside a simd region. 3808 // OpenMP [2.8.1,simd Construct, Restrictions] 3809 // An ordered construct with the simd clause is the only OpenMP 3810 // construct that can appear in the simd region. 3811 // Allowing a SIMD construct nested in another SIMD construct is an 3812 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3813 // message. 3814 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 3815 // The only OpenMP constructs that can be encountered during execution of 3816 // a simd region are the atomic construct, the loop construct, the simd 3817 // construct and the ordered construct with the simd clause. 3818 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3819 ? diag::err_omp_prohibited_region_simd 3820 : diag::warn_omp_nesting_simd) 3821 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 3822 return CurrentRegion != OMPD_simd; 3823 } 3824 if (ParentRegion == OMPD_atomic) { 3825 // OpenMP [2.16, Nesting of Regions] 3826 // OpenMP constructs may not be nested inside an atomic region. 3827 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3828 return true; 3829 } 3830 if (CurrentRegion == OMPD_section) { 3831 // OpenMP [2.7.2, sections Construct, Restrictions] 3832 // Orphaned section directives are prohibited. That is, the section 3833 // directives must appear within the sections construct and must not be 3834 // encountered elsewhere in the sections region. 3835 if (ParentRegion != OMPD_sections && 3836 ParentRegion != OMPD_parallel_sections) { 3837 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3838 << (ParentRegion != OMPD_unknown) 3839 << getOpenMPDirectiveName(ParentRegion); 3840 return true; 3841 } 3842 return false; 3843 } 3844 // Allow some constructs (except teams and cancellation constructs) to be 3845 // orphaned (they could be used in functions, called from OpenMP regions 3846 // with the required preconditions). 3847 if (ParentRegion == OMPD_unknown && 3848 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3849 CurrentRegion != OMPD_cancellation_point && 3850 CurrentRegion != OMPD_cancel) 3851 return false; 3852 if (CurrentRegion == OMPD_cancellation_point || 3853 CurrentRegion == OMPD_cancel) { 3854 // OpenMP [2.16, Nesting of Regions] 3855 // A cancellation point construct for which construct-type-clause is 3856 // taskgroup must be nested inside a task construct. A cancellation 3857 // point construct for which construct-type-clause is not taskgroup must 3858 // be closely nested inside an OpenMP construct that matches the type 3859 // specified in construct-type-clause. 3860 // A cancel construct for which construct-type-clause is taskgroup must be 3861 // nested inside a task construct. A cancel construct for which 3862 // construct-type-clause is not taskgroup must be closely nested inside an 3863 // OpenMP construct that matches the type specified in 3864 // construct-type-clause. 3865 NestingProhibited = 3866 !((CancelRegion == OMPD_parallel && 3867 (ParentRegion == OMPD_parallel || 3868 ParentRegion == OMPD_target_parallel)) || 3869 (CancelRegion == OMPD_for && 3870 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3871 ParentRegion == OMPD_target_parallel_for || 3872 ParentRegion == OMPD_distribute_parallel_for || 3873 ParentRegion == OMPD_teams_distribute_parallel_for || 3874 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3875 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3876 (CancelRegion == OMPD_sections && 3877 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3878 ParentRegion == OMPD_parallel_sections))); 3879 OrphanSeen = ParentRegion == OMPD_unknown; 3880 } else if (CurrentRegion == OMPD_master) { 3881 // OpenMP [2.16, Nesting of Regions] 3882 // A master region may not be closely nested inside a worksharing, 3883 // atomic, or explicit task region. 3884 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3885 isOpenMPTaskingDirective(ParentRegion); 3886 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3887 // OpenMP [2.16, Nesting of Regions] 3888 // A critical region may not be nested (closely or otherwise) inside a 3889 // critical region with the same name. Note that this restriction is not 3890 // sufficient to prevent deadlock. 3891 SourceLocation PreviousCriticalLoc; 3892 bool DeadLock = Stack->hasDirective( 3893 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3894 const DeclarationNameInfo &DNI, 3895 SourceLocation Loc) { 3896 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3897 PreviousCriticalLoc = Loc; 3898 return true; 3899 } 3900 return false; 3901 }, 3902 false /* skip top directive */); 3903 if (DeadLock) { 3904 SemaRef.Diag(StartLoc, 3905 diag::err_omp_prohibited_region_critical_same_name) 3906 << CurrentName.getName(); 3907 if (PreviousCriticalLoc.isValid()) 3908 SemaRef.Diag(PreviousCriticalLoc, 3909 diag::note_omp_previous_critical_region); 3910 return true; 3911 } 3912 } else if (CurrentRegion == OMPD_barrier) { 3913 // OpenMP [2.16, Nesting of Regions] 3914 // A barrier region may not be closely nested inside a worksharing, 3915 // explicit task, critical, ordered, atomic, or master region. 3916 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3917 isOpenMPTaskingDirective(ParentRegion) || 3918 ParentRegion == OMPD_master || 3919 ParentRegion == OMPD_critical || 3920 ParentRegion == OMPD_ordered; 3921 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3922 !isOpenMPParallelDirective(CurrentRegion) && 3923 !isOpenMPTeamsDirective(CurrentRegion)) { 3924 // OpenMP [2.16, Nesting of Regions] 3925 // A worksharing region may not be closely nested inside a worksharing, 3926 // explicit task, critical, ordered, atomic, or master region. 3927 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3928 isOpenMPTaskingDirective(ParentRegion) || 3929 ParentRegion == OMPD_master || 3930 ParentRegion == OMPD_critical || 3931 ParentRegion == OMPD_ordered; 3932 Recommend = ShouldBeInParallelRegion; 3933 } else if (CurrentRegion == OMPD_ordered) { 3934 // OpenMP [2.16, Nesting of Regions] 3935 // An ordered region may not be closely nested inside a critical, 3936 // atomic, or explicit task region. 3937 // An ordered region must be closely nested inside a loop region (or 3938 // parallel loop region) with an ordered clause. 3939 // OpenMP [2.8.1,simd Construct, Restrictions] 3940 // An ordered construct with the simd clause is the only OpenMP construct 3941 // that can appear in the simd region. 3942 NestingProhibited = ParentRegion == OMPD_critical || 3943 isOpenMPTaskingDirective(ParentRegion) || 3944 !(isOpenMPSimdDirective(ParentRegion) || 3945 Stack->isParentOrderedRegion()); 3946 Recommend = ShouldBeInOrderedRegion; 3947 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3948 // OpenMP [2.16, Nesting of Regions] 3949 // If specified, a teams construct must be contained within a target 3950 // construct. 3951 NestingProhibited = 3952 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 3953 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 3954 ParentRegion != OMPD_target); 3955 OrphanSeen = ParentRegion == OMPD_unknown; 3956 Recommend = ShouldBeInTargetRegion; 3957 } 3958 if (!NestingProhibited && 3959 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3960 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3961 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3962 // OpenMP [2.16, Nesting of Regions] 3963 // distribute, parallel, parallel sections, parallel workshare, and the 3964 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3965 // constructs that can be closely nested in the teams region. 3966 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3967 !isOpenMPDistributeDirective(CurrentRegion); 3968 Recommend = ShouldBeInParallelRegion; 3969 } 3970 if (!NestingProhibited && 3971 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3972 // OpenMP 4.5 [2.17 Nesting of Regions] 3973 // The region associated with the distribute construct must be strictly 3974 // nested inside a teams region 3975 NestingProhibited = 3976 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3977 Recommend = ShouldBeInTeamsRegion; 3978 } 3979 if (!NestingProhibited && 3980 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3981 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3982 // OpenMP 4.5 [2.17 Nesting of Regions] 3983 // If a target, target update, target data, target enter data, or 3984 // target exit data construct is encountered during execution of a 3985 // target region, the behavior is unspecified. 3986 NestingProhibited = Stack->hasDirective( 3987 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3988 SourceLocation) { 3989 if (isOpenMPTargetExecutionDirective(K)) { 3990 OffendingRegion = K; 3991 return true; 3992 } 3993 return false; 3994 }, 3995 false /* don't skip top directive */); 3996 CloseNesting = false; 3997 } 3998 if (NestingProhibited) { 3999 if (OrphanSeen) { 4000 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4001 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4002 } else { 4003 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4004 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4005 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4006 } 4007 return true; 4008 } 4009 } 4010 return false; 4011 } 4012 4013 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4014 ArrayRef<OMPClause *> Clauses, 4015 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4016 bool ErrorFound = false; 4017 unsigned NamedModifiersNumber = 0; 4018 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 4019 OMPD_unknown + 1); 4020 SmallVector<SourceLocation, 4> NameModifierLoc; 4021 for (const OMPClause *C : Clauses) { 4022 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4023 // At most one if clause without a directive-name-modifier can appear on 4024 // the directive. 4025 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4026 if (FoundNameModifiers[CurNM]) { 4027 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4028 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4029 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4030 ErrorFound = true; 4031 } else if (CurNM != OMPD_unknown) { 4032 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4033 ++NamedModifiersNumber; 4034 } 4035 FoundNameModifiers[CurNM] = IC; 4036 if (CurNM == OMPD_unknown) 4037 continue; 4038 // Check if the specified name modifier is allowed for the current 4039 // directive. 4040 // At most one if clause with the particular directive-name-modifier can 4041 // appear on the directive. 4042 bool MatchFound = false; 4043 for (auto NM : AllowedNameModifiers) { 4044 if (CurNM == NM) { 4045 MatchFound = true; 4046 break; 4047 } 4048 } 4049 if (!MatchFound) { 4050 S.Diag(IC->getNameModifierLoc(), 4051 diag::err_omp_wrong_if_directive_name_modifier) 4052 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4053 ErrorFound = true; 4054 } 4055 } 4056 } 4057 // If any if clause on the directive includes a directive-name-modifier then 4058 // all if clauses on the directive must include a directive-name-modifier. 4059 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4060 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4061 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4062 diag::err_omp_no_more_if_clause); 4063 } else { 4064 std::string Values; 4065 std::string Sep(", "); 4066 unsigned AllowedCnt = 0; 4067 unsigned TotalAllowedNum = 4068 AllowedNameModifiers.size() - NamedModifiersNumber; 4069 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4070 ++Cnt) { 4071 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4072 if (!FoundNameModifiers[NM]) { 4073 Values += "'"; 4074 Values += getOpenMPDirectiveName(NM); 4075 Values += "'"; 4076 if (AllowedCnt + 2 == TotalAllowedNum) 4077 Values += " or "; 4078 else if (AllowedCnt + 1 != TotalAllowedNum) 4079 Values += Sep; 4080 ++AllowedCnt; 4081 } 4082 } 4083 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4084 diag::err_omp_unnamed_if_clause) 4085 << (TotalAllowedNum > 1) << Values; 4086 } 4087 for (SourceLocation Loc : NameModifierLoc) { 4088 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4089 } 4090 ErrorFound = true; 4091 } 4092 return ErrorFound; 4093 } 4094 4095 static std::pair<ValueDecl *, bool> 4096 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4097 SourceRange &ERange, bool AllowArraySection = false) { 4098 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4099 RefExpr->containsUnexpandedParameterPack()) 4100 return std::make_pair(nullptr, true); 4101 4102 // OpenMP [3.1, C/C++] 4103 // A list item is a variable name. 4104 // OpenMP [2.9.3.3, Restrictions, p.1] 4105 // A variable that is part of another variable (as an array or 4106 // structure element) cannot appear in a private clause. 4107 RefExpr = RefExpr->IgnoreParens(); 4108 enum { 4109 NoArrayExpr = -1, 4110 ArraySubscript = 0, 4111 OMPArraySection = 1 4112 } IsArrayExpr = NoArrayExpr; 4113 if (AllowArraySection) { 4114 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4115 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4116 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4117 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4118 RefExpr = Base; 4119 IsArrayExpr = ArraySubscript; 4120 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4121 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4122 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4123 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4124 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4125 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4126 RefExpr = Base; 4127 IsArrayExpr = OMPArraySection; 4128 } 4129 } 4130 ELoc = RefExpr->getExprLoc(); 4131 ERange = RefExpr->getSourceRange(); 4132 RefExpr = RefExpr->IgnoreParenImpCasts(); 4133 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4134 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4135 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4136 (S.getCurrentThisType().isNull() || !ME || 4137 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4138 !isa<FieldDecl>(ME->getMemberDecl()))) { 4139 if (IsArrayExpr != NoArrayExpr) { 4140 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4141 << ERange; 4142 } else { 4143 S.Diag(ELoc, 4144 AllowArraySection 4145 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4146 : diag::err_omp_expected_var_name_member_expr) 4147 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4148 } 4149 return std::make_pair(nullptr, false); 4150 } 4151 return std::make_pair( 4152 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4153 } 4154 4155 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4156 ArrayRef<OMPClause *> Clauses) { 4157 assert(!S.CurContext->isDependentContext() && 4158 "Expected non-dependent context."); 4159 auto AllocateRange = 4160 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4161 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4162 DeclToCopy; 4163 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4164 return isOpenMPPrivate(C->getClauseKind()); 4165 }); 4166 for (OMPClause *Cl : PrivateRange) { 4167 MutableArrayRef<Expr *>::iterator I, It, Et; 4168 if (Cl->getClauseKind() == OMPC_private) { 4169 auto *PC = cast<OMPPrivateClause>(Cl); 4170 I = PC->private_copies().begin(); 4171 It = PC->varlist_begin(); 4172 Et = PC->varlist_end(); 4173 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4174 auto *PC = cast<OMPFirstprivateClause>(Cl); 4175 I = PC->private_copies().begin(); 4176 It = PC->varlist_begin(); 4177 Et = PC->varlist_end(); 4178 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4179 auto *PC = cast<OMPLastprivateClause>(Cl); 4180 I = PC->private_copies().begin(); 4181 It = PC->varlist_begin(); 4182 Et = PC->varlist_end(); 4183 } else if (Cl->getClauseKind() == OMPC_linear) { 4184 auto *PC = cast<OMPLinearClause>(Cl); 4185 I = PC->privates().begin(); 4186 It = PC->varlist_begin(); 4187 Et = PC->varlist_end(); 4188 } else if (Cl->getClauseKind() == OMPC_reduction) { 4189 auto *PC = cast<OMPReductionClause>(Cl); 4190 I = PC->privates().begin(); 4191 It = PC->varlist_begin(); 4192 Et = PC->varlist_end(); 4193 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4194 auto *PC = cast<OMPTaskReductionClause>(Cl); 4195 I = PC->privates().begin(); 4196 It = PC->varlist_begin(); 4197 Et = PC->varlist_end(); 4198 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4199 auto *PC = cast<OMPInReductionClause>(Cl); 4200 I = PC->privates().begin(); 4201 It = PC->varlist_begin(); 4202 Et = PC->varlist_end(); 4203 } else { 4204 llvm_unreachable("Expected private clause."); 4205 } 4206 for (Expr *E : llvm::make_range(It, Et)) { 4207 if (!*I) { 4208 ++I; 4209 continue; 4210 } 4211 SourceLocation ELoc; 4212 SourceRange ERange; 4213 Expr *SimpleRefExpr = E; 4214 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4215 /*AllowArraySection=*/true); 4216 DeclToCopy.try_emplace(Res.first, 4217 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4218 ++I; 4219 } 4220 } 4221 for (OMPClause *C : AllocateRange) { 4222 auto *AC = cast<OMPAllocateClause>(C); 4223 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4224 getAllocatorKind(S, Stack, AC->getAllocator()); 4225 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4226 // For task, taskloop or target directives, allocation requests to memory 4227 // allocators with the trait access set to thread result in unspecified 4228 // behavior. 4229 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4230 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4231 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4232 S.Diag(AC->getAllocator()->getExprLoc(), 4233 diag::warn_omp_allocate_thread_on_task_target_directive) 4234 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4235 } 4236 for (Expr *E : AC->varlists()) { 4237 SourceLocation ELoc; 4238 SourceRange ERange; 4239 Expr *SimpleRefExpr = E; 4240 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4241 ValueDecl *VD = Res.first; 4242 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4243 if (!isOpenMPPrivate(Data.CKind)) { 4244 S.Diag(E->getExprLoc(), 4245 diag::err_omp_expected_private_copy_for_allocate); 4246 continue; 4247 } 4248 VarDecl *PrivateVD = DeclToCopy[VD]; 4249 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4250 AllocatorKind, AC->getAllocator())) 4251 continue; 4252 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4253 E->getSourceRange()); 4254 } 4255 } 4256 } 4257 4258 StmtResult Sema::ActOnOpenMPExecutableDirective( 4259 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4260 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4261 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4262 StmtResult Res = StmtError(); 4263 // First check CancelRegion which is then used in checkNestingOfRegions. 4264 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4265 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4266 StartLoc)) 4267 return StmtError(); 4268 4269 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4270 VarsWithInheritedDSAType VarsWithInheritedDSA; 4271 bool ErrorFound = false; 4272 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4273 if (AStmt && !CurContext->isDependentContext()) { 4274 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4275 4276 // Check default data sharing attributes for referenced variables. 4277 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4278 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4279 Stmt *S = AStmt; 4280 while (--ThisCaptureLevel >= 0) 4281 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4282 DSAChecker.Visit(S); 4283 if (!isOpenMPTargetDataManagementDirective(Kind) && 4284 !isOpenMPTaskingDirective(Kind)) { 4285 // Visit subcaptures to generate implicit clauses for captured vars. 4286 auto *CS = cast<CapturedStmt>(AStmt); 4287 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4288 getOpenMPCaptureRegions(CaptureRegions, Kind); 4289 // Ignore outer tasking regions for target directives. 4290 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4291 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4292 DSAChecker.visitSubCaptures(CS); 4293 } 4294 if (DSAChecker.isErrorFound()) 4295 return StmtError(); 4296 // Generate list of implicitly defined firstprivate variables. 4297 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4298 4299 SmallVector<Expr *, 4> ImplicitFirstprivates( 4300 DSAChecker.getImplicitFirstprivate().begin(), 4301 DSAChecker.getImplicitFirstprivate().end()); 4302 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4303 DSAChecker.getImplicitMap().end()); 4304 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4305 for (OMPClause *C : Clauses) { 4306 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4307 for (Expr *E : IRC->taskgroup_descriptors()) 4308 if (E) 4309 ImplicitFirstprivates.emplace_back(E); 4310 } 4311 } 4312 if (!ImplicitFirstprivates.empty()) { 4313 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4314 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4315 SourceLocation())) { 4316 ClausesWithImplicit.push_back(Implicit); 4317 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4318 ImplicitFirstprivates.size(); 4319 } else { 4320 ErrorFound = true; 4321 } 4322 } 4323 if (!ImplicitMaps.empty()) { 4324 CXXScopeSpec MapperIdScopeSpec; 4325 DeclarationNameInfo MapperId; 4326 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4327 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4328 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4329 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4330 ClausesWithImplicit.emplace_back(Implicit); 4331 ErrorFound |= 4332 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4333 } else { 4334 ErrorFound = true; 4335 } 4336 } 4337 } 4338 4339 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4340 switch (Kind) { 4341 case OMPD_parallel: 4342 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4343 EndLoc); 4344 AllowedNameModifiers.push_back(OMPD_parallel); 4345 break; 4346 case OMPD_simd: 4347 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4348 VarsWithInheritedDSA); 4349 break; 4350 case OMPD_for: 4351 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4352 VarsWithInheritedDSA); 4353 break; 4354 case OMPD_for_simd: 4355 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4356 EndLoc, VarsWithInheritedDSA); 4357 break; 4358 case OMPD_sections: 4359 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4360 EndLoc); 4361 break; 4362 case OMPD_section: 4363 assert(ClausesWithImplicit.empty() && 4364 "No clauses are allowed for 'omp section' directive"); 4365 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4366 break; 4367 case OMPD_single: 4368 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4369 EndLoc); 4370 break; 4371 case OMPD_master: 4372 assert(ClausesWithImplicit.empty() && 4373 "No clauses are allowed for 'omp master' directive"); 4374 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4375 break; 4376 case OMPD_critical: 4377 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4378 StartLoc, EndLoc); 4379 break; 4380 case OMPD_parallel_for: 4381 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4382 EndLoc, VarsWithInheritedDSA); 4383 AllowedNameModifiers.push_back(OMPD_parallel); 4384 break; 4385 case OMPD_parallel_for_simd: 4386 Res = ActOnOpenMPParallelForSimdDirective( 4387 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4388 AllowedNameModifiers.push_back(OMPD_parallel); 4389 break; 4390 case OMPD_parallel_sections: 4391 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4392 StartLoc, EndLoc); 4393 AllowedNameModifiers.push_back(OMPD_parallel); 4394 break; 4395 case OMPD_task: 4396 Res = 4397 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4398 AllowedNameModifiers.push_back(OMPD_task); 4399 break; 4400 case OMPD_taskyield: 4401 assert(ClausesWithImplicit.empty() && 4402 "No clauses are allowed for 'omp taskyield' directive"); 4403 assert(AStmt == nullptr && 4404 "No associated statement allowed for 'omp taskyield' directive"); 4405 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4406 break; 4407 case OMPD_barrier: 4408 assert(ClausesWithImplicit.empty() && 4409 "No clauses are allowed for 'omp barrier' directive"); 4410 assert(AStmt == nullptr && 4411 "No associated statement allowed for 'omp barrier' directive"); 4412 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4413 break; 4414 case OMPD_taskwait: 4415 assert(ClausesWithImplicit.empty() && 4416 "No clauses are allowed for 'omp taskwait' directive"); 4417 assert(AStmt == nullptr && 4418 "No associated statement allowed for 'omp taskwait' directive"); 4419 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4420 break; 4421 case OMPD_taskgroup: 4422 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4423 EndLoc); 4424 break; 4425 case OMPD_flush: 4426 assert(AStmt == nullptr && 4427 "No associated statement allowed for 'omp flush' directive"); 4428 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4429 break; 4430 case OMPD_ordered: 4431 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4432 EndLoc); 4433 break; 4434 case OMPD_atomic: 4435 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4436 EndLoc); 4437 break; 4438 case OMPD_teams: 4439 Res = 4440 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4441 break; 4442 case OMPD_target: 4443 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4444 EndLoc); 4445 AllowedNameModifiers.push_back(OMPD_target); 4446 break; 4447 case OMPD_target_parallel: 4448 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4449 StartLoc, EndLoc); 4450 AllowedNameModifiers.push_back(OMPD_target); 4451 AllowedNameModifiers.push_back(OMPD_parallel); 4452 break; 4453 case OMPD_target_parallel_for: 4454 Res = ActOnOpenMPTargetParallelForDirective( 4455 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4456 AllowedNameModifiers.push_back(OMPD_target); 4457 AllowedNameModifiers.push_back(OMPD_parallel); 4458 break; 4459 case OMPD_cancellation_point: 4460 assert(ClausesWithImplicit.empty() && 4461 "No clauses are allowed for 'omp cancellation point' directive"); 4462 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4463 "cancellation point' directive"); 4464 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4465 break; 4466 case OMPD_cancel: 4467 assert(AStmt == nullptr && 4468 "No associated statement allowed for 'omp cancel' directive"); 4469 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4470 CancelRegion); 4471 AllowedNameModifiers.push_back(OMPD_cancel); 4472 break; 4473 case OMPD_target_data: 4474 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4475 EndLoc); 4476 AllowedNameModifiers.push_back(OMPD_target_data); 4477 break; 4478 case OMPD_target_enter_data: 4479 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4480 EndLoc, AStmt); 4481 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4482 break; 4483 case OMPD_target_exit_data: 4484 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4485 EndLoc, AStmt); 4486 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4487 break; 4488 case OMPD_taskloop: 4489 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4490 EndLoc, VarsWithInheritedDSA); 4491 AllowedNameModifiers.push_back(OMPD_taskloop); 4492 break; 4493 case OMPD_taskloop_simd: 4494 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4495 EndLoc, VarsWithInheritedDSA); 4496 AllowedNameModifiers.push_back(OMPD_taskloop); 4497 break; 4498 case OMPD_master_taskloop: 4499 Res = ActOnOpenMPMasterTaskLoopDirective( 4500 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4501 AllowedNameModifiers.push_back(OMPD_taskloop); 4502 break; 4503 case OMPD_master_taskloop_simd: 4504 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4505 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4506 AllowedNameModifiers.push_back(OMPD_taskloop); 4507 break; 4508 case OMPD_parallel_master_taskloop: 4509 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4510 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4511 AllowedNameModifiers.push_back(OMPD_taskloop); 4512 AllowedNameModifiers.push_back(OMPD_parallel); 4513 break; 4514 case OMPD_parallel_master_taskloop_simd: 4515 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4516 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4517 AllowedNameModifiers.push_back(OMPD_taskloop); 4518 AllowedNameModifiers.push_back(OMPD_parallel); 4519 break; 4520 case OMPD_distribute: 4521 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4522 EndLoc, VarsWithInheritedDSA); 4523 break; 4524 case OMPD_target_update: 4525 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4526 EndLoc, AStmt); 4527 AllowedNameModifiers.push_back(OMPD_target_update); 4528 break; 4529 case OMPD_distribute_parallel_for: 4530 Res = ActOnOpenMPDistributeParallelForDirective( 4531 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4532 AllowedNameModifiers.push_back(OMPD_parallel); 4533 break; 4534 case OMPD_distribute_parallel_for_simd: 4535 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4536 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4537 AllowedNameModifiers.push_back(OMPD_parallel); 4538 break; 4539 case OMPD_distribute_simd: 4540 Res = ActOnOpenMPDistributeSimdDirective( 4541 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4542 break; 4543 case OMPD_target_parallel_for_simd: 4544 Res = ActOnOpenMPTargetParallelForSimdDirective( 4545 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4546 AllowedNameModifiers.push_back(OMPD_target); 4547 AllowedNameModifiers.push_back(OMPD_parallel); 4548 break; 4549 case OMPD_target_simd: 4550 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4551 EndLoc, VarsWithInheritedDSA); 4552 AllowedNameModifiers.push_back(OMPD_target); 4553 break; 4554 case OMPD_teams_distribute: 4555 Res = ActOnOpenMPTeamsDistributeDirective( 4556 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4557 break; 4558 case OMPD_teams_distribute_simd: 4559 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4560 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4561 break; 4562 case OMPD_teams_distribute_parallel_for_simd: 4563 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4564 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4565 AllowedNameModifiers.push_back(OMPD_parallel); 4566 break; 4567 case OMPD_teams_distribute_parallel_for: 4568 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4569 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4570 AllowedNameModifiers.push_back(OMPD_parallel); 4571 break; 4572 case OMPD_target_teams: 4573 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4574 EndLoc); 4575 AllowedNameModifiers.push_back(OMPD_target); 4576 break; 4577 case OMPD_target_teams_distribute: 4578 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4579 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4580 AllowedNameModifiers.push_back(OMPD_target); 4581 break; 4582 case OMPD_target_teams_distribute_parallel_for: 4583 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4584 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4585 AllowedNameModifiers.push_back(OMPD_target); 4586 AllowedNameModifiers.push_back(OMPD_parallel); 4587 break; 4588 case OMPD_target_teams_distribute_parallel_for_simd: 4589 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4590 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4591 AllowedNameModifiers.push_back(OMPD_target); 4592 AllowedNameModifiers.push_back(OMPD_parallel); 4593 break; 4594 case OMPD_target_teams_distribute_simd: 4595 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4596 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4597 AllowedNameModifiers.push_back(OMPD_target); 4598 break; 4599 case OMPD_declare_target: 4600 case OMPD_end_declare_target: 4601 case OMPD_threadprivate: 4602 case OMPD_allocate: 4603 case OMPD_declare_reduction: 4604 case OMPD_declare_mapper: 4605 case OMPD_declare_simd: 4606 case OMPD_requires: 4607 case OMPD_declare_variant: 4608 llvm_unreachable("OpenMP Directive is not allowed"); 4609 case OMPD_unknown: 4610 llvm_unreachable("Unknown OpenMP directive"); 4611 } 4612 4613 ErrorFound = Res.isInvalid() || ErrorFound; 4614 4615 // Check variables in the clauses if default(none) was specified. 4616 if (DSAStack->getDefaultDSA() == DSA_none) { 4617 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4618 for (OMPClause *C : Clauses) { 4619 switch (C->getClauseKind()) { 4620 case OMPC_num_threads: 4621 case OMPC_dist_schedule: 4622 // Do not analyse if no parent teams directive. 4623 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4624 break; 4625 continue; 4626 case OMPC_if: 4627 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4628 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4629 break; 4630 continue; 4631 case OMPC_schedule: 4632 break; 4633 case OMPC_grainsize: 4634 case OMPC_num_tasks: 4635 case OMPC_final: 4636 case OMPC_priority: 4637 // Do not analyze if no parent parallel directive. 4638 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective())) 4639 break; 4640 continue; 4641 case OMPC_ordered: 4642 case OMPC_device: 4643 case OMPC_num_teams: 4644 case OMPC_thread_limit: 4645 case OMPC_hint: 4646 case OMPC_collapse: 4647 case OMPC_safelen: 4648 case OMPC_simdlen: 4649 case OMPC_default: 4650 case OMPC_proc_bind: 4651 case OMPC_private: 4652 case OMPC_firstprivate: 4653 case OMPC_lastprivate: 4654 case OMPC_shared: 4655 case OMPC_reduction: 4656 case OMPC_task_reduction: 4657 case OMPC_in_reduction: 4658 case OMPC_linear: 4659 case OMPC_aligned: 4660 case OMPC_copyin: 4661 case OMPC_copyprivate: 4662 case OMPC_nowait: 4663 case OMPC_untied: 4664 case OMPC_mergeable: 4665 case OMPC_allocate: 4666 case OMPC_read: 4667 case OMPC_write: 4668 case OMPC_update: 4669 case OMPC_capture: 4670 case OMPC_seq_cst: 4671 case OMPC_depend: 4672 case OMPC_threads: 4673 case OMPC_simd: 4674 case OMPC_map: 4675 case OMPC_nogroup: 4676 case OMPC_defaultmap: 4677 case OMPC_to: 4678 case OMPC_from: 4679 case OMPC_use_device_ptr: 4680 case OMPC_is_device_ptr: 4681 continue; 4682 case OMPC_allocator: 4683 case OMPC_flush: 4684 case OMPC_threadprivate: 4685 case OMPC_uniform: 4686 case OMPC_unknown: 4687 case OMPC_unified_address: 4688 case OMPC_unified_shared_memory: 4689 case OMPC_reverse_offload: 4690 case OMPC_dynamic_allocators: 4691 case OMPC_atomic_default_mem_order: 4692 case OMPC_device_type: 4693 case OMPC_match: 4694 llvm_unreachable("Unexpected clause"); 4695 } 4696 for (Stmt *CC : C->children()) { 4697 if (CC) 4698 DSAChecker.Visit(CC); 4699 } 4700 } 4701 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4702 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4703 } 4704 for (const auto &P : VarsWithInheritedDSA) { 4705 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4706 continue; 4707 ErrorFound = true; 4708 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4709 << P.first << P.second->getSourceRange(); 4710 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4711 } 4712 4713 if (!AllowedNameModifiers.empty()) 4714 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4715 ErrorFound; 4716 4717 if (ErrorFound) 4718 return StmtError(); 4719 4720 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4721 Res.getAs<OMPExecutableDirective>() 4722 ->getStructuredBlock() 4723 ->setIsOMPStructuredBlock(true); 4724 } 4725 4726 if (!CurContext->isDependentContext() && 4727 isOpenMPTargetExecutionDirective(Kind) && 4728 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4729 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4730 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4731 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4732 // Register target to DSA Stack. 4733 DSAStack->addTargetDirLocation(StartLoc); 4734 } 4735 4736 return Res; 4737 } 4738 4739 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4740 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4741 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4742 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4743 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4744 assert(Aligneds.size() == Alignments.size()); 4745 assert(Linears.size() == LinModifiers.size()); 4746 assert(Linears.size() == Steps.size()); 4747 if (!DG || DG.get().isNull()) 4748 return DeclGroupPtrTy(); 4749 4750 const int SimdId = 0; 4751 if (!DG.get().isSingleDecl()) { 4752 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4753 << SimdId; 4754 return DG; 4755 } 4756 Decl *ADecl = DG.get().getSingleDecl(); 4757 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4758 ADecl = FTD->getTemplatedDecl(); 4759 4760 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4761 if (!FD) { 4762 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4763 return DeclGroupPtrTy(); 4764 } 4765 4766 // OpenMP [2.8.2, declare simd construct, Description] 4767 // The parameter of the simdlen clause must be a constant positive integer 4768 // expression. 4769 ExprResult SL; 4770 if (Simdlen) 4771 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4772 // OpenMP [2.8.2, declare simd construct, Description] 4773 // The special this pointer can be used as if was one of the arguments to the 4774 // function in any of the linear, aligned, or uniform clauses. 4775 // The uniform clause declares one or more arguments to have an invariant 4776 // value for all concurrent invocations of the function in the execution of a 4777 // single SIMD loop. 4778 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4779 const Expr *UniformedLinearThis = nullptr; 4780 for (const Expr *E : Uniforms) { 4781 E = E->IgnoreParenImpCasts(); 4782 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4783 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4784 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4785 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4786 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4787 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4788 continue; 4789 } 4790 if (isa<CXXThisExpr>(E)) { 4791 UniformedLinearThis = E; 4792 continue; 4793 } 4794 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4795 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4796 } 4797 // OpenMP [2.8.2, declare simd construct, Description] 4798 // The aligned clause declares that the object to which each list item points 4799 // is aligned to the number of bytes expressed in the optional parameter of 4800 // the aligned clause. 4801 // The special this pointer can be used as if was one of the arguments to the 4802 // function in any of the linear, aligned, or uniform clauses. 4803 // The type of list items appearing in the aligned clause must be array, 4804 // pointer, reference to array, or reference to pointer. 4805 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4806 const Expr *AlignedThis = nullptr; 4807 for (const Expr *E : Aligneds) { 4808 E = E->IgnoreParenImpCasts(); 4809 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4810 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4811 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4812 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4813 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4814 ->getCanonicalDecl() == CanonPVD) { 4815 // OpenMP [2.8.1, simd construct, Restrictions] 4816 // A list-item cannot appear in more than one aligned clause. 4817 if (AlignedArgs.count(CanonPVD) > 0) { 4818 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4819 << 1 << E->getSourceRange(); 4820 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4821 diag::note_omp_explicit_dsa) 4822 << getOpenMPClauseName(OMPC_aligned); 4823 continue; 4824 } 4825 AlignedArgs[CanonPVD] = E; 4826 QualType QTy = PVD->getType() 4827 .getNonReferenceType() 4828 .getUnqualifiedType() 4829 .getCanonicalType(); 4830 const Type *Ty = QTy.getTypePtrOrNull(); 4831 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4832 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4833 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4834 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4835 } 4836 continue; 4837 } 4838 } 4839 if (isa<CXXThisExpr>(E)) { 4840 if (AlignedThis) { 4841 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4842 << 2 << E->getSourceRange(); 4843 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4844 << getOpenMPClauseName(OMPC_aligned); 4845 } 4846 AlignedThis = E; 4847 continue; 4848 } 4849 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4850 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4851 } 4852 // The optional parameter of the aligned clause, alignment, must be a constant 4853 // positive integer expression. If no optional parameter is specified, 4854 // implementation-defined default alignments for SIMD instructions on the 4855 // target platforms are assumed. 4856 SmallVector<const Expr *, 4> NewAligns; 4857 for (Expr *E : Alignments) { 4858 ExprResult Align; 4859 if (E) 4860 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4861 NewAligns.push_back(Align.get()); 4862 } 4863 // OpenMP [2.8.2, declare simd construct, Description] 4864 // The linear clause declares one or more list items to be private to a SIMD 4865 // lane and to have a linear relationship with respect to the iteration space 4866 // of a loop. 4867 // The special this pointer can be used as if was one of the arguments to the 4868 // function in any of the linear, aligned, or uniform clauses. 4869 // When a linear-step expression is specified in a linear clause it must be 4870 // either a constant integer expression or an integer-typed parameter that is 4871 // specified in a uniform clause on the directive. 4872 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4873 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4874 auto MI = LinModifiers.begin(); 4875 for (const Expr *E : Linears) { 4876 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4877 ++MI; 4878 E = E->IgnoreParenImpCasts(); 4879 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4880 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4881 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4882 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4883 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4884 ->getCanonicalDecl() == CanonPVD) { 4885 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4886 // A list-item cannot appear in more than one linear clause. 4887 if (LinearArgs.count(CanonPVD) > 0) { 4888 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4889 << getOpenMPClauseName(OMPC_linear) 4890 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4891 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4892 diag::note_omp_explicit_dsa) 4893 << getOpenMPClauseName(OMPC_linear); 4894 continue; 4895 } 4896 // Each argument can appear in at most one uniform or linear clause. 4897 if (UniformedArgs.count(CanonPVD) > 0) { 4898 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4899 << getOpenMPClauseName(OMPC_linear) 4900 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4901 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4902 diag::note_omp_explicit_dsa) 4903 << getOpenMPClauseName(OMPC_uniform); 4904 continue; 4905 } 4906 LinearArgs[CanonPVD] = E; 4907 if (E->isValueDependent() || E->isTypeDependent() || 4908 E->isInstantiationDependent() || 4909 E->containsUnexpandedParameterPack()) 4910 continue; 4911 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4912 PVD->getOriginalType()); 4913 continue; 4914 } 4915 } 4916 if (isa<CXXThisExpr>(E)) { 4917 if (UniformedLinearThis) { 4918 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4919 << getOpenMPClauseName(OMPC_linear) 4920 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4921 << E->getSourceRange(); 4922 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4923 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4924 : OMPC_linear); 4925 continue; 4926 } 4927 UniformedLinearThis = E; 4928 if (E->isValueDependent() || E->isTypeDependent() || 4929 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4930 continue; 4931 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4932 E->getType()); 4933 continue; 4934 } 4935 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4936 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4937 } 4938 Expr *Step = nullptr; 4939 Expr *NewStep = nullptr; 4940 SmallVector<Expr *, 4> NewSteps; 4941 for (Expr *E : Steps) { 4942 // Skip the same step expression, it was checked already. 4943 if (Step == E || !E) { 4944 NewSteps.push_back(E ? NewStep : nullptr); 4945 continue; 4946 } 4947 Step = E; 4948 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4949 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4950 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4951 if (UniformedArgs.count(CanonPVD) == 0) { 4952 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4953 << Step->getSourceRange(); 4954 } else if (E->isValueDependent() || E->isTypeDependent() || 4955 E->isInstantiationDependent() || 4956 E->containsUnexpandedParameterPack() || 4957 CanonPVD->getType()->hasIntegerRepresentation()) { 4958 NewSteps.push_back(Step); 4959 } else { 4960 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4961 << Step->getSourceRange(); 4962 } 4963 continue; 4964 } 4965 NewStep = Step; 4966 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4967 !Step->isInstantiationDependent() && 4968 !Step->containsUnexpandedParameterPack()) { 4969 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4970 .get(); 4971 if (NewStep) 4972 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4973 } 4974 NewSteps.push_back(NewStep); 4975 } 4976 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4977 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4978 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4979 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4980 const_cast<Expr **>(Linears.data()), Linears.size(), 4981 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4982 NewSteps.data(), NewSteps.size(), SR); 4983 ADecl->addAttr(NewAttr); 4984 return DG; 4985 } 4986 4987 Optional<std::pair<FunctionDecl *, Expr *>> 4988 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 4989 Expr *VariantRef, SourceRange SR) { 4990 if (!DG || DG.get().isNull()) 4991 return None; 4992 4993 const int VariantId = 1; 4994 // Must be applied only to single decl. 4995 if (!DG.get().isSingleDecl()) { 4996 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4997 << VariantId << SR; 4998 return None; 4999 } 5000 Decl *ADecl = DG.get().getSingleDecl(); 5001 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5002 ADecl = FTD->getTemplatedDecl(); 5003 5004 // Decl must be a function. 5005 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5006 if (!FD) { 5007 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5008 << VariantId << SR; 5009 return None; 5010 } 5011 5012 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5013 return FD->hasAttrs() && 5014 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5015 FD->hasAttr<TargetAttr>()); 5016 }; 5017 // OpenMP is not compatible with CPU-specific attributes. 5018 if (HasMultiVersionAttributes(FD)) { 5019 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5020 << SR; 5021 return None; 5022 } 5023 5024 // Allow #pragma omp declare variant only if the function is not used. 5025 if (FD->isUsed(false)) 5026 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5027 << FD->getLocation(); 5028 5029 // Check if the function was emitted already. 5030 const FunctionDecl *Definition; 5031 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5032 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5033 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5034 << FD->getLocation(); 5035 5036 // The VariantRef must point to function. 5037 if (!VariantRef) { 5038 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5039 return None; 5040 } 5041 5042 // Do not check templates, wait until instantiation. 5043 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5044 VariantRef->containsUnexpandedParameterPack() || 5045 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5046 return std::make_pair(FD, VariantRef); 5047 5048 // Convert VariantRef expression to the type of the original function to 5049 // resolve possible conflicts. 5050 ExprResult VariantRefCast; 5051 if (LangOpts.CPlusPlus) { 5052 QualType FnPtrType; 5053 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5054 if (Method && !Method->isStatic()) { 5055 const Type *ClassType = 5056 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5057 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5058 ExprResult ER; 5059 { 5060 // Build adrr_of unary op to correctly handle type checks for member 5061 // functions. 5062 Sema::TentativeAnalysisScope Trap(*this); 5063 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5064 VariantRef); 5065 } 5066 if (!ER.isUsable()) { 5067 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5068 << VariantId << VariantRef->getSourceRange(); 5069 return None; 5070 } 5071 VariantRef = ER.get(); 5072 } else { 5073 FnPtrType = Context.getPointerType(FD->getType()); 5074 } 5075 ImplicitConversionSequence ICS = 5076 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5077 /*SuppressUserConversions=*/false, 5078 /*AllowExplicit=*/false, 5079 /*InOverloadResolution=*/false, 5080 /*CStyle=*/false, 5081 /*AllowObjCWritebackConversion=*/false); 5082 if (ICS.isFailure()) { 5083 Diag(VariantRef->getExprLoc(), 5084 diag::err_omp_declare_variant_incompat_types) 5085 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 5086 return None; 5087 } 5088 VariantRefCast = PerformImplicitConversion( 5089 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5090 if (!VariantRefCast.isUsable()) 5091 return None; 5092 // Drop previously built artificial addr_of unary op for member functions. 5093 if (Method && !Method->isStatic()) { 5094 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5095 if (auto *UO = dyn_cast<UnaryOperator>( 5096 PossibleAddrOfVariantRef->IgnoreImplicit())) 5097 VariantRefCast = UO->getSubExpr(); 5098 } 5099 } else { 5100 VariantRefCast = VariantRef; 5101 } 5102 5103 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5104 if (!ER.isUsable() || 5105 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5106 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5107 << VariantId << VariantRef->getSourceRange(); 5108 return None; 5109 } 5110 5111 // The VariantRef must point to function. 5112 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5113 if (!DRE) { 5114 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5115 << VariantId << VariantRef->getSourceRange(); 5116 return None; 5117 } 5118 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5119 if (!NewFD) { 5120 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5121 << VariantId << VariantRef->getSourceRange(); 5122 return None; 5123 } 5124 5125 // Check if variant function is not marked with declare variant directive. 5126 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5127 Diag(VariantRef->getExprLoc(), 5128 diag::warn_omp_declare_variant_marked_as_declare_variant) 5129 << VariantRef->getSourceRange(); 5130 SourceRange SR = 5131 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5132 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5133 return None; 5134 } 5135 5136 enum DoesntSupport { 5137 VirtFuncs = 1, 5138 Constructors = 3, 5139 Destructors = 4, 5140 DeletedFuncs = 5, 5141 DefaultedFuncs = 6, 5142 ConstexprFuncs = 7, 5143 ConstevalFuncs = 8, 5144 }; 5145 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5146 if (CXXFD->isVirtual()) { 5147 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5148 << VirtFuncs; 5149 return None; 5150 } 5151 5152 if (isa<CXXConstructorDecl>(FD)) { 5153 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5154 << Constructors; 5155 return None; 5156 } 5157 5158 if (isa<CXXDestructorDecl>(FD)) { 5159 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5160 << Destructors; 5161 return None; 5162 } 5163 } 5164 5165 if (FD->isDeleted()) { 5166 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5167 << DeletedFuncs; 5168 return None; 5169 } 5170 5171 if (FD->isDefaulted()) { 5172 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5173 << DefaultedFuncs; 5174 return None; 5175 } 5176 5177 if (FD->isConstexpr()) { 5178 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5179 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5180 return None; 5181 } 5182 5183 // Check general compatibility. 5184 if (areMultiversionVariantFunctionsCompatible( 5185 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5186 PartialDiagnosticAt( 5187 SR.getBegin(), 5188 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5189 PartialDiagnosticAt( 5190 VariantRef->getExprLoc(), 5191 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5192 PartialDiagnosticAt(VariantRef->getExprLoc(), 5193 PDiag(diag::err_omp_declare_variant_diff) 5194 << FD->getLocation()), 5195 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5196 /*CLinkageMayDiffer=*/true)) 5197 return None; 5198 return std::make_pair(FD, cast<Expr>(DRE)); 5199 } 5200 5201 void Sema::ActOnOpenMPDeclareVariantDirective( 5202 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5203 ArrayRef<OMPCtxSelectorData> Data) { 5204 if (Data.empty()) 5205 return; 5206 SmallVector<Expr *, 4> CtxScores; 5207 SmallVector<unsigned, 4> CtxSets; 5208 SmallVector<unsigned, 4> Ctxs; 5209 SmallVector<StringRef, 4> ImplVendors; 5210 bool IsError = false; 5211 for (const OMPCtxSelectorData &D : Data) { 5212 OpenMPContextSelectorSetKind CtxSet = D.CtxSet; 5213 OpenMPContextSelectorKind Ctx = D.Ctx; 5214 if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown) 5215 return; 5216 Expr *Score = nullptr; 5217 if (D.Score.isUsable()) { 5218 Score = D.Score.get(); 5219 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5220 !Score->isInstantiationDependent() && 5221 !Score->containsUnexpandedParameterPack()) { 5222 Score = 5223 PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score) 5224 .get(); 5225 if (Score) 5226 Score = VerifyIntegerConstantExpression(Score).get(); 5227 } 5228 } else { 5229 Score = ActOnIntegerConstant(SourceLocation(), 0).get(); 5230 } 5231 switch (CtxSet) { 5232 case OMP_CTX_SET_implementation: 5233 switch (Ctx) { 5234 case OMP_CTX_vendor: 5235 ImplVendors.append(D.Names.begin(), D.Names.end()); 5236 break; 5237 case OMP_CTX_unknown: 5238 llvm_unreachable("Unexpected context selector kind."); 5239 } 5240 break; 5241 case OMP_CTX_SET_unknown: 5242 llvm_unreachable("Unexpected context selector set kind."); 5243 } 5244 IsError = IsError || !Score; 5245 CtxSets.push_back(CtxSet); 5246 Ctxs.push_back(Ctx); 5247 CtxScores.push_back(Score); 5248 } 5249 if (!IsError) { 5250 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5251 Context, VariantRef, CtxScores.begin(), CtxScores.size(), 5252 CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(), 5253 ImplVendors.begin(), ImplVendors.size(), SR); 5254 FD->addAttr(NewAttr); 5255 } 5256 } 5257 5258 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5259 FunctionDecl *Func, 5260 bool MightBeOdrUse) { 5261 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5262 5263 if (!Func->isDependentContext() && Func->hasAttrs()) { 5264 for (OMPDeclareVariantAttr *A : 5265 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5266 // TODO: add checks for active OpenMP context where possible. 5267 Expr *VariantRef = A->getVariantFuncRef(); 5268 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5269 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5270 if (!F->isDefined() && F->isTemplateInstantiation()) 5271 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5272 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5273 } 5274 } 5275 } 5276 5277 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5278 Stmt *AStmt, 5279 SourceLocation StartLoc, 5280 SourceLocation EndLoc) { 5281 if (!AStmt) 5282 return StmtError(); 5283 5284 auto *CS = cast<CapturedStmt>(AStmt); 5285 // 1.2.2 OpenMP Language Terminology 5286 // Structured block - An executable statement with a single entry at the 5287 // top and a single exit at the bottom. 5288 // The point of exit cannot be a branch out of the structured block. 5289 // longjmp() and throw() must not violate the entry/exit criteria. 5290 CS->getCapturedDecl()->setNothrow(); 5291 5292 setFunctionHasBranchProtectedScope(); 5293 5294 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5295 DSAStack->isCancelRegion()); 5296 } 5297 5298 namespace { 5299 /// Iteration space of a single for loop. 5300 struct LoopIterationSpace final { 5301 /// True if the condition operator is the strict compare operator (<, > or 5302 /// !=). 5303 bool IsStrictCompare = false; 5304 /// Condition of the loop. 5305 Expr *PreCond = nullptr; 5306 /// This expression calculates the number of iterations in the loop. 5307 /// It is always possible to calculate it before starting the loop. 5308 Expr *NumIterations = nullptr; 5309 /// The loop counter variable. 5310 Expr *CounterVar = nullptr; 5311 /// Private loop counter variable. 5312 Expr *PrivateCounterVar = nullptr; 5313 /// This is initializer for the initial value of #CounterVar. 5314 Expr *CounterInit = nullptr; 5315 /// This is step for the #CounterVar used to generate its update: 5316 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5317 Expr *CounterStep = nullptr; 5318 /// Should step be subtracted? 5319 bool Subtract = false; 5320 /// Source range of the loop init. 5321 SourceRange InitSrcRange; 5322 /// Source range of the loop condition. 5323 SourceRange CondSrcRange; 5324 /// Source range of the loop increment. 5325 SourceRange IncSrcRange; 5326 /// Minimum value that can have the loop control variable. Used to support 5327 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5328 /// since only such variables can be used in non-loop invariant expressions. 5329 Expr *MinValue = nullptr; 5330 /// Maximum value that can have the loop control variable. Used to support 5331 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5332 /// since only such variables can be used in non-loop invariant expressions. 5333 Expr *MaxValue = nullptr; 5334 /// true, if the lower bound depends on the outer loop control var. 5335 bool IsNonRectangularLB = false; 5336 /// true, if the upper bound depends on the outer loop control var. 5337 bool IsNonRectangularUB = false; 5338 /// Index of the loop this loop depends on and forms non-rectangular loop 5339 /// nest. 5340 unsigned LoopDependentIdx = 0; 5341 /// Final condition for the non-rectangular loop nest support. It is used to 5342 /// check that the number of iterations for this particular counter must be 5343 /// finished. 5344 Expr *FinalCondition = nullptr; 5345 }; 5346 5347 /// Helper class for checking canonical form of the OpenMP loops and 5348 /// extracting iteration space of each loop in the loop nest, that will be used 5349 /// for IR generation. 5350 class OpenMPIterationSpaceChecker { 5351 /// Reference to Sema. 5352 Sema &SemaRef; 5353 /// Data-sharing stack. 5354 DSAStackTy &Stack; 5355 /// A location for diagnostics (when there is no some better location). 5356 SourceLocation DefaultLoc; 5357 /// A location for diagnostics (when increment is not compatible). 5358 SourceLocation ConditionLoc; 5359 /// A source location for referring to loop init later. 5360 SourceRange InitSrcRange; 5361 /// A source location for referring to condition later. 5362 SourceRange ConditionSrcRange; 5363 /// A source location for referring to increment later. 5364 SourceRange IncrementSrcRange; 5365 /// Loop variable. 5366 ValueDecl *LCDecl = nullptr; 5367 /// Reference to loop variable. 5368 Expr *LCRef = nullptr; 5369 /// Lower bound (initializer for the var). 5370 Expr *LB = nullptr; 5371 /// Upper bound. 5372 Expr *UB = nullptr; 5373 /// Loop step (increment). 5374 Expr *Step = nullptr; 5375 /// This flag is true when condition is one of: 5376 /// Var < UB 5377 /// Var <= UB 5378 /// UB > Var 5379 /// UB >= Var 5380 /// This will have no value when the condition is != 5381 llvm::Optional<bool> TestIsLessOp; 5382 /// This flag is true when condition is strict ( < or > ). 5383 bool TestIsStrictOp = false; 5384 /// This flag is true when step is subtracted on each iteration. 5385 bool SubtractStep = false; 5386 /// The outer loop counter this loop depends on (if any). 5387 const ValueDecl *DepDecl = nullptr; 5388 /// Contains number of loop (starts from 1) on which loop counter init 5389 /// expression of this loop depends on. 5390 Optional<unsigned> InitDependOnLC; 5391 /// Contains number of loop (starts from 1) on which loop counter condition 5392 /// expression of this loop depends on. 5393 Optional<unsigned> CondDependOnLC; 5394 /// Checks if the provide statement depends on the loop counter. 5395 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5396 /// Original condition required for checking of the exit condition for 5397 /// non-rectangular loop. 5398 Expr *Condition = nullptr; 5399 5400 public: 5401 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5402 SourceLocation DefaultLoc) 5403 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5404 ConditionLoc(DefaultLoc) {} 5405 /// Check init-expr for canonical loop form and save loop counter 5406 /// variable - #Var and its initialization value - #LB. 5407 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5408 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5409 /// for less/greater and for strict/non-strict comparison. 5410 bool checkAndSetCond(Expr *S); 5411 /// Check incr-expr for canonical loop form and return true if it 5412 /// does not conform, otherwise save loop step (#Step). 5413 bool checkAndSetInc(Expr *S); 5414 /// Return the loop counter variable. 5415 ValueDecl *getLoopDecl() const { return LCDecl; } 5416 /// Return the reference expression to loop counter variable. 5417 Expr *getLoopDeclRefExpr() const { return LCRef; } 5418 /// Source range of the loop init. 5419 SourceRange getInitSrcRange() const { return InitSrcRange; } 5420 /// Source range of the loop condition. 5421 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5422 /// Source range of the loop increment. 5423 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5424 /// True if the step should be subtracted. 5425 bool shouldSubtractStep() const { return SubtractStep; } 5426 /// True, if the compare operator is strict (<, > or !=). 5427 bool isStrictTestOp() const { return TestIsStrictOp; } 5428 /// Build the expression to calculate the number of iterations. 5429 Expr *buildNumIterations( 5430 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5431 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5432 /// Build the precondition expression for the loops. 5433 Expr * 5434 buildPreCond(Scope *S, Expr *Cond, 5435 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5436 /// Build reference expression to the counter be used for codegen. 5437 DeclRefExpr * 5438 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5439 DSAStackTy &DSA) const; 5440 /// Build reference expression to the private counter be used for 5441 /// codegen. 5442 Expr *buildPrivateCounterVar() const; 5443 /// Build initialization of the counter be used for codegen. 5444 Expr *buildCounterInit() const; 5445 /// Build step of the counter be used for codegen. 5446 Expr *buildCounterStep() const; 5447 /// Build loop data with counter value for depend clauses in ordered 5448 /// directives. 5449 Expr * 5450 buildOrderedLoopData(Scope *S, Expr *Counter, 5451 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5452 SourceLocation Loc, Expr *Inc = nullptr, 5453 OverloadedOperatorKind OOK = OO_Amp); 5454 /// Builds the minimum value for the loop counter. 5455 std::pair<Expr *, Expr *> buildMinMaxValues( 5456 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5457 /// Builds final condition for the non-rectangular loops. 5458 Expr *buildFinalCondition(Scope *S) const; 5459 /// Return true if any expression is dependent. 5460 bool dependent() const; 5461 /// Returns true if the initializer forms non-rectangular loop. 5462 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5463 /// Returns true if the condition forms non-rectangular loop. 5464 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5465 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5466 unsigned getLoopDependentIdx() const { 5467 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5468 } 5469 5470 private: 5471 /// Check the right-hand side of an assignment in the increment 5472 /// expression. 5473 bool checkAndSetIncRHS(Expr *RHS); 5474 /// Helper to set loop counter variable and its initializer. 5475 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5476 bool EmitDiags); 5477 /// Helper to set upper bound. 5478 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5479 SourceRange SR, SourceLocation SL); 5480 /// Helper to set loop increment. 5481 bool setStep(Expr *NewStep, bool Subtract); 5482 }; 5483 5484 bool OpenMPIterationSpaceChecker::dependent() const { 5485 if (!LCDecl) { 5486 assert(!LB && !UB && !Step); 5487 return false; 5488 } 5489 return LCDecl->getType()->isDependentType() || 5490 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5491 (Step && Step->isValueDependent()); 5492 } 5493 5494 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5495 Expr *NewLCRefExpr, 5496 Expr *NewLB, bool EmitDiags) { 5497 // State consistency checking to ensure correct usage. 5498 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5499 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5500 if (!NewLCDecl || !NewLB) 5501 return true; 5502 LCDecl = getCanonicalDecl(NewLCDecl); 5503 LCRef = NewLCRefExpr; 5504 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5505 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5506 if ((Ctor->isCopyOrMoveConstructor() || 5507 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5508 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5509 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5510 LB = NewLB; 5511 if (EmitDiags) 5512 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5513 return false; 5514 } 5515 5516 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5517 llvm::Optional<bool> LessOp, 5518 bool StrictOp, SourceRange SR, 5519 SourceLocation SL) { 5520 // State consistency checking to ensure correct usage. 5521 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5522 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5523 if (!NewUB) 5524 return true; 5525 UB = NewUB; 5526 if (LessOp) 5527 TestIsLessOp = LessOp; 5528 TestIsStrictOp = StrictOp; 5529 ConditionSrcRange = SR; 5530 ConditionLoc = SL; 5531 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5532 return false; 5533 } 5534 5535 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5536 // State consistency checking to ensure correct usage. 5537 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5538 if (!NewStep) 5539 return true; 5540 if (!NewStep->isValueDependent()) { 5541 // Check that the step is integer expression. 5542 SourceLocation StepLoc = NewStep->getBeginLoc(); 5543 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5544 StepLoc, getExprAsWritten(NewStep)); 5545 if (Val.isInvalid()) 5546 return true; 5547 NewStep = Val.get(); 5548 5549 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5550 // If test-expr is of form var relational-op b and relational-op is < or 5551 // <= then incr-expr must cause var to increase on each iteration of the 5552 // loop. If test-expr is of form var relational-op b and relational-op is 5553 // > or >= then incr-expr must cause var to decrease on each iteration of 5554 // the loop. 5555 // If test-expr is of form b relational-op var and relational-op is < or 5556 // <= then incr-expr must cause var to decrease on each iteration of the 5557 // loop. If test-expr is of form b relational-op var and relational-op is 5558 // > or >= then incr-expr must cause var to increase on each iteration of 5559 // the loop. 5560 llvm::APSInt Result; 5561 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5562 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5563 bool IsConstNeg = 5564 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5565 bool IsConstPos = 5566 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5567 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5568 5569 // != with increment is treated as <; != with decrement is treated as > 5570 if (!TestIsLessOp.hasValue()) 5571 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5572 if (UB && (IsConstZero || 5573 (TestIsLessOp.getValue() ? 5574 (IsConstNeg || (IsUnsigned && Subtract)) : 5575 (IsConstPos || (IsUnsigned && !Subtract))))) { 5576 SemaRef.Diag(NewStep->getExprLoc(), 5577 diag::err_omp_loop_incr_not_compatible) 5578 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5579 SemaRef.Diag(ConditionLoc, 5580 diag::note_omp_loop_cond_requres_compatible_incr) 5581 << TestIsLessOp.getValue() << ConditionSrcRange; 5582 return true; 5583 } 5584 if (TestIsLessOp.getValue() == Subtract) { 5585 NewStep = 5586 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5587 .get(); 5588 Subtract = !Subtract; 5589 } 5590 } 5591 5592 Step = NewStep; 5593 SubtractStep = Subtract; 5594 return false; 5595 } 5596 5597 namespace { 5598 /// Checker for the non-rectangular loops. Checks if the initializer or 5599 /// condition expression references loop counter variable. 5600 class LoopCounterRefChecker final 5601 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5602 Sema &SemaRef; 5603 DSAStackTy &Stack; 5604 const ValueDecl *CurLCDecl = nullptr; 5605 const ValueDecl *DepDecl = nullptr; 5606 const ValueDecl *PrevDepDecl = nullptr; 5607 bool IsInitializer = true; 5608 unsigned BaseLoopId = 0; 5609 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5610 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5611 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5612 << (IsInitializer ? 0 : 1); 5613 return false; 5614 } 5615 const auto &&Data = Stack.isLoopControlVariable(VD); 5616 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5617 // The type of the loop iterator on which we depend may not have a random 5618 // access iterator type. 5619 if (Data.first && VD->getType()->isRecordType()) { 5620 SmallString<128> Name; 5621 llvm::raw_svector_ostream OS(Name); 5622 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5623 /*Qualified=*/true); 5624 SemaRef.Diag(E->getExprLoc(), 5625 diag::err_omp_wrong_dependency_iterator_type) 5626 << OS.str(); 5627 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5628 return false; 5629 } 5630 if (Data.first && 5631 (DepDecl || (PrevDepDecl && 5632 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5633 if (!DepDecl && PrevDepDecl) 5634 DepDecl = PrevDepDecl; 5635 SmallString<128> Name; 5636 llvm::raw_svector_ostream OS(Name); 5637 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5638 /*Qualified=*/true); 5639 SemaRef.Diag(E->getExprLoc(), 5640 diag::err_omp_invariant_or_linear_dependency) 5641 << OS.str(); 5642 return false; 5643 } 5644 if (Data.first) { 5645 DepDecl = VD; 5646 BaseLoopId = Data.first; 5647 } 5648 return Data.first; 5649 } 5650 5651 public: 5652 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5653 const ValueDecl *VD = E->getDecl(); 5654 if (isa<VarDecl>(VD)) 5655 return checkDecl(E, VD); 5656 return false; 5657 } 5658 bool VisitMemberExpr(const MemberExpr *E) { 5659 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5660 const ValueDecl *VD = E->getMemberDecl(); 5661 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5662 return checkDecl(E, VD); 5663 } 5664 return false; 5665 } 5666 bool VisitStmt(const Stmt *S) { 5667 bool Res = false; 5668 for (const Stmt *Child : S->children()) 5669 Res = (Child && Visit(Child)) || Res; 5670 return Res; 5671 } 5672 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5673 const ValueDecl *CurLCDecl, bool IsInitializer, 5674 const ValueDecl *PrevDepDecl = nullptr) 5675 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5676 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5677 unsigned getBaseLoopId() const { 5678 assert(CurLCDecl && "Expected loop dependency."); 5679 return BaseLoopId; 5680 } 5681 const ValueDecl *getDepDecl() const { 5682 assert(CurLCDecl && "Expected loop dependency."); 5683 return DepDecl; 5684 } 5685 }; 5686 } // namespace 5687 5688 Optional<unsigned> 5689 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5690 bool IsInitializer) { 5691 // Check for the non-rectangular loops. 5692 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5693 DepDecl); 5694 if (LoopStmtChecker.Visit(S)) { 5695 DepDecl = LoopStmtChecker.getDepDecl(); 5696 return LoopStmtChecker.getBaseLoopId(); 5697 } 5698 return llvm::None; 5699 } 5700 5701 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5702 // Check init-expr for canonical loop form and save loop counter 5703 // variable - #Var and its initialization value - #LB. 5704 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5705 // var = lb 5706 // integer-type var = lb 5707 // random-access-iterator-type var = lb 5708 // pointer-type var = lb 5709 // 5710 if (!S) { 5711 if (EmitDiags) { 5712 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5713 } 5714 return true; 5715 } 5716 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5717 if (!ExprTemp->cleanupsHaveSideEffects()) 5718 S = ExprTemp->getSubExpr(); 5719 5720 InitSrcRange = S->getSourceRange(); 5721 if (Expr *E = dyn_cast<Expr>(S)) 5722 S = E->IgnoreParens(); 5723 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5724 if (BO->getOpcode() == BO_Assign) { 5725 Expr *LHS = BO->getLHS()->IgnoreParens(); 5726 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5727 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5728 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5729 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5730 EmitDiags); 5731 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5732 } 5733 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5734 if (ME->isArrow() && 5735 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5736 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5737 EmitDiags); 5738 } 5739 } 5740 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5741 if (DS->isSingleDecl()) { 5742 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5743 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5744 // Accept non-canonical init form here but emit ext. warning. 5745 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5746 SemaRef.Diag(S->getBeginLoc(), 5747 diag::ext_omp_loop_not_canonical_init) 5748 << S->getSourceRange(); 5749 return setLCDeclAndLB( 5750 Var, 5751 buildDeclRefExpr(SemaRef, Var, 5752 Var->getType().getNonReferenceType(), 5753 DS->getBeginLoc()), 5754 Var->getInit(), EmitDiags); 5755 } 5756 } 5757 } 5758 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5759 if (CE->getOperator() == OO_Equal) { 5760 Expr *LHS = CE->getArg(0); 5761 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5762 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5763 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5764 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5765 EmitDiags); 5766 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5767 } 5768 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5769 if (ME->isArrow() && 5770 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5771 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5772 EmitDiags); 5773 } 5774 } 5775 } 5776 5777 if (dependent() || SemaRef.CurContext->isDependentContext()) 5778 return false; 5779 if (EmitDiags) { 5780 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5781 << S->getSourceRange(); 5782 } 5783 return true; 5784 } 5785 5786 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5787 /// variable (which may be the loop variable) if possible. 5788 static const ValueDecl *getInitLCDecl(const Expr *E) { 5789 if (!E) 5790 return nullptr; 5791 E = getExprAsWritten(E); 5792 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5793 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5794 if ((Ctor->isCopyOrMoveConstructor() || 5795 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5796 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5797 E = CE->getArg(0)->IgnoreParenImpCasts(); 5798 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5799 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5800 return getCanonicalDecl(VD); 5801 } 5802 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5803 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5804 return getCanonicalDecl(ME->getMemberDecl()); 5805 return nullptr; 5806 } 5807 5808 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5809 // Check test-expr for canonical form, save upper-bound UB, flags for 5810 // less/greater and for strict/non-strict comparison. 5811 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5812 // var relational-op b 5813 // b relational-op var 5814 // 5815 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5816 if (!S) { 5817 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5818 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5819 return true; 5820 } 5821 Condition = S; 5822 S = getExprAsWritten(S); 5823 SourceLocation CondLoc = S->getBeginLoc(); 5824 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5825 if (BO->isRelationalOp()) { 5826 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5827 return setUB(BO->getRHS(), 5828 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5829 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5830 BO->getSourceRange(), BO->getOperatorLoc()); 5831 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5832 return setUB(BO->getLHS(), 5833 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5834 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5835 BO->getSourceRange(), BO->getOperatorLoc()); 5836 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5837 return setUB( 5838 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5839 /*LessOp=*/llvm::None, 5840 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5841 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5842 if (CE->getNumArgs() == 2) { 5843 auto Op = CE->getOperator(); 5844 switch (Op) { 5845 case OO_Greater: 5846 case OO_GreaterEqual: 5847 case OO_Less: 5848 case OO_LessEqual: 5849 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5850 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5851 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5852 CE->getOperatorLoc()); 5853 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5854 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5855 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5856 CE->getOperatorLoc()); 5857 break; 5858 case OO_ExclaimEqual: 5859 if (IneqCondIsCanonical) 5860 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5861 : CE->getArg(0), 5862 /*LessOp=*/llvm::None, 5863 /*StrictOp=*/true, CE->getSourceRange(), 5864 CE->getOperatorLoc()); 5865 break; 5866 default: 5867 break; 5868 } 5869 } 5870 } 5871 if (dependent() || SemaRef.CurContext->isDependentContext()) 5872 return false; 5873 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5874 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5875 return true; 5876 } 5877 5878 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5879 // RHS of canonical loop form increment can be: 5880 // var + incr 5881 // incr + var 5882 // var - incr 5883 // 5884 RHS = RHS->IgnoreParenImpCasts(); 5885 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5886 if (BO->isAdditiveOp()) { 5887 bool IsAdd = BO->getOpcode() == BO_Add; 5888 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5889 return setStep(BO->getRHS(), !IsAdd); 5890 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5891 return setStep(BO->getLHS(), /*Subtract=*/false); 5892 } 5893 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5894 bool IsAdd = CE->getOperator() == OO_Plus; 5895 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5896 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5897 return setStep(CE->getArg(1), !IsAdd); 5898 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5899 return setStep(CE->getArg(0), /*Subtract=*/false); 5900 } 5901 } 5902 if (dependent() || SemaRef.CurContext->isDependentContext()) 5903 return false; 5904 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5905 << RHS->getSourceRange() << LCDecl; 5906 return true; 5907 } 5908 5909 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5910 // Check incr-expr for canonical loop form and return true if it 5911 // does not conform. 5912 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5913 // ++var 5914 // var++ 5915 // --var 5916 // var-- 5917 // var += incr 5918 // var -= incr 5919 // var = var + incr 5920 // var = incr + var 5921 // var = var - incr 5922 // 5923 if (!S) { 5924 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5925 return true; 5926 } 5927 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5928 if (!ExprTemp->cleanupsHaveSideEffects()) 5929 S = ExprTemp->getSubExpr(); 5930 5931 IncrementSrcRange = S->getSourceRange(); 5932 S = S->IgnoreParens(); 5933 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5934 if (UO->isIncrementDecrementOp() && 5935 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5936 return setStep(SemaRef 5937 .ActOnIntegerConstant(UO->getBeginLoc(), 5938 (UO->isDecrementOp() ? -1 : 1)) 5939 .get(), 5940 /*Subtract=*/false); 5941 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5942 switch (BO->getOpcode()) { 5943 case BO_AddAssign: 5944 case BO_SubAssign: 5945 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5946 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5947 break; 5948 case BO_Assign: 5949 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5950 return checkAndSetIncRHS(BO->getRHS()); 5951 break; 5952 default: 5953 break; 5954 } 5955 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5956 switch (CE->getOperator()) { 5957 case OO_PlusPlus: 5958 case OO_MinusMinus: 5959 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5960 return setStep(SemaRef 5961 .ActOnIntegerConstant( 5962 CE->getBeginLoc(), 5963 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5964 .get(), 5965 /*Subtract=*/false); 5966 break; 5967 case OO_PlusEqual: 5968 case OO_MinusEqual: 5969 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5970 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5971 break; 5972 case OO_Equal: 5973 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5974 return checkAndSetIncRHS(CE->getArg(1)); 5975 break; 5976 default: 5977 break; 5978 } 5979 } 5980 if (dependent() || SemaRef.CurContext->isDependentContext()) 5981 return false; 5982 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5983 << S->getSourceRange() << LCDecl; 5984 return true; 5985 } 5986 5987 static ExprResult 5988 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5989 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5990 if (SemaRef.CurContext->isDependentContext()) 5991 return ExprResult(Capture); 5992 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5993 return SemaRef.PerformImplicitConversion( 5994 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5995 /*AllowExplicit=*/true); 5996 auto I = Captures.find(Capture); 5997 if (I != Captures.end()) 5998 return buildCapture(SemaRef, Capture, I->second); 5999 DeclRefExpr *Ref = nullptr; 6000 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6001 Captures[Capture] = Ref; 6002 return Res; 6003 } 6004 6005 /// Build the expression to calculate the number of iterations. 6006 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6007 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6008 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6009 ExprResult Diff; 6010 QualType VarType = LCDecl->getType().getNonReferenceType(); 6011 if (VarType->isIntegerType() || VarType->isPointerType() || 6012 SemaRef.getLangOpts().CPlusPlus) { 6013 Expr *LBVal = LB; 6014 Expr *UBVal = UB; 6015 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6016 // max(LB(MinVal), LB(MaxVal)) 6017 if (InitDependOnLC) { 6018 const LoopIterationSpace &IS = 6019 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6020 InitDependOnLC.getValueOr( 6021 CondDependOnLC.getValueOr(0))]; 6022 if (!IS.MinValue || !IS.MaxValue) 6023 return nullptr; 6024 // OuterVar = Min 6025 ExprResult MinValue = 6026 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6027 if (!MinValue.isUsable()) 6028 return nullptr; 6029 6030 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6031 IS.CounterVar, MinValue.get()); 6032 if (!LBMinVal.isUsable()) 6033 return nullptr; 6034 // OuterVar = Min, LBVal 6035 LBMinVal = 6036 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6037 if (!LBMinVal.isUsable()) 6038 return nullptr; 6039 // (OuterVar = Min, LBVal) 6040 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6041 if (!LBMinVal.isUsable()) 6042 return nullptr; 6043 6044 // OuterVar = Max 6045 ExprResult MaxValue = 6046 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6047 if (!MaxValue.isUsable()) 6048 return nullptr; 6049 6050 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6051 IS.CounterVar, MaxValue.get()); 6052 if (!LBMaxVal.isUsable()) 6053 return nullptr; 6054 // OuterVar = Max, LBVal 6055 LBMaxVal = 6056 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6057 if (!LBMaxVal.isUsable()) 6058 return nullptr; 6059 // (OuterVar = Max, LBVal) 6060 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6061 if (!LBMaxVal.isUsable()) 6062 return nullptr; 6063 6064 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6065 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6066 if (!LBMin || !LBMax) 6067 return nullptr; 6068 // LB(MinVal) < LB(MaxVal) 6069 ExprResult MinLessMaxRes = 6070 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6071 if (!MinLessMaxRes.isUsable()) 6072 return nullptr; 6073 Expr *MinLessMax = 6074 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6075 if (!MinLessMax) 6076 return nullptr; 6077 if (TestIsLessOp.getValue()) { 6078 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6079 // LB(MaxVal)) 6080 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6081 MinLessMax, LBMin, LBMax); 6082 if (!MinLB.isUsable()) 6083 return nullptr; 6084 LBVal = MinLB.get(); 6085 } else { 6086 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6087 // LB(MaxVal)) 6088 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6089 MinLessMax, LBMax, LBMin); 6090 if (!MaxLB.isUsable()) 6091 return nullptr; 6092 LBVal = MaxLB.get(); 6093 } 6094 } 6095 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6096 // min(UB(MinVal), UB(MaxVal)) 6097 if (CondDependOnLC) { 6098 const LoopIterationSpace &IS = 6099 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6100 InitDependOnLC.getValueOr( 6101 CondDependOnLC.getValueOr(0))]; 6102 if (!IS.MinValue || !IS.MaxValue) 6103 return nullptr; 6104 // OuterVar = Min 6105 ExprResult MinValue = 6106 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6107 if (!MinValue.isUsable()) 6108 return nullptr; 6109 6110 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6111 IS.CounterVar, MinValue.get()); 6112 if (!UBMinVal.isUsable()) 6113 return nullptr; 6114 // OuterVar = Min, UBVal 6115 UBMinVal = 6116 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6117 if (!UBMinVal.isUsable()) 6118 return nullptr; 6119 // (OuterVar = Min, UBVal) 6120 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6121 if (!UBMinVal.isUsable()) 6122 return nullptr; 6123 6124 // OuterVar = Max 6125 ExprResult MaxValue = 6126 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6127 if (!MaxValue.isUsable()) 6128 return nullptr; 6129 6130 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6131 IS.CounterVar, MaxValue.get()); 6132 if (!UBMaxVal.isUsable()) 6133 return nullptr; 6134 // OuterVar = Max, UBVal 6135 UBMaxVal = 6136 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6137 if (!UBMaxVal.isUsable()) 6138 return nullptr; 6139 // (OuterVar = Max, UBVal) 6140 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6141 if (!UBMaxVal.isUsable()) 6142 return nullptr; 6143 6144 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6145 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6146 if (!UBMin || !UBMax) 6147 return nullptr; 6148 // UB(MinVal) > UB(MaxVal) 6149 ExprResult MinGreaterMaxRes = 6150 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6151 if (!MinGreaterMaxRes.isUsable()) 6152 return nullptr; 6153 Expr *MinGreaterMax = 6154 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6155 if (!MinGreaterMax) 6156 return nullptr; 6157 if (TestIsLessOp.getValue()) { 6158 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6159 // UB(MaxVal)) 6160 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6161 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6162 if (!MaxUB.isUsable()) 6163 return nullptr; 6164 UBVal = MaxUB.get(); 6165 } else { 6166 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6167 // UB(MaxVal)) 6168 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6169 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6170 if (!MinUB.isUsable()) 6171 return nullptr; 6172 UBVal = MinUB.get(); 6173 } 6174 } 6175 // Upper - Lower 6176 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6177 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6178 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6179 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6180 if (!Upper || !Lower) 6181 return nullptr; 6182 6183 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6184 6185 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6186 // BuildBinOp already emitted error, this one is to point user to upper 6187 // and lower bound, and to tell what is passed to 'operator-'. 6188 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6189 << Upper->getSourceRange() << Lower->getSourceRange(); 6190 return nullptr; 6191 } 6192 } 6193 6194 if (!Diff.isUsable()) 6195 return nullptr; 6196 6197 // Upper - Lower [- 1] 6198 if (TestIsStrictOp) 6199 Diff = SemaRef.BuildBinOp( 6200 S, DefaultLoc, BO_Sub, Diff.get(), 6201 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6202 if (!Diff.isUsable()) 6203 return nullptr; 6204 6205 // Upper - Lower [- 1] + Step 6206 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6207 if (!NewStep.isUsable()) 6208 return nullptr; 6209 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6210 if (!Diff.isUsable()) 6211 return nullptr; 6212 6213 // Parentheses (for dumping/debugging purposes only). 6214 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6215 if (!Diff.isUsable()) 6216 return nullptr; 6217 6218 // (Upper - Lower [- 1] + Step) / Step 6219 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6220 if (!Diff.isUsable()) 6221 return nullptr; 6222 6223 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6224 QualType Type = Diff.get()->getType(); 6225 ASTContext &C = SemaRef.Context; 6226 bool UseVarType = VarType->hasIntegerRepresentation() && 6227 C.getTypeSize(Type) > C.getTypeSize(VarType); 6228 if (!Type->isIntegerType() || UseVarType) { 6229 unsigned NewSize = 6230 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6231 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6232 : Type->hasSignedIntegerRepresentation(); 6233 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6234 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6235 Diff = SemaRef.PerformImplicitConversion( 6236 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6237 if (!Diff.isUsable()) 6238 return nullptr; 6239 } 6240 } 6241 if (LimitedType) { 6242 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6243 if (NewSize != C.getTypeSize(Type)) { 6244 if (NewSize < C.getTypeSize(Type)) { 6245 assert(NewSize == 64 && "incorrect loop var size"); 6246 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6247 << InitSrcRange << ConditionSrcRange; 6248 } 6249 QualType NewType = C.getIntTypeForBitwidth( 6250 NewSize, Type->hasSignedIntegerRepresentation() || 6251 C.getTypeSize(Type) < NewSize); 6252 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6253 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6254 Sema::AA_Converting, true); 6255 if (!Diff.isUsable()) 6256 return nullptr; 6257 } 6258 } 6259 } 6260 6261 return Diff.get(); 6262 } 6263 6264 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6265 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6266 // Do not build for iterators, they cannot be used in non-rectangular loop 6267 // nests. 6268 if (LCDecl->getType()->isRecordType()) 6269 return std::make_pair(nullptr, nullptr); 6270 // If we subtract, the min is in the condition, otherwise the min is in the 6271 // init value. 6272 Expr *MinExpr = nullptr; 6273 Expr *MaxExpr = nullptr; 6274 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6275 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6276 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6277 : CondDependOnLC.hasValue(); 6278 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6279 : InitDependOnLC.hasValue(); 6280 Expr *Lower = 6281 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6282 Expr *Upper = 6283 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6284 if (!Upper || !Lower) 6285 return std::make_pair(nullptr, nullptr); 6286 6287 if (TestIsLessOp.getValue()) 6288 MinExpr = Lower; 6289 else 6290 MaxExpr = Upper; 6291 6292 // Build minimum/maximum value based on number of iterations. 6293 ExprResult Diff; 6294 QualType VarType = LCDecl->getType().getNonReferenceType(); 6295 6296 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6297 if (!Diff.isUsable()) 6298 return std::make_pair(nullptr, nullptr); 6299 6300 // Upper - Lower [- 1] 6301 if (TestIsStrictOp) 6302 Diff = SemaRef.BuildBinOp( 6303 S, DefaultLoc, BO_Sub, Diff.get(), 6304 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6305 if (!Diff.isUsable()) 6306 return std::make_pair(nullptr, nullptr); 6307 6308 // Upper - Lower [- 1] + Step 6309 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6310 if (!NewStep.isUsable()) 6311 return std::make_pair(nullptr, nullptr); 6312 6313 // Parentheses (for dumping/debugging purposes only). 6314 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6315 if (!Diff.isUsable()) 6316 return std::make_pair(nullptr, nullptr); 6317 6318 // (Upper - Lower [- 1]) / Step 6319 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6320 if (!Diff.isUsable()) 6321 return std::make_pair(nullptr, nullptr); 6322 6323 // ((Upper - Lower [- 1]) / Step) * Step 6324 // Parentheses (for dumping/debugging purposes only). 6325 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6326 if (!Diff.isUsable()) 6327 return std::make_pair(nullptr, nullptr); 6328 6329 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6330 if (!Diff.isUsable()) 6331 return std::make_pair(nullptr, nullptr); 6332 6333 // Convert to the original type or ptrdiff_t, if original type is pointer. 6334 if (!VarType->isAnyPointerType() && 6335 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6336 Diff = SemaRef.PerformImplicitConversion( 6337 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6338 } else if (VarType->isAnyPointerType() && 6339 !SemaRef.Context.hasSameType( 6340 Diff.get()->getType(), 6341 SemaRef.Context.getUnsignedPointerDiffType())) { 6342 Diff = SemaRef.PerformImplicitConversion( 6343 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6344 Sema::AA_Converting, /*AllowExplicit=*/true); 6345 } 6346 if (!Diff.isUsable()) 6347 return std::make_pair(nullptr, nullptr); 6348 6349 // Parentheses (for dumping/debugging purposes only). 6350 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6351 if (!Diff.isUsable()) 6352 return std::make_pair(nullptr, nullptr); 6353 6354 if (TestIsLessOp.getValue()) { 6355 // MinExpr = Lower; 6356 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6357 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6358 if (!Diff.isUsable()) 6359 return std::make_pair(nullptr, nullptr); 6360 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6361 if (!Diff.isUsable()) 6362 return std::make_pair(nullptr, nullptr); 6363 MaxExpr = Diff.get(); 6364 } else { 6365 // MaxExpr = Upper; 6366 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6367 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6368 if (!Diff.isUsable()) 6369 return std::make_pair(nullptr, nullptr); 6370 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6371 if (!Diff.isUsable()) 6372 return std::make_pair(nullptr, nullptr); 6373 MinExpr = Diff.get(); 6374 } 6375 6376 return std::make_pair(MinExpr, MaxExpr); 6377 } 6378 6379 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6380 if (InitDependOnLC || CondDependOnLC) 6381 return Condition; 6382 return nullptr; 6383 } 6384 6385 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6386 Scope *S, Expr *Cond, 6387 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6388 // Do not build a precondition when the condition/initialization is dependent 6389 // to prevent pessimistic early loop exit. 6390 // TODO: this can be improved by calculating min/max values but not sure that 6391 // it will be very effective. 6392 if (CondDependOnLC || InitDependOnLC) 6393 return SemaRef.PerformImplicitConversion( 6394 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6395 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6396 /*AllowExplicit=*/true).get(); 6397 6398 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6399 Sema::TentativeAnalysisScope Trap(SemaRef); 6400 6401 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6402 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6403 if (!NewLB.isUsable() || !NewUB.isUsable()) 6404 return nullptr; 6405 6406 ExprResult CondExpr = 6407 SemaRef.BuildBinOp(S, DefaultLoc, 6408 TestIsLessOp.getValue() ? 6409 (TestIsStrictOp ? BO_LT : BO_LE) : 6410 (TestIsStrictOp ? BO_GT : BO_GE), 6411 NewLB.get(), NewUB.get()); 6412 if (CondExpr.isUsable()) { 6413 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6414 SemaRef.Context.BoolTy)) 6415 CondExpr = SemaRef.PerformImplicitConversion( 6416 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6417 /*AllowExplicit=*/true); 6418 } 6419 6420 // Otherwise use original loop condition and evaluate it in runtime. 6421 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6422 } 6423 6424 /// Build reference expression to the counter be used for codegen. 6425 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6426 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6427 DSAStackTy &DSA) const { 6428 auto *VD = dyn_cast<VarDecl>(LCDecl); 6429 if (!VD) { 6430 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6431 DeclRefExpr *Ref = buildDeclRefExpr( 6432 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6433 const DSAStackTy::DSAVarData Data = 6434 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6435 // If the loop control decl is explicitly marked as private, do not mark it 6436 // as captured again. 6437 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6438 Captures.insert(std::make_pair(LCRef, Ref)); 6439 return Ref; 6440 } 6441 return cast<DeclRefExpr>(LCRef); 6442 } 6443 6444 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6445 if (LCDecl && !LCDecl->isInvalidDecl()) { 6446 QualType Type = LCDecl->getType().getNonReferenceType(); 6447 VarDecl *PrivateVar = buildVarDecl( 6448 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6449 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6450 isa<VarDecl>(LCDecl) 6451 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6452 : nullptr); 6453 if (PrivateVar->isInvalidDecl()) 6454 return nullptr; 6455 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6456 } 6457 return nullptr; 6458 } 6459 6460 /// Build initialization of the counter to be used for codegen. 6461 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6462 6463 /// Build step of the counter be used for codegen. 6464 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6465 6466 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6467 Scope *S, Expr *Counter, 6468 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6469 Expr *Inc, OverloadedOperatorKind OOK) { 6470 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6471 if (!Cnt) 6472 return nullptr; 6473 if (Inc) { 6474 assert((OOK == OO_Plus || OOK == OO_Minus) && 6475 "Expected only + or - operations for depend clauses."); 6476 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6477 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6478 if (!Cnt) 6479 return nullptr; 6480 } 6481 ExprResult Diff; 6482 QualType VarType = LCDecl->getType().getNonReferenceType(); 6483 if (VarType->isIntegerType() || VarType->isPointerType() || 6484 SemaRef.getLangOpts().CPlusPlus) { 6485 // Upper - Lower 6486 Expr *Upper = TestIsLessOp.getValue() 6487 ? Cnt 6488 : tryBuildCapture(SemaRef, UB, Captures).get(); 6489 Expr *Lower = TestIsLessOp.getValue() 6490 ? tryBuildCapture(SemaRef, LB, Captures).get() 6491 : Cnt; 6492 if (!Upper || !Lower) 6493 return nullptr; 6494 6495 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6496 6497 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6498 // BuildBinOp already emitted error, this one is to point user to upper 6499 // and lower bound, and to tell what is passed to 'operator-'. 6500 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6501 << Upper->getSourceRange() << Lower->getSourceRange(); 6502 return nullptr; 6503 } 6504 } 6505 6506 if (!Diff.isUsable()) 6507 return nullptr; 6508 6509 // Parentheses (for dumping/debugging purposes only). 6510 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6511 if (!Diff.isUsable()) 6512 return nullptr; 6513 6514 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6515 if (!NewStep.isUsable()) 6516 return nullptr; 6517 // (Upper - Lower) / Step 6518 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6519 if (!Diff.isUsable()) 6520 return nullptr; 6521 6522 return Diff.get(); 6523 } 6524 } // namespace 6525 6526 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6527 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6528 assert(Init && "Expected loop in canonical form."); 6529 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6530 if (AssociatedLoops > 0 && 6531 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6532 DSAStack->loopStart(); 6533 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6534 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6535 if (ValueDecl *D = ISC.getLoopDecl()) { 6536 auto *VD = dyn_cast<VarDecl>(D); 6537 DeclRefExpr *PrivateRef = nullptr; 6538 if (!VD) { 6539 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6540 VD = Private; 6541 } else { 6542 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6543 /*WithInit=*/false); 6544 VD = cast<VarDecl>(PrivateRef->getDecl()); 6545 } 6546 } 6547 DSAStack->addLoopControlVariable(D, VD); 6548 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6549 if (LD != D->getCanonicalDecl()) { 6550 DSAStack->resetPossibleLoopCounter(); 6551 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6552 MarkDeclarationsReferencedInExpr( 6553 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6554 Var->getType().getNonLValueExprType(Context), 6555 ForLoc, /*RefersToCapture=*/true)); 6556 } 6557 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6558 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6559 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6560 // associated for-loop of a simd construct with just one associated 6561 // for-loop may be listed in a linear clause with a constant-linear-step 6562 // that is the increment of the associated for-loop. The loop iteration 6563 // variable(s) in the associated for-loop(s) of a for or parallel for 6564 // construct may be listed in a private or lastprivate clause. 6565 DSAStackTy::DSAVarData DVar = 6566 DSAStack->getTopDSA(D, /*FromParent=*/false); 6567 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6568 // is declared in the loop and it is predetermined as a private. 6569 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6570 OpenMPClauseKind PredeterminedCKind = 6571 isOpenMPSimdDirective(DKind) 6572 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6573 : OMPC_private; 6574 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6575 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6576 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6577 DVar.CKind != OMPC_private))) || 6578 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6579 DKind == OMPD_master_taskloop || 6580 DKind == OMPD_parallel_master_taskloop || 6581 isOpenMPDistributeDirective(DKind)) && 6582 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6583 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6584 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6585 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6586 << getOpenMPClauseName(DVar.CKind) 6587 << getOpenMPDirectiveName(DKind) 6588 << getOpenMPClauseName(PredeterminedCKind); 6589 if (DVar.RefExpr == nullptr) 6590 DVar.CKind = PredeterminedCKind; 6591 reportOriginalDsa(*this, DSAStack, D, DVar, 6592 /*IsLoopIterVar=*/true); 6593 } else if (LoopDeclRefExpr) { 6594 // Make the loop iteration variable private (for worksharing 6595 // constructs), linear (for simd directives with the only one 6596 // associated loop) or lastprivate (for simd directives with several 6597 // collapsed or ordered loops). 6598 if (DVar.CKind == OMPC_unknown) 6599 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6600 PrivateRef); 6601 } 6602 } 6603 } 6604 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6605 } 6606 } 6607 6608 /// Called on a for stmt to check and extract its iteration space 6609 /// for further processing (such as collapsing). 6610 static bool checkOpenMPIterationSpace( 6611 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6612 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6613 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6614 Expr *OrderedLoopCountExpr, 6615 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6616 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6617 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6618 // OpenMP [2.9.1, Canonical Loop Form] 6619 // for (init-expr; test-expr; incr-expr) structured-block 6620 // for (range-decl: range-expr) structured-block 6621 auto *For = dyn_cast_or_null<ForStmt>(S); 6622 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6623 // Ranged for is supported only in OpenMP 5.0. 6624 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6625 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6626 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6627 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6628 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6629 if (TotalNestedLoopCount > 1) { 6630 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6631 SemaRef.Diag(DSA.getConstructLoc(), 6632 diag::note_omp_collapse_ordered_expr) 6633 << 2 << CollapseLoopCountExpr->getSourceRange() 6634 << OrderedLoopCountExpr->getSourceRange(); 6635 else if (CollapseLoopCountExpr) 6636 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6637 diag::note_omp_collapse_ordered_expr) 6638 << 0 << CollapseLoopCountExpr->getSourceRange(); 6639 else 6640 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6641 diag::note_omp_collapse_ordered_expr) 6642 << 1 << OrderedLoopCountExpr->getSourceRange(); 6643 } 6644 return true; 6645 } 6646 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6647 "No loop body."); 6648 6649 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6650 For ? For->getForLoc() : CXXFor->getForLoc()); 6651 6652 // Check init. 6653 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6654 if (ISC.checkAndSetInit(Init)) 6655 return true; 6656 6657 bool HasErrors = false; 6658 6659 // Check loop variable's type. 6660 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6661 // OpenMP [2.6, Canonical Loop Form] 6662 // Var is one of the following: 6663 // A variable of signed or unsigned integer type. 6664 // For C++, a variable of a random access iterator type. 6665 // For C, a variable of a pointer type. 6666 QualType VarType = LCDecl->getType().getNonReferenceType(); 6667 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6668 !VarType->isPointerType() && 6669 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6670 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6671 << SemaRef.getLangOpts().CPlusPlus; 6672 HasErrors = true; 6673 } 6674 6675 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6676 // a Construct 6677 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6678 // parallel for construct is (are) private. 6679 // The loop iteration variable in the associated for-loop of a simd 6680 // construct with just one associated for-loop is linear with a 6681 // constant-linear-step that is the increment of the associated for-loop. 6682 // Exclude loop var from the list of variables with implicitly defined data 6683 // sharing attributes. 6684 VarsWithImplicitDSA.erase(LCDecl); 6685 6686 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6687 6688 // Check test-expr. 6689 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6690 6691 // Check incr-expr. 6692 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6693 } 6694 6695 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6696 return HasErrors; 6697 6698 // Build the loop's iteration space representation. 6699 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6700 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6701 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6702 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6703 (isOpenMPWorksharingDirective(DKind) || 6704 isOpenMPTaskLoopDirective(DKind) || 6705 isOpenMPDistributeDirective(DKind)), 6706 Captures); 6707 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6708 ISC.buildCounterVar(Captures, DSA); 6709 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6710 ISC.buildPrivateCounterVar(); 6711 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6712 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6713 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6714 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6715 ISC.getConditionSrcRange(); 6716 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6717 ISC.getIncrementSrcRange(); 6718 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6719 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6720 ISC.isStrictTestOp(); 6721 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6722 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6723 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6724 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6725 ISC.buildFinalCondition(DSA.getCurScope()); 6726 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6727 ISC.doesInitDependOnLC(); 6728 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6729 ISC.doesCondDependOnLC(); 6730 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6731 ISC.getLoopDependentIdx(); 6732 6733 HasErrors |= 6734 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6735 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6736 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6737 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6738 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6739 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6740 if (!HasErrors && DSA.isOrderedRegion()) { 6741 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6742 if (CurrentNestedLoopCount < 6743 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6744 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6745 CurrentNestedLoopCount, 6746 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6747 DSA.getOrderedRegionParam().second->setLoopCounter( 6748 CurrentNestedLoopCount, 6749 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6750 } 6751 } 6752 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6753 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6754 // Erroneous case - clause has some problems. 6755 continue; 6756 } 6757 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6758 Pair.second.size() <= CurrentNestedLoopCount) { 6759 // Erroneous case - clause has some problems. 6760 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6761 continue; 6762 } 6763 Expr *CntValue; 6764 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6765 CntValue = ISC.buildOrderedLoopData( 6766 DSA.getCurScope(), 6767 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6768 Pair.first->getDependencyLoc()); 6769 else 6770 CntValue = ISC.buildOrderedLoopData( 6771 DSA.getCurScope(), 6772 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6773 Pair.first->getDependencyLoc(), 6774 Pair.second[CurrentNestedLoopCount].first, 6775 Pair.second[CurrentNestedLoopCount].second); 6776 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6777 } 6778 } 6779 6780 return HasErrors; 6781 } 6782 6783 /// Build 'VarRef = Start. 6784 static ExprResult 6785 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6786 ExprResult Start, bool IsNonRectangularLB, 6787 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6788 // Build 'VarRef = Start. 6789 ExprResult NewStart = IsNonRectangularLB 6790 ? Start.get() 6791 : tryBuildCapture(SemaRef, Start.get(), Captures); 6792 if (!NewStart.isUsable()) 6793 return ExprError(); 6794 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6795 VarRef.get()->getType())) { 6796 NewStart = SemaRef.PerformImplicitConversion( 6797 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6798 /*AllowExplicit=*/true); 6799 if (!NewStart.isUsable()) 6800 return ExprError(); 6801 } 6802 6803 ExprResult Init = 6804 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6805 return Init; 6806 } 6807 6808 /// Build 'VarRef = Start + Iter * Step'. 6809 static ExprResult buildCounterUpdate( 6810 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6811 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6812 bool IsNonRectangularLB, 6813 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6814 // Add parentheses (for debugging purposes only). 6815 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6816 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6817 !Step.isUsable()) 6818 return ExprError(); 6819 6820 ExprResult NewStep = Step; 6821 if (Captures) 6822 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6823 if (NewStep.isInvalid()) 6824 return ExprError(); 6825 ExprResult Update = 6826 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6827 if (!Update.isUsable()) 6828 return ExprError(); 6829 6830 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6831 // 'VarRef = Start (+|-) Iter * Step'. 6832 if (!Start.isUsable()) 6833 return ExprError(); 6834 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6835 if (!NewStart.isUsable()) 6836 return ExprError(); 6837 if (Captures && !IsNonRectangularLB) 6838 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6839 if (NewStart.isInvalid()) 6840 return ExprError(); 6841 6842 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6843 ExprResult SavedUpdate = Update; 6844 ExprResult UpdateVal; 6845 if (VarRef.get()->getType()->isOverloadableType() || 6846 NewStart.get()->getType()->isOverloadableType() || 6847 Update.get()->getType()->isOverloadableType()) { 6848 Sema::TentativeAnalysisScope Trap(SemaRef); 6849 6850 Update = 6851 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6852 if (Update.isUsable()) { 6853 UpdateVal = 6854 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6855 VarRef.get(), SavedUpdate.get()); 6856 if (UpdateVal.isUsable()) { 6857 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6858 UpdateVal.get()); 6859 } 6860 } 6861 } 6862 6863 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6864 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6865 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6866 NewStart.get(), SavedUpdate.get()); 6867 if (!Update.isUsable()) 6868 return ExprError(); 6869 6870 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6871 VarRef.get()->getType())) { 6872 Update = SemaRef.PerformImplicitConversion( 6873 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6874 if (!Update.isUsable()) 6875 return ExprError(); 6876 } 6877 6878 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6879 } 6880 return Update; 6881 } 6882 6883 /// Convert integer expression \a E to make it have at least \a Bits 6884 /// bits. 6885 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6886 if (E == nullptr) 6887 return ExprError(); 6888 ASTContext &C = SemaRef.Context; 6889 QualType OldType = E->getType(); 6890 unsigned HasBits = C.getTypeSize(OldType); 6891 if (HasBits >= Bits) 6892 return ExprResult(E); 6893 // OK to convert to signed, because new type has more bits than old. 6894 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6895 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6896 true); 6897 } 6898 6899 /// Check if the given expression \a E is a constant integer that fits 6900 /// into \a Bits bits. 6901 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6902 if (E == nullptr) 6903 return false; 6904 llvm::APSInt Result; 6905 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6906 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6907 return false; 6908 } 6909 6910 /// Build preinits statement for the given declarations. 6911 static Stmt *buildPreInits(ASTContext &Context, 6912 MutableArrayRef<Decl *> PreInits) { 6913 if (!PreInits.empty()) { 6914 return new (Context) DeclStmt( 6915 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6916 SourceLocation(), SourceLocation()); 6917 } 6918 return nullptr; 6919 } 6920 6921 /// Build preinits statement for the given declarations. 6922 static Stmt * 6923 buildPreInits(ASTContext &Context, 6924 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6925 if (!Captures.empty()) { 6926 SmallVector<Decl *, 16> PreInits; 6927 for (const auto &Pair : Captures) 6928 PreInits.push_back(Pair.second->getDecl()); 6929 return buildPreInits(Context, PreInits); 6930 } 6931 return nullptr; 6932 } 6933 6934 /// Build postupdate expression for the given list of postupdates expressions. 6935 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6936 Expr *PostUpdate = nullptr; 6937 if (!PostUpdates.empty()) { 6938 for (Expr *E : PostUpdates) { 6939 Expr *ConvE = S.BuildCStyleCastExpr( 6940 E->getExprLoc(), 6941 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6942 E->getExprLoc(), E) 6943 .get(); 6944 PostUpdate = PostUpdate 6945 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6946 PostUpdate, ConvE) 6947 .get() 6948 : ConvE; 6949 } 6950 } 6951 return PostUpdate; 6952 } 6953 6954 /// Called on a for stmt to check itself and nested loops (if any). 6955 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6956 /// number of collapsed loops otherwise. 6957 static unsigned 6958 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6959 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6960 DSAStackTy &DSA, 6961 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6962 OMPLoopDirective::HelperExprs &Built) { 6963 unsigned NestedLoopCount = 1; 6964 if (CollapseLoopCountExpr) { 6965 // Found 'collapse' clause - calculate collapse number. 6966 Expr::EvalResult Result; 6967 if (!CollapseLoopCountExpr->isValueDependent() && 6968 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6969 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6970 } else { 6971 Built.clear(/*Size=*/1); 6972 return 1; 6973 } 6974 } 6975 unsigned OrderedLoopCount = 1; 6976 if (OrderedLoopCountExpr) { 6977 // Found 'ordered' clause - calculate collapse number. 6978 Expr::EvalResult EVResult; 6979 if (!OrderedLoopCountExpr->isValueDependent() && 6980 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6981 SemaRef.getASTContext())) { 6982 llvm::APSInt Result = EVResult.Val.getInt(); 6983 if (Result.getLimitedValue() < NestedLoopCount) { 6984 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6985 diag::err_omp_wrong_ordered_loop_count) 6986 << OrderedLoopCountExpr->getSourceRange(); 6987 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6988 diag::note_collapse_loop_count) 6989 << CollapseLoopCountExpr->getSourceRange(); 6990 } 6991 OrderedLoopCount = Result.getLimitedValue(); 6992 } else { 6993 Built.clear(/*Size=*/1); 6994 return 1; 6995 } 6996 } 6997 // This is helper routine for loop directives (e.g., 'for', 'simd', 6998 // 'for simd', etc.). 6999 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7000 SmallVector<LoopIterationSpace, 4> IterSpaces( 7001 std::max(OrderedLoopCount, NestedLoopCount)); 7002 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7003 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7004 if (checkOpenMPIterationSpace( 7005 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7006 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7007 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7008 return 0; 7009 // Move on to the next nested for loop, or to the loop body. 7010 // OpenMP [2.8.1, simd construct, Restrictions] 7011 // All loops associated with the construct must be perfectly nested; that 7012 // is, there must be no intervening code nor any OpenMP directive between 7013 // any two loops. 7014 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7015 CurStmt = For->getBody(); 7016 } else { 7017 assert(isa<CXXForRangeStmt>(CurStmt) && 7018 "Expected canonical for or range-based for loops."); 7019 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7020 } 7021 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7022 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7023 } 7024 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7025 if (checkOpenMPIterationSpace( 7026 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7027 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7028 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7029 return 0; 7030 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7031 // Handle initialization of captured loop iterator variables. 7032 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7033 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7034 Captures[DRE] = DRE; 7035 } 7036 } 7037 // Move on to the next nested for loop, or to the loop body. 7038 // OpenMP [2.8.1, simd construct, Restrictions] 7039 // All loops associated with the construct must be perfectly nested; that 7040 // is, there must be no intervening code nor any OpenMP directive between 7041 // any two loops. 7042 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7043 CurStmt = For->getBody(); 7044 } else { 7045 assert(isa<CXXForRangeStmt>(CurStmt) && 7046 "Expected canonical for or range-based for loops."); 7047 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7048 } 7049 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7050 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7051 } 7052 7053 Built.clear(/* size */ NestedLoopCount); 7054 7055 if (SemaRef.CurContext->isDependentContext()) 7056 return NestedLoopCount; 7057 7058 // An example of what is generated for the following code: 7059 // 7060 // #pragma omp simd collapse(2) ordered(2) 7061 // for (i = 0; i < NI; ++i) 7062 // for (k = 0; k < NK; ++k) 7063 // for (j = J0; j < NJ; j+=2) { 7064 // <loop body> 7065 // } 7066 // 7067 // We generate the code below. 7068 // Note: the loop body may be outlined in CodeGen. 7069 // Note: some counters may be C++ classes, operator- is used to find number of 7070 // iterations and operator+= to calculate counter value. 7071 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7072 // or i64 is currently supported). 7073 // 7074 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7075 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7076 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7077 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7078 // // similar updates for vars in clauses (e.g. 'linear') 7079 // <loop body (using local i and j)> 7080 // } 7081 // i = NI; // assign final values of counters 7082 // j = NJ; 7083 // 7084 7085 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7086 // the iteration counts of the collapsed for loops. 7087 // Precondition tests if there is at least one iteration (all conditions are 7088 // true). 7089 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7090 Expr *N0 = IterSpaces[0].NumIterations; 7091 ExprResult LastIteration32 = 7092 widenIterationCount(/*Bits=*/32, 7093 SemaRef 7094 .PerformImplicitConversion( 7095 N0->IgnoreImpCasts(), N0->getType(), 7096 Sema::AA_Converting, /*AllowExplicit=*/true) 7097 .get(), 7098 SemaRef); 7099 ExprResult LastIteration64 = widenIterationCount( 7100 /*Bits=*/64, 7101 SemaRef 7102 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7103 Sema::AA_Converting, 7104 /*AllowExplicit=*/true) 7105 .get(), 7106 SemaRef); 7107 7108 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7109 return NestedLoopCount; 7110 7111 ASTContext &C = SemaRef.Context; 7112 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7113 7114 Scope *CurScope = DSA.getCurScope(); 7115 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7116 if (PreCond.isUsable()) { 7117 PreCond = 7118 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7119 PreCond.get(), IterSpaces[Cnt].PreCond); 7120 } 7121 Expr *N = IterSpaces[Cnt].NumIterations; 7122 SourceLocation Loc = N->getExprLoc(); 7123 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7124 if (LastIteration32.isUsable()) 7125 LastIteration32 = SemaRef.BuildBinOp( 7126 CurScope, Loc, BO_Mul, LastIteration32.get(), 7127 SemaRef 7128 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7129 Sema::AA_Converting, 7130 /*AllowExplicit=*/true) 7131 .get()); 7132 if (LastIteration64.isUsable()) 7133 LastIteration64 = SemaRef.BuildBinOp( 7134 CurScope, Loc, BO_Mul, LastIteration64.get(), 7135 SemaRef 7136 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7137 Sema::AA_Converting, 7138 /*AllowExplicit=*/true) 7139 .get()); 7140 } 7141 7142 // Choose either the 32-bit or 64-bit version. 7143 ExprResult LastIteration = LastIteration64; 7144 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7145 (LastIteration32.isUsable() && 7146 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7147 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7148 fitsInto( 7149 /*Bits=*/32, 7150 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7151 LastIteration64.get(), SemaRef)))) 7152 LastIteration = LastIteration32; 7153 QualType VType = LastIteration.get()->getType(); 7154 QualType RealVType = VType; 7155 QualType StrideVType = VType; 7156 if (isOpenMPTaskLoopDirective(DKind)) { 7157 VType = 7158 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7159 StrideVType = 7160 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7161 } 7162 7163 if (!LastIteration.isUsable()) 7164 return 0; 7165 7166 // Save the number of iterations. 7167 ExprResult NumIterations = LastIteration; 7168 { 7169 LastIteration = SemaRef.BuildBinOp( 7170 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7171 LastIteration.get(), 7172 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7173 if (!LastIteration.isUsable()) 7174 return 0; 7175 } 7176 7177 // Calculate the last iteration number beforehand instead of doing this on 7178 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7179 llvm::APSInt Result; 7180 bool IsConstant = 7181 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7182 ExprResult CalcLastIteration; 7183 if (!IsConstant) { 7184 ExprResult SaveRef = 7185 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7186 LastIteration = SaveRef; 7187 7188 // Prepare SaveRef + 1. 7189 NumIterations = SemaRef.BuildBinOp( 7190 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7191 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7192 if (!NumIterations.isUsable()) 7193 return 0; 7194 } 7195 7196 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7197 7198 // Build variables passed into runtime, necessary for worksharing directives. 7199 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7200 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7201 isOpenMPDistributeDirective(DKind)) { 7202 // Lower bound variable, initialized with zero. 7203 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7204 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7205 SemaRef.AddInitializerToDecl(LBDecl, 7206 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7207 /*DirectInit*/ false); 7208 7209 // Upper bound variable, initialized with last iteration number. 7210 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7211 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7212 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7213 /*DirectInit*/ false); 7214 7215 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7216 // This will be used to implement clause 'lastprivate'. 7217 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7218 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7219 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7220 SemaRef.AddInitializerToDecl(ILDecl, 7221 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7222 /*DirectInit*/ false); 7223 7224 // Stride variable returned by runtime (we initialize it to 1 by default). 7225 VarDecl *STDecl = 7226 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7227 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7228 SemaRef.AddInitializerToDecl(STDecl, 7229 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7230 /*DirectInit*/ false); 7231 7232 // Build expression: UB = min(UB, LastIteration) 7233 // It is necessary for CodeGen of directives with static scheduling. 7234 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7235 UB.get(), LastIteration.get()); 7236 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7237 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7238 LastIteration.get(), UB.get()); 7239 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7240 CondOp.get()); 7241 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7242 7243 // If we have a combined directive that combines 'distribute', 'for' or 7244 // 'simd' we need to be able to access the bounds of the schedule of the 7245 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7246 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7247 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7248 // Lower bound variable, initialized with zero. 7249 VarDecl *CombLBDecl = 7250 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7251 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7252 SemaRef.AddInitializerToDecl( 7253 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7254 /*DirectInit*/ false); 7255 7256 // Upper bound variable, initialized with last iteration number. 7257 VarDecl *CombUBDecl = 7258 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7259 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7260 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7261 /*DirectInit*/ false); 7262 7263 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7264 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7265 ExprResult CombCondOp = 7266 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7267 LastIteration.get(), CombUB.get()); 7268 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7269 CombCondOp.get()); 7270 CombEUB = 7271 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7272 7273 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7274 // We expect to have at least 2 more parameters than the 'parallel' 7275 // directive does - the lower and upper bounds of the previous schedule. 7276 assert(CD->getNumParams() >= 4 && 7277 "Unexpected number of parameters in loop combined directive"); 7278 7279 // Set the proper type for the bounds given what we learned from the 7280 // enclosed loops. 7281 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7282 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7283 7284 // Previous lower and upper bounds are obtained from the region 7285 // parameters. 7286 PrevLB = 7287 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7288 PrevUB = 7289 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7290 } 7291 } 7292 7293 // Build the iteration variable and its initialization before loop. 7294 ExprResult IV; 7295 ExprResult Init, CombInit; 7296 { 7297 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7298 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7299 Expr *RHS = 7300 (isOpenMPWorksharingDirective(DKind) || 7301 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7302 ? LB.get() 7303 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7304 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7305 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7306 7307 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7308 Expr *CombRHS = 7309 (isOpenMPWorksharingDirective(DKind) || 7310 isOpenMPTaskLoopDirective(DKind) || 7311 isOpenMPDistributeDirective(DKind)) 7312 ? CombLB.get() 7313 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7314 CombInit = 7315 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7316 CombInit = 7317 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7318 } 7319 } 7320 7321 bool UseStrictCompare = 7322 RealVType->hasUnsignedIntegerRepresentation() && 7323 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7324 return LIS.IsStrictCompare; 7325 }); 7326 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7327 // unsigned IV)) for worksharing loops. 7328 SourceLocation CondLoc = AStmt->getBeginLoc(); 7329 Expr *BoundUB = UB.get(); 7330 if (UseStrictCompare) { 7331 BoundUB = 7332 SemaRef 7333 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7334 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7335 .get(); 7336 BoundUB = 7337 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7338 } 7339 ExprResult Cond = 7340 (isOpenMPWorksharingDirective(DKind) || 7341 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7342 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7343 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7344 BoundUB) 7345 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7346 NumIterations.get()); 7347 ExprResult CombDistCond; 7348 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7349 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7350 NumIterations.get()); 7351 } 7352 7353 ExprResult CombCond; 7354 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7355 Expr *BoundCombUB = CombUB.get(); 7356 if (UseStrictCompare) { 7357 BoundCombUB = 7358 SemaRef 7359 .BuildBinOp( 7360 CurScope, CondLoc, BO_Add, BoundCombUB, 7361 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7362 .get(); 7363 BoundCombUB = 7364 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7365 .get(); 7366 } 7367 CombCond = 7368 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7369 IV.get(), BoundCombUB); 7370 } 7371 // Loop increment (IV = IV + 1) 7372 SourceLocation IncLoc = AStmt->getBeginLoc(); 7373 ExprResult Inc = 7374 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7375 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7376 if (!Inc.isUsable()) 7377 return 0; 7378 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7379 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7380 if (!Inc.isUsable()) 7381 return 0; 7382 7383 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7384 // Used for directives with static scheduling. 7385 // In combined construct, add combined version that use CombLB and CombUB 7386 // base variables for the update 7387 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7388 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7389 isOpenMPDistributeDirective(DKind)) { 7390 // LB + ST 7391 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7392 if (!NextLB.isUsable()) 7393 return 0; 7394 // LB = LB + ST 7395 NextLB = 7396 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7397 NextLB = 7398 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7399 if (!NextLB.isUsable()) 7400 return 0; 7401 // UB + ST 7402 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7403 if (!NextUB.isUsable()) 7404 return 0; 7405 // UB = UB + ST 7406 NextUB = 7407 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7408 NextUB = 7409 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7410 if (!NextUB.isUsable()) 7411 return 0; 7412 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7413 CombNextLB = 7414 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7415 if (!NextLB.isUsable()) 7416 return 0; 7417 // LB = LB + ST 7418 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7419 CombNextLB.get()); 7420 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7421 /*DiscardedValue*/ false); 7422 if (!CombNextLB.isUsable()) 7423 return 0; 7424 // UB + ST 7425 CombNextUB = 7426 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7427 if (!CombNextUB.isUsable()) 7428 return 0; 7429 // UB = UB + ST 7430 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7431 CombNextUB.get()); 7432 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7433 /*DiscardedValue*/ false); 7434 if (!CombNextUB.isUsable()) 7435 return 0; 7436 } 7437 } 7438 7439 // Create increment expression for distribute loop when combined in a same 7440 // directive with for as IV = IV + ST; ensure upper bound expression based 7441 // on PrevUB instead of NumIterations - used to implement 'for' when found 7442 // in combination with 'distribute', like in 'distribute parallel for' 7443 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7444 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7445 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7446 DistCond = SemaRef.BuildBinOp( 7447 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7448 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7449 7450 DistInc = 7451 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7452 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7453 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7454 DistInc.get()); 7455 DistInc = 7456 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7457 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7458 7459 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7460 // construct 7461 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7462 ExprResult IsUBGreater = 7463 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7464 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7465 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7466 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7467 CondOp.get()); 7468 PrevEUB = 7469 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7470 7471 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7472 // parallel for is in combination with a distribute directive with 7473 // schedule(static, 1) 7474 Expr *BoundPrevUB = PrevUB.get(); 7475 if (UseStrictCompare) { 7476 BoundPrevUB = 7477 SemaRef 7478 .BuildBinOp( 7479 CurScope, CondLoc, BO_Add, BoundPrevUB, 7480 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7481 .get(); 7482 BoundPrevUB = 7483 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7484 .get(); 7485 } 7486 ParForInDistCond = 7487 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7488 IV.get(), BoundPrevUB); 7489 } 7490 7491 // Build updates and final values of the loop counters. 7492 bool HasErrors = false; 7493 Built.Counters.resize(NestedLoopCount); 7494 Built.Inits.resize(NestedLoopCount); 7495 Built.Updates.resize(NestedLoopCount); 7496 Built.Finals.resize(NestedLoopCount); 7497 Built.DependentCounters.resize(NestedLoopCount); 7498 Built.DependentInits.resize(NestedLoopCount); 7499 Built.FinalsConditions.resize(NestedLoopCount); 7500 { 7501 // We implement the following algorithm for obtaining the 7502 // original loop iteration variable values based on the 7503 // value of the collapsed loop iteration variable IV. 7504 // 7505 // Let n+1 be the number of collapsed loops in the nest. 7506 // Iteration variables (I0, I1, .... In) 7507 // Iteration counts (N0, N1, ... Nn) 7508 // 7509 // Acc = IV; 7510 // 7511 // To compute Ik for loop k, 0 <= k <= n, generate: 7512 // Prod = N(k+1) * N(k+2) * ... * Nn; 7513 // Ik = Acc / Prod; 7514 // Acc -= Ik * Prod; 7515 // 7516 ExprResult Acc = IV; 7517 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7518 LoopIterationSpace &IS = IterSpaces[Cnt]; 7519 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7520 ExprResult Iter; 7521 7522 // Compute prod 7523 ExprResult Prod = 7524 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7525 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7526 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7527 IterSpaces[K].NumIterations); 7528 7529 // Iter = Acc / Prod 7530 // If there is at least one more inner loop to avoid 7531 // multiplication by 1. 7532 if (Cnt + 1 < NestedLoopCount) 7533 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7534 Acc.get(), Prod.get()); 7535 else 7536 Iter = Acc; 7537 if (!Iter.isUsable()) { 7538 HasErrors = true; 7539 break; 7540 } 7541 7542 // Update Acc: 7543 // Acc -= Iter * Prod 7544 // Check if there is at least one more inner loop to avoid 7545 // multiplication by 1. 7546 if (Cnt + 1 < NestedLoopCount) 7547 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7548 Iter.get(), Prod.get()); 7549 else 7550 Prod = Iter; 7551 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7552 Acc.get(), Prod.get()); 7553 7554 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7555 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7556 DeclRefExpr *CounterVar = buildDeclRefExpr( 7557 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7558 /*RefersToCapture=*/true); 7559 ExprResult Init = 7560 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7561 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7562 if (!Init.isUsable()) { 7563 HasErrors = true; 7564 break; 7565 } 7566 ExprResult Update = buildCounterUpdate( 7567 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7568 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7569 if (!Update.isUsable()) { 7570 HasErrors = true; 7571 break; 7572 } 7573 7574 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7575 ExprResult Final = 7576 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7577 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7578 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7579 if (!Final.isUsable()) { 7580 HasErrors = true; 7581 break; 7582 } 7583 7584 if (!Update.isUsable() || !Final.isUsable()) { 7585 HasErrors = true; 7586 break; 7587 } 7588 // Save results 7589 Built.Counters[Cnt] = IS.CounterVar; 7590 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7591 Built.Inits[Cnt] = Init.get(); 7592 Built.Updates[Cnt] = Update.get(); 7593 Built.Finals[Cnt] = Final.get(); 7594 Built.DependentCounters[Cnt] = nullptr; 7595 Built.DependentInits[Cnt] = nullptr; 7596 Built.FinalsConditions[Cnt] = nullptr; 7597 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7598 Built.DependentCounters[Cnt] = 7599 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7600 Built.DependentInits[Cnt] = 7601 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7602 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7603 } 7604 } 7605 } 7606 7607 if (HasErrors) 7608 return 0; 7609 7610 // Save results 7611 Built.IterationVarRef = IV.get(); 7612 Built.LastIteration = LastIteration.get(); 7613 Built.NumIterations = NumIterations.get(); 7614 Built.CalcLastIteration = SemaRef 7615 .ActOnFinishFullExpr(CalcLastIteration.get(), 7616 /*DiscardedValue=*/false) 7617 .get(); 7618 Built.PreCond = PreCond.get(); 7619 Built.PreInits = buildPreInits(C, Captures); 7620 Built.Cond = Cond.get(); 7621 Built.Init = Init.get(); 7622 Built.Inc = Inc.get(); 7623 Built.LB = LB.get(); 7624 Built.UB = UB.get(); 7625 Built.IL = IL.get(); 7626 Built.ST = ST.get(); 7627 Built.EUB = EUB.get(); 7628 Built.NLB = NextLB.get(); 7629 Built.NUB = NextUB.get(); 7630 Built.PrevLB = PrevLB.get(); 7631 Built.PrevUB = PrevUB.get(); 7632 Built.DistInc = DistInc.get(); 7633 Built.PrevEUB = PrevEUB.get(); 7634 Built.DistCombinedFields.LB = CombLB.get(); 7635 Built.DistCombinedFields.UB = CombUB.get(); 7636 Built.DistCombinedFields.EUB = CombEUB.get(); 7637 Built.DistCombinedFields.Init = CombInit.get(); 7638 Built.DistCombinedFields.Cond = CombCond.get(); 7639 Built.DistCombinedFields.NLB = CombNextLB.get(); 7640 Built.DistCombinedFields.NUB = CombNextUB.get(); 7641 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7642 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7643 7644 return NestedLoopCount; 7645 } 7646 7647 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7648 auto CollapseClauses = 7649 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7650 if (CollapseClauses.begin() != CollapseClauses.end()) 7651 return (*CollapseClauses.begin())->getNumForLoops(); 7652 return nullptr; 7653 } 7654 7655 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7656 auto OrderedClauses = 7657 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7658 if (OrderedClauses.begin() != OrderedClauses.end()) 7659 return (*OrderedClauses.begin())->getNumForLoops(); 7660 return nullptr; 7661 } 7662 7663 static bool checkSimdlenSafelenSpecified(Sema &S, 7664 const ArrayRef<OMPClause *> Clauses) { 7665 const OMPSafelenClause *Safelen = nullptr; 7666 const OMPSimdlenClause *Simdlen = nullptr; 7667 7668 for (const OMPClause *Clause : Clauses) { 7669 if (Clause->getClauseKind() == OMPC_safelen) 7670 Safelen = cast<OMPSafelenClause>(Clause); 7671 else if (Clause->getClauseKind() == OMPC_simdlen) 7672 Simdlen = cast<OMPSimdlenClause>(Clause); 7673 if (Safelen && Simdlen) 7674 break; 7675 } 7676 7677 if (Simdlen && Safelen) { 7678 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7679 const Expr *SafelenLength = Safelen->getSafelen(); 7680 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7681 SimdlenLength->isInstantiationDependent() || 7682 SimdlenLength->containsUnexpandedParameterPack()) 7683 return false; 7684 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7685 SafelenLength->isInstantiationDependent() || 7686 SafelenLength->containsUnexpandedParameterPack()) 7687 return false; 7688 Expr::EvalResult SimdlenResult, SafelenResult; 7689 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7690 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7691 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7692 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7693 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7694 // If both simdlen and safelen clauses are specified, the value of the 7695 // simdlen parameter must be less than or equal to the value of the safelen 7696 // parameter. 7697 if (SimdlenRes > SafelenRes) { 7698 S.Diag(SimdlenLength->getExprLoc(), 7699 diag::err_omp_wrong_simdlen_safelen_values) 7700 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7701 return true; 7702 } 7703 } 7704 return false; 7705 } 7706 7707 StmtResult 7708 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7709 SourceLocation StartLoc, SourceLocation EndLoc, 7710 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7711 if (!AStmt) 7712 return StmtError(); 7713 7714 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7715 OMPLoopDirective::HelperExprs B; 7716 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7717 // define the nested loops number. 7718 unsigned NestedLoopCount = checkOpenMPLoop( 7719 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7720 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7721 if (NestedLoopCount == 0) 7722 return StmtError(); 7723 7724 assert((CurContext->isDependentContext() || B.builtAll()) && 7725 "omp simd loop exprs were not built"); 7726 7727 if (!CurContext->isDependentContext()) { 7728 // Finalize the clauses that need pre-built expressions for CodeGen. 7729 for (OMPClause *C : Clauses) { 7730 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7731 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7732 B.NumIterations, *this, CurScope, 7733 DSAStack)) 7734 return StmtError(); 7735 } 7736 } 7737 7738 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7739 return StmtError(); 7740 7741 setFunctionHasBranchProtectedScope(); 7742 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7743 Clauses, AStmt, B); 7744 } 7745 7746 StmtResult 7747 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7748 SourceLocation StartLoc, SourceLocation EndLoc, 7749 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7750 if (!AStmt) 7751 return StmtError(); 7752 7753 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7754 OMPLoopDirective::HelperExprs B; 7755 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7756 // define the nested loops number. 7757 unsigned NestedLoopCount = checkOpenMPLoop( 7758 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7759 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7760 if (NestedLoopCount == 0) 7761 return StmtError(); 7762 7763 assert((CurContext->isDependentContext() || B.builtAll()) && 7764 "omp for loop exprs were not built"); 7765 7766 if (!CurContext->isDependentContext()) { 7767 // Finalize the clauses that need pre-built expressions for CodeGen. 7768 for (OMPClause *C : Clauses) { 7769 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7770 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7771 B.NumIterations, *this, CurScope, 7772 DSAStack)) 7773 return StmtError(); 7774 } 7775 } 7776 7777 setFunctionHasBranchProtectedScope(); 7778 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7779 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7780 } 7781 7782 StmtResult Sema::ActOnOpenMPForSimdDirective( 7783 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7784 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7785 if (!AStmt) 7786 return StmtError(); 7787 7788 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7789 OMPLoopDirective::HelperExprs B; 7790 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7791 // define the nested loops number. 7792 unsigned NestedLoopCount = 7793 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7794 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7795 VarsWithImplicitDSA, B); 7796 if (NestedLoopCount == 0) 7797 return StmtError(); 7798 7799 assert((CurContext->isDependentContext() || B.builtAll()) && 7800 "omp for simd loop exprs were not built"); 7801 7802 if (!CurContext->isDependentContext()) { 7803 // Finalize the clauses that need pre-built expressions for CodeGen. 7804 for (OMPClause *C : Clauses) { 7805 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7806 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7807 B.NumIterations, *this, CurScope, 7808 DSAStack)) 7809 return StmtError(); 7810 } 7811 } 7812 7813 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7814 return StmtError(); 7815 7816 setFunctionHasBranchProtectedScope(); 7817 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7818 Clauses, AStmt, B); 7819 } 7820 7821 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7822 Stmt *AStmt, 7823 SourceLocation StartLoc, 7824 SourceLocation EndLoc) { 7825 if (!AStmt) 7826 return StmtError(); 7827 7828 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7829 auto BaseStmt = AStmt; 7830 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7831 BaseStmt = CS->getCapturedStmt(); 7832 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7833 auto S = C->children(); 7834 if (S.begin() == S.end()) 7835 return StmtError(); 7836 // All associated statements must be '#pragma omp section' except for 7837 // the first one. 7838 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7839 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7840 if (SectionStmt) 7841 Diag(SectionStmt->getBeginLoc(), 7842 diag::err_omp_sections_substmt_not_section); 7843 return StmtError(); 7844 } 7845 cast<OMPSectionDirective>(SectionStmt) 7846 ->setHasCancel(DSAStack->isCancelRegion()); 7847 } 7848 } else { 7849 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7850 return StmtError(); 7851 } 7852 7853 setFunctionHasBranchProtectedScope(); 7854 7855 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7856 DSAStack->isCancelRegion()); 7857 } 7858 7859 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7860 SourceLocation StartLoc, 7861 SourceLocation EndLoc) { 7862 if (!AStmt) 7863 return StmtError(); 7864 7865 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7866 7867 setFunctionHasBranchProtectedScope(); 7868 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7869 7870 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7871 DSAStack->isCancelRegion()); 7872 } 7873 7874 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7875 Stmt *AStmt, 7876 SourceLocation StartLoc, 7877 SourceLocation EndLoc) { 7878 if (!AStmt) 7879 return StmtError(); 7880 7881 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7882 7883 setFunctionHasBranchProtectedScope(); 7884 7885 // OpenMP [2.7.3, single Construct, Restrictions] 7886 // The copyprivate clause must not be used with the nowait clause. 7887 const OMPClause *Nowait = nullptr; 7888 const OMPClause *Copyprivate = nullptr; 7889 for (const OMPClause *Clause : Clauses) { 7890 if (Clause->getClauseKind() == OMPC_nowait) 7891 Nowait = Clause; 7892 else if (Clause->getClauseKind() == OMPC_copyprivate) 7893 Copyprivate = Clause; 7894 if (Copyprivate && Nowait) { 7895 Diag(Copyprivate->getBeginLoc(), 7896 diag::err_omp_single_copyprivate_with_nowait); 7897 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7898 return StmtError(); 7899 } 7900 } 7901 7902 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7903 } 7904 7905 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7906 SourceLocation StartLoc, 7907 SourceLocation EndLoc) { 7908 if (!AStmt) 7909 return StmtError(); 7910 7911 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7912 7913 setFunctionHasBranchProtectedScope(); 7914 7915 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7916 } 7917 7918 StmtResult Sema::ActOnOpenMPCriticalDirective( 7919 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7920 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7921 if (!AStmt) 7922 return StmtError(); 7923 7924 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7925 7926 bool ErrorFound = false; 7927 llvm::APSInt Hint; 7928 SourceLocation HintLoc; 7929 bool DependentHint = false; 7930 for (const OMPClause *C : Clauses) { 7931 if (C->getClauseKind() == OMPC_hint) { 7932 if (!DirName.getName()) { 7933 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7934 ErrorFound = true; 7935 } 7936 Expr *E = cast<OMPHintClause>(C)->getHint(); 7937 if (E->isTypeDependent() || E->isValueDependent() || 7938 E->isInstantiationDependent()) { 7939 DependentHint = true; 7940 } else { 7941 Hint = E->EvaluateKnownConstInt(Context); 7942 HintLoc = C->getBeginLoc(); 7943 } 7944 } 7945 } 7946 if (ErrorFound) 7947 return StmtError(); 7948 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7949 if (Pair.first && DirName.getName() && !DependentHint) { 7950 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7951 Diag(StartLoc, diag::err_omp_critical_with_hint); 7952 if (HintLoc.isValid()) 7953 Diag(HintLoc, diag::note_omp_critical_hint_here) 7954 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7955 else 7956 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7957 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7958 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7959 << 1 7960 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7961 /*Radix=*/10, /*Signed=*/false); 7962 } else { 7963 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7964 } 7965 } 7966 } 7967 7968 setFunctionHasBranchProtectedScope(); 7969 7970 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7971 Clauses, AStmt); 7972 if (!Pair.first && DirName.getName() && !DependentHint) 7973 DSAStack->addCriticalWithHint(Dir, Hint); 7974 return Dir; 7975 } 7976 7977 StmtResult Sema::ActOnOpenMPParallelForDirective( 7978 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7979 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7980 if (!AStmt) 7981 return StmtError(); 7982 7983 auto *CS = cast<CapturedStmt>(AStmt); 7984 // 1.2.2 OpenMP Language Terminology 7985 // Structured block - An executable statement with a single entry at the 7986 // top and a single exit at the bottom. 7987 // The point of exit cannot be a branch out of the structured block. 7988 // longjmp() and throw() must not violate the entry/exit criteria. 7989 CS->getCapturedDecl()->setNothrow(); 7990 7991 OMPLoopDirective::HelperExprs B; 7992 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7993 // define the nested loops number. 7994 unsigned NestedLoopCount = 7995 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7996 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7997 VarsWithImplicitDSA, B); 7998 if (NestedLoopCount == 0) 7999 return StmtError(); 8000 8001 assert((CurContext->isDependentContext() || B.builtAll()) && 8002 "omp parallel for loop exprs were not built"); 8003 8004 if (!CurContext->isDependentContext()) { 8005 // Finalize the clauses that need pre-built expressions for CodeGen. 8006 for (OMPClause *C : Clauses) { 8007 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8008 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8009 B.NumIterations, *this, CurScope, 8010 DSAStack)) 8011 return StmtError(); 8012 } 8013 } 8014 8015 setFunctionHasBranchProtectedScope(); 8016 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8017 NestedLoopCount, Clauses, AStmt, B, 8018 DSAStack->isCancelRegion()); 8019 } 8020 8021 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8022 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8023 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8024 if (!AStmt) 8025 return StmtError(); 8026 8027 auto *CS = cast<CapturedStmt>(AStmt); 8028 // 1.2.2 OpenMP Language Terminology 8029 // Structured block - An executable statement with a single entry at the 8030 // top and a single exit at the bottom. 8031 // The point of exit cannot be a branch out of the structured block. 8032 // longjmp() and throw() must not violate the entry/exit criteria. 8033 CS->getCapturedDecl()->setNothrow(); 8034 8035 OMPLoopDirective::HelperExprs B; 8036 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8037 // define the nested loops number. 8038 unsigned NestedLoopCount = 8039 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8040 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8041 VarsWithImplicitDSA, B); 8042 if (NestedLoopCount == 0) 8043 return StmtError(); 8044 8045 if (!CurContext->isDependentContext()) { 8046 // Finalize the clauses that need pre-built expressions for CodeGen. 8047 for (OMPClause *C : Clauses) { 8048 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8049 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8050 B.NumIterations, *this, CurScope, 8051 DSAStack)) 8052 return StmtError(); 8053 } 8054 } 8055 8056 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8057 return StmtError(); 8058 8059 setFunctionHasBranchProtectedScope(); 8060 return OMPParallelForSimdDirective::Create( 8061 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8062 } 8063 8064 StmtResult 8065 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8066 Stmt *AStmt, SourceLocation StartLoc, 8067 SourceLocation EndLoc) { 8068 if (!AStmt) 8069 return StmtError(); 8070 8071 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8072 auto BaseStmt = AStmt; 8073 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8074 BaseStmt = CS->getCapturedStmt(); 8075 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8076 auto S = C->children(); 8077 if (S.begin() == S.end()) 8078 return StmtError(); 8079 // All associated statements must be '#pragma omp section' except for 8080 // the first one. 8081 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8082 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8083 if (SectionStmt) 8084 Diag(SectionStmt->getBeginLoc(), 8085 diag::err_omp_parallel_sections_substmt_not_section); 8086 return StmtError(); 8087 } 8088 cast<OMPSectionDirective>(SectionStmt) 8089 ->setHasCancel(DSAStack->isCancelRegion()); 8090 } 8091 } else { 8092 Diag(AStmt->getBeginLoc(), 8093 diag::err_omp_parallel_sections_not_compound_stmt); 8094 return StmtError(); 8095 } 8096 8097 setFunctionHasBranchProtectedScope(); 8098 8099 return OMPParallelSectionsDirective::Create( 8100 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8101 } 8102 8103 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8104 Stmt *AStmt, SourceLocation StartLoc, 8105 SourceLocation EndLoc) { 8106 if (!AStmt) 8107 return StmtError(); 8108 8109 auto *CS = cast<CapturedStmt>(AStmt); 8110 // 1.2.2 OpenMP Language Terminology 8111 // Structured block - An executable statement with a single entry at the 8112 // top and a single exit at the bottom. 8113 // The point of exit cannot be a branch out of the structured block. 8114 // longjmp() and throw() must not violate the entry/exit criteria. 8115 CS->getCapturedDecl()->setNothrow(); 8116 8117 setFunctionHasBranchProtectedScope(); 8118 8119 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8120 DSAStack->isCancelRegion()); 8121 } 8122 8123 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8124 SourceLocation EndLoc) { 8125 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8126 } 8127 8128 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8129 SourceLocation EndLoc) { 8130 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8131 } 8132 8133 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8134 SourceLocation EndLoc) { 8135 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8136 } 8137 8138 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8139 Stmt *AStmt, 8140 SourceLocation StartLoc, 8141 SourceLocation EndLoc) { 8142 if (!AStmt) 8143 return StmtError(); 8144 8145 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8146 8147 setFunctionHasBranchProtectedScope(); 8148 8149 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8150 AStmt, 8151 DSAStack->getTaskgroupReductionRef()); 8152 } 8153 8154 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8155 SourceLocation StartLoc, 8156 SourceLocation EndLoc) { 8157 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8158 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8159 } 8160 8161 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8162 Stmt *AStmt, 8163 SourceLocation StartLoc, 8164 SourceLocation EndLoc) { 8165 const OMPClause *DependFound = nullptr; 8166 const OMPClause *DependSourceClause = nullptr; 8167 const OMPClause *DependSinkClause = nullptr; 8168 bool ErrorFound = false; 8169 const OMPThreadsClause *TC = nullptr; 8170 const OMPSIMDClause *SC = nullptr; 8171 for (const OMPClause *C : Clauses) { 8172 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8173 DependFound = C; 8174 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8175 if (DependSourceClause) { 8176 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8177 << getOpenMPDirectiveName(OMPD_ordered) 8178 << getOpenMPClauseName(OMPC_depend) << 2; 8179 ErrorFound = true; 8180 } else { 8181 DependSourceClause = C; 8182 } 8183 if (DependSinkClause) { 8184 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8185 << 0; 8186 ErrorFound = true; 8187 } 8188 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8189 if (DependSourceClause) { 8190 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8191 << 1; 8192 ErrorFound = true; 8193 } 8194 DependSinkClause = C; 8195 } 8196 } else if (C->getClauseKind() == OMPC_threads) { 8197 TC = cast<OMPThreadsClause>(C); 8198 } else if (C->getClauseKind() == OMPC_simd) { 8199 SC = cast<OMPSIMDClause>(C); 8200 } 8201 } 8202 if (!ErrorFound && !SC && 8203 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8204 // OpenMP [2.8.1,simd Construct, Restrictions] 8205 // An ordered construct with the simd clause is the only OpenMP construct 8206 // that can appear in the simd region. 8207 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8208 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8209 ErrorFound = true; 8210 } else if (DependFound && (TC || SC)) { 8211 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8212 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8213 ErrorFound = true; 8214 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8215 Diag(DependFound->getBeginLoc(), 8216 diag::err_omp_ordered_directive_without_param); 8217 ErrorFound = true; 8218 } else if (TC || Clauses.empty()) { 8219 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8220 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8221 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8222 << (TC != nullptr); 8223 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8224 ErrorFound = true; 8225 } 8226 } 8227 if ((!AStmt && !DependFound) || ErrorFound) 8228 return StmtError(); 8229 8230 if (AStmt) { 8231 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8232 8233 setFunctionHasBranchProtectedScope(); 8234 } 8235 8236 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8237 } 8238 8239 namespace { 8240 /// Helper class for checking expression in 'omp atomic [update]' 8241 /// construct. 8242 class OpenMPAtomicUpdateChecker { 8243 /// Error results for atomic update expressions. 8244 enum ExprAnalysisErrorCode { 8245 /// A statement is not an expression statement. 8246 NotAnExpression, 8247 /// Expression is not builtin binary or unary operation. 8248 NotABinaryOrUnaryExpression, 8249 /// Unary operation is not post-/pre- increment/decrement operation. 8250 NotAnUnaryIncDecExpression, 8251 /// An expression is not of scalar type. 8252 NotAScalarType, 8253 /// A binary operation is not an assignment operation. 8254 NotAnAssignmentOp, 8255 /// RHS part of the binary operation is not a binary expression. 8256 NotABinaryExpression, 8257 /// RHS part is not additive/multiplicative/shift/biwise binary 8258 /// expression. 8259 NotABinaryOperator, 8260 /// RHS binary operation does not have reference to the updated LHS 8261 /// part. 8262 NotAnUpdateExpression, 8263 /// No errors is found. 8264 NoError 8265 }; 8266 /// Reference to Sema. 8267 Sema &SemaRef; 8268 /// A location for note diagnostics (when error is found). 8269 SourceLocation NoteLoc; 8270 /// 'x' lvalue part of the source atomic expression. 8271 Expr *X; 8272 /// 'expr' rvalue part of the source atomic expression. 8273 Expr *E; 8274 /// Helper expression of the form 8275 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8276 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8277 Expr *UpdateExpr; 8278 /// Is 'x' a LHS in a RHS part of full update expression. It is 8279 /// important for non-associative operations. 8280 bool IsXLHSInRHSPart; 8281 BinaryOperatorKind Op; 8282 SourceLocation OpLoc; 8283 /// true if the source expression is a postfix unary operation, false 8284 /// if it is a prefix unary operation. 8285 bool IsPostfixUpdate; 8286 8287 public: 8288 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8289 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8290 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8291 /// Check specified statement that it is suitable for 'atomic update' 8292 /// constructs and extract 'x', 'expr' and Operation from the original 8293 /// expression. If DiagId and NoteId == 0, then only check is performed 8294 /// without error notification. 8295 /// \param DiagId Diagnostic which should be emitted if error is found. 8296 /// \param NoteId Diagnostic note for the main error message. 8297 /// \return true if statement is not an update expression, false otherwise. 8298 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8299 /// Return the 'x' lvalue part of the source atomic expression. 8300 Expr *getX() const { return X; } 8301 /// Return the 'expr' rvalue part of the source atomic expression. 8302 Expr *getExpr() const { return E; } 8303 /// Return the update expression used in calculation of the updated 8304 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8305 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8306 Expr *getUpdateExpr() const { return UpdateExpr; } 8307 /// Return true if 'x' is LHS in RHS part of full update expression, 8308 /// false otherwise. 8309 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8310 8311 /// true if the source expression is a postfix unary operation, false 8312 /// if it is a prefix unary operation. 8313 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8314 8315 private: 8316 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8317 unsigned NoteId = 0); 8318 }; 8319 } // namespace 8320 8321 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8322 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8323 ExprAnalysisErrorCode ErrorFound = NoError; 8324 SourceLocation ErrorLoc, NoteLoc; 8325 SourceRange ErrorRange, NoteRange; 8326 // Allowed constructs are: 8327 // x = x binop expr; 8328 // x = expr binop x; 8329 if (AtomicBinOp->getOpcode() == BO_Assign) { 8330 X = AtomicBinOp->getLHS(); 8331 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8332 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8333 if (AtomicInnerBinOp->isMultiplicativeOp() || 8334 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8335 AtomicInnerBinOp->isBitwiseOp()) { 8336 Op = AtomicInnerBinOp->getOpcode(); 8337 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8338 Expr *LHS = AtomicInnerBinOp->getLHS(); 8339 Expr *RHS = AtomicInnerBinOp->getRHS(); 8340 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8341 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8342 /*Canonical=*/true); 8343 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8344 /*Canonical=*/true); 8345 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8346 /*Canonical=*/true); 8347 if (XId == LHSId) { 8348 E = RHS; 8349 IsXLHSInRHSPart = true; 8350 } else if (XId == RHSId) { 8351 E = LHS; 8352 IsXLHSInRHSPart = false; 8353 } else { 8354 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8355 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8356 NoteLoc = X->getExprLoc(); 8357 NoteRange = X->getSourceRange(); 8358 ErrorFound = NotAnUpdateExpression; 8359 } 8360 } else { 8361 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8362 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8363 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8364 NoteRange = SourceRange(NoteLoc, NoteLoc); 8365 ErrorFound = NotABinaryOperator; 8366 } 8367 } else { 8368 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8369 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8370 ErrorFound = NotABinaryExpression; 8371 } 8372 } else { 8373 ErrorLoc = AtomicBinOp->getExprLoc(); 8374 ErrorRange = AtomicBinOp->getSourceRange(); 8375 NoteLoc = AtomicBinOp->getOperatorLoc(); 8376 NoteRange = SourceRange(NoteLoc, NoteLoc); 8377 ErrorFound = NotAnAssignmentOp; 8378 } 8379 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8380 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8381 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8382 return true; 8383 } 8384 if (SemaRef.CurContext->isDependentContext()) 8385 E = X = UpdateExpr = nullptr; 8386 return ErrorFound != NoError; 8387 } 8388 8389 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8390 unsigned NoteId) { 8391 ExprAnalysisErrorCode ErrorFound = NoError; 8392 SourceLocation ErrorLoc, NoteLoc; 8393 SourceRange ErrorRange, NoteRange; 8394 // Allowed constructs are: 8395 // x++; 8396 // x--; 8397 // ++x; 8398 // --x; 8399 // x binop= expr; 8400 // x = x binop expr; 8401 // x = expr binop x; 8402 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8403 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8404 if (AtomicBody->getType()->isScalarType() || 8405 AtomicBody->isInstantiationDependent()) { 8406 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8407 AtomicBody->IgnoreParenImpCasts())) { 8408 // Check for Compound Assignment Operation 8409 Op = BinaryOperator::getOpForCompoundAssignment( 8410 AtomicCompAssignOp->getOpcode()); 8411 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8412 E = AtomicCompAssignOp->getRHS(); 8413 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8414 IsXLHSInRHSPart = true; 8415 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8416 AtomicBody->IgnoreParenImpCasts())) { 8417 // Check for Binary Operation 8418 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8419 return true; 8420 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8421 AtomicBody->IgnoreParenImpCasts())) { 8422 // Check for Unary Operation 8423 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8424 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8425 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8426 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8427 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8428 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8429 IsXLHSInRHSPart = true; 8430 } else { 8431 ErrorFound = NotAnUnaryIncDecExpression; 8432 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8433 ErrorRange = AtomicUnaryOp->getSourceRange(); 8434 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8435 NoteRange = SourceRange(NoteLoc, NoteLoc); 8436 } 8437 } else if (!AtomicBody->isInstantiationDependent()) { 8438 ErrorFound = NotABinaryOrUnaryExpression; 8439 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8440 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8441 } 8442 } else { 8443 ErrorFound = NotAScalarType; 8444 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8445 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8446 } 8447 } else { 8448 ErrorFound = NotAnExpression; 8449 NoteLoc = ErrorLoc = S->getBeginLoc(); 8450 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8451 } 8452 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8453 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8454 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8455 return true; 8456 } 8457 if (SemaRef.CurContext->isDependentContext()) 8458 E = X = UpdateExpr = nullptr; 8459 if (ErrorFound == NoError && E && X) { 8460 // Build an update expression of form 'OpaqueValueExpr(x) binop 8461 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8462 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8463 auto *OVEX = new (SemaRef.getASTContext()) 8464 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8465 auto *OVEExpr = new (SemaRef.getASTContext()) 8466 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8467 ExprResult Update = 8468 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8469 IsXLHSInRHSPart ? OVEExpr : OVEX); 8470 if (Update.isInvalid()) 8471 return true; 8472 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8473 Sema::AA_Casting); 8474 if (Update.isInvalid()) 8475 return true; 8476 UpdateExpr = Update.get(); 8477 } 8478 return ErrorFound != NoError; 8479 } 8480 8481 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8482 Stmt *AStmt, 8483 SourceLocation StartLoc, 8484 SourceLocation EndLoc) { 8485 if (!AStmt) 8486 return StmtError(); 8487 8488 auto *CS = cast<CapturedStmt>(AStmt); 8489 // 1.2.2 OpenMP Language Terminology 8490 // Structured block - An executable statement with a single entry at the 8491 // top and a single exit at the bottom. 8492 // The point of exit cannot be a branch out of the structured block. 8493 // longjmp() and throw() must not violate the entry/exit criteria. 8494 OpenMPClauseKind AtomicKind = OMPC_unknown; 8495 SourceLocation AtomicKindLoc; 8496 for (const OMPClause *C : Clauses) { 8497 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8498 C->getClauseKind() == OMPC_update || 8499 C->getClauseKind() == OMPC_capture) { 8500 if (AtomicKind != OMPC_unknown) { 8501 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8502 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8503 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8504 << getOpenMPClauseName(AtomicKind); 8505 } else { 8506 AtomicKind = C->getClauseKind(); 8507 AtomicKindLoc = C->getBeginLoc(); 8508 } 8509 } 8510 } 8511 8512 Stmt *Body = CS->getCapturedStmt(); 8513 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8514 Body = EWC->getSubExpr(); 8515 8516 Expr *X = nullptr; 8517 Expr *V = nullptr; 8518 Expr *E = nullptr; 8519 Expr *UE = nullptr; 8520 bool IsXLHSInRHSPart = false; 8521 bool IsPostfixUpdate = false; 8522 // OpenMP [2.12.6, atomic Construct] 8523 // In the next expressions: 8524 // * x and v (as applicable) are both l-value expressions with scalar type. 8525 // * During the execution of an atomic region, multiple syntactic 8526 // occurrences of x must designate the same storage location. 8527 // * Neither of v and expr (as applicable) may access the storage location 8528 // designated by x. 8529 // * Neither of x and expr (as applicable) may access the storage location 8530 // designated by v. 8531 // * expr is an expression with scalar type. 8532 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8533 // * binop, binop=, ++, and -- are not overloaded operators. 8534 // * The expression x binop expr must be numerically equivalent to x binop 8535 // (expr). This requirement is satisfied if the operators in expr have 8536 // precedence greater than binop, or by using parentheses around expr or 8537 // subexpressions of expr. 8538 // * The expression expr binop x must be numerically equivalent to (expr) 8539 // binop x. This requirement is satisfied if the operators in expr have 8540 // precedence equal to or greater than binop, or by using parentheses around 8541 // expr or subexpressions of expr. 8542 // * For forms that allow multiple occurrences of x, the number of times 8543 // that x is evaluated is unspecified. 8544 if (AtomicKind == OMPC_read) { 8545 enum { 8546 NotAnExpression, 8547 NotAnAssignmentOp, 8548 NotAScalarType, 8549 NotAnLValue, 8550 NoError 8551 } ErrorFound = NoError; 8552 SourceLocation ErrorLoc, NoteLoc; 8553 SourceRange ErrorRange, NoteRange; 8554 // If clause is read: 8555 // v = x; 8556 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8557 const auto *AtomicBinOp = 8558 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8559 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8560 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8561 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8562 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8563 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8564 if (!X->isLValue() || !V->isLValue()) { 8565 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8566 ErrorFound = NotAnLValue; 8567 ErrorLoc = AtomicBinOp->getExprLoc(); 8568 ErrorRange = AtomicBinOp->getSourceRange(); 8569 NoteLoc = NotLValueExpr->getExprLoc(); 8570 NoteRange = NotLValueExpr->getSourceRange(); 8571 } 8572 } else if (!X->isInstantiationDependent() || 8573 !V->isInstantiationDependent()) { 8574 const Expr *NotScalarExpr = 8575 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8576 ? V 8577 : X; 8578 ErrorFound = NotAScalarType; 8579 ErrorLoc = AtomicBinOp->getExprLoc(); 8580 ErrorRange = AtomicBinOp->getSourceRange(); 8581 NoteLoc = NotScalarExpr->getExprLoc(); 8582 NoteRange = NotScalarExpr->getSourceRange(); 8583 } 8584 } else if (!AtomicBody->isInstantiationDependent()) { 8585 ErrorFound = NotAnAssignmentOp; 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 } 8593 } else { 8594 ErrorFound = NotAnExpression; 8595 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8596 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8597 } 8598 if (ErrorFound != NoError) { 8599 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8600 << ErrorRange; 8601 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8602 << NoteRange; 8603 return StmtError(); 8604 } 8605 if (CurContext->isDependentContext()) 8606 V = X = nullptr; 8607 } else if (AtomicKind == OMPC_write) { 8608 enum { 8609 NotAnExpression, 8610 NotAnAssignmentOp, 8611 NotAScalarType, 8612 NotAnLValue, 8613 NoError 8614 } ErrorFound = NoError; 8615 SourceLocation ErrorLoc, NoteLoc; 8616 SourceRange ErrorRange, NoteRange; 8617 // If clause is write: 8618 // x = expr; 8619 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8620 const auto *AtomicBinOp = 8621 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8622 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8623 X = AtomicBinOp->getLHS(); 8624 E = AtomicBinOp->getRHS(); 8625 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8626 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8627 if (!X->isLValue()) { 8628 ErrorFound = NotAnLValue; 8629 ErrorLoc = AtomicBinOp->getExprLoc(); 8630 ErrorRange = AtomicBinOp->getSourceRange(); 8631 NoteLoc = X->getExprLoc(); 8632 NoteRange = X->getSourceRange(); 8633 } 8634 } else if (!X->isInstantiationDependent() || 8635 !E->isInstantiationDependent()) { 8636 const Expr *NotScalarExpr = 8637 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8638 ? E 8639 : X; 8640 ErrorFound = NotAScalarType; 8641 ErrorLoc = AtomicBinOp->getExprLoc(); 8642 ErrorRange = AtomicBinOp->getSourceRange(); 8643 NoteLoc = NotScalarExpr->getExprLoc(); 8644 NoteRange = NotScalarExpr->getSourceRange(); 8645 } 8646 } else if (!AtomicBody->isInstantiationDependent()) { 8647 ErrorFound = NotAnAssignmentOp; 8648 ErrorLoc = AtomicBody->getExprLoc(); 8649 ErrorRange = AtomicBody->getSourceRange(); 8650 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8651 : AtomicBody->getExprLoc(); 8652 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8653 : AtomicBody->getSourceRange(); 8654 } 8655 } else { 8656 ErrorFound = NotAnExpression; 8657 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8658 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8659 } 8660 if (ErrorFound != NoError) { 8661 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8662 << ErrorRange; 8663 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8664 << NoteRange; 8665 return StmtError(); 8666 } 8667 if (CurContext->isDependentContext()) 8668 E = X = nullptr; 8669 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8670 // If clause is update: 8671 // x++; 8672 // x--; 8673 // ++x; 8674 // --x; 8675 // x binop= expr; 8676 // x = x binop expr; 8677 // x = expr binop x; 8678 OpenMPAtomicUpdateChecker Checker(*this); 8679 if (Checker.checkStatement( 8680 Body, (AtomicKind == OMPC_update) 8681 ? diag::err_omp_atomic_update_not_expression_statement 8682 : diag::err_omp_atomic_not_expression_statement, 8683 diag::note_omp_atomic_update)) 8684 return StmtError(); 8685 if (!CurContext->isDependentContext()) { 8686 E = Checker.getExpr(); 8687 X = Checker.getX(); 8688 UE = Checker.getUpdateExpr(); 8689 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8690 } 8691 } else if (AtomicKind == OMPC_capture) { 8692 enum { 8693 NotAnAssignmentOp, 8694 NotACompoundStatement, 8695 NotTwoSubstatements, 8696 NotASpecificExpression, 8697 NoError 8698 } ErrorFound = NoError; 8699 SourceLocation ErrorLoc, NoteLoc; 8700 SourceRange ErrorRange, NoteRange; 8701 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8702 // If clause is a capture: 8703 // v = x++; 8704 // v = x--; 8705 // v = ++x; 8706 // v = --x; 8707 // v = x binop= expr; 8708 // v = x = x binop expr; 8709 // v = x = expr binop x; 8710 const auto *AtomicBinOp = 8711 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8712 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8713 V = AtomicBinOp->getLHS(); 8714 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8715 OpenMPAtomicUpdateChecker Checker(*this); 8716 if (Checker.checkStatement( 8717 Body, diag::err_omp_atomic_capture_not_expression_statement, 8718 diag::note_omp_atomic_update)) 8719 return StmtError(); 8720 E = Checker.getExpr(); 8721 X = Checker.getX(); 8722 UE = Checker.getUpdateExpr(); 8723 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8724 IsPostfixUpdate = Checker.isPostfixUpdate(); 8725 } else if (!AtomicBody->isInstantiationDependent()) { 8726 ErrorLoc = AtomicBody->getExprLoc(); 8727 ErrorRange = AtomicBody->getSourceRange(); 8728 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8729 : AtomicBody->getExprLoc(); 8730 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8731 : AtomicBody->getSourceRange(); 8732 ErrorFound = NotAnAssignmentOp; 8733 } 8734 if (ErrorFound != NoError) { 8735 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8736 << ErrorRange; 8737 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8738 return StmtError(); 8739 } 8740 if (CurContext->isDependentContext()) 8741 UE = V = E = X = nullptr; 8742 } else { 8743 // If clause is a capture: 8744 // { v = x; x = expr; } 8745 // { v = x; x++; } 8746 // { v = x; x--; } 8747 // { v = x; ++x; } 8748 // { v = x; --x; } 8749 // { v = x; x binop= expr; } 8750 // { v = x; x = x binop expr; } 8751 // { v = x; x = expr binop x; } 8752 // { x++; v = x; } 8753 // { x--; v = x; } 8754 // { ++x; v = x; } 8755 // { --x; v = x; } 8756 // { x binop= expr; v = x; } 8757 // { x = x binop expr; v = x; } 8758 // { x = expr binop x; v = x; } 8759 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8760 // Check that this is { expr1; expr2; } 8761 if (CS->size() == 2) { 8762 Stmt *First = CS->body_front(); 8763 Stmt *Second = CS->body_back(); 8764 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8765 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8766 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8767 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8768 // Need to find what subexpression is 'v' and what is 'x'. 8769 OpenMPAtomicUpdateChecker Checker(*this); 8770 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8771 BinaryOperator *BinOp = nullptr; 8772 if (IsUpdateExprFound) { 8773 BinOp = dyn_cast<BinaryOperator>(First); 8774 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8775 } 8776 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8777 // { v = x; x++; } 8778 // { v = x; x--; } 8779 // { v = x; ++x; } 8780 // { v = x; --x; } 8781 // { v = x; x binop= expr; } 8782 // { v = x; x = x binop expr; } 8783 // { v = x; x = expr binop x; } 8784 // Check that the first expression has form v = x. 8785 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8786 llvm::FoldingSetNodeID XId, PossibleXId; 8787 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8788 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8789 IsUpdateExprFound = XId == PossibleXId; 8790 if (IsUpdateExprFound) { 8791 V = BinOp->getLHS(); 8792 X = Checker.getX(); 8793 E = Checker.getExpr(); 8794 UE = Checker.getUpdateExpr(); 8795 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8796 IsPostfixUpdate = true; 8797 } 8798 } 8799 if (!IsUpdateExprFound) { 8800 IsUpdateExprFound = !Checker.checkStatement(First); 8801 BinOp = nullptr; 8802 if (IsUpdateExprFound) { 8803 BinOp = dyn_cast<BinaryOperator>(Second); 8804 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8805 } 8806 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8807 // { x++; v = x; } 8808 // { x--; v = x; } 8809 // { ++x; v = x; } 8810 // { --x; v = x; } 8811 // { x binop= expr; v = x; } 8812 // { x = x binop expr; v = x; } 8813 // { x = expr binop x; v = x; } 8814 // Check that the second expression has form v = x. 8815 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8816 llvm::FoldingSetNodeID XId, PossibleXId; 8817 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8818 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8819 IsUpdateExprFound = XId == PossibleXId; 8820 if (IsUpdateExprFound) { 8821 V = BinOp->getLHS(); 8822 X = Checker.getX(); 8823 E = Checker.getExpr(); 8824 UE = Checker.getUpdateExpr(); 8825 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8826 IsPostfixUpdate = false; 8827 } 8828 } 8829 } 8830 if (!IsUpdateExprFound) { 8831 // { v = x; x = expr; } 8832 auto *FirstExpr = dyn_cast<Expr>(First); 8833 auto *SecondExpr = dyn_cast<Expr>(Second); 8834 if (!FirstExpr || !SecondExpr || 8835 !(FirstExpr->isInstantiationDependent() || 8836 SecondExpr->isInstantiationDependent())) { 8837 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8838 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8839 ErrorFound = NotAnAssignmentOp; 8840 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8841 : First->getBeginLoc(); 8842 NoteRange = ErrorRange = FirstBinOp 8843 ? FirstBinOp->getSourceRange() 8844 : SourceRange(ErrorLoc, ErrorLoc); 8845 } else { 8846 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8847 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8848 ErrorFound = NotAnAssignmentOp; 8849 NoteLoc = ErrorLoc = SecondBinOp 8850 ? SecondBinOp->getOperatorLoc() 8851 : Second->getBeginLoc(); 8852 NoteRange = ErrorRange = 8853 SecondBinOp ? SecondBinOp->getSourceRange() 8854 : SourceRange(ErrorLoc, ErrorLoc); 8855 } else { 8856 Expr *PossibleXRHSInFirst = 8857 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8858 Expr *PossibleXLHSInSecond = 8859 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8860 llvm::FoldingSetNodeID X1Id, X2Id; 8861 PossibleXRHSInFirst->Profile(X1Id, Context, 8862 /*Canonical=*/true); 8863 PossibleXLHSInSecond->Profile(X2Id, Context, 8864 /*Canonical=*/true); 8865 IsUpdateExprFound = X1Id == X2Id; 8866 if (IsUpdateExprFound) { 8867 V = FirstBinOp->getLHS(); 8868 X = SecondBinOp->getLHS(); 8869 E = SecondBinOp->getRHS(); 8870 UE = nullptr; 8871 IsXLHSInRHSPart = false; 8872 IsPostfixUpdate = true; 8873 } else { 8874 ErrorFound = NotASpecificExpression; 8875 ErrorLoc = FirstBinOp->getExprLoc(); 8876 ErrorRange = FirstBinOp->getSourceRange(); 8877 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8878 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8879 } 8880 } 8881 } 8882 } 8883 } 8884 } else { 8885 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8886 NoteRange = ErrorRange = 8887 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8888 ErrorFound = NotTwoSubstatements; 8889 } 8890 } else { 8891 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8892 NoteRange = ErrorRange = 8893 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8894 ErrorFound = NotACompoundStatement; 8895 } 8896 if (ErrorFound != NoError) { 8897 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8898 << ErrorRange; 8899 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8900 return StmtError(); 8901 } 8902 if (CurContext->isDependentContext()) 8903 UE = V = E = X = nullptr; 8904 } 8905 } 8906 8907 setFunctionHasBranchProtectedScope(); 8908 8909 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8910 X, V, E, UE, IsXLHSInRHSPart, 8911 IsPostfixUpdate); 8912 } 8913 8914 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8915 Stmt *AStmt, 8916 SourceLocation StartLoc, 8917 SourceLocation EndLoc) { 8918 if (!AStmt) 8919 return StmtError(); 8920 8921 auto *CS = cast<CapturedStmt>(AStmt); 8922 // 1.2.2 OpenMP Language Terminology 8923 // Structured block - An executable statement with a single entry at the 8924 // top and a single exit at the bottom. 8925 // The point of exit cannot be a branch out of the structured block. 8926 // longjmp() and throw() must not violate the entry/exit criteria. 8927 CS->getCapturedDecl()->setNothrow(); 8928 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8929 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8930 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8931 // 1.2.2 OpenMP Language Terminology 8932 // Structured block - An executable statement with a single entry at the 8933 // top and a single exit at the bottom. 8934 // The point of exit cannot be a branch out of the structured block. 8935 // longjmp() and throw() must not violate the entry/exit criteria. 8936 CS->getCapturedDecl()->setNothrow(); 8937 } 8938 8939 // OpenMP [2.16, Nesting of Regions] 8940 // If specified, a teams construct must be contained within a target 8941 // construct. That target construct must contain no statements or directives 8942 // outside of the teams construct. 8943 if (DSAStack->hasInnerTeamsRegion()) { 8944 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8945 bool OMPTeamsFound = true; 8946 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8947 auto I = CS->body_begin(); 8948 while (I != CS->body_end()) { 8949 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8950 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8951 OMPTeamsFound) { 8952 8953 OMPTeamsFound = false; 8954 break; 8955 } 8956 ++I; 8957 } 8958 assert(I != CS->body_end() && "Not found statement"); 8959 S = *I; 8960 } else { 8961 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8962 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8963 } 8964 if (!OMPTeamsFound) { 8965 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8966 Diag(DSAStack->getInnerTeamsRegionLoc(), 8967 diag::note_omp_nested_teams_construct_here); 8968 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8969 << isa<OMPExecutableDirective>(S); 8970 return StmtError(); 8971 } 8972 } 8973 8974 setFunctionHasBranchProtectedScope(); 8975 8976 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8977 } 8978 8979 StmtResult 8980 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8981 Stmt *AStmt, SourceLocation StartLoc, 8982 SourceLocation EndLoc) { 8983 if (!AStmt) 8984 return StmtError(); 8985 8986 auto *CS = cast<CapturedStmt>(AStmt); 8987 // 1.2.2 OpenMP Language Terminology 8988 // Structured block - An executable statement with a single entry at the 8989 // top and a single exit at the bottom. 8990 // The point of exit cannot be a branch out of the structured block. 8991 // longjmp() and throw() must not violate the entry/exit criteria. 8992 CS->getCapturedDecl()->setNothrow(); 8993 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8994 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8995 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8996 // 1.2.2 OpenMP Language Terminology 8997 // Structured block - An executable statement with a single entry at the 8998 // top and a single exit at the bottom. 8999 // The point of exit cannot be a branch out of the structured block. 9000 // longjmp() and throw() must not violate the entry/exit criteria. 9001 CS->getCapturedDecl()->setNothrow(); 9002 } 9003 9004 setFunctionHasBranchProtectedScope(); 9005 9006 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9007 AStmt); 9008 } 9009 9010 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9011 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9012 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9013 if (!AStmt) 9014 return StmtError(); 9015 9016 auto *CS = cast<CapturedStmt>(AStmt); 9017 // 1.2.2 OpenMP Language Terminology 9018 // Structured block - An executable statement with a single entry at the 9019 // top and a single exit at the bottom. 9020 // The point of exit cannot be a branch out of the structured block. 9021 // longjmp() and throw() must not violate the entry/exit criteria. 9022 CS->getCapturedDecl()->setNothrow(); 9023 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9024 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9025 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9026 // 1.2.2 OpenMP Language Terminology 9027 // Structured block - An executable statement with a single entry at the 9028 // top and a single exit at the bottom. 9029 // The point of exit cannot be a branch out of the structured block. 9030 // longjmp() and throw() must not violate the entry/exit criteria. 9031 CS->getCapturedDecl()->setNothrow(); 9032 } 9033 9034 OMPLoopDirective::HelperExprs B; 9035 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9036 // define the nested loops number. 9037 unsigned NestedLoopCount = 9038 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9039 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9040 VarsWithImplicitDSA, B); 9041 if (NestedLoopCount == 0) 9042 return StmtError(); 9043 9044 assert((CurContext->isDependentContext() || B.builtAll()) && 9045 "omp target parallel for loop exprs were not built"); 9046 9047 if (!CurContext->isDependentContext()) { 9048 // Finalize the clauses that need pre-built expressions for CodeGen. 9049 for (OMPClause *C : Clauses) { 9050 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9051 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9052 B.NumIterations, *this, CurScope, 9053 DSAStack)) 9054 return StmtError(); 9055 } 9056 } 9057 9058 setFunctionHasBranchProtectedScope(); 9059 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9060 NestedLoopCount, Clauses, AStmt, 9061 B, DSAStack->isCancelRegion()); 9062 } 9063 9064 /// Check for existence of a map clause in the list of clauses. 9065 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9066 const OpenMPClauseKind K) { 9067 return llvm::any_of( 9068 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9069 } 9070 9071 template <typename... Params> 9072 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9073 const Params... ClauseTypes) { 9074 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9075 } 9076 9077 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9078 Stmt *AStmt, 9079 SourceLocation StartLoc, 9080 SourceLocation EndLoc) { 9081 if (!AStmt) 9082 return StmtError(); 9083 9084 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9085 9086 // OpenMP [2.10.1, Restrictions, p. 97] 9087 // At least one map clause must appear on the directive. 9088 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9089 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9090 << "'map' or 'use_device_ptr'" 9091 << getOpenMPDirectiveName(OMPD_target_data); 9092 return StmtError(); 9093 } 9094 9095 setFunctionHasBranchProtectedScope(); 9096 9097 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9098 AStmt); 9099 } 9100 9101 StmtResult 9102 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9103 SourceLocation StartLoc, 9104 SourceLocation EndLoc, Stmt *AStmt) { 9105 if (!AStmt) 9106 return StmtError(); 9107 9108 auto *CS = cast<CapturedStmt>(AStmt); 9109 // 1.2.2 OpenMP Language Terminology 9110 // Structured block - An executable statement with a single entry at the 9111 // top and a single exit at the bottom. 9112 // The point of exit cannot be a branch out of the structured block. 9113 // longjmp() and throw() must not violate the entry/exit criteria. 9114 CS->getCapturedDecl()->setNothrow(); 9115 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9116 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9117 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9118 // 1.2.2 OpenMP Language Terminology 9119 // Structured block - An executable statement with a single entry at the 9120 // top and a single exit at the bottom. 9121 // The point of exit cannot be a branch out of the structured block. 9122 // longjmp() and throw() must not violate the entry/exit criteria. 9123 CS->getCapturedDecl()->setNothrow(); 9124 } 9125 9126 // OpenMP [2.10.2, Restrictions, p. 99] 9127 // At least one map clause must appear on the directive. 9128 if (!hasClauses(Clauses, OMPC_map)) { 9129 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9130 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9131 return StmtError(); 9132 } 9133 9134 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9135 AStmt); 9136 } 9137 9138 StmtResult 9139 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9140 SourceLocation StartLoc, 9141 SourceLocation EndLoc, Stmt *AStmt) { 9142 if (!AStmt) 9143 return StmtError(); 9144 9145 auto *CS = cast<CapturedStmt>(AStmt); 9146 // 1.2.2 OpenMP Language Terminology 9147 // Structured block - An executable statement with a single entry at the 9148 // top and a single exit at the bottom. 9149 // The point of exit cannot be a branch out of the structured block. 9150 // longjmp() and throw() must not violate the entry/exit criteria. 9151 CS->getCapturedDecl()->setNothrow(); 9152 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9153 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9154 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9155 // 1.2.2 OpenMP Language Terminology 9156 // Structured block - An executable statement with a single entry at the 9157 // top and a single exit at the bottom. 9158 // The point of exit cannot be a branch out of the structured block. 9159 // longjmp() and throw() must not violate the entry/exit criteria. 9160 CS->getCapturedDecl()->setNothrow(); 9161 } 9162 9163 // OpenMP [2.10.3, Restrictions, p. 102] 9164 // At least one map clause must appear on the directive. 9165 if (!hasClauses(Clauses, OMPC_map)) { 9166 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9167 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9168 return StmtError(); 9169 } 9170 9171 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9172 AStmt); 9173 } 9174 9175 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9176 SourceLocation StartLoc, 9177 SourceLocation EndLoc, 9178 Stmt *AStmt) { 9179 if (!AStmt) 9180 return StmtError(); 9181 9182 auto *CS = cast<CapturedStmt>(AStmt); 9183 // 1.2.2 OpenMP Language Terminology 9184 // Structured block - An executable statement with a single entry at the 9185 // top and a single exit at the bottom. 9186 // The point of exit cannot be a branch out of the structured block. 9187 // longjmp() and throw() must not violate the entry/exit criteria. 9188 CS->getCapturedDecl()->setNothrow(); 9189 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9190 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9191 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9192 // 1.2.2 OpenMP Language Terminology 9193 // Structured block - An executable statement with a single entry at the 9194 // top and a single exit at the bottom. 9195 // The point of exit cannot be a branch out of the structured block. 9196 // longjmp() and throw() must not violate the entry/exit criteria. 9197 CS->getCapturedDecl()->setNothrow(); 9198 } 9199 9200 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9201 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9202 return StmtError(); 9203 } 9204 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9205 AStmt); 9206 } 9207 9208 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9209 Stmt *AStmt, SourceLocation StartLoc, 9210 SourceLocation EndLoc) { 9211 if (!AStmt) 9212 return StmtError(); 9213 9214 auto *CS = cast<CapturedStmt>(AStmt); 9215 // 1.2.2 OpenMP Language Terminology 9216 // Structured block - An executable statement with a single entry at the 9217 // top and a single exit at the bottom. 9218 // The point of exit cannot be a branch out of the structured block. 9219 // longjmp() and throw() must not violate the entry/exit criteria. 9220 CS->getCapturedDecl()->setNothrow(); 9221 9222 setFunctionHasBranchProtectedScope(); 9223 9224 DSAStack->setParentTeamsRegionLoc(StartLoc); 9225 9226 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9227 } 9228 9229 StmtResult 9230 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9231 SourceLocation EndLoc, 9232 OpenMPDirectiveKind CancelRegion) { 9233 if (DSAStack->isParentNowaitRegion()) { 9234 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9235 return StmtError(); 9236 } 9237 if (DSAStack->isParentOrderedRegion()) { 9238 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9239 return StmtError(); 9240 } 9241 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9242 CancelRegion); 9243 } 9244 9245 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9246 SourceLocation StartLoc, 9247 SourceLocation EndLoc, 9248 OpenMPDirectiveKind CancelRegion) { 9249 if (DSAStack->isParentNowaitRegion()) { 9250 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9251 return StmtError(); 9252 } 9253 if (DSAStack->isParentOrderedRegion()) { 9254 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9255 return StmtError(); 9256 } 9257 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9258 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9259 CancelRegion); 9260 } 9261 9262 static bool checkGrainsizeNumTasksClauses(Sema &S, 9263 ArrayRef<OMPClause *> Clauses) { 9264 const OMPClause *PrevClause = nullptr; 9265 bool ErrorFound = false; 9266 for (const OMPClause *C : Clauses) { 9267 if (C->getClauseKind() == OMPC_grainsize || 9268 C->getClauseKind() == OMPC_num_tasks) { 9269 if (!PrevClause) 9270 PrevClause = C; 9271 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9272 S.Diag(C->getBeginLoc(), 9273 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9274 << getOpenMPClauseName(C->getClauseKind()) 9275 << getOpenMPClauseName(PrevClause->getClauseKind()); 9276 S.Diag(PrevClause->getBeginLoc(), 9277 diag::note_omp_previous_grainsize_num_tasks) 9278 << getOpenMPClauseName(PrevClause->getClauseKind()); 9279 ErrorFound = true; 9280 } 9281 } 9282 } 9283 return ErrorFound; 9284 } 9285 9286 static bool checkReductionClauseWithNogroup(Sema &S, 9287 ArrayRef<OMPClause *> Clauses) { 9288 const OMPClause *ReductionClause = nullptr; 9289 const OMPClause *NogroupClause = nullptr; 9290 for (const OMPClause *C : Clauses) { 9291 if (C->getClauseKind() == OMPC_reduction) { 9292 ReductionClause = C; 9293 if (NogroupClause) 9294 break; 9295 continue; 9296 } 9297 if (C->getClauseKind() == OMPC_nogroup) { 9298 NogroupClause = C; 9299 if (ReductionClause) 9300 break; 9301 continue; 9302 } 9303 } 9304 if (ReductionClause && NogroupClause) { 9305 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9306 << SourceRange(NogroupClause->getBeginLoc(), 9307 NogroupClause->getEndLoc()); 9308 return true; 9309 } 9310 return false; 9311 } 9312 9313 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9314 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9315 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9316 if (!AStmt) 9317 return StmtError(); 9318 9319 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9320 OMPLoopDirective::HelperExprs B; 9321 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9322 // define the nested loops number. 9323 unsigned NestedLoopCount = 9324 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9325 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9326 VarsWithImplicitDSA, B); 9327 if (NestedLoopCount == 0) 9328 return StmtError(); 9329 9330 assert((CurContext->isDependentContext() || B.builtAll()) && 9331 "omp for loop exprs were not built"); 9332 9333 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9334 // The grainsize clause and num_tasks clause are mutually exclusive and may 9335 // not appear on the same taskloop directive. 9336 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9337 return StmtError(); 9338 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9339 // If a reduction clause is present on the taskloop directive, the nogroup 9340 // clause must not be specified. 9341 if (checkReductionClauseWithNogroup(*this, Clauses)) 9342 return StmtError(); 9343 9344 setFunctionHasBranchProtectedScope(); 9345 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9346 NestedLoopCount, Clauses, AStmt, B); 9347 } 9348 9349 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9350 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9351 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9352 if (!AStmt) 9353 return StmtError(); 9354 9355 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9356 OMPLoopDirective::HelperExprs B; 9357 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9358 // define the nested loops number. 9359 unsigned NestedLoopCount = 9360 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9361 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9362 VarsWithImplicitDSA, B); 9363 if (NestedLoopCount == 0) 9364 return StmtError(); 9365 9366 assert((CurContext->isDependentContext() || B.builtAll()) && 9367 "omp for loop exprs were not built"); 9368 9369 if (!CurContext->isDependentContext()) { 9370 // Finalize the clauses that need pre-built expressions for CodeGen. 9371 for (OMPClause *C : Clauses) { 9372 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9373 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9374 B.NumIterations, *this, CurScope, 9375 DSAStack)) 9376 return StmtError(); 9377 } 9378 } 9379 9380 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9381 // The grainsize clause and num_tasks clause are mutually exclusive and may 9382 // not appear on the same taskloop directive. 9383 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9384 return StmtError(); 9385 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9386 // If a reduction clause is present on the taskloop directive, the nogroup 9387 // clause must not be specified. 9388 if (checkReductionClauseWithNogroup(*this, Clauses)) 9389 return StmtError(); 9390 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9391 return StmtError(); 9392 9393 setFunctionHasBranchProtectedScope(); 9394 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9395 NestedLoopCount, Clauses, AStmt, B); 9396 } 9397 9398 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9399 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9400 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9401 if (!AStmt) 9402 return StmtError(); 9403 9404 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9405 OMPLoopDirective::HelperExprs B; 9406 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9407 // define the nested loops number. 9408 unsigned NestedLoopCount = 9409 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9410 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9411 VarsWithImplicitDSA, B); 9412 if (NestedLoopCount == 0) 9413 return StmtError(); 9414 9415 assert((CurContext->isDependentContext() || B.builtAll()) && 9416 "omp for loop exprs were not built"); 9417 9418 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9419 // The grainsize clause and num_tasks clause are mutually exclusive and may 9420 // not appear on the same taskloop directive. 9421 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9422 return StmtError(); 9423 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9424 // If a reduction clause is present on the taskloop directive, the nogroup 9425 // clause must not be specified. 9426 if (checkReductionClauseWithNogroup(*this, Clauses)) 9427 return StmtError(); 9428 9429 setFunctionHasBranchProtectedScope(); 9430 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9431 NestedLoopCount, Clauses, AStmt, B); 9432 } 9433 9434 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9435 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9436 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9437 if (!AStmt) 9438 return StmtError(); 9439 9440 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9441 OMPLoopDirective::HelperExprs B; 9442 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9443 // define the nested loops number. 9444 unsigned NestedLoopCount = 9445 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9446 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9447 VarsWithImplicitDSA, B); 9448 if (NestedLoopCount == 0) 9449 return StmtError(); 9450 9451 assert((CurContext->isDependentContext() || B.builtAll()) && 9452 "omp for loop exprs were not built"); 9453 9454 if (!CurContext->isDependentContext()) { 9455 // Finalize the clauses that need pre-built expressions for CodeGen. 9456 for (OMPClause *C : Clauses) { 9457 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9458 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9459 B.NumIterations, *this, CurScope, 9460 DSAStack)) 9461 return StmtError(); 9462 } 9463 } 9464 9465 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9466 // The grainsize clause and num_tasks clause are mutually exclusive and may 9467 // not appear on the same taskloop directive. 9468 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9469 return StmtError(); 9470 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9471 // If a reduction clause is present on the taskloop directive, the nogroup 9472 // clause must not be specified. 9473 if (checkReductionClauseWithNogroup(*this, Clauses)) 9474 return StmtError(); 9475 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9476 return StmtError(); 9477 9478 setFunctionHasBranchProtectedScope(); 9479 return OMPMasterTaskLoopSimdDirective::Create( 9480 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9481 } 9482 9483 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9484 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9485 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9486 if (!AStmt) 9487 return StmtError(); 9488 9489 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9490 auto *CS = cast<CapturedStmt>(AStmt); 9491 // 1.2.2 OpenMP Language Terminology 9492 // Structured block - An executable statement with a single entry at the 9493 // top and a single exit at the bottom. 9494 // The point of exit cannot be a branch out of the structured block. 9495 // longjmp() and throw() must not violate the entry/exit criteria. 9496 CS->getCapturedDecl()->setNothrow(); 9497 for (int ThisCaptureLevel = 9498 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9499 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9500 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9501 // 1.2.2 OpenMP Language Terminology 9502 // Structured block - An executable statement with a single entry at the 9503 // top and a single exit at the bottom. 9504 // The point of exit cannot be a branch out of the structured block. 9505 // longjmp() and throw() must not violate the entry/exit criteria. 9506 CS->getCapturedDecl()->setNothrow(); 9507 } 9508 9509 OMPLoopDirective::HelperExprs B; 9510 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9511 // define the nested loops number. 9512 unsigned NestedLoopCount = checkOpenMPLoop( 9513 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9514 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9515 VarsWithImplicitDSA, B); 9516 if (NestedLoopCount == 0) 9517 return StmtError(); 9518 9519 assert((CurContext->isDependentContext() || B.builtAll()) && 9520 "omp for loop exprs were not built"); 9521 9522 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9523 // The grainsize clause and num_tasks clause are mutually exclusive and may 9524 // not appear on the same taskloop directive. 9525 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9526 return StmtError(); 9527 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9528 // If a reduction clause is present on the taskloop directive, the nogroup 9529 // clause must not be specified. 9530 if (checkReductionClauseWithNogroup(*this, Clauses)) 9531 return StmtError(); 9532 9533 setFunctionHasBranchProtectedScope(); 9534 return OMPParallelMasterTaskLoopDirective::Create( 9535 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9536 } 9537 9538 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 9539 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9540 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9541 if (!AStmt) 9542 return StmtError(); 9543 9544 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9545 auto *CS = cast<CapturedStmt>(AStmt); 9546 // 1.2.2 OpenMP Language Terminology 9547 // Structured block - An executable statement with a single entry at the 9548 // top and a single exit at the bottom. 9549 // The point of exit cannot be a branch out of the structured block. 9550 // longjmp() and throw() must not violate the entry/exit criteria. 9551 CS->getCapturedDecl()->setNothrow(); 9552 for (int ThisCaptureLevel = 9553 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 9554 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9555 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9556 // 1.2.2 OpenMP Language Terminology 9557 // Structured block - An executable statement with a single entry at the 9558 // top and a single exit at the bottom. 9559 // The point of exit cannot be a branch out of the structured block. 9560 // longjmp() and throw() must not violate the entry/exit criteria. 9561 CS->getCapturedDecl()->setNothrow(); 9562 } 9563 9564 OMPLoopDirective::HelperExprs B; 9565 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9566 // define the nested loops number. 9567 unsigned NestedLoopCount = checkOpenMPLoop( 9568 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9569 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9570 VarsWithImplicitDSA, B); 9571 if (NestedLoopCount == 0) 9572 return StmtError(); 9573 9574 assert((CurContext->isDependentContext() || B.builtAll()) && 9575 "omp for loop exprs were not built"); 9576 9577 if (!CurContext->isDependentContext()) { 9578 // Finalize the clauses that need pre-built expressions for CodeGen. 9579 for (OMPClause *C : Clauses) { 9580 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9581 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9582 B.NumIterations, *this, CurScope, 9583 DSAStack)) 9584 return StmtError(); 9585 } 9586 } 9587 9588 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9589 // The grainsize clause and num_tasks clause are mutually exclusive and may 9590 // not appear on the same taskloop directive. 9591 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9592 return StmtError(); 9593 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9594 // If a reduction clause is present on the taskloop directive, the nogroup 9595 // clause must not be specified. 9596 if (checkReductionClauseWithNogroup(*this, Clauses)) 9597 return StmtError(); 9598 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9599 return StmtError(); 9600 9601 setFunctionHasBranchProtectedScope(); 9602 return OMPParallelMasterTaskLoopSimdDirective::Create( 9603 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9604 } 9605 9606 StmtResult Sema::ActOnOpenMPDistributeDirective( 9607 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9608 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9609 if (!AStmt) 9610 return StmtError(); 9611 9612 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9613 OMPLoopDirective::HelperExprs B; 9614 // In presence of clause 'collapse' with number of loops, it will 9615 // define the nested loops number. 9616 unsigned NestedLoopCount = 9617 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9618 nullptr /*ordered not a clause on distribute*/, AStmt, 9619 *this, *DSAStack, VarsWithImplicitDSA, B); 9620 if (NestedLoopCount == 0) 9621 return StmtError(); 9622 9623 assert((CurContext->isDependentContext() || B.builtAll()) && 9624 "omp for loop exprs were not built"); 9625 9626 setFunctionHasBranchProtectedScope(); 9627 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9628 NestedLoopCount, Clauses, AStmt, B); 9629 } 9630 9631 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9632 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9633 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9634 if (!AStmt) 9635 return StmtError(); 9636 9637 auto *CS = cast<CapturedStmt>(AStmt); 9638 // 1.2.2 OpenMP Language Terminology 9639 // Structured block - An executable statement with a single entry at the 9640 // top and a single exit at the bottom. 9641 // The point of exit cannot be a branch out of the structured block. 9642 // longjmp() and throw() must not violate the entry/exit criteria. 9643 CS->getCapturedDecl()->setNothrow(); 9644 for (int ThisCaptureLevel = 9645 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9646 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9647 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9648 // 1.2.2 OpenMP Language Terminology 9649 // Structured block - An executable statement with a single entry at the 9650 // top and a single exit at the bottom. 9651 // The point of exit cannot be a branch out of the structured block. 9652 // longjmp() and throw() must not violate the entry/exit criteria. 9653 CS->getCapturedDecl()->setNothrow(); 9654 } 9655 9656 OMPLoopDirective::HelperExprs B; 9657 // In presence of clause 'collapse' with number of loops, it will 9658 // define the nested loops number. 9659 unsigned NestedLoopCount = checkOpenMPLoop( 9660 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9661 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9662 VarsWithImplicitDSA, B); 9663 if (NestedLoopCount == 0) 9664 return StmtError(); 9665 9666 assert((CurContext->isDependentContext() || B.builtAll()) && 9667 "omp for loop exprs were not built"); 9668 9669 setFunctionHasBranchProtectedScope(); 9670 return OMPDistributeParallelForDirective::Create( 9671 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9672 DSAStack->isCancelRegion()); 9673 } 9674 9675 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9676 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9677 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9678 if (!AStmt) 9679 return StmtError(); 9680 9681 auto *CS = cast<CapturedStmt>(AStmt); 9682 // 1.2.2 OpenMP Language Terminology 9683 // Structured block - An executable statement with a single entry at the 9684 // top and a single exit at the bottom. 9685 // The point of exit cannot be a branch out of the structured block. 9686 // longjmp() and throw() must not violate the entry/exit criteria. 9687 CS->getCapturedDecl()->setNothrow(); 9688 for (int ThisCaptureLevel = 9689 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9690 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9691 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9692 // 1.2.2 OpenMP Language Terminology 9693 // Structured block - An executable statement with a single entry at the 9694 // top and a single exit at the bottom. 9695 // The point of exit cannot be a branch out of the structured block. 9696 // longjmp() and throw() must not violate the entry/exit criteria. 9697 CS->getCapturedDecl()->setNothrow(); 9698 } 9699 9700 OMPLoopDirective::HelperExprs B; 9701 // In presence of clause 'collapse' with number of loops, it will 9702 // define the nested loops number. 9703 unsigned NestedLoopCount = checkOpenMPLoop( 9704 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9705 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9706 VarsWithImplicitDSA, B); 9707 if (NestedLoopCount == 0) 9708 return StmtError(); 9709 9710 assert((CurContext->isDependentContext() || B.builtAll()) && 9711 "omp for loop exprs were not built"); 9712 9713 if (!CurContext->isDependentContext()) { 9714 // Finalize the clauses that need pre-built expressions for CodeGen. 9715 for (OMPClause *C : Clauses) { 9716 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9717 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9718 B.NumIterations, *this, CurScope, 9719 DSAStack)) 9720 return StmtError(); 9721 } 9722 } 9723 9724 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9725 return StmtError(); 9726 9727 setFunctionHasBranchProtectedScope(); 9728 return OMPDistributeParallelForSimdDirective::Create( 9729 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9730 } 9731 9732 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9733 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9734 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9735 if (!AStmt) 9736 return StmtError(); 9737 9738 auto *CS = cast<CapturedStmt>(AStmt); 9739 // 1.2.2 OpenMP Language Terminology 9740 // Structured block - An executable statement with a single entry at the 9741 // top and a single exit at the bottom. 9742 // The point of exit cannot be a branch out of the structured block. 9743 // longjmp() and throw() must not violate the entry/exit criteria. 9744 CS->getCapturedDecl()->setNothrow(); 9745 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9746 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9747 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9748 // 1.2.2 OpenMP Language Terminology 9749 // Structured block - An executable statement with a single entry at the 9750 // top and a single exit at the bottom. 9751 // The point of exit cannot be a branch out of the structured block. 9752 // longjmp() and throw() must not violate the entry/exit criteria. 9753 CS->getCapturedDecl()->setNothrow(); 9754 } 9755 9756 OMPLoopDirective::HelperExprs B; 9757 // In presence of clause 'collapse' with number of loops, it will 9758 // define the nested loops number. 9759 unsigned NestedLoopCount = 9760 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9761 nullptr /*ordered not a clause on distribute*/, CS, *this, 9762 *DSAStack, VarsWithImplicitDSA, B); 9763 if (NestedLoopCount == 0) 9764 return StmtError(); 9765 9766 assert((CurContext->isDependentContext() || B.builtAll()) && 9767 "omp for loop exprs were not built"); 9768 9769 if (!CurContext->isDependentContext()) { 9770 // Finalize the clauses that need pre-built expressions for CodeGen. 9771 for (OMPClause *C : Clauses) { 9772 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9773 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9774 B.NumIterations, *this, CurScope, 9775 DSAStack)) 9776 return StmtError(); 9777 } 9778 } 9779 9780 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9781 return StmtError(); 9782 9783 setFunctionHasBranchProtectedScope(); 9784 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9785 NestedLoopCount, Clauses, AStmt, B); 9786 } 9787 9788 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9789 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9790 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9791 if (!AStmt) 9792 return StmtError(); 9793 9794 auto *CS = cast<CapturedStmt>(AStmt); 9795 // 1.2.2 OpenMP Language Terminology 9796 // Structured block - An executable statement with a single entry at the 9797 // top and a single exit at the bottom. 9798 // The point of exit cannot be a branch out of the structured block. 9799 // longjmp() and throw() must not violate the entry/exit criteria. 9800 CS->getCapturedDecl()->setNothrow(); 9801 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9802 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9803 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9804 // 1.2.2 OpenMP Language Terminology 9805 // Structured block - An executable statement with a single entry at the 9806 // top and a single exit at the bottom. 9807 // The point of exit cannot be a branch out of the structured block. 9808 // longjmp() and throw() must not violate the entry/exit criteria. 9809 CS->getCapturedDecl()->setNothrow(); 9810 } 9811 9812 OMPLoopDirective::HelperExprs B; 9813 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9814 // define the nested loops number. 9815 unsigned NestedLoopCount = checkOpenMPLoop( 9816 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9817 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9818 VarsWithImplicitDSA, B); 9819 if (NestedLoopCount == 0) 9820 return StmtError(); 9821 9822 assert((CurContext->isDependentContext() || B.builtAll()) && 9823 "omp target parallel for simd loop exprs were not built"); 9824 9825 if (!CurContext->isDependentContext()) { 9826 // Finalize the clauses that need pre-built expressions for CodeGen. 9827 for (OMPClause *C : Clauses) { 9828 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9829 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9830 B.NumIterations, *this, CurScope, 9831 DSAStack)) 9832 return StmtError(); 9833 } 9834 } 9835 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9836 return StmtError(); 9837 9838 setFunctionHasBranchProtectedScope(); 9839 return OMPTargetParallelForSimdDirective::Create( 9840 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9841 } 9842 9843 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9844 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9845 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9846 if (!AStmt) 9847 return StmtError(); 9848 9849 auto *CS = cast<CapturedStmt>(AStmt); 9850 // 1.2.2 OpenMP Language Terminology 9851 // Structured block - An executable statement with a single entry at the 9852 // top and a single exit at the bottom. 9853 // The point of exit cannot be a branch out of the structured block. 9854 // longjmp() and throw() must not violate the entry/exit criteria. 9855 CS->getCapturedDecl()->setNothrow(); 9856 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9857 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9858 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9859 // 1.2.2 OpenMP Language Terminology 9860 // Structured block - An executable statement with a single entry at the 9861 // top and a single exit at the bottom. 9862 // The point of exit cannot be a branch out of the structured block. 9863 // longjmp() and throw() must not violate the entry/exit criteria. 9864 CS->getCapturedDecl()->setNothrow(); 9865 } 9866 9867 OMPLoopDirective::HelperExprs B; 9868 // In presence of clause 'collapse' with number of loops, it will define the 9869 // nested loops number. 9870 unsigned NestedLoopCount = 9871 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9872 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9873 VarsWithImplicitDSA, B); 9874 if (NestedLoopCount == 0) 9875 return StmtError(); 9876 9877 assert((CurContext->isDependentContext() || B.builtAll()) && 9878 "omp target simd loop exprs were not built"); 9879 9880 if (!CurContext->isDependentContext()) { 9881 // Finalize the clauses that need pre-built expressions for CodeGen. 9882 for (OMPClause *C : Clauses) { 9883 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9884 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9885 B.NumIterations, *this, CurScope, 9886 DSAStack)) 9887 return StmtError(); 9888 } 9889 } 9890 9891 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9892 return StmtError(); 9893 9894 setFunctionHasBranchProtectedScope(); 9895 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9896 NestedLoopCount, Clauses, AStmt, B); 9897 } 9898 9899 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9900 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9901 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9902 if (!AStmt) 9903 return StmtError(); 9904 9905 auto *CS = cast<CapturedStmt>(AStmt); 9906 // 1.2.2 OpenMP Language Terminology 9907 // Structured block - An executable statement with a single entry at the 9908 // top and a single exit at the bottom. 9909 // The point of exit cannot be a branch out of the structured block. 9910 // longjmp() and throw() must not violate the entry/exit criteria. 9911 CS->getCapturedDecl()->setNothrow(); 9912 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9913 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9914 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9915 // 1.2.2 OpenMP Language Terminology 9916 // Structured block - An executable statement with a single entry at the 9917 // top and a single exit at the bottom. 9918 // The point of exit cannot be a branch out of the structured block. 9919 // longjmp() and throw() must not violate the entry/exit criteria. 9920 CS->getCapturedDecl()->setNothrow(); 9921 } 9922 9923 OMPLoopDirective::HelperExprs B; 9924 // In presence of clause 'collapse' with number of loops, it will 9925 // define the nested loops number. 9926 unsigned NestedLoopCount = 9927 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9928 nullptr /*ordered not a clause on distribute*/, CS, *this, 9929 *DSAStack, VarsWithImplicitDSA, B); 9930 if (NestedLoopCount == 0) 9931 return StmtError(); 9932 9933 assert((CurContext->isDependentContext() || B.builtAll()) && 9934 "omp teams distribute loop exprs were not built"); 9935 9936 setFunctionHasBranchProtectedScope(); 9937 9938 DSAStack->setParentTeamsRegionLoc(StartLoc); 9939 9940 return OMPTeamsDistributeDirective::Create( 9941 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9942 } 9943 9944 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9945 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9946 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9947 if (!AStmt) 9948 return StmtError(); 9949 9950 auto *CS = cast<CapturedStmt>(AStmt); 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 for (int ThisCaptureLevel = 9958 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9959 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9960 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9961 // 1.2.2 OpenMP Language Terminology 9962 // Structured block - An executable statement with a single entry at the 9963 // top and a single exit at the bottom. 9964 // The point of exit cannot be a branch out of the structured block. 9965 // longjmp() and throw() must not violate the entry/exit criteria. 9966 CS->getCapturedDecl()->setNothrow(); 9967 } 9968 9969 9970 OMPLoopDirective::HelperExprs B; 9971 // In presence of clause 'collapse' with number of loops, it will 9972 // define the nested loops number. 9973 unsigned NestedLoopCount = checkOpenMPLoop( 9974 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9975 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9976 VarsWithImplicitDSA, B); 9977 9978 if (NestedLoopCount == 0) 9979 return StmtError(); 9980 9981 assert((CurContext->isDependentContext() || B.builtAll()) && 9982 "omp teams distribute simd loop exprs were not built"); 9983 9984 if (!CurContext->isDependentContext()) { 9985 // Finalize the clauses that need pre-built expressions for CodeGen. 9986 for (OMPClause *C : Clauses) { 9987 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9988 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9989 B.NumIterations, *this, CurScope, 9990 DSAStack)) 9991 return StmtError(); 9992 } 9993 } 9994 9995 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9996 return StmtError(); 9997 9998 setFunctionHasBranchProtectedScope(); 9999 10000 DSAStack->setParentTeamsRegionLoc(StartLoc); 10001 10002 return OMPTeamsDistributeSimdDirective::Create( 10003 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10004 } 10005 10006 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10007 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10008 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10009 if (!AStmt) 10010 return StmtError(); 10011 10012 auto *CS = cast<CapturedStmt>(AStmt); 10013 // 1.2.2 OpenMP Language Terminology 10014 // Structured block - An executable statement with a single entry at the 10015 // top and a single exit at the bottom. 10016 // The point of exit cannot be a branch out of the structured block. 10017 // longjmp() and throw() must not violate the entry/exit criteria. 10018 CS->getCapturedDecl()->setNothrow(); 10019 10020 for (int ThisCaptureLevel = 10021 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10022 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10023 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10024 // 1.2.2 OpenMP Language Terminology 10025 // Structured block - An executable statement with a single entry at the 10026 // top and a single exit at the bottom. 10027 // The point of exit cannot be a branch out of the structured block. 10028 // longjmp() and throw() must not violate the entry/exit criteria. 10029 CS->getCapturedDecl()->setNothrow(); 10030 } 10031 10032 OMPLoopDirective::HelperExprs B; 10033 // In presence of clause 'collapse' with number of loops, it will 10034 // define the nested loops number. 10035 unsigned NestedLoopCount = checkOpenMPLoop( 10036 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10037 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10038 VarsWithImplicitDSA, B); 10039 10040 if (NestedLoopCount == 0) 10041 return StmtError(); 10042 10043 assert((CurContext->isDependentContext() || B.builtAll()) && 10044 "omp for loop exprs were not built"); 10045 10046 if (!CurContext->isDependentContext()) { 10047 // Finalize the clauses that need pre-built expressions for CodeGen. 10048 for (OMPClause *C : Clauses) { 10049 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10050 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10051 B.NumIterations, *this, CurScope, 10052 DSAStack)) 10053 return StmtError(); 10054 } 10055 } 10056 10057 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10058 return StmtError(); 10059 10060 setFunctionHasBranchProtectedScope(); 10061 10062 DSAStack->setParentTeamsRegionLoc(StartLoc); 10063 10064 return OMPTeamsDistributeParallelForSimdDirective::Create( 10065 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10066 } 10067 10068 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10069 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10070 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10071 if (!AStmt) 10072 return StmtError(); 10073 10074 auto *CS = cast<CapturedStmt>(AStmt); 10075 // 1.2.2 OpenMP Language Terminology 10076 // Structured block - An executable statement with a single entry at the 10077 // top and a single exit at the bottom. 10078 // The point of exit cannot be a branch out of the structured block. 10079 // longjmp() and throw() must not violate the entry/exit criteria. 10080 CS->getCapturedDecl()->setNothrow(); 10081 10082 for (int ThisCaptureLevel = 10083 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10084 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10085 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10086 // 1.2.2 OpenMP Language Terminology 10087 // Structured block - An executable statement with a single entry at the 10088 // top and a single exit at the bottom. 10089 // The point of exit cannot be a branch out of the structured block. 10090 // longjmp() and throw() must not violate the entry/exit criteria. 10091 CS->getCapturedDecl()->setNothrow(); 10092 } 10093 10094 OMPLoopDirective::HelperExprs B; 10095 // In presence of clause 'collapse' with number of loops, it will 10096 // define the nested loops number. 10097 unsigned NestedLoopCount = checkOpenMPLoop( 10098 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10099 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10100 VarsWithImplicitDSA, B); 10101 10102 if (NestedLoopCount == 0) 10103 return StmtError(); 10104 10105 assert((CurContext->isDependentContext() || B.builtAll()) && 10106 "omp for loop exprs were not built"); 10107 10108 setFunctionHasBranchProtectedScope(); 10109 10110 DSAStack->setParentTeamsRegionLoc(StartLoc); 10111 10112 return OMPTeamsDistributeParallelForDirective::Create( 10113 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10114 DSAStack->isCancelRegion()); 10115 } 10116 10117 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10118 Stmt *AStmt, 10119 SourceLocation StartLoc, 10120 SourceLocation EndLoc) { 10121 if (!AStmt) 10122 return StmtError(); 10123 10124 auto *CS = cast<CapturedStmt>(AStmt); 10125 // 1.2.2 OpenMP Language Terminology 10126 // Structured block - An executable statement with a single entry at the 10127 // top and a single exit at the bottom. 10128 // The point of exit cannot be a branch out of the structured block. 10129 // longjmp() and throw() must not violate the entry/exit criteria. 10130 CS->getCapturedDecl()->setNothrow(); 10131 10132 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10133 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10134 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10135 // 1.2.2 OpenMP Language Terminology 10136 // Structured block - An executable statement with a single entry at the 10137 // top and a single exit at the bottom. 10138 // The point of exit cannot be a branch out of the structured block. 10139 // longjmp() and throw() must not violate the entry/exit criteria. 10140 CS->getCapturedDecl()->setNothrow(); 10141 } 10142 setFunctionHasBranchProtectedScope(); 10143 10144 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10145 AStmt); 10146 } 10147 10148 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10149 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10150 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10151 if (!AStmt) 10152 return StmtError(); 10153 10154 auto *CS = cast<CapturedStmt>(AStmt); 10155 // 1.2.2 OpenMP Language Terminology 10156 // Structured block - An executable statement with a single entry at the 10157 // top and a single exit at the bottom. 10158 // The point of exit cannot be a branch out of the structured block. 10159 // longjmp() and throw() must not violate the entry/exit criteria. 10160 CS->getCapturedDecl()->setNothrow(); 10161 for (int ThisCaptureLevel = 10162 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10163 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10164 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10165 // 1.2.2 OpenMP Language Terminology 10166 // Structured block - An executable statement with a single entry at the 10167 // top and a single exit at the bottom. 10168 // The point of exit cannot be a branch out of the structured block. 10169 // longjmp() and throw() must not violate the entry/exit criteria. 10170 CS->getCapturedDecl()->setNothrow(); 10171 } 10172 10173 OMPLoopDirective::HelperExprs B; 10174 // In presence of clause 'collapse' with number of loops, it will 10175 // define the nested loops number. 10176 unsigned NestedLoopCount = checkOpenMPLoop( 10177 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10178 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10179 VarsWithImplicitDSA, B); 10180 if (NestedLoopCount == 0) 10181 return StmtError(); 10182 10183 assert((CurContext->isDependentContext() || B.builtAll()) && 10184 "omp target teams distribute loop exprs were not built"); 10185 10186 setFunctionHasBranchProtectedScope(); 10187 return OMPTargetTeamsDistributeDirective::Create( 10188 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10189 } 10190 10191 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10192 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10193 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10194 if (!AStmt) 10195 return StmtError(); 10196 10197 auto *CS = cast<CapturedStmt>(AStmt); 10198 // 1.2.2 OpenMP Language Terminology 10199 // Structured block - An executable statement with a single entry at the 10200 // top and a single exit at the bottom. 10201 // The point of exit cannot be a branch out of the structured block. 10202 // longjmp() and throw() must not violate the entry/exit criteria. 10203 CS->getCapturedDecl()->setNothrow(); 10204 for (int ThisCaptureLevel = 10205 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10206 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10207 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10208 // 1.2.2 OpenMP Language Terminology 10209 // Structured block - An executable statement with a single entry at the 10210 // top and a single exit at the bottom. 10211 // The point of exit cannot be a branch out of the structured block. 10212 // longjmp() and throw() must not violate the entry/exit criteria. 10213 CS->getCapturedDecl()->setNothrow(); 10214 } 10215 10216 OMPLoopDirective::HelperExprs B; 10217 // In presence of clause 'collapse' with number of loops, it will 10218 // define the nested loops number. 10219 unsigned NestedLoopCount = checkOpenMPLoop( 10220 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10221 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10222 VarsWithImplicitDSA, B); 10223 if (NestedLoopCount == 0) 10224 return StmtError(); 10225 10226 assert((CurContext->isDependentContext() || B.builtAll()) && 10227 "omp target teams distribute parallel for loop exprs were not built"); 10228 10229 if (!CurContext->isDependentContext()) { 10230 // Finalize the clauses that need pre-built expressions for CodeGen. 10231 for (OMPClause *C : Clauses) { 10232 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10233 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10234 B.NumIterations, *this, CurScope, 10235 DSAStack)) 10236 return StmtError(); 10237 } 10238 } 10239 10240 setFunctionHasBranchProtectedScope(); 10241 return OMPTargetTeamsDistributeParallelForDirective::Create( 10242 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10243 DSAStack->isCancelRegion()); 10244 } 10245 10246 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10247 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10248 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10249 if (!AStmt) 10250 return StmtError(); 10251 10252 auto *CS = cast<CapturedStmt>(AStmt); 10253 // 1.2.2 OpenMP Language Terminology 10254 // Structured block - An executable statement with a single entry at the 10255 // top and a single exit at the bottom. 10256 // The point of exit cannot be a branch out of the structured block. 10257 // longjmp() and throw() must not violate the entry/exit criteria. 10258 CS->getCapturedDecl()->setNothrow(); 10259 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10260 OMPD_target_teams_distribute_parallel_for_simd); 10261 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10262 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10263 // 1.2.2 OpenMP Language Terminology 10264 // Structured block - An executable statement with a single entry at the 10265 // top and a single exit at the bottom. 10266 // The point of exit cannot be a branch out of the structured block. 10267 // longjmp() and throw() must not violate the entry/exit criteria. 10268 CS->getCapturedDecl()->setNothrow(); 10269 } 10270 10271 OMPLoopDirective::HelperExprs B; 10272 // In presence of clause 'collapse' with number of loops, it will 10273 // define the nested loops number. 10274 unsigned NestedLoopCount = 10275 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10276 getCollapseNumberExpr(Clauses), 10277 nullptr /*ordered not a clause on distribute*/, CS, *this, 10278 *DSAStack, VarsWithImplicitDSA, B); 10279 if (NestedLoopCount == 0) 10280 return StmtError(); 10281 10282 assert((CurContext->isDependentContext() || B.builtAll()) && 10283 "omp target teams distribute parallel for simd loop exprs were not " 10284 "built"); 10285 10286 if (!CurContext->isDependentContext()) { 10287 // Finalize the clauses that need pre-built expressions for CodeGen. 10288 for (OMPClause *C : Clauses) { 10289 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10290 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10291 B.NumIterations, *this, CurScope, 10292 DSAStack)) 10293 return StmtError(); 10294 } 10295 } 10296 10297 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10298 return StmtError(); 10299 10300 setFunctionHasBranchProtectedScope(); 10301 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10302 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10303 } 10304 10305 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10306 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10307 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10308 if (!AStmt) 10309 return StmtError(); 10310 10311 auto *CS = cast<CapturedStmt>(AStmt); 10312 // 1.2.2 OpenMP Language Terminology 10313 // Structured block - An executable statement with a single entry at the 10314 // top and a single exit at the bottom. 10315 // The point of exit cannot be a branch out of the structured block. 10316 // longjmp() and throw() must not violate the entry/exit criteria. 10317 CS->getCapturedDecl()->setNothrow(); 10318 for (int ThisCaptureLevel = 10319 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10320 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10321 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10322 // 1.2.2 OpenMP Language Terminology 10323 // Structured block - An executable statement with a single entry at the 10324 // top and a single exit at the bottom. 10325 // The point of exit cannot be a branch out of the structured block. 10326 // longjmp() and throw() must not violate the entry/exit criteria. 10327 CS->getCapturedDecl()->setNothrow(); 10328 } 10329 10330 OMPLoopDirective::HelperExprs B; 10331 // In presence of clause 'collapse' with number of loops, it will 10332 // define the nested loops number. 10333 unsigned NestedLoopCount = checkOpenMPLoop( 10334 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10335 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10336 VarsWithImplicitDSA, B); 10337 if (NestedLoopCount == 0) 10338 return StmtError(); 10339 10340 assert((CurContext->isDependentContext() || B.builtAll()) && 10341 "omp target teams distribute simd loop exprs were not built"); 10342 10343 if (!CurContext->isDependentContext()) { 10344 // Finalize the clauses that need pre-built expressions for CodeGen. 10345 for (OMPClause *C : Clauses) { 10346 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10347 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10348 B.NumIterations, *this, CurScope, 10349 DSAStack)) 10350 return StmtError(); 10351 } 10352 } 10353 10354 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10355 return StmtError(); 10356 10357 setFunctionHasBranchProtectedScope(); 10358 return OMPTargetTeamsDistributeSimdDirective::Create( 10359 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10360 } 10361 10362 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10363 SourceLocation StartLoc, 10364 SourceLocation LParenLoc, 10365 SourceLocation EndLoc) { 10366 OMPClause *Res = nullptr; 10367 switch (Kind) { 10368 case OMPC_final: 10369 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10370 break; 10371 case OMPC_num_threads: 10372 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10373 break; 10374 case OMPC_safelen: 10375 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10376 break; 10377 case OMPC_simdlen: 10378 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10379 break; 10380 case OMPC_allocator: 10381 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10382 break; 10383 case OMPC_collapse: 10384 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10385 break; 10386 case OMPC_ordered: 10387 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10388 break; 10389 case OMPC_device: 10390 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10391 break; 10392 case OMPC_num_teams: 10393 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10394 break; 10395 case OMPC_thread_limit: 10396 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10397 break; 10398 case OMPC_priority: 10399 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10400 break; 10401 case OMPC_grainsize: 10402 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10403 break; 10404 case OMPC_num_tasks: 10405 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10406 break; 10407 case OMPC_hint: 10408 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10409 break; 10410 case OMPC_if: 10411 case OMPC_default: 10412 case OMPC_proc_bind: 10413 case OMPC_schedule: 10414 case OMPC_private: 10415 case OMPC_firstprivate: 10416 case OMPC_lastprivate: 10417 case OMPC_shared: 10418 case OMPC_reduction: 10419 case OMPC_task_reduction: 10420 case OMPC_in_reduction: 10421 case OMPC_linear: 10422 case OMPC_aligned: 10423 case OMPC_copyin: 10424 case OMPC_copyprivate: 10425 case OMPC_nowait: 10426 case OMPC_untied: 10427 case OMPC_mergeable: 10428 case OMPC_threadprivate: 10429 case OMPC_allocate: 10430 case OMPC_flush: 10431 case OMPC_read: 10432 case OMPC_write: 10433 case OMPC_update: 10434 case OMPC_capture: 10435 case OMPC_seq_cst: 10436 case OMPC_depend: 10437 case OMPC_threads: 10438 case OMPC_simd: 10439 case OMPC_map: 10440 case OMPC_nogroup: 10441 case OMPC_dist_schedule: 10442 case OMPC_defaultmap: 10443 case OMPC_unknown: 10444 case OMPC_uniform: 10445 case OMPC_to: 10446 case OMPC_from: 10447 case OMPC_use_device_ptr: 10448 case OMPC_is_device_ptr: 10449 case OMPC_unified_address: 10450 case OMPC_unified_shared_memory: 10451 case OMPC_reverse_offload: 10452 case OMPC_dynamic_allocators: 10453 case OMPC_atomic_default_mem_order: 10454 case OMPC_device_type: 10455 case OMPC_match: 10456 llvm_unreachable("Clause is not allowed."); 10457 } 10458 return Res; 10459 } 10460 10461 // An OpenMP directive such as 'target parallel' has two captured regions: 10462 // for the 'target' and 'parallel' respectively. This function returns 10463 // the region in which to capture expressions associated with a clause. 10464 // A return value of OMPD_unknown signifies that the expression should not 10465 // be captured. 10466 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10467 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10468 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10469 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10470 switch (CKind) { 10471 case OMPC_if: 10472 switch (DKind) { 10473 case OMPD_target_parallel: 10474 case OMPD_target_parallel_for: 10475 case OMPD_target_parallel_for_simd: 10476 // If this clause applies to the nested 'parallel' region, capture within 10477 // the 'target' region, otherwise do not capture. 10478 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10479 CaptureRegion = OMPD_target; 10480 break; 10481 case OMPD_target_teams_distribute_parallel_for: 10482 case OMPD_target_teams_distribute_parallel_for_simd: 10483 // If this clause applies to the nested 'parallel' region, capture within 10484 // the 'teams' region, otherwise do not capture. 10485 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10486 CaptureRegion = OMPD_teams; 10487 break; 10488 case OMPD_teams_distribute_parallel_for: 10489 case OMPD_teams_distribute_parallel_for_simd: 10490 CaptureRegion = OMPD_teams; 10491 break; 10492 case OMPD_target_update: 10493 case OMPD_target_enter_data: 10494 case OMPD_target_exit_data: 10495 CaptureRegion = OMPD_task; 10496 break; 10497 case OMPD_parallel_master_taskloop: 10498 case OMPD_parallel_master_taskloop_simd: 10499 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10500 CaptureRegion = OMPD_parallel; 10501 break; 10502 case OMPD_cancel: 10503 case OMPD_parallel: 10504 case OMPD_parallel_sections: 10505 case OMPD_parallel_for: 10506 case OMPD_parallel_for_simd: 10507 case OMPD_target: 10508 case OMPD_target_simd: 10509 case OMPD_target_teams: 10510 case OMPD_target_teams_distribute: 10511 case OMPD_target_teams_distribute_simd: 10512 case OMPD_distribute_parallel_for: 10513 case OMPD_distribute_parallel_for_simd: 10514 case OMPD_task: 10515 case OMPD_taskloop: 10516 case OMPD_taskloop_simd: 10517 case OMPD_master_taskloop: 10518 case OMPD_master_taskloop_simd: 10519 case OMPD_target_data: 10520 // Do not capture if-clause expressions. 10521 break; 10522 case OMPD_threadprivate: 10523 case OMPD_allocate: 10524 case OMPD_taskyield: 10525 case OMPD_barrier: 10526 case OMPD_taskwait: 10527 case OMPD_cancellation_point: 10528 case OMPD_flush: 10529 case OMPD_declare_reduction: 10530 case OMPD_declare_mapper: 10531 case OMPD_declare_simd: 10532 case OMPD_declare_variant: 10533 case OMPD_declare_target: 10534 case OMPD_end_declare_target: 10535 case OMPD_teams: 10536 case OMPD_simd: 10537 case OMPD_for: 10538 case OMPD_for_simd: 10539 case OMPD_sections: 10540 case OMPD_section: 10541 case OMPD_single: 10542 case OMPD_master: 10543 case OMPD_critical: 10544 case OMPD_taskgroup: 10545 case OMPD_distribute: 10546 case OMPD_ordered: 10547 case OMPD_atomic: 10548 case OMPD_distribute_simd: 10549 case OMPD_teams_distribute: 10550 case OMPD_teams_distribute_simd: 10551 case OMPD_requires: 10552 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10553 case OMPD_unknown: 10554 llvm_unreachable("Unknown OpenMP directive"); 10555 } 10556 break; 10557 case OMPC_num_threads: 10558 switch (DKind) { 10559 case OMPD_target_parallel: 10560 case OMPD_target_parallel_for: 10561 case OMPD_target_parallel_for_simd: 10562 CaptureRegion = OMPD_target; 10563 break; 10564 case OMPD_teams_distribute_parallel_for: 10565 case OMPD_teams_distribute_parallel_for_simd: 10566 case OMPD_target_teams_distribute_parallel_for: 10567 case OMPD_target_teams_distribute_parallel_for_simd: 10568 CaptureRegion = OMPD_teams; 10569 break; 10570 case OMPD_parallel: 10571 case OMPD_parallel_sections: 10572 case OMPD_parallel_for: 10573 case OMPD_parallel_for_simd: 10574 case OMPD_distribute_parallel_for: 10575 case OMPD_distribute_parallel_for_simd: 10576 case OMPD_parallel_master_taskloop: 10577 case OMPD_parallel_master_taskloop_simd: 10578 // Do not capture num_threads-clause expressions. 10579 break; 10580 case OMPD_target_data: 10581 case OMPD_target_enter_data: 10582 case OMPD_target_exit_data: 10583 case OMPD_target_update: 10584 case OMPD_target: 10585 case OMPD_target_simd: 10586 case OMPD_target_teams: 10587 case OMPD_target_teams_distribute: 10588 case OMPD_target_teams_distribute_simd: 10589 case OMPD_cancel: 10590 case OMPD_task: 10591 case OMPD_taskloop: 10592 case OMPD_taskloop_simd: 10593 case OMPD_master_taskloop: 10594 case OMPD_master_taskloop_simd: 10595 case OMPD_threadprivate: 10596 case OMPD_allocate: 10597 case OMPD_taskyield: 10598 case OMPD_barrier: 10599 case OMPD_taskwait: 10600 case OMPD_cancellation_point: 10601 case OMPD_flush: 10602 case OMPD_declare_reduction: 10603 case OMPD_declare_mapper: 10604 case OMPD_declare_simd: 10605 case OMPD_declare_variant: 10606 case OMPD_declare_target: 10607 case OMPD_end_declare_target: 10608 case OMPD_teams: 10609 case OMPD_simd: 10610 case OMPD_for: 10611 case OMPD_for_simd: 10612 case OMPD_sections: 10613 case OMPD_section: 10614 case OMPD_single: 10615 case OMPD_master: 10616 case OMPD_critical: 10617 case OMPD_taskgroup: 10618 case OMPD_distribute: 10619 case OMPD_ordered: 10620 case OMPD_atomic: 10621 case OMPD_distribute_simd: 10622 case OMPD_teams_distribute: 10623 case OMPD_teams_distribute_simd: 10624 case OMPD_requires: 10625 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10626 case OMPD_unknown: 10627 llvm_unreachable("Unknown OpenMP directive"); 10628 } 10629 break; 10630 case OMPC_num_teams: 10631 switch (DKind) { 10632 case OMPD_target_teams: 10633 case OMPD_target_teams_distribute: 10634 case OMPD_target_teams_distribute_simd: 10635 case OMPD_target_teams_distribute_parallel_for: 10636 case OMPD_target_teams_distribute_parallel_for_simd: 10637 CaptureRegion = OMPD_target; 10638 break; 10639 case OMPD_teams_distribute_parallel_for: 10640 case OMPD_teams_distribute_parallel_for_simd: 10641 case OMPD_teams: 10642 case OMPD_teams_distribute: 10643 case OMPD_teams_distribute_simd: 10644 // Do not capture num_teams-clause expressions. 10645 break; 10646 case OMPD_distribute_parallel_for: 10647 case OMPD_distribute_parallel_for_simd: 10648 case OMPD_task: 10649 case OMPD_taskloop: 10650 case OMPD_taskloop_simd: 10651 case OMPD_master_taskloop: 10652 case OMPD_master_taskloop_simd: 10653 case OMPD_parallel_master_taskloop: 10654 case OMPD_parallel_master_taskloop_simd: 10655 case OMPD_target_data: 10656 case OMPD_target_enter_data: 10657 case OMPD_target_exit_data: 10658 case OMPD_target_update: 10659 case OMPD_cancel: 10660 case OMPD_parallel: 10661 case OMPD_parallel_sections: 10662 case OMPD_parallel_for: 10663 case OMPD_parallel_for_simd: 10664 case OMPD_target: 10665 case OMPD_target_simd: 10666 case OMPD_target_parallel: 10667 case OMPD_target_parallel_for: 10668 case OMPD_target_parallel_for_simd: 10669 case OMPD_threadprivate: 10670 case OMPD_allocate: 10671 case OMPD_taskyield: 10672 case OMPD_barrier: 10673 case OMPD_taskwait: 10674 case OMPD_cancellation_point: 10675 case OMPD_flush: 10676 case OMPD_declare_reduction: 10677 case OMPD_declare_mapper: 10678 case OMPD_declare_simd: 10679 case OMPD_declare_variant: 10680 case OMPD_declare_target: 10681 case OMPD_end_declare_target: 10682 case OMPD_simd: 10683 case OMPD_for: 10684 case OMPD_for_simd: 10685 case OMPD_sections: 10686 case OMPD_section: 10687 case OMPD_single: 10688 case OMPD_master: 10689 case OMPD_critical: 10690 case OMPD_taskgroup: 10691 case OMPD_distribute: 10692 case OMPD_ordered: 10693 case OMPD_atomic: 10694 case OMPD_distribute_simd: 10695 case OMPD_requires: 10696 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10697 case OMPD_unknown: 10698 llvm_unreachable("Unknown OpenMP directive"); 10699 } 10700 break; 10701 case OMPC_thread_limit: 10702 switch (DKind) { 10703 case OMPD_target_teams: 10704 case OMPD_target_teams_distribute: 10705 case OMPD_target_teams_distribute_simd: 10706 case OMPD_target_teams_distribute_parallel_for: 10707 case OMPD_target_teams_distribute_parallel_for_simd: 10708 CaptureRegion = OMPD_target; 10709 break; 10710 case OMPD_teams_distribute_parallel_for: 10711 case OMPD_teams_distribute_parallel_for_simd: 10712 case OMPD_teams: 10713 case OMPD_teams_distribute: 10714 case OMPD_teams_distribute_simd: 10715 // Do not capture thread_limit-clause expressions. 10716 break; 10717 case OMPD_distribute_parallel_for: 10718 case OMPD_distribute_parallel_for_simd: 10719 case OMPD_task: 10720 case OMPD_taskloop: 10721 case OMPD_taskloop_simd: 10722 case OMPD_master_taskloop: 10723 case OMPD_master_taskloop_simd: 10724 case OMPD_parallel_master_taskloop: 10725 case OMPD_parallel_master_taskloop_simd: 10726 case OMPD_target_data: 10727 case OMPD_target_enter_data: 10728 case OMPD_target_exit_data: 10729 case OMPD_target_update: 10730 case OMPD_cancel: 10731 case OMPD_parallel: 10732 case OMPD_parallel_sections: 10733 case OMPD_parallel_for: 10734 case OMPD_parallel_for_simd: 10735 case OMPD_target: 10736 case OMPD_target_simd: 10737 case OMPD_target_parallel: 10738 case OMPD_target_parallel_for: 10739 case OMPD_target_parallel_for_simd: 10740 case OMPD_threadprivate: 10741 case OMPD_allocate: 10742 case OMPD_taskyield: 10743 case OMPD_barrier: 10744 case OMPD_taskwait: 10745 case OMPD_cancellation_point: 10746 case OMPD_flush: 10747 case OMPD_declare_reduction: 10748 case OMPD_declare_mapper: 10749 case OMPD_declare_simd: 10750 case OMPD_declare_variant: 10751 case OMPD_declare_target: 10752 case OMPD_end_declare_target: 10753 case OMPD_simd: 10754 case OMPD_for: 10755 case OMPD_for_simd: 10756 case OMPD_sections: 10757 case OMPD_section: 10758 case OMPD_single: 10759 case OMPD_master: 10760 case OMPD_critical: 10761 case OMPD_taskgroup: 10762 case OMPD_distribute: 10763 case OMPD_ordered: 10764 case OMPD_atomic: 10765 case OMPD_distribute_simd: 10766 case OMPD_requires: 10767 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10768 case OMPD_unknown: 10769 llvm_unreachable("Unknown OpenMP directive"); 10770 } 10771 break; 10772 case OMPC_schedule: 10773 switch (DKind) { 10774 case OMPD_parallel_for: 10775 case OMPD_parallel_for_simd: 10776 case OMPD_distribute_parallel_for: 10777 case OMPD_distribute_parallel_for_simd: 10778 case OMPD_teams_distribute_parallel_for: 10779 case OMPD_teams_distribute_parallel_for_simd: 10780 case OMPD_target_parallel_for: 10781 case OMPD_target_parallel_for_simd: 10782 case OMPD_target_teams_distribute_parallel_for: 10783 case OMPD_target_teams_distribute_parallel_for_simd: 10784 CaptureRegion = OMPD_parallel; 10785 break; 10786 case OMPD_for: 10787 case OMPD_for_simd: 10788 // Do not capture schedule-clause expressions. 10789 break; 10790 case OMPD_task: 10791 case OMPD_taskloop: 10792 case OMPD_taskloop_simd: 10793 case OMPD_master_taskloop: 10794 case OMPD_master_taskloop_simd: 10795 case OMPD_parallel_master_taskloop: 10796 case OMPD_parallel_master_taskloop_simd: 10797 case OMPD_target_data: 10798 case OMPD_target_enter_data: 10799 case OMPD_target_exit_data: 10800 case OMPD_target_update: 10801 case OMPD_teams: 10802 case OMPD_teams_distribute: 10803 case OMPD_teams_distribute_simd: 10804 case OMPD_target_teams_distribute: 10805 case OMPD_target_teams_distribute_simd: 10806 case OMPD_target: 10807 case OMPD_target_simd: 10808 case OMPD_target_parallel: 10809 case OMPD_cancel: 10810 case OMPD_parallel: 10811 case OMPD_parallel_sections: 10812 case OMPD_threadprivate: 10813 case OMPD_allocate: 10814 case OMPD_taskyield: 10815 case OMPD_barrier: 10816 case OMPD_taskwait: 10817 case OMPD_cancellation_point: 10818 case OMPD_flush: 10819 case OMPD_declare_reduction: 10820 case OMPD_declare_mapper: 10821 case OMPD_declare_simd: 10822 case OMPD_declare_variant: 10823 case OMPD_declare_target: 10824 case OMPD_end_declare_target: 10825 case OMPD_simd: 10826 case OMPD_sections: 10827 case OMPD_section: 10828 case OMPD_single: 10829 case OMPD_master: 10830 case OMPD_critical: 10831 case OMPD_taskgroup: 10832 case OMPD_distribute: 10833 case OMPD_ordered: 10834 case OMPD_atomic: 10835 case OMPD_distribute_simd: 10836 case OMPD_target_teams: 10837 case OMPD_requires: 10838 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10839 case OMPD_unknown: 10840 llvm_unreachable("Unknown OpenMP directive"); 10841 } 10842 break; 10843 case OMPC_dist_schedule: 10844 switch (DKind) { 10845 case OMPD_teams_distribute_parallel_for: 10846 case OMPD_teams_distribute_parallel_for_simd: 10847 case OMPD_teams_distribute: 10848 case OMPD_teams_distribute_simd: 10849 case OMPD_target_teams_distribute_parallel_for: 10850 case OMPD_target_teams_distribute_parallel_for_simd: 10851 case OMPD_target_teams_distribute: 10852 case OMPD_target_teams_distribute_simd: 10853 CaptureRegion = OMPD_teams; 10854 break; 10855 case OMPD_distribute_parallel_for: 10856 case OMPD_distribute_parallel_for_simd: 10857 case OMPD_distribute: 10858 case OMPD_distribute_simd: 10859 // Do not capture thread_limit-clause expressions. 10860 break; 10861 case OMPD_parallel_for: 10862 case OMPD_parallel_for_simd: 10863 case OMPD_target_parallel_for_simd: 10864 case OMPD_target_parallel_for: 10865 case OMPD_task: 10866 case OMPD_taskloop: 10867 case OMPD_taskloop_simd: 10868 case OMPD_master_taskloop: 10869 case OMPD_master_taskloop_simd: 10870 case OMPD_parallel_master_taskloop: 10871 case OMPD_parallel_master_taskloop_simd: 10872 case OMPD_target_data: 10873 case OMPD_target_enter_data: 10874 case OMPD_target_exit_data: 10875 case OMPD_target_update: 10876 case OMPD_teams: 10877 case OMPD_target: 10878 case OMPD_target_simd: 10879 case OMPD_target_parallel: 10880 case OMPD_cancel: 10881 case OMPD_parallel: 10882 case OMPD_parallel_sections: 10883 case OMPD_threadprivate: 10884 case OMPD_allocate: 10885 case OMPD_taskyield: 10886 case OMPD_barrier: 10887 case OMPD_taskwait: 10888 case OMPD_cancellation_point: 10889 case OMPD_flush: 10890 case OMPD_declare_reduction: 10891 case OMPD_declare_mapper: 10892 case OMPD_declare_simd: 10893 case OMPD_declare_variant: 10894 case OMPD_declare_target: 10895 case OMPD_end_declare_target: 10896 case OMPD_simd: 10897 case OMPD_for: 10898 case OMPD_for_simd: 10899 case OMPD_sections: 10900 case OMPD_section: 10901 case OMPD_single: 10902 case OMPD_master: 10903 case OMPD_critical: 10904 case OMPD_taskgroup: 10905 case OMPD_ordered: 10906 case OMPD_atomic: 10907 case OMPD_target_teams: 10908 case OMPD_requires: 10909 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10910 case OMPD_unknown: 10911 llvm_unreachable("Unknown OpenMP directive"); 10912 } 10913 break; 10914 case OMPC_device: 10915 switch (DKind) { 10916 case OMPD_target_update: 10917 case OMPD_target_enter_data: 10918 case OMPD_target_exit_data: 10919 case OMPD_target: 10920 case OMPD_target_simd: 10921 case OMPD_target_teams: 10922 case OMPD_target_parallel: 10923 case OMPD_target_teams_distribute: 10924 case OMPD_target_teams_distribute_simd: 10925 case OMPD_target_parallel_for: 10926 case OMPD_target_parallel_for_simd: 10927 case OMPD_target_teams_distribute_parallel_for: 10928 case OMPD_target_teams_distribute_parallel_for_simd: 10929 CaptureRegion = OMPD_task; 10930 break; 10931 case OMPD_target_data: 10932 // Do not capture device-clause expressions. 10933 break; 10934 case OMPD_teams_distribute_parallel_for: 10935 case OMPD_teams_distribute_parallel_for_simd: 10936 case OMPD_teams: 10937 case OMPD_teams_distribute: 10938 case OMPD_teams_distribute_simd: 10939 case OMPD_distribute_parallel_for: 10940 case OMPD_distribute_parallel_for_simd: 10941 case OMPD_task: 10942 case OMPD_taskloop: 10943 case OMPD_taskloop_simd: 10944 case OMPD_master_taskloop: 10945 case OMPD_master_taskloop_simd: 10946 case OMPD_parallel_master_taskloop: 10947 case OMPD_parallel_master_taskloop_simd: 10948 case OMPD_cancel: 10949 case OMPD_parallel: 10950 case OMPD_parallel_sections: 10951 case OMPD_parallel_for: 10952 case OMPD_parallel_for_simd: 10953 case OMPD_threadprivate: 10954 case OMPD_allocate: 10955 case OMPD_taskyield: 10956 case OMPD_barrier: 10957 case OMPD_taskwait: 10958 case OMPD_cancellation_point: 10959 case OMPD_flush: 10960 case OMPD_declare_reduction: 10961 case OMPD_declare_mapper: 10962 case OMPD_declare_simd: 10963 case OMPD_declare_variant: 10964 case OMPD_declare_target: 10965 case OMPD_end_declare_target: 10966 case OMPD_simd: 10967 case OMPD_for: 10968 case OMPD_for_simd: 10969 case OMPD_sections: 10970 case OMPD_section: 10971 case OMPD_single: 10972 case OMPD_master: 10973 case OMPD_critical: 10974 case OMPD_taskgroup: 10975 case OMPD_distribute: 10976 case OMPD_ordered: 10977 case OMPD_atomic: 10978 case OMPD_distribute_simd: 10979 case OMPD_requires: 10980 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10981 case OMPD_unknown: 10982 llvm_unreachable("Unknown OpenMP directive"); 10983 } 10984 break; 10985 case OMPC_grainsize: 10986 case OMPC_num_tasks: 10987 case OMPC_final: 10988 case OMPC_priority: 10989 switch (DKind) { 10990 case OMPD_task: 10991 case OMPD_taskloop: 10992 case OMPD_taskloop_simd: 10993 case OMPD_master_taskloop: 10994 case OMPD_master_taskloop_simd: 10995 break; 10996 case OMPD_parallel_master_taskloop: 10997 case OMPD_parallel_master_taskloop_simd: 10998 CaptureRegion = OMPD_parallel; 10999 break; 11000 case OMPD_target_update: 11001 case OMPD_target_enter_data: 11002 case OMPD_target_exit_data: 11003 case OMPD_target: 11004 case OMPD_target_simd: 11005 case OMPD_target_teams: 11006 case OMPD_target_parallel: 11007 case OMPD_target_teams_distribute: 11008 case OMPD_target_teams_distribute_simd: 11009 case OMPD_target_parallel_for: 11010 case OMPD_target_parallel_for_simd: 11011 case OMPD_target_teams_distribute_parallel_for: 11012 case OMPD_target_teams_distribute_parallel_for_simd: 11013 case OMPD_target_data: 11014 case OMPD_teams_distribute_parallel_for: 11015 case OMPD_teams_distribute_parallel_for_simd: 11016 case OMPD_teams: 11017 case OMPD_teams_distribute: 11018 case OMPD_teams_distribute_simd: 11019 case OMPD_distribute_parallel_for: 11020 case OMPD_distribute_parallel_for_simd: 11021 case OMPD_cancel: 11022 case OMPD_parallel: 11023 case OMPD_parallel_sections: 11024 case OMPD_parallel_for: 11025 case OMPD_parallel_for_simd: 11026 case OMPD_threadprivate: 11027 case OMPD_allocate: 11028 case OMPD_taskyield: 11029 case OMPD_barrier: 11030 case OMPD_taskwait: 11031 case OMPD_cancellation_point: 11032 case OMPD_flush: 11033 case OMPD_declare_reduction: 11034 case OMPD_declare_mapper: 11035 case OMPD_declare_simd: 11036 case OMPD_declare_variant: 11037 case OMPD_declare_target: 11038 case OMPD_end_declare_target: 11039 case OMPD_simd: 11040 case OMPD_for: 11041 case OMPD_for_simd: 11042 case OMPD_sections: 11043 case OMPD_section: 11044 case OMPD_single: 11045 case OMPD_master: 11046 case OMPD_critical: 11047 case OMPD_taskgroup: 11048 case OMPD_distribute: 11049 case OMPD_ordered: 11050 case OMPD_atomic: 11051 case OMPD_distribute_simd: 11052 case OMPD_requires: 11053 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11054 case OMPD_unknown: 11055 llvm_unreachable("Unknown OpenMP directive"); 11056 } 11057 break; 11058 case OMPC_firstprivate: 11059 case OMPC_lastprivate: 11060 case OMPC_reduction: 11061 case OMPC_task_reduction: 11062 case OMPC_in_reduction: 11063 case OMPC_linear: 11064 case OMPC_default: 11065 case OMPC_proc_bind: 11066 case OMPC_safelen: 11067 case OMPC_simdlen: 11068 case OMPC_allocator: 11069 case OMPC_collapse: 11070 case OMPC_private: 11071 case OMPC_shared: 11072 case OMPC_aligned: 11073 case OMPC_copyin: 11074 case OMPC_copyprivate: 11075 case OMPC_ordered: 11076 case OMPC_nowait: 11077 case OMPC_untied: 11078 case OMPC_mergeable: 11079 case OMPC_threadprivate: 11080 case OMPC_allocate: 11081 case OMPC_flush: 11082 case OMPC_read: 11083 case OMPC_write: 11084 case OMPC_update: 11085 case OMPC_capture: 11086 case OMPC_seq_cst: 11087 case OMPC_depend: 11088 case OMPC_threads: 11089 case OMPC_simd: 11090 case OMPC_map: 11091 case OMPC_nogroup: 11092 case OMPC_hint: 11093 case OMPC_defaultmap: 11094 case OMPC_unknown: 11095 case OMPC_uniform: 11096 case OMPC_to: 11097 case OMPC_from: 11098 case OMPC_use_device_ptr: 11099 case OMPC_is_device_ptr: 11100 case OMPC_unified_address: 11101 case OMPC_unified_shared_memory: 11102 case OMPC_reverse_offload: 11103 case OMPC_dynamic_allocators: 11104 case OMPC_atomic_default_mem_order: 11105 case OMPC_device_type: 11106 case OMPC_match: 11107 llvm_unreachable("Unexpected OpenMP clause."); 11108 } 11109 return CaptureRegion; 11110 } 11111 11112 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11113 Expr *Condition, SourceLocation StartLoc, 11114 SourceLocation LParenLoc, 11115 SourceLocation NameModifierLoc, 11116 SourceLocation ColonLoc, 11117 SourceLocation EndLoc) { 11118 Expr *ValExpr = Condition; 11119 Stmt *HelperValStmt = nullptr; 11120 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11121 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11122 !Condition->isInstantiationDependent() && 11123 !Condition->containsUnexpandedParameterPack()) { 11124 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11125 if (Val.isInvalid()) 11126 return nullptr; 11127 11128 ValExpr = Val.get(); 11129 11130 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11131 CaptureRegion = 11132 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 11133 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11134 ValExpr = MakeFullExpr(ValExpr).get(); 11135 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11136 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11137 HelperValStmt = buildPreInits(Context, Captures); 11138 } 11139 } 11140 11141 return new (Context) 11142 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11143 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11144 } 11145 11146 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11147 SourceLocation StartLoc, 11148 SourceLocation LParenLoc, 11149 SourceLocation EndLoc) { 11150 Expr *ValExpr = Condition; 11151 Stmt *HelperValStmt = nullptr; 11152 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11153 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11154 !Condition->isInstantiationDependent() && 11155 !Condition->containsUnexpandedParameterPack()) { 11156 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11157 if (Val.isInvalid()) 11158 return nullptr; 11159 11160 ValExpr = MakeFullExpr(Val.get()).get(); 11161 11162 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11163 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final); 11164 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11165 ValExpr = MakeFullExpr(ValExpr).get(); 11166 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11167 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11168 HelperValStmt = buildPreInits(Context, Captures); 11169 } 11170 } 11171 11172 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11173 StartLoc, LParenLoc, EndLoc); 11174 } 11175 11176 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11177 Expr *Op) { 11178 if (!Op) 11179 return ExprError(); 11180 11181 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11182 public: 11183 IntConvertDiagnoser() 11184 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11185 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11186 QualType T) override { 11187 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11188 } 11189 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11190 QualType T) override { 11191 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11192 } 11193 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11194 QualType T, 11195 QualType ConvTy) override { 11196 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11197 } 11198 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11199 QualType ConvTy) override { 11200 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11201 << ConvTy->isEnumeralType() << ConvTy; 11202 } 11203 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11204 QualType T) override { 11205 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11206 } 11207 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11208 QualType ConvTy) override { 11209 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11210 << ConvTy->isEnumeralType() << ConvTy; 11211 } 11212 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11213 QualType) override { 11214 llvm_unreachable("conversion functions are permitted"); 11215 } 11216 } ConvertDiagnoser; 11217 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11218 } 11219 11220 static bool 11221 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11222 bool StrictlyPositive, bool BuildCapture = false, 11223 OpenMPDirectiveKind DKind = OMPD_unknown, 11224 OpenMPDirectiveKind *CaptureRegion = nullptr, 11225 Stmt **HelperValStmt = nullptr) { 11226 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11227 !ValExpr->isInstantiationDependent()) { 11228 SourceLocation Loc = ValExpr->getExprLoc(); 11229 ExprResult Value = 11230 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11231 if (Value.isInvalid()) 11232 return false; 11233 11234 ValExpr = Value.get(); 11235 // The expression must evaluate to a non-negative integer value. 11236 llvm::APSInt Result; 11237 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11238 Result.isSigned() && 11239 !((!StrictlyPositive && Result.isNonNegative()) || 11240 (StrictlyPositive && Result.isStrictlyPositive()))) { 11241 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11242 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11243 << ValExpr->getSourceRange(); 11244 return false; 11245 } 11246 if (!BuildCapture) 11247 return true; 11248 *CaptureRegion = getOpenMPCaptureRegionForClause(DKind, CKind); 11249 if (*CaptureRegion != OMPD_unknown && 11250 !SemaRef.CurContext->isDependentContext()) { 11251 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11252 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11253 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11254 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11255 } 11256 } 11257 return true; 11258 } 11259 11260 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11261 SourceLocation StartLoc, 11262 SourceLocation LParenLoc, 11263 SourceLocation EndLoc) { 11264 Expr *ValExpr = NumThreads; 11265 Stmt *HelperValStmt = nullptr; 11266 11267 // OpenMP [2.5, Restrictions] 11268 // The num_threads expression must evaluate to a positive integer value. 11269 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11270 /*StrictlyPositive=*/true)) 11271 return nullptr; 11272 11273 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11274 OpenMPDirectiveKind CaptureRegion = 11275 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 11276 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11277 ValExpr = MakeFullExpr(ValExpr).get(); 11278 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11279 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11280 HelperValStmt = buildPreInits(Context, Captures); 11281 } 11282 11283 return new (Context) OMPNumThreadsClause( 11284 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11285 } 11286 11287 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11288 OpenMPClauseKind CKind, 11289 bool StrictlyPositive) { 11290 if (!E) 11291 return ExprError(); 11292 if (E->isValueDependent() || E->isTypeDependent() || 11293 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11294 return E; 11295 llvm::APSInt Result; 11296 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11297 if (ICE.isInvalid()) 11298 return ExprError(); 11299 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11300 (!StrictlyPositive && !Result.isNonNegative())) { 11301 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11302 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11303 << E->getSourceRange(); 11304 return ExprError(); 11305 } 11306 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11307 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11308 << E->getSourceRange(); 11309 return ExprError(); 11310 } 11311 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11312 DSAStack->setAssociatedLoops(Result.getExtValue()); 11313 else if (CKind == OMPC_ordered) 11314 DSAStack->setAssociatedLoops(Result.getExtValue()); 11315 return ICE; 11316 } 11317 11318 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11319 SourceLocation LParenLoc, 11320 SourceLocation EndLoc) { 11321 // OpenMP [2.8.1, simd construct, Description] 11322 // The parameter of the safelen clause must be a constant 11323 // positive integer expression. 11324 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11325 if (Safelen.isInvalid()) 11326 return nullptr; 11327 return new (Context) 11328 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11329 } 11330 11331 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11332 SourceLocation LParenLoc, 11333 SourceLocation EndLoc) { 11334 // OpenMP [2.8.1, simd construct, Description] 11335 // The parameter of the simdlen clause must be a constant 11336 // positive integer expression. 11337 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11338 if (Simdlen.isInvalid()) 11339 return nullptr; 11340 return new (Context) 11341 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11342 } 11343 11344 /// Tries to find omp_allocator_handle_t type. 11345 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11346 DSAStackTy *Stack) { 11347 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11348 if (!OMPAllocatorHandleT.isNull()) 11349 return true; 11350 // Build the predefined allocator expressions. 11351 bool ErrorFound = false; 11352 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11353 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11354 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11355 StringRef Allocator = 11356 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11357 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11358 auto *VD = dyn_cast_or_null<ValueDecl>( 11359 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11360 if (!VD) { 11361 ErrorFound = true; 11362 break; 11363 } 11364 QualType AllocatorType = 11365 VD->getType().getNonLValueExprType(S.getASTContext()); 11366 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11367 if (!Res.isUsable()) { 11368 ErrorFound = true; 11369 break; 11370 } 11371 if (OMPAllocatorHandleT.isNull()) 11372 OMPAllocatorHandleT = AllocatorType; 11373 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11374 ErrorFound = true; 11375 break; 11376 } 11377 Stack->setAllocator(AllocatorKind, Res.get()); 11378 } 11379 if (ErrorFound) { 11380 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11381 return false; 11382 } 11383 OMPAllocatorHandleT.addConst(); 11384 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11385 return true; 11386 } 11387 11388 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11389 SourceLocation LParenLoc, 11390 SourceLocation EndLoc) { 11391 // OpenMP [2.11.3, allocate Directive, Description] 11392 // allocator is an expression of omp_allocator_handle_t type. 11393 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11394 return nullptr; 11395 11396 ExprResult Allocator = DefaultLvalueConversion(A); 11397 if (Allocator.isInvalid()) 11398 return nullptr; 11399 Allocator = PerformImplicitConversion(Allocator.get(), 11400 DSAStack->getOMPAllocatorHandleT(), 11401 Sema::AA_Initializing, 11402 /*AllowExplicit=*/true); 11403 if (Allocator.isInvalid()) 11404 return nullptr; 11405 return new (Context) 11406 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11407 } 11408 11409 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11410 SourceLocation StartLoc, 11411 SourceLocation LParenLoc, 11412 SourceLocation EndLoc) { 11413 // OpenMP [2.7.1, loop construct, Description] 11414 // OpenMP [2.8.1, simd construct, Description] 11415 // OpenMP [2.9.6, distribute construct, Description] 11416 // The parameter of the collapse clause must be a constant 11417 // positive integer expression. 11418 ExprResult NumForLoopsResult = 11419 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11420 if (NumForLoopsResult.isInvalid()) 11421 return nullptr; 11422 return new (Context) 11423 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11424 } 11425 11426 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11427 SourceLocation EndLoc, 11428 SourceLocation LParenLoc, 11429 Expr *NumForLoops) { 11430 // OpenMP [2.7.1, loop construct, Description] 11431 // OpenMP [2.8.1, simd construct, Description] 11432 // OpenMP [2.9.6, distribute construct, Description] 11433 // The parameter of the ordered clause must be a constant 11434 // positive integer expression if any. 11435 if (NumForLoops && LParenLoc.isValid()) { 11436 ExprResult NumForLoopsResult = 11437 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11438 if (NumForLoopsResult.isInvalid()) 11439 return nullptr; 11440 NumForLoops = NumForLoopsResult.get(); 11441 } else { 11442 NumForLoops = nullptr; 11443 } 11444 auto *Clause = OMPOrderedClause::Create( 11445 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11446 StartLoc, LParenLoc, EndLoc); 11447 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11448 return Clause; 11449 } 11450 11451 OMPClause *Sema::ActOnOpenMPSimpleClause( 11452 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11453 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11454 OMPClause *Res = nullptr; 11455 switch (Kind) { 11456 case OMPC_default: 11457 Res = 11458 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11459 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11460 break; 11461 case OMPC_proc_bind: 11462 Res = ActOnOpenMPProcBindClause( 11463 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11464 LParenLoc, EndLoc); 11465 break; 11466 case OMPC_atomic_default_mem_order: 11467 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11468 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11469 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11470 break; 11471 case OMPC_if: 11472 case OMPC_final: 11473 case OMPC_num_threads: 11474 case OMPC_safelen: 11475 case OMPC_simdlen: 11476 case OMPC_allocator: 11477 case OMPC_collapse: 11478 case OMPC_schedule: 11479 case OMPC_private: 11480 case OMPC_firstprivate: 11481 case OMPC_lastprivate: 11482 case OMPC_shared: 11483 case OMPC_reduction: 11484 case OMPC_task_reduction: 11485 case OMPC_in_reduction: 11486 case OMPC_linear: 11487 case OMPC_aligned: 11488 case OMPC_copyin: 11489 case OMPC_copyprivate: 11490 case OMPC_ordered: 11491 case OMPC_nowait: 11492 case OMPC_untied: 11493 case OMPC_mergeable: 11494 case OMPC_threadprivate: 11495 case OMPC_allocate: 11496 case OMPC_flush: 11497 case OMPC_read: 11498 case OMPC_write: 11499 case OMPC_update: 11500 case OMPC_capture: 11501 case OMPC_seq_cst: 11502 case OMPC_depend: 11503 case OMPC_device: 11504 case OMPC_threads: 11505 case OMPC_simd: 11506 case OMPC_map: 11507 case OMPC_num_teams: 11508 case OMPC_thread_limit: 11509 case OMPC_priority: 11510 case OMPC_grainsize: 11511 case OMPC_nogroup: 11512 case OMPC_num_tasks: 11513 case OMPC_hint: 11514 case OMPC_dist_schedule: 11515 case OMPC_defaultmap: 11516 case OMPC_unknown: 11517 case OMPC_uniform: 11518 case OMPC_to: 11519 case OMPC_from: 11520 case OMPC_use_device_ptr: 11521 case OMPC_is_device_ptr: 11522 case OMPC_unified_address: 11523 case OMPC_unified_shared_memory: 11524 case OMPC_reverse_offload: 11525 case OMPC_dynamic_allocators: 11526 case OMPC_device_type: 11527 case OMPC_match: 11528 llvm_unreachable("Clause is not allowed."); 11529 } 11530 return Res; 11531 } 11532 11533 static std::string 11534 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11535 ArrayRef<unsigned> Exclude = llvm::None) { 11536 SmallString<256> Buffer; 11537 llvm::raw_svector_ostream Out(Buffer); 11538 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11539 unsigned Skipped = Exclude.size(); 11540 auto S = Exclude.begin(), E = Exclude.end(); 11541 for (unsigned I = First; I < Last; ++I) { 11542 if (std::find(S, E, I) != E) { 11543 --Skipped; 11544 continue; 11545 } 11546 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11547 if (I == Bound - Skipped) 11548 Out << " or "; 11549 else if (I != Bound + 1 - Skipped) 11550 Out << ", "; 11551 } 11552 return Out.str(); 11553 } 11554 11555 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11556 SourceLocation KindKwLoc, 11557 SourceLocation StartLoc, 11558 SourceLocation LParenLoc, 11559 SourceLocation EndLoc) { 11560 if (Kind == OMPC_DEFAULT_unknown) { 11561 static_assert(OMPC_DEFAULT_unknown > 0, 11562 "OMPC_DEFAULT_unknown not greater than 0"); 11563 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11564 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11565 /*Last=*/OMPC_DEFAULT_unknown) 11566 << getOpenMPClauseName(OMPC_default); 11567 return nullptr; 11568 } 11569 switch (Kind) { 11570 case OMPC_DEFAULT_none: 11571 DSAStack->setDefaultDSANone(KindKwLoc); 11572 break; 11573 case OMPC_DEFAULT_shared: 11574 DSAStack->setDefaultDSAShared(KindKwLoc); 11575 break; 11576 case OMPC_DEFAULT_unknown: 11577 llvm_unreachable("Clause kind is not allowed."); 11578 break; 11579 } 11580 return new (Context) 11581 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11582 } 11583 11584 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11585 SourceLocation KindKwLoc, 11586 SourceLocation StartLoc, 11587 SourceLocation LParenLoc, 11588 SourceLocation EndLoc) { 11589 if (Kind == OMPC_PROC_BIND_unknown) { 11590 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11591 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11592 /*Last=*/OMPC_PROC_BIND_unknown) 11593 << getOpenMPClauseName(OMPC_proc_bind); 11594 return nullptr; 11595 } 11596 return new (Context) 11597 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11598 } 11599 11600 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11601 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11602 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11603 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11604 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11605 << getListOfPossibleValues( 11606 OMPC_atomic_default_mem_order, /*First=*/0, 11607 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11608 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11609 return nullptr; 11610 } 11611 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11612 LParenLoc, EndLoc); 11613 } 11614 11615 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11616 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11617 SourceLocation StartLoc, SourceLocation LParenLoc, 11618 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11619 SourceLocation EndLoc) { 11620 OMPClause *Res = nullptr; 11621 switch (Kind) { 11622 case OMPC_schedule: 11623 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11624 assert(Argument.size() == NumberOfElements && 11625 ArgumentLoc.size() == NumberOfElements); 11626 Res = ActOnOpenMPScheduleClause( 11627 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11628 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11629 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11630 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11631 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11632 break; 11633 case OMPC_if: 11634 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11635 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11636 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11637 DelimLoc, EndLoc); 11638 break; 11639 case OMPC_dist_schedule: 11640 Res = ActOnOpenMPDistScheduleClause( 11641 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11642 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11643 break; 11644 case OMPC_defaultmap: 11645 enum { Modifier, DefaultmapKind }; 11646 Res = ActOnOpenMPDefaultmapClause( 11647 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11648 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11649 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11650 EndLoc); 11651 break; 11652 case OMPC_final: 11653 case OMPC_num_threads: 11654 case OMPC_safelen: 11655 case OMPC_simdlen: 11656 case OMPC_allocator: 11657 case OMPC_collapse: 11658 case OMPC_default: 11659 case OMPC_proc_bind: 11660 case OMPC_private: 11661 case OMPC_firstprivate: 11662 case OMPC_lastprivate: 11663 case OMPC_shared: 11664 case OMPC_reduction: 11665 case OMPC_task_reduction: 11666 case OMPC_in_reduction: 11667 case OMPC_linear: 11668 case OMPC_aligned: 11669 case OMPC_copyin: 11670 case OMPC_copyprivate: 11671 case OMPC_ordered: 11672 case OMPC_nowait: 11673 case OMPC_untied: 11674 case OMPC_mergeable: 11675 case OMPC_threadprivate: 11676 case OMPC_allocate: 11677 case OMPC_flush: 11678 case OMPC_read: 11679 case OMPC_write: 11680 case OMPC_update: 11681 case OMPC_capture: 11682 case OMPC_seq_cst: 11683 case OMPC_depend: 11684 case OMPC_device: 11685 case OMPC_threads: 11686 case OMPC_simd: 11687 case OMPC_map: 11688 case OMPC_num_teams: 11689 case OMPC_thread_limit: 11690 case OMPC_priority: 11691 case OMPC_grainsize: 11692 case OMPC_nogroup: 11693 case OMPC_num_tasks: 11694 case OMPC_hint: 11695 case OMPC_unknown: 11696 case OMPC_uniform: 11697 case OMPC_to: 11698 case OMPC_from: 11699 case OMPC_use_device_ptr: 11700 case OMPC_is_device_ptr: 11701 case OMPC_unified_address: 11702 case OMPC_unified_shared_memory: 11703 case OMPC_reverse_offload: 11704 case OMPC_dynamic_allocators: 11705 case OMPC_atomic_default_mem_order: 11706 case OMPC_device_type: 11707 case OMPC_match: 11708 llvm_unreachable("Clause is not allowed."); 11709 } 11710 return Res; 11711 } 11712 11713 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11714 OpenMPScheduleClauseModifier M2, 11715 SourceLocation M1Loc, SourceLocation M2Loc) { 11716 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11717 SmallVector<unsigned, 2> Excluded; 11718 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11719 Excluded.push_back(M2); 11720 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11721 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11722 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11723 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11724 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11725 << getListOfPossibleValues(OMPC_schedule, 11726 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11727 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11728 Excluded) 11729 << getOpenMPClauseName(OMPC_schedule); 11730 return true; 11731 } 11732 return false; 11733 } 11734 11735 OMPClause *Sema::ActOnOpenMPScheduleClause( 11736 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11737 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11738 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11739 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11740 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11741 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11742 return nullptr; 11743 // OpenMP, 2.7.1, Loop Construct, Restrictions 11744 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11745 // but not both. 11746 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11747 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11748 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11749 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11750 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11751 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11752 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11753 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11754 return nullptr; 11755 } 11756 if (Kind == OMPC_SCHEDULE_unknown) { 11757 std::string Values; 11758 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11759 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11760 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11761 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11762 Exclude); 11763 } else { 11764 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11765 /*Last=*/OMPC_SCHEDULE_unknown); 11766 } 11767 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11768 << Values << getOpenMPClauseName(OMPC_schedule); 11769 return nullptr; 11770 } 11771 // OpenMP, 2.7.1, Loop Construct, Restrictions 11772 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11773 // schedule(guided). 11774 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11775 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11776 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11777 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11778 diag::err_omp_schedule_nonmonotonic_static); 11779 return nullptr; 11780 } 11781 Expr *ValExpr = ChunkSize; 11782 Stmt *HelperValStmt = nullptr; 11783 if (ChunkSize) { 11784 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11785 !ChunkSize->isInstantiationDependent() && 11786 !ChunkSize->containsUnexpandedParameterPack()) { 11787 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11788 ExprResult Val = 11789 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11790 if (Val.isInvalid()) 11791 return nullptr; 11792 11793 ValExpr = Val.get(); 11794 11795 // OpenMP [2.7.1, Restrictions] 11796 // chunk_size must be a loop invariant integer expression with a positive 11797 // value. 11798 llvm::APSInt Result; 11799 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11800 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11801 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11802 << "schedule" << 1 << ChunkSize->getSourceRange(); 11803 return nullptr; 11804 } 11805 } else if (getOpenMPCaptureRegionForClause( 11806 DSAStack->getCurrentDirective(), OMPC_schedule) != 11807 OMPD_unknown && 11808 !CurContext->isDependentContext()) { 11809 ValExpr = MakeFullExpr(ValExpr).get(); 11810 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11811 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11812 HelperValStmt = buildPreInits(Context, Captures); 11813 } 11814 } 11815 } 11816 11817 return new (Context) 11818 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11819 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11820 } 11821 11822 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11823 SourceLocation StartLoc, 11824 SourceLocation EndLoc) { 11825 OMPClause *Res = nullptr; 11826 switch (Kind) { 11827 case OMPC_ordered: 11828 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11829 break; 11830 case OMPC_nowait: 11831 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11832 break; 11833 case OMPC_untied: 11834 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11835 break; 11836 case OMPC_mergeable: 11837 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11838 break; 11839 case OMPC_read: 11840 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11841 break; 11842 case OMPC_write: 11843 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11844 break; 11845 case OMPC_update: 11846 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11847 break; 11848 case OMPC_capture: 11849 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11850 break; 11851 case OMPC_seq_cst: 11852 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11853 break; 11854 case OMPC_threads: 11855 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11856 break; 11857 case OMPC_simd: 11858 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11859 break; 11860 case OMPC_nogroup: 11861 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11862 break; 11863 case OMPC_unified_address: 11864 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11865 break; 11866 case OMPC_unified_shared_memory: 11867 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11868 break; 11869 case OMPC_reverse_offload: 11870 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11871 break; 11872 case OMPC_dynamic_allocators: 11873 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11874 break; 11875 case OMPC_if: 11876 case OMPC_final: 11877 case OMPC_num_threads: 11878 case OMPC_safelen: 11879 case OMPC_simdlen: 11880 case OMPC_allocator: 11881 case OMPC_collapse: 11882 case OMPC_schedule: 11883 case OMPC_private: 11884 case OMPC_firstprivate: 11885 case OMPC_lastprivate: 11886 case OMPC_shared: 11887 case OMPC_reduction: 11888 case OMPC_task_reduction: 11889 case OMPC_in_reduction: 11890 case OMPC_linear: 11891 case OMPC_aligned: 11892 case OMPC_copyin: 11893 case OMPC_copyprivate: 11894 case OMPC_default: 11895 case OMPC_proc_bind: 11896 case OMPC_threadprivate: 11897 case OMPC_allocate: 11898 case OMPC_flush: 11899 case OMPC_depend: 11900 case OMPC_device: 11901 case OMPC_map: 11902 case OMPC_num_teams: 11903 case OMPC_thread_limit: 11904 case OMPC_priority: 11905 case OMPC_grainsize: 11906 case OMPC_num_tasks: 11907 case OMPC_hint: 11908 case OMPC_dist_schedule: 11909 case OMPC_defaultmap: 11910 case OMPC_unknown: 11911 case OMPC_uniform: 11912 case OMPC_to: 11913 case OMPC_from: 11914 case OMPC_use_device_ptr: 11915 case OMPC_is_device_ptr: 11916 case OMPC_atomic_default_mem_order: 11917 case OMPC_device_type: 11918 case OMPC_match: 11919 llvm_unreachable("Clause is not allowed."); 11920 } 11921 return Res; 11922 } 11923 11924 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11925 SourceLocation EndLoc) { 11926 DSAStack->setNowaitRegion(); 11927 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11928 } 11929 11930 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11931 SourceLocation EndLoc) { 11932 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11933 } 11934 11935 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11936 SourceLocation EndLoc) { 11937 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11938 } 11939 11940 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11941 SourceLocation EndLoc) { 11942 return new (Context) OMPReadClause(StartLoc, EndLoc); 11943 } 11944 11945 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11946 SourceLocation EndLoc) { 11947 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11948 } 11949 11950 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11951 SourceLocation EndLoc) { 11952 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11953 } 11954 11955 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11956 SourceLocation EndLoc) { 11957 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11958 } 11959 11960 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11961 SourceLocation EndLoc) { 11962 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11963 } 11964 11965 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11966 SourceLocation EndLoc) { 11967 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11968 } 11969 11970 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11971 SourceLocation EndLoc) { 11972 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11973 } 11974 11975 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11976 SourceLocation EndLoc) { 11977 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11978 } 11979 11980 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11981 SourceLocation EndLoc) { 11982 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11983 } 11984 11985 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11986 SourceLocation EndLoc) { 11987 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11988 } 11989 11990 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11991 SourceLocation EndLoc) { 11992 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11993 } 11994 11995 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11996 SourceLocation EndLoc) { 11997 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11998 } 11999 12000 OMPClause *Sema::ActOnOpenMPVarListClause( 12001 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12002 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12003 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12004 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 12005 OpenMPLinearClauseKind LinKind, 12006 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12007 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 12008 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 12009 SourceLocation StartLoc = Locs.StartLoc; 12010 SourceLocation LParenLoc = Locs.LParenLoc; 12011 SourceLocation EndLoc = Locs.EndLoc; 12012 OMPClause *Res = nullptr; 12013 switch (Kind) { 12014 case OMPC_private: 12015 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12016 break; 12017 case OMPC_firstprivate: 12018 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12019 break; 12020 case OMPC_lastprivate: 12021 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12022 break; 12023 case OMPC_shared: 12024 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12025 break; 12026 case OMPC_reduction: 12027 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12028 EndLoc, ReductionOrMapperIdScopeSpec, 12029 ReductionOrMapperId); 12030 break; 12031 case OMPC_task_reduction: 12032 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12033 EndLoc, ReductionOrMapperIdScopeSpec, 12034 ReductionOrMapperId); 12035 break; 12036 case OMPC_in_reduction: 12037 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12038 EndLoc, ReductionOrMapperIdScopeSpec, 12039 ReductionOrMapperId); 12040 break; 12041 case OMPC_linear: 12042 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 12043 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 12044 break; 12045 case OMPC_aligned: 12046 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12047 ColonLoc, EndLoc); 12048 break; 12049 case OMPC_copyin: 12050 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12051 break; 12052 case OMPC_copyprivate: 12053 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12054 break; 12055 case OMPC_flush: 12056 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12057 break; 12058 case OMPC_depend: 12059 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 12060 StartLoc, LParenLoc, EndLoc); 12061 break; 12062 case OMPC_map: 12063 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 12064 ReductionOrMapperIdScopeSpec, 12065 ReductionOrMapperId, MapType, IsMapTypeImplicit, 12066 DepLinMapLoc, ColonLoc, VarList, Locs); 12067 break; 12068 case OMPC_to: 12069 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12070 ReductionOrMapperId, Locs); 12071 break; 12072 case OMPC_from: 12073 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12074 ReductionOrMapperId, Locs); 12075 break; 12076 case OMPC_use_device_ptr: 12077 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12078 break; 12079 case OMPC_is_device_ptr: 12080 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12081 break; 12082 case OMPC_allocate: 12083 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12084 ColonLoc, EndLoc); 12085 break; 12086 case OMPC_if: 12087 case OMPC_final: 12088 case OMPC_num_threads: 12089 case OMPC_safelen: 12090 case OMPC_simdlen: 12091 case OMPC_allocator: 12092 case OMPC_collapse: 12093 case OMPC_default: 12094 case OMPC_proc_bind: 12095 case OMPC_schedule: 12096 case OMPC_ordered: 12097 case OMPC_nowait: 12098 case OMPC_untied: 12099 case OMPC_mergeable: 12100 case OMPC_threadprivate: 12101 case OMPC_read: 12102 case OMPC_write: 12103 case OMPC_update: 12104 case OMPC_capture: 12105 case OMPC_seq_cst: 12106 case OMPC_device: 12107 case OMPC_threads: 12108 case OMPC_simd: 12109 case OMPC_num_teams: 12110 case OMPC_thread_limit: 12111 case OMPC_priority: 12112 case OMPC_grainsize: 12113 case OMPC_nogroup: 12114 case OMPC_num_tasks: 12115 case OMPC_hint: 12116 case OMPC_dist_schedule: 12117 case OMPC_defaultmap: 12118 case OMPC_unknown: 12119 case OMPC_uniform: 12120 case OMPC_unified_address: 12121 case OMPC_unified_shared_memory: 12122 case OMPC_reverse_offload: 12123 case OMPC_dynamic_allocators: 12124 case OMPC_atomic_default_mem_order: 12125 case OMPC_device_type: 12126 case OMPC_match: 12127 llvm_unreachable("Clause is not allowed."); 12128 } 12129 return Res; 12130 } 12131 12132 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12133 ExprObjectKind OK, SourceLocation Loc) { 12134 ExprResult Res = BuildDeclRefExpr( 12135 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12136 if (!Res.isUsable()) 12137 return ExprError(); 12138 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12139 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12140 if (!Res.isUsable()) 12141 return ExprError(); 12142 } 12143 if (VK != VK_LValue && Res.get()->isGLValue()) { 12144 Res = DefaultLvalueConversion(Res.get()); 12145 if (!Res.isUsable()) 12146 return ExprError(); 12147 } 12148 return Res; 12149 } 12150 12151 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12152 SourceLocation StartLoc, 12153 SourceLocation LParenLoc, 12154 SourceLocation EndLoc) { 12155 SmallVector<Expr *, 8> Vars; 12156 SmallVector<Expr *, 8> PrivateCopies; 12157 for (Expr *RefExpr : VarList) { 12158 assert(RefExpr && "NULL expr in OpenMP private clause."); 12159 SourceLocation ELoc; 12160 SourceRange ERange; 12161 Expr *SimpleRefExpr = RefExpr; 12162 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12163 if (Res.second) { 12164 // It will be analyzed later. 12165 Vars.push_back(RefExpr); 12166 PrivateCopies.push_back(nullptr); 12167 } 12168 ValueDecl *D = Res.first; 12169 if (!D) 12170 continue; 12171 12172 QualType Type = D->getType(); 12173 auto *VD = dyn_cast<VarDecl>(D); 12174 12175 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12176 // A variable that appears in a private clause must not have an incomplete 12177 // type or a reference type. 12178 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12179 continue; 12180 Type = Type.getNonReferenceType(); 12181 12182 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12183 // A variable that is privatized must not have a const-qualified type 12184 // unless it is of class type with a mutable member. This restriction does 12185 // not apply to the firstprivate clause. 12186 // 12187 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12188 // A variable that appears in a private clause must not have a 12189 // const-qualified type unless it is of class type with a mutable member. 12190 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12191 continue; 12192 12193 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12194 // in a Construct] 12195 // Variables with the predetermined data-sharing attributes may not be 12196 // listed in data-sharing attributes clauses, except for the cases 12197 // listed below. For these exceptions only, listing a predetermined 12198 // variable in a data-sharing attribute clause is allowed and overrides 12199 // the variable's predetermined data-sharing attributes. 12200 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12201 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12202 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12203 << getOpenMPClauseName(OMPC_private); 12204 reportOriginalDsa(*this, DSAStack, D, DVar); 12205 continue; 12206 } 12207 12208 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12209 // Variably modified types are not supported for tasks. 12210 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12211 isOpenMPTaskingDirective(CurrDir)) { 12212 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12213 << getOpenMPClauseName(OMPC_private) << Type 12214 << getOpenMPDirectiveName(CurrDir); 12215 bool IsDecl = 12216 !VD || 12217 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12218 Diag(D->getLocation(), 12219 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12220 << D; 12221 continue; 12222 } 12223 12224 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12225 // A list item cannot appear in both a map clause and a data-sharing 12226 // attribute clause on the same construct 12227 // 12228 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12229 // A list item cannot appear in both a map clause and a data-sharing 12230 // attribute clause on the same construct unless the construct is a 12231 // combined construct. 12232 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12233 CurrDir == OMPD_target) { 12234 OpenMPClauseKind ConflictKind; 12235 if (DSAStack->checkMappableExprComponentListsForDecl( 12236 VD, /*CurrentRegionOnly=*/true, 12237 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12238 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12239 ConflictKind = WhereFoundClauseKind; 12240 return true; 12241 })) { 12242 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12243 << getOpenMPClauseName(OMPC_private) 12244 << getOpenMPClauseName(ConflictKind) 12245 << getOpenMPDirectiveName(CurrDir); 12246 reportOriginalDsa(*this, DSAStack, D, DVar); 12247 continue; 12248 } 12249 } 12250 12251 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12252 // A variable of class type (or array thereof) that appears in a private 12253 // clause requires an accessible, unambiguous default constructor for the 12254 // class type. 12255 // Generate helper private variable and initialize it with the default 12256 // value. The address of the original variable is replaced by the address of 12257 // the new private variable in CodeGen. This new variable is not added to 12258 // IdResolver, so the code in the OpenMP region uses original variable for 12259 // proper diagnostics. 12260 Type = Type.getUnqualifiedType(); 12261 VarDecl *VDPrivate = 12262 buildVarDecl(*this, ELoc, Type, D->getName(), 12263 D->hasAttrs() ? &D->getAttrs() : nullptr, 12264 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12265 ActOnUninitializedDecl(VDPrivate); 12266 if (VDPrivate->isInvalidDecl()) 12267 continue; 12268 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12269 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12270 12271 DeclRefExpr *Ref = nullptr; 12272 if (!VD && !CurContext->isDependentContext()) 12273 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12274 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12275 Vars.push_back((VD || CurContext->isDependentContext()) 12276 ? RefExpr->IgnoreParens() 12277 : Ref); 12278 PrivateCopies.push_back(VDPrivateRefExpr); 12279 } 12280 12281 if (Vars.empty()) 12282 return nullptr; 12283 12284 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12285 PrivateCopies); 12286 } 12287 12288 namespace { 12289 class DiagsUninitializedSeveretyRAII { 12290 private: 12291 DiagnosticsEngine &Diags; 12292 SourceLocation SavedLoc; 12293 bool IsIgnored = false; 12294 12295 public: 12296 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12297 bool IsIgnored) 12298 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12299 if (!IsIgnored) { 12300 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12301 /*Map*/ diag::Severity::Ignored, Loc); 12302 } 12303 } 12304 ~DiagsUninitializedSeveretyRAII() { 12305 if (!IsIgnored) 12306 Diags.popMappings(SavedLoc); 12307 } 12308 }; 12309 } 12310 12311 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12312 SourceLocation StartLoc, 12313 SourceLocation LParenLoc, 12314 SourceLocation EndLoc) { 12315 SmallVector<Expr *, 8> Vars; 12316 SmallVector<Expr *, 8> PrivateCopies; 12317 SmallVector<Expr *, 8> Inits; 12318 SmallVector<Decl *, 4> ExprCaptures; 12319 bool IsImplicitClause = 12320 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12321 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12322 12323 for (Expr *RefExpr : VarList) { 12324 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12325 SourceLocation ELoc; 12326 SourceRange ERange; 12327 Expr *SimpleRefExpr = RefExpr; 12328 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12329 if (Res.second) { 12330 // It will be analyzed later. 12331 Vars.push_back(RefExpr); 12332 PrivateCopies.push_back(nullptr); 12333 Inits.push_back(nullptr); 12334 } 12335 ValueDecl *D = Res.first; 12336 if (!D) 12337 continue; 12338 12339 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12340 QualType Type = D->getType(); 12341 auto *VD = dyn_cast<VarDecl>(D); 12342 12343 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12344 // A variable that appears in a private clause must not have an incomplete 12345 // type or a reference type. 12346 if (RequireCompleteType(ELoc, Type, 12347 diag::err_omp_firstprivate_incomplete_type)) 12348 continue; 12349 Type = Type.getNonReferenceType(); 12350 12351 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12352 // A variable of class type (or array thereof) that appears in a private 12353 // clause requires an accessible, unambiguous copy constructor for the 12354 // class type. 12355 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12356 12357 // If an implicit firstprivate variable found it was checked already. 12358 DSAStackTy::DSAVarData TopDVar; 12359 if (!IsImplicitClause) { 12360 DSAStackTy::DSAVarData DVar = 12361 DSAStack->getTopDSA(D, /*FromParent=*/false); 12362 TopDVar = DVar; 12363 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12364 bool IsConstant = ElemType.isConstant(Context); 12365 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12366 // A list item that specifies a given variable may not appear in more 12367 // than one clause on the same directive, except that a variable may be 12368 // specified in both firstprivate and lastprivate clauses. 12369 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12370 // A list item may appear in a firstprivate or lastprivate clause but not 12371 // both. 12372 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12373 (isOpenMPDistributeDirective(CurrDir) || 12374 DVar.CKind != OMPC_lastprivate) && 12375 DVar.RefExpr) { 12376 Diag(ELoc, diag::err_omp_wrong_dsa) 12377 << getOpenMPClauseName(DVar.CKind) 12378 << getOpenMPClauseName(OMPC_firstprivate); 12379 reportOriginalDsa(*this, DSAStack, D, DVar); 12380 continue; 12381 } 12382 12383 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12384 // in a Construct] 12385 // Variables with the predetermined data-sharing attributes may not be 12386 // listed in data-sharing attributes clauses, except for the cases 12387 // listed below. For these exceptions only, listing a predetermined 12388 // variable in a data-sharing attribute clause is allowed and overrides 12389 // the variable's predetermined data-sharing attributes. 12390 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12391 // in a Construct, C/C++, p.2] 12392 // Variables with const-qualified type having no mutable member may be 12393 // listed in a firstprivate clause, even if they are static data members. 12394 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12395 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12396 Diag(ELoc, diag::err_omp_wrong_dsa) 12397 << getOpenMPClauseName(DVar.CKind) 12398 << getOpenMPClauseName(OMPC_firstprivate); 12399 reportOriginalDsa(*this, DSAStack, D, DVar); 12400 continue; 12401 } 12402 12403 // OpenMP [2.9.3.4, Restrictions, p.2] 12404 // A list item that is private within a parallel region must not appear 12405 // in a firstprivate clause on a worksharing construct if any of the 12406 // worksharing regions arising from the worksharing construct ever bind 12407 // to any of the parallel regions arising from the parallel construct. 12408 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12409 // A list item that is private within a teams region must not appear in a 12410 // firstprivate clause on a distribute construct if any of the distribute 12411 // regions arising from the distribute construct ever bind to any of the 12412 // teams regions arising from the teams construct. 12413 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12414 // A list item that appears in a reduction clause of a teams construct 12415 // must not appear in a firstprivate clause on a distribute construct if 12416 // any of the distribute regions arising from the distribute construct 12417 // ever bind to any of the teams regions arising from the teams construct. 12418 if ((isOpenMPWorksharingDirective(CurrDir) || 12419 isOpenMPDistributeDirective(CurrDir)) && 12420 !isOpenMPParallelDirective(CurrDir) && 12421 !isOpenMPTeamsDirective(CurrDir)) { 12422 DVar = DSAStack->getImplicitDSA(D, true); 12423 if (DVar.CKind != OMPC_shared && 12424 (isOpenMPParallelDirective(DVar.DKind) || 12425 isOpenMPTeamsDirective(DVar.DKind) || 12426 DVar.DKind == OMPD_unknown)) { 12427 Diag(ELoc, diag::err_omp_required_access) 12428 << getOpenMPClauseName(OMPC_firstprivate) 12429 << getOpenMPClauseName(OMPC_shared); 12430 reportOriginalDsa(*this, DSAStack, D, DVar); 12431 continue; 12432 } 12433 } 12434 // OpenMP [2.9.3.4, Restrictions, p.3] 12435 // A list item that appears in a reduction clause of a parallel construct 12436 // must not appear in a firstprivate clause on a worksharing or task 12437 // construct if any of the worksharing or task regions arising from the 12438 // worksharing or task construct ever bind to any of the parallel regions 12439 // arising from the parallel construct. 12440 // OpenMP [2.9.3.4, Restrictions, p.4] 12441 // A list item that appears in a reduction clause in worksharing 12442 // construct must not appear in a firstprivate clause in a task construct 12443 // encountered during execution of any of the worksharing regions arising 12444 // from the worksharing construct. 12445 if (isOpenMPTaskingDirective(CurrDir)) { 12446 DVar = DSAStack->hasInnermostDSA( 12447 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12448 [](OpenMPDirectiveKind K) { 12449 return isOpenMPParallelDirective(K) || 12450 isOpenMPWorksharingDirective(K) || 12451 isOpenMPTeamsDirective(K); 12452 }, 12453 /*FromParent=*/true); 12454 if (DVar.CKind == OMPC_reduction && 12455 (isOpenMPParallelDirective(DVar.DKind) || 12456 isOpenMPWorksharingDirective(DVar.DKind) || 12457 isOpenMPTeamsDirective(DVar.DKind))) { 12458 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12459 << getOpenMPDirectiveName(DVar.DKind); 12460 reportOriginalDsa(*this, DSAStack, D, DVar); 12461 continue; 12462 } 12463 } 12464 12465 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12466 // A list item cannot appear in both a map clause and a data-sharing 12467 // attribute clause on the same construct 12468 // 12469 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12470 // A list item cannot appear in both a map clause and a data-sharing 12471 // attribute clause on the same construct unless the construct is a 12472 // combined construct. 12473 if ((LangOpts.OpenMP <= 45 && 12474 isOpenMPTargetExecutionDirective(CurrDir)) || 12475 CurrDir == OMPD_target) { 12476 OpenMPClauseKind ConflictKind; 12477 if (DSAStack->checkMappableExprComponentListsForDecl( 12478 VD, /*CurrentRegionOnly=*/true, 12479 [&ConflictKind]( 12480 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12481 OpenMPClauseKind WhereFoundClauseKind) { 12482 ConflictKind = WhereFoundClauseKind; 12483 return true; 12484 })) { 12485 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12486 << getOpenMPClauseName(OMPC_firstprivate) 12487 << getOpenMPClauseName(ConflictKind) 12488 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12489 reportOriginalDsa(*this, DSAStack, D, DVar); 12490 continue; 12491 } 12492 } 12493 } 12494 12495 // Variably modified types are not supported for tasks. 12496 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12497 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12498 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12499 << getOpenMPClauseName(OMPC_firstprivate) << Type 12500 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12501 bool IsDecl = 12502 !VD || 12503 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12504 Diag(D->getLocation(), 12505 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12506 << D; 12507 continue; 12508 } 12509 12510 Type = Type.getUnqualifiedType(); 12511 VarDecl *VDPrivate = 12512 buildVarDecl(*this, ELoc, Type, D->getName(), 12513 D->hasAttrs() ? &D->getAttrs() : nullptr, 12514 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12515 // Generate helper private variable and initialize it with the value of the 12516 // original variable. The address of the original variable is replaced by 12517 // the address of the new private variable in the CodeGen. This new variable 12518 // is not added to IdResolver, so the code in the OpenMP region uses 12519 // original variable for proper diagnostics and variable capturing. 12520 Expr *VDInitRefExpr = nullptr; 12521 // For arrays generate initializer for single element and replace it by the 12522 // original array element in CodeGen. 12523 if (Type->isArrayType()) { 12524 VarDecl *VDInit = 12525 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12526 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12527 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12528 ElemType = ElemType.getUnqualifiedType(); 12529 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12530 ".firstprivate.temp"); 12531 InitializedEntity Entity = 12532 InitializedEntity::InitializeVariable(VDInitTemp); 12533 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12534 12535 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12536 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12537 if (Result.isInvalid()) 12538 VDPrivate->setInvalidDecl(); 12539 else 12540 VDPrivate->setInit(Result.getAs<Expr>()); 12541 // Remove temp variable declaration. 12542 Context.Deallocate(VDInitTemp); 12543 } else { 12544 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12545 ".firstprivate.temp"); 12546 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12547 RefExpr->getExprLoc()); 12548 AddInitializerToDecl(VDPrivate, 12549 DefaultLvalueConversion(VDInitRefExpr).get(), 12550 /*DirectInit=*/false); 12551 } 12552 if (VDPrivate->isInvalidDecl()) { 12553 if (IsImplicitClause) { 12554 Diag(RefExpr->getExprLoc(), 12555 diag::note_omp_task_predetermined_firstprivate_here); 12556 } 12557 continue; 12558 } 12559 CurContext->addDecl(VDPrivate); 12560 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12561 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12562 RefExpr->getExprLoc()); 12563 DeclRefExpr *Ref = nullptr; 12564 if (!VD && !CurContext->isDependentContext()) { 12565 if (TopDVar.CKind == OMPC_lastprivate) { 12566 Ref = TopDVar.PrivateCopy; 12567 } else { 12568 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12569 if (!isOpenMPCapturedDecl(D)) 12570 ExprCaptures.push_back(Ref->getDecl()); 12571 } 12572 } 12573 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12574 Vars.push_back((VD || CurContext->isDependentContext()) 12575 ? RefExpr->IgnoreParens() 12576 : Ref); 12577 PrivateCopies.push_back(VDPrivateRefExpr); 12578 Inits.push_back(VDInitRefExpr); 12579 } 12580 12581 if (Vars.empty()) 12582 return nullptr; 12583 12584 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12585 Vars, PrivateCopies, Inits, 12586 buildPreInits(Context, ExprCaptures)); 12587 } 12588 12589 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12590 SourceLocation StartLoc, 12591 SourceLocation LParenLoc, 12592 SourceLocation EndLoc) { 12593 SmallVector<Expr *, 8> Vars; 12594 SmallVector<Expr *, 8> SrcExprs; 12595 SmallVector<Expr *, 8> DstExprs; 12596 SmallVector<Expr *, 8> AssignmentOps; 12597 SmallVector<Decl *, 4> ExprCaptures; 12598 SmallVector<Expr *, 4> ExprPostUpdates; 12599 for (Expr *RefExpr : VarList) { 12600 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12601 SourceLocation ELoc; 12602 SourceRange ERange; 12603 Expr *SimpleRefExpr = RefExpr; 12604 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12605 if (Res.second) { 12606 // It will be analyzed later. 12607 Vars.push_back(RefExpr); 12608 SrcExprs.push_back(nullptr); 12609 DstExprs.push_back(nullptr); 12610 AssignmentOps.push_back(nullptr); 12611 } 12612 ValueDecl *D = Res.first; 12613 if (!D) 12614 continue; 12615 12616 QualType Type = D->getType(); 12617 auto *VD = dyn_cast<VarDecl>(D); 12618 12619 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12620 // A variable that appears in a lastprivate clause must not have an 12621 // incomplete type or a reference type. 12622 if (RequireCompleteType(ELoc, Type, 12623 diag::err_omp_lastprivate_incomplete_type)) 12624 continue; 12625 Type = Type.getNonReferenceType(); 12626 12627 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12628 // A variable that is privatized must not have a const-qualified type 12629 // unless it is of class type with a mutable member. This restriction does 12630 // not apply to the firstprivate clause. 12631 // 12632 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12633 // A variable that appears in a lastprivate clause must not have a 12634 // const-qualified type unless it is of class type with a mutable member. 12635 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12636 continue; 12637 12638 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12639 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12640 // in a Construct] 12641 // Variables with the predetermined data-sharing attributes may not be 12642 // listed in data-sharing attributes clauses, except for the cases 12643 // listed below. 12644 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12645 // A list item may appear in a firstprivate or lastprivate clause but not 12646 // both. 12647 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12648 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12649 (isOpenMPDistributeDirective(CurrDir) || 12650 DVar.CKind != OMPC_firstprivate) && 12651 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12652 Diag(ELoc, diag::err_omp_wrong_dsa) 12653 << getOpenMPClauseName(DVar.CKind) 12654 << getOpenMPClauseName(OMPC_lastprivate); 12655 reportOriginalDsa(*this, DSAStack, D, DVar); 12656 continue; 12657 } 12658 12659 // OpenMP [2.14.3.5, Restrictions, p.2] 12660 // A list item that is private within a parallel region, or that appears in 12661 // the reduction clause of a parallel construct, must not appear in a 12662 // lastprivate clause on a worksharing construct if any of the corresponding 12663 // worksharing regions ever binds to any of the corresponding parallel 12664 // regions. 12665 DSAStackTy::DSAVarData TopDVar = DVar; 12666 if (isOpenMPWorksharingDirective(CurrDir) && 12667 !isOpenMPParallelDirective(CurrDir) && 12668 !isOpenMPTeamsDirective(CurrDir)) { 12669 DVar = DSAStack->getImplicitDSA(D, true); 12670 if (DVar.CKind != OMPC_shared) { 12671 Diag(ELoc, diag::err_omp_required_access) 12672 << getOpenMPClauseName(OMPC_lastprivate) 12673 << getOpenMPClauseName(OMPC_shared); 12674 reportOriginalDsa(*this, DSAStack, D, DVar); 12675 continue; 12676 } 12677 } 12678 12679 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12680 // A variable of class type (or array thereof) that appears in a 12681 // lastprivate clause requires an accessible, unambiguous default 12682 // constructor for the class type, unless the list item is also specified 12683 // in a firstprivate clause. 12684 // A variable of class type (or array thereof) that appears in a 12685 // lastprivate clause requires an accessible, unambiguous copy assignment 12686 // operator for the class type. 12687 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12688 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12689 Type.getUnqualifiedType(), ".lastprivate.src", 12690 D->hasAttrs() ? &D->getAttrs() : nullptr); 12691 DeclRefExpr *PseudoSrcExpr = 12692 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12693 VarDecl *DstVD = 12694 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12695 D->hasAttrs() ? &D->getAttrs() : nullptr); 12696 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12697 // For arrays generate assignment operation for single element and replace 12698 // it by the original array element in CodeGen. 12699 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12700 PseudoDstExpr, PseudoSrcExpr); 12701 if (AssignmentOp.isInvalid()) 12702 continue; 12703 AssignmentOp = 12704 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12705 if (AssignmentOp.isInvalid()) 12706 continue; 12707 12708 DeclRefExpr *Ref = nullptr; 12709 if (!VD && !CurContext->isDependentContext()) { 12710 if (TopDVar.CKind == OMPC_firstprivate) { 12711 Ref = TopDVar.PrivateCopy; 12712 } else { 12713 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12714 if (!isOpenMPCapturedDecl(D)) 12715 ExprCaptures.push_back(Ref->getDecl()); 12716 } 12717 if (TopDVar.CKind == OMPC_firstprivate || 12718 (!isOpenMPCapturedDecl(D) && 12719 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12720 ExprResult RefRes = DefaultLvalueConversion(Ref); 12721 if (!RefRes.isUsable()) 12722 continue; 12723 ExprResult PostUpdateRes = 12724 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12725 RefRes.get()); 12726 if (!PostUpdateRes.isUsable()) 12727 continue; 12728 ExprPostUpdates.push_back( 12729 IgnoredValueConversions(PostUpdateRes.get()).get()); 12730 } 12731 } 12732 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12733 Vars.push_back((VD || CurContext->isDependentContext()) 12734 ? RefExpr->IgnoreParens() 12735 : Ref); 12736 SrcExprs.push_back(PseudoSrcExpr); 12737 DstExprs.push_back(PseudoDstExpr); 12738 AssignmentOps.push_back(AssignmentOp.get()); 12739 } 12740 12741 if (Vars.empty()) 12742 return nullptr; 12743 12744 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12745 Vars, SrcExprs, DstExprs, AssignmentOps, 12746 buildPreInits(Context, ExprCaptures), 12747 buildPostUpdate(*this, ExprPostUpdates)); 12748 } 12749 12750 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12751 SourceLocation StartLoc, 12752 SourceLocation LParenLoc, 12753 SourceLocation EndLoc) { 12754 SmallVector<Expr *, 8> Vars; 12755 for (Expr *RefExpr : VarList) { 12756 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12757 SourceLocation ELoc; 12758 SourceRange ERange; 12759 Expr *SimpleRefExpr = RefExpr; 12760 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12761 if (Res.second) { 12762 // It will be analyzed later. 12763 Vars.push_back(RefExpr); 12764 } 12765 ValueDecl *D = Res.first; 12766 if (!D) 12767 continue; 12768 12769 auto *VD = dyn_cast<VarDecl>(D); 12770 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12771 // in a Construct] 12772 // Variables with the predetermined data-sharing attributes may not be 12773 // listed in data-sharing attributes clauses, except for the cases 12774 // listed below. For these exceptions only, listing a predetermined 12775 // variable in a data-sharing attribute clause is allowed and overrides 12776 // the variable's predetermined data-sharing attributes. 12777 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12778 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12779 DVar.RefExpr) { 12780 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12781 << getOpenMPClauseName(OMPC_shared); 12782 reportOriginalDsa(*this, DSAStack, D, DVar); 12783 continue; 12784 } 12785 12786 DeclRefExpr *Ref = nullptr; 12787 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12788 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12789 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12790 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12791 ? RefExpr->IgnoreParens() 12792 : Ref); 12793 } 12794 12795 if (Vars.empty()) 12796 return nullptr; 12797 12798 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12799 } 12800 12801 namespace { 12802 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12803 DSAStackTy *Stack; 12804 12805 public: 12806 bool VisitDeclRefExpr(DeclRefExpr *E) { 12807 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12808 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12809 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12810 return false; 12811 if (DVar.CKind != OMPC_unknown) 12812 return true; 12813 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12814 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12815 /*FromParent=*/true); 12816 return DVarPrivate.CKind != OMPC_unknown; 12817 } 12818 return false; 12819 } 12820 bool VisitStmt(Stmt *S) { 12821 for (Stmt *Child : S->children()) { 12822 if (Child && Visit(Child)) 12823 return true; 12824 } 12825 return false; 12826 } 12827 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12828 }; 12829 } // namespace 12830 12831 namespace { 12832 // Transform MemberExpression for specified FieldDecl of current class to 12833 // DeclRefExpr to specified OMPCapturedExprDecl. 12834 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12835 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12836 ValueDecl *Field = nullptr; 12837 DeclRefExpr *CapturedExpr = nullptr; 12838 12839 public: 12840 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12841 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12842 12843 ExprResult TransformMemberExpr(MemberExpr *E) { 12844 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12845 E->getMemberDecl() == Field) { 12846 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12847 return CapturedExpr; 12848 } 12849 return BaseTransform::TransformMemberExpr(E); 12850 } 12851 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12852 }; 12853 } // namespace 12854 12855 template <typename T, typename U> 12856 static T filterLookupForUDReductionAndMapper( 12857 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12858 for (U &Set : Lookups) { 12859 for (auto *D : Set) { 12860 if (T Res = Gen(cast<ValueDecl>(D))) 12861 return Res; 12862 } 12863 } 12864 return T(); 12865 } 12866 12867 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12868 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12869 12870 for (auto RD : D->redecls()) { 12871 // Don't bother with extra checks if we already know this one isn't visible. 12872 if (RD == D) 12873 continue; 12874 12875 auto ND = cast<NamedDecl>(RD); 12876 if (LookupResult::isVisible(SemaRef, ND)) 12877 return ND; 12878 } 12879 12880 return nullptr; 12881 } 12882 12883 static void 12884 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12885 SourceLocation Loc, QualType Ty, 12886 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12887 // Find all of the associated namespaces and classes based on the 12888 // arguments we have. 12889 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12890 Sema::AssociatedClassSet AssociatedClasses; 12891 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12892 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12893 AssociatedClasses); 12894 12895 // C++ [basic.lookup.argdep]p3: 12896 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12897 // and let Y be the lookup set produced by argument dependent 12898 // lookup (defined as follows). If X contains [...] then Y is 12899 // empty. Otherwise Y is the set of declarations found in the 12900 // namespaces associated with the argument types as described 12901 // below. The set of declarations found by the lookup of the name 12902 // is the union of X and Y. 12903 // 12904 // Here, we compute Y and add its members to the overloaded 12905 // candidate set. 12906 for (auto *NS : AssociatedNamespaces) { 12907 // When considering an associated namespace, the lookup is the 12908 // same as the lookup performed when the associated namespace is 12909 // used as a qualifier (3.4.3.2) except that: 12910 // 12911 // -- Any using-directives in the associated namespace are 12912 // ignored. 12913 // 12914 // -- Any namespace-scope friend functions declared in 12915 // associated classes are visible within their respective 12916 // namespaces even if they are not visible during an ordinary 12917 // lookup (11.4). 12918 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12919 for (auto *D : R) { 12920 auto *Underlying = D; 12921 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12922 Underlying = USD->getTargetDecl(); 12923 12924 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12925 !isa<OMPDeclareMapperDecl>(Underlying)) 12926 continue; 12927 12928 if (!SemaRef.isVisible(D)) { 12929 D = findAcceptableDecl(SemaRef, D); 12930 if (!D) 12931 continue; 12932 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12933 Underlying = USD->getTargetDecl(); 12934 } 12935 Lookups.emplace_back(); 12936 Lookups.back().addDecl(Underlying); 12937 } 12938 } 12939 } 12940 12941 static ExprResult 12942 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12943 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12944 const DeclarationNameInfo &ReductionId, QualType Ty, 12945 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12946 if (ReductionIdScopeSpec.isInvalid()) 12947 return ExprError(); 12948 SmallVector<UnresolvedSet<8>, 4> Lookups; 12949 if (S) { 12950 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12951 Lookup.suppressDiagnostics(); 12952 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12953 NamedDecl *D = Lookup.getRepresentativeDecl(); 12954 do { 12955 S = S->getParent(); 12956 } while (S && !S->isDeclScope(D)); 12957 if (S) 12958 S = S->getParent(); 12959 Lookups.emplace_back(); 12960 Lookups.back().append(Lookup.begin(), Lookup.end()); 12961 Lookup.clear(); 12962 } 12963 } else if (auto *ULE = 12964 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12965 Lookups.push_back(UnresolvedSet<8>()); 12966 Decl *PrevD = nullptr; 12967 for (NamedDecl *D : ULE->decls()) { 12968 if (D == PrevD) 12969 Lookups.push_back(UnresolvedSet<8>()); 12970 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12971 Lookups.back().addDecl(DRD); 12972 PrevD = D; 12973 } 12974 } 12975 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12976 Ty->isInstantiationDependentType() || 12977 Ty->containsUnexpandedParameterPack() || 12978 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12979 return !D->isInvalidDecl() && 12980 (D->getType()->isDependentType() || 12981 D->getType()->isInstantiationDependentType() || 12982 D->getType()->containsUnexpandedParameterPack()); 12983 })) { 12984 UnresolvedSet<8> ResSet; 12985 for (const UnresolvedSet<8> &Set : Lookups) { 12986 if (Set.empty()) 12987 continue; 12988 ResSet.append(Set.begin(), Set.end()); 12989 // The last item marks the end of all declarations at the specified scope. 12990 ResSet.addDecl(Set[Set.size() - 1]); 12991 } 12992 return UnresolvedLookupExpr::Create( 12993 SemaRef.Context, /*NamingClass=*/nullptr, 12994 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12995 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12996 } 12997 // Lookup inside the classes. 12998 // C++ [over.match.oper]p3: 12999 // For a unary operator @ with an operand of a type whose 13000 // cv-unqualified version is T1, and for a binary operator @ with 13001 // a left operand of a type whose cv-unqualified version is T1 and 13002 // a right operand of a type whose cv-unqualified version is T2, 13003 // three sets of candidate functions, designated member 13004 // candidates, non-member candidates and built-in candidates, are 13005 // constructed as follows: 13006 // -- If T1 is a complete class type or a class currently being 13007 // defined, the set of member candidates is the result of the 13008 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13009 // the set of member candidates is empty. 13010 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13011 Lookup.suppressDiagnostics(); 13012 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13013 // Complete the type if it can be completed. 13014 // If the type is neither complete nor being defined, bail out now. 13015 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13016 TyRec->getDecl()->getDefinition()) { 13017 Lookup.clear(); 13018 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13019 if (Lookup.empty()) { 13020 Lookups.emplace_back(); 13021 Lookups.back().append(Lookup.begin(), Lookup.end()); 13022 } 13023 } 13024 } 13025 // Perform ADL. 13026 if (SemaRef.getLangOpts().CPlusPlus) 13027 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13028 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13029 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13030 if (!D->isInvalidDecl() && 13031 SemaRef.Context.hasSameType(D->getType(), Ty)) 13032 return D; 13033 return nullptr; 13034 })) 13035 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13036 VK_LValue, Loc); 13037 if (SemaRef.getLangOpts().CPlusPlus) { 13038 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13039 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13040 if (!D->isInvalidDecl() && 13041 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13042 !Ty.isMoreQualifiedThan(D->getType())) 13043 return D; 13044 return nullptr; 13045 })) { 13046 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13047 /*DetectVirtual=*/false); 13048 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13049 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13050 VD->getType().getUnqualifiedType()))) { 13051 if (SemaRef.CheckBaseClassAccess( 13052 Loc, VD->getType(), Ty, Paths.front(), 13053 /*DiagID=*/0) != Sema::AR_inaccessible) { 13054 SemaRef.BuildBasePathArray(Paths, BasePath); 13055 return SemaRef.BuildDeclRefExpr( 13056 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13057 } 13058 } 13059 } 13060 } 13061 } 13062 if (ReductionIdScopeSpec.isSet()) { 13063 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 13064 return ExprError(); 13065 } 13066 return ExprEmpty(); 13067 } 13068 13069 namespace { 13070 /// Data for the reduction-based clauses. 13071 struct ReductionData { 13072 /// List of original reduction items. 13073 SmallVector<Expr *, 8> Vars; 13074 /// List of private copies of the reduction items. 13075 SmallVector<Expr *, 8> Privates; 13076 /// LHS expressions for the reduction_op expressions. 13077 SmallVector<Expr *, 8> LHSs; 13078 /// RHS expressions for the reduction_op expressions. 13079 SmallVector<Expr *, 8> RHSs; 13080 /// Reduction operation expression. 13081 SmallVector<Expr *, 8> ReductionOps; 13082 /// Taskgroup descriptors for the corresponding reduction items in 13083 /// in_reduction clauses. 13084 SmallVector<Expr *, 8> TaskgroupDescriptors; 13085 /// List of captures for clause. 13086 SmallVector<Decl *, 4> ExprCaptures; 13087 /// List of postupdate expressions. 13088 SmallVector<Expr *, 4> ExprPostUpdates; 13089 ReductionData() = delete; 13090 /// Reserves required memory for the reduction data. 13091 ReductionData(unsigned Size) { 13092 Vars.reserve(Size); 13093 Privates.reserve(Size); 13094 LHSs.reserve(Size); 13095 RHSs.reserve(Size); 13096 ReductionOps.reserve(Size); 13097 TaskgroupDescriptors.reserve(Size); 13098 ExprCaptures.reserve(Size); 13099 ExprPostUpdates.reserve(Size); 13100 } 13101 /// Stores reduction item and reduction operation only (required for dependent 13102 /// reduction item). 13103 void push(Expr *Item, Expr *ReductionOp) { 13104 Vars.emplace_back(Item); 13105 Privates.emplace_back(nullptr); 13106 LHSs.emplace_back(nullptr); 13107 RHSs.emplace_back(nullptr); 13108 ReductionOps.emplace_back(ReductionOp); 13109 TaskgroupDescriptors.emplace_back(nullptr); 13110 } 13111 /// Stores reduction data. 13112 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13113 Expr *TaskgroupDescriptor) { 13114 Vars.emplace_back(Item); 13115 Privates.emplace_back(Private); 13116 LHSs.emplace_back(LHS); 13117 RHSs.emplace_back(RHS); 13118 ReductionOps.emplace_back(ReductionOp); 13119 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13120 } 13121 }; 13122 } // namespace 13123 13124 static bool checkOMPArraySectionConstantForReduction( 13125 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13126 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13127 const Expr *Length = OASE->getLength(); 13128 if (Length == nullptr) { 13129 // For array sections of the form [1:] or [:], we would need to analyze 13130 // the lower bound... 13131 if (OASE->getColonLoc().isValid()) 13132 return false; 13133 13134 // This is an array subscript which has implicit length 1! 13135 SingleElement = true; 13136 ArraySizes.push_back(llvm::APSInt::get(1)); 13137 } else { 13138 Expr::EvalResult Result; 13139 if (!Length->EvaluateAsInt(Result, Context)) 13140 return false; 13141 13142 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13143 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13144 ArraySizes.push_back(ConstantLengthValue); 13145 } 13146 13147 // Get the base of this array section and walk up from there. 13148 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13149 13150 // We require length = 1 for all array sections except the right-most to 13151 // guarantee that the memory region is contiguous and has no holes in it. 13152 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13153 Length = TempOASE->getLength(); 13154 if (Length == nullptr) { 13155 // For array sections of the form [1:] or [:], we would need to analyze 13156 // the lower bound... 13157 if (OASE->getColonLoc().isValid()) 13158 return false; 13159 13160 // This is an array subscript which has implicit length 1! 13161 ArraySizes.push_back(llvm::APSInt::get(1)); 13162 } else { 13163 Expr::EvalResult Result; 13164 if (!Length->EvaluateAsInt(Result, Context)) 13165 return false; 13166 13167 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13168 if (ConstantLengthValue.getSExtValue() != 1) 13169 return false; 13170 13171 ArraySizes.push_back(ConstantLengthValue); 13172 } 13173 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13174 } 13175 13176 // If we have a single element, we don't need to add the implicit lengths. 13177 if (!SingleElement) { 13178 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13179 // Has implicit length 1! 13180 ArraySizes.push_back(llvm::APSInt::get(1)); 13181 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13182 } 13183 } 13184 13185 // This array section can be privatized as a single value or as a constant 13186 // sized array. 13187 return true; 13188 } 13189 13190 static bool actOnOMPReductionKindClause( 13191 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13192 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13193 SourceLocation ColonLoc, SourceLocation EndLoc, 13194 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13195 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13196 DeclarationName DN = ReductionId.getName(); 13197 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13198 BinaryOperatorKind BOK = BO_Comma; 13199 13200 ASTContext &Context = S.Context; 13201 // OpenMP [2.14.3.6, reduction clause] 13202 // C 13203 // reduction-identifier is either an identifier or one of the following 13204 // operators: +, -, *, &, |, ^, && and || 13205 // C++ 13206 // reduction-identifier is either an id-expression or one of the following 13207 // operators: +, -, *, &, |, ^, && and || 13208 switch (OOK) { 13209 case OO_Plus: 13210 case OO_Minus: 13211 BOK = BO_Add; 13212 break; 13213 case OO_Star: 13214 BOK = BO_Mul; 13215 break; 13216 case OO_Amp: 13217 BOK = BO_And; 13218 break; 13219 case OO_Pipe: 13220 BOK = BO_Or; 13221 break; 13222 case OO_Caret: 13223 BOK = BO_Xor; 13224 break; 13225 case OO_AmpAmp: 13226 BOK = BO_LAnd; 13227 break; 13228 case OO_PipePipe: 13229 BOK = BO_LOr; 13230 break; 13231 case OO_New: 13232 case OO_Delete: 13233 case OO_Array_New: 13234 case OO_Array_Delete: 13235 case OO_Slash: 13236 case OO_Percent: 13237 case OO_Tilde: 13238 case OO_Exclaim: 13239 case OO_Equal: 13240 case OO_Less: 13241 case OO_Greater: 13242 case OO_LessEqual: 13243 case OO_GreaterEqual: 13244 case OO_PlusEqual: 13245 case OO_MinusEqual: 13246 case OO_StarEqual: 13247 case OO_SlashEqual: 13248 case OO_PercentEqual: 13249 case OO_CaretEqual: 13250 case OO_AmpEqual: 13251 case OO_PipeEqual: 13252 case OO_LessLess: 13253 case OO_GreaterGreater: 13254 case OO_LessLessEqual: 13255 case OO_GreaterGreaterEqual: 13256 case OO_EqualEqual: 13257 case OO_ExclaimEqual: 13258 case OO_Spaceship: 13259 case OO_PlusPlus: 13260 case OO_MinusMinus: 13261 case OO_Comma: 13262 case OO_ArrowStar: 13263 case OO_Arrow: 13264 case OO_Call: 13265 case OO_Subscript: 13266 case OO_Conditional: 13267 case OO_Coawait: 13268 case NUM_OVERLOADED_OPERATORS: 13269 llvm_unreachable("Unexpected reduction identifier"); 13270 case OO_None: 13271 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13272 if (II->isStr("max")) 13273 BOK = BO_GT; 13274 else if (II->isStr("min")) 13275 BOK = BO_LT; 13276 } 13277 break; 13278 } 13279 SourceRange ReductionIdRange; 13280 if (ReductionIdScopeSpec.isValid()) 13281 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13282 else 13283 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13284 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13285 13286 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13287 bool FirstIter = true; 13288 for (Expr *RefExpr : VarList) { 13289 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13290 // OpenMP [2.1, C/C++] 13291 // A list item is a variable or array section, subject to the restrictions 13292 // specified in Section 2.4 on page 42 and in each of the sections 13293 // describing clauses and directives for which a list appears. 13294 // OpenMP [2.14.3.3, Restrictions, p.1] 13295 // A variable that is part of another variable (as an array or 13296 // structure element) cannot appear in a private clause. 13297 if (!FirstIter && IR != ER) 13298 ++IR; 13299 FirstIter = false; 13300 SourceLocation ELoc; 13301 SourceRange ERange; 13302 Expr *SimpleRefExpr = RefExpr; 13303 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13304 /*AllowArraySection=*/true); 13305 if (Res.second) { 13306 // Try to find 'declare reduction' corresponding construct before using 13307 // builtin/overloaded operators. 13308 QualType Type = Context.DependentTy; 13309 CXXCastPath BasePath; 13310 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13311 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13312 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13313 Expr *ReductionOp = nullptr; 13314 if (S.CurContext->isDependentContext() && 13315 (DeclareReductionRef.isUnset() || 13316 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13317 ReductionOp = DeclareReductionRef.get(); 13318 // It will be analyzed later. 13319 RD.push(RefExpr, ReductionOp); 13320 } 13321 ValueDecl *D = Res.first; 13322 if (!D) 13323 continue; 13324 13325 Expr *TaskgroupDescriptor = nullptr; 13326 QualType Type; 13327 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13328 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13329 if (ASE) { 13330 Type = ASE->getType().getNonReferenceType(); 13331 } else if (OASE) { 13332 QualType BaseType = 13333 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13334 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13335 Type = ATy->getElementType(); 13336 else 13337 Type = BaseType->getPointeeType(); 13338 Type = Type.getNonReferenceType(); 13339 } else { 13340 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13341 } 13342 auto *VD = dyn_cast<VarDecl>(D); 13343 13344 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13345 // A variable that appears in a private clause must not have an incomplete 13346 // type or a reference type. 13347 if (S.RequireCompleteType(ELoc, D->getType(), 13348 diag::err_omp_reduction_incomplete_type)) 13349 continue; 13350 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13351 // A list item that appears in a reduction clause must not be 13352 // const-qualified. 13353 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13354 /*AcceptIfMutable*/ false, ASE || OASE)) 13355 continue; 13356 13357 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13358 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13359 // If a list-item is a reference type then it must bind to the same object 13360 // for all threads of the team. 13361 if (!ASE && !OASE) { 13362 if (VD) { 13363 VarDecl *VDDef = VD->getDefinition(); 13364 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13365 DSARefChecker Check(Stack); 13366 if (Check.Visit(VDDef->getInit())) { 13367 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13368 << getOpenMPClauseName(ClauseKind) << ERange; 13369 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13370 continue; 13371 } 13372 } 13373 } 13374 13375 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13376 // in a Construct] 13377 // Variables with the predetermined data-sharing attributes may not be 13378 // listed in data-sharing attributes clauses, except for the cases 13379 // listed below. For these exceptions only, listing a predetermined 13380 // variable in a data-sharing attribute clause is allowed and overrides 13381 // the variable's predetermined data-sharing attributes. 13382 // OpenMP [2.14.3.6, Restrictions, p.3] 13383 // Any number of reduction clauses can be specified on the directive, 13384 // but a list item can appear only once in the reduction clauses for that 13385 // directive. 13386 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13387 if (DVar.CKind == OMPC_reduction) { 13388 S.Diag(ELoc, diag::err_omp_once_referenced) 13389 << getOpenMPClauseName(ClauseKind); 13390 if (DVar.RefExpr) 13391 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13392 continue; 13393 } 13394 if (DVar.CKind != OMPC_unknown) { 13395 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13396 << getOpenMPClauseName(DVar.CKind) 13397 << getOpenMPClauseName(OMPC_reduction); 13398 reportOriginalDsa(S, Stack, D, DVar); 13399 continue; 13400 } 13401 13402 // OpenMP [2.14.3.6, Restrictions, p.1] 13403 // A list item that appears in a reduction clause of a worksharing 13404 // construct must be shared in the parallel regions to which any of the 13405 // worksharing regions arising from the worksharing construct bind. 13406 if (isOpenMPWorksharingDirective(CurrDir) && 13407 !isOpenMPParallelDirective(CurrDir) && 13408 !isOpenMPTeamsDirective(CurrDir)) { 13409 DVar = Stack->getImplicitDSA(D, true); 13410 if (DVar.CKind != OMPC_shared) { 13411 S.Diag(ELoc, diag::err_omp_required_access) 13412 << getOpenMPClauseName(OMPC_reduction) 13413 << getOpenMPClauseName(OMPC_shared); 13414 reportOriginalDsa(S, Stack, D, DVar); 13415 continue; 13416 } 13417 } 13418 } 13419 13420 // Try to find 'declare reduction' corresponding construct before using 13421 // builtin/overloaded operators. 13422 CXXCastPath BasePath; 13423 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13424 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13425 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13426 if (DeclareReductionRef.isInvalid()) 13427 continue; 13428 if (S.CurContext->isDependentContext() && 13429 (DeclareReductionRef.isUnset() || 13430 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13431 RD.push(RefExpr, DeclareReductionRef.get()); 13432 continue; 13433 } 13434 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13435 // Not allowed reduction identifier is found. 13436 S.Diag(ReductionId.getBeginLoc(), 13437 diag::err_omp_unknown_reduction_identifier) 13438 << Type << ReductionIdRange; 13439 continue; 13440 } 13441 13442 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13443 // The type of a list item that appears in a reduction clause must be valid 13444 // for the reduction-identifier. For a max or min reduction in C, the type 13445 // of the list item must be an allowed arithmetic data type: char, int, 13446 // float, double, or _Bool, possibly modified with long, short, signed, or 13447 // unsigned. For a max or min reduction in C++, the type of the list item 13448 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13449 // double, or bool, possibly modified with long, short, signed, or unsigned. 13450 if (DeclareReductionRef.isUnset()) { 13451 if ((BOK == BO_GT || BOK == BO_LT) && 13452 !(Type->isScalarType() || 13453 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13454 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13455 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13456 if (!ASE && !OASE) { 13457 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13458 VarDecl::DeclarationOnly; 13459 S.Diag(D->getLocation(), 13460 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13461 << D; 13462 } 13463 continue; 13464 } 13465 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13466 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13467 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13468 << getOpenMPClauseName(ClauseKind); 13469 if (!ASE && !OASE) { 13470 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13471 VarDecl::DeclarationOnly; 13472 S.Diag(D->getLocation(), 13473 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13474 << D; 13475 } 13476 continue; 13477 } 13478 } 13479 13480 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13481 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13482 D->hasAttrs() ? &D->getAttrs() : nullptr); 13483 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13484 D->hasAttrs() ? &D->getAttrs() : nullptr); 13485 QualType PrivateTy = Type; 13486 13487 // Try if we can determine constant lengths for all array sections and avoid 13488 // the VLA. 13489 bool ConstantLengthOASE = false; 13490 if (OASE) { 13491 bool SingleElement; 13492 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13493 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13494 Context, OASE, SingleElement, ArraySizes); 13495 13496 // If we don't have a single element, we must emit a constant array type. 13497 if (ConstantLengthOASE && !SingleElement) { 13498 for (llvm::APSInt &Size : ArraySizes) 13499 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13500 ArrayType::Normal, 13501 /*IndexTypeQuals=*/0); 13502 } 13503 } 13504 13505 if ((OASE && !ConstantLengthOASE) || 13506 (!OASE && !ASE && 13507 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13508 if (!Context.getTargetInfo().isVLASupported()) { 13509 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13510 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13511 S.Diag(ELoc, diag::note_vla_unsupported); 13512 } else { 13513 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13514 S.targetDiag(ELoc, diag::note_vla_unsupported); 13515 } 13516 continue; 13517 } 13518 // For arrays/array sections only: 13519 // Create pseudo array type for private copy. The size for this array will 13520 // be generated during codegen. 13521 // For array subscripts or single variables Private Ty is the same as Type 13522 // (type of the variable or single array element). 13523 PrivateTy = Context.getVariableArrayType( 13524 Type, 13525 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13526 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13527 } else if (!ASE && !OASE && 13528 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13529 PrivateTy = D->getType().getNonReferenceType(); 13530 } 13531 // Private copy. 13532 VarDecl *PrivateVD = 13533 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13534 D->hasAttrs() ? &D->getAttrs() : nullptr, 13535 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13536 // Add initializer for private variable. 13537 Expr *Init = nullptr; 13538 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13539 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13540 if (DeclareReductionRef.isUsable()) { 13541 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13542 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13543 if (DRD->getInitializer()) { 13544 Init = DRDRef; 13545 RHSVD->setInit(DRDRef); 13546 RHSVD->setInitStyle(VarDecl::CallInit); 13547 } 13548 } else { 13549 switch (BOK) { 13550 case BO_Add: 13551 case BO_Xor: 13552 case BO_Or: 13553 case BO_LOr: 13554 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13555 if (Type->isScalarType() || Type->isAnyComplexType()) 13556 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13557 break; 13558 case BO_Mul: 13559 case BO_LAnd: 13560 if (Type->isScalarType() || Type->isAnyComplexType()) { 13561 // '*' and '&&' reduction ops - initializer is '1'. 13562 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13563 } 13564 break; 13565 case BO_And: { 13566 // '&' reduction op - initializer is '~0'. 13567 QualType OrigType = Type; 13568 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13569 Type = ComplexTy->getElementType(); 13570 if (Type->isRealFloatingType()) { 13571 llvm::APFloat InitValue = 13572 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13573 /*isIEEE=*/true); 13574 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13575 Type, ELoc); 13576 } else if (Type->isScalarType()) { 13577 uint64_t Size = Context.getTypeSize(Type); 13578 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13579 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13580 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13581 } 13582 if (Init && OrigType->isAnyComplexType()) { 13583 // Init = 0xFFFF + 0xFFFFi; 13584 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13585 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13586 } 13587 Type = OrigType; 13588 break; 13589 } 13590 case BO_LT: 13591 case BO_GT: { 13592 // 'min' reduction op - initializer is 'Largest representable number in 13593 // the reduction list item type'. 13594 // 'max' reduction op - initializer is 'Least representable number in 13595 // the reduction list item type'. 13596 if (Type->isIntegerType() || Type->isPointerType()) { 13597 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13598 uint64_t Size = Context.getTypeSize(Type); 13599 QualType IntTy = 13600 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13601 llvm::APInt InitValue = 13602 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13603 : llvm::APInt::getMinValue(Size) 13604 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13605 : llvm::APInt::getMaxValue(Size); 13606 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13607 if (Type->isPointerType()) { 13608 // Cast to pointer type. 13609 ExprResult CastExpr = S.BuildCStyleCastExpr( 13610 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13611 if (CastExpr.isInvalid()) 13612 continue; 13613 Init = CastExpr.get(); 13614 } 13615 } else if (Type->isRealFloatingType()) { 13616 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13617 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13618 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13619 Type, ELoc); 13620 } 13621 break; 13622 } 13623 case BO_PtrMemD: 13624 case BO_PtrMemI: 13625 case BO_MulAssign: 13626 case BO_Div: 13627 case BO_Rem: 13628 case BO_Sub: 13629 case BO_Shl: 13630 case BO_Shr: 13631 case BO_LE: 13632 case BO_GE: 13633 case BO_EQ: 13634 case BO_NE: 13635 case BO_Cmp: 13636 case BO_AndAssign: 13637 case BO_XorAssign: 13638 case BO_OrAssign: 13639 case BO_Assign: 13640 case BO_AddAssign: 13641 case BO_SubAssign: 13642 case BO_DivAssign: 13643 case BO_RemAssign: 13644 case BO_ShlAssign: 13645 case BO_ShrAssign: 13646 case BO_Comma: 13647 llvm_unreachable("Unexpected reduction operation"); 13648 } 13649 } 13650 if (Init && DeclareReductionRef.isUnset()) 13651 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13652 else if (!Init) 13653 S.ActOnUninitializedDecl(RHSVD); 13654 if (RHSVD->isInvalidDecl()) 13655 continue; 13656 if (!RHSVD->hasInit() && 13657 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13658 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13659 << Type << ReductionIdRange; 13660 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13661 VarDecl::DeclarationOnly; 13662 S.Diag(D->getLocation(), 13663 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13664 << D; 13665 continue; 13666 } 13667 // Store initializer for single element in private copy. Will be used during 13668 // codegen. 13669 PrivateVD->setInit(RHSVD->getInit()); 13670 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13671 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13672 ExprResult ReductionOp; 13673 if (DeclareReductionRef.isUsable()) { 13674 QualType RedTy = DeclareReductionRef.get()->getType(); 13675 QualType PtrRedTy = Context.getPointerType(RedTy); 13676 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13677 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13678 if (!BasePath.empty()) { 13679 LHS = S.DefaultLvalueConversion(LHS.get()); 13680 RHS = S.DefaultLvalueConversion(RHS.get()); 13681 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13682 CK_UncheckedDerivedToBase, LHS.get(), 13683 &BasePath, LHS.get()->getValueKind()); 13684 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13685 CK_UncheckedDerivedToBase, RHS.get(), 13686 &BasePath, RHS.get()->getValueKind()); 13687 } 13688 FunctionProtoType::ExtProtoInfo EPI; 13689 QualType Params[] = {PtrRedTy, PtrRedTy}; 13690 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13691 auto *OVE = new (Context) OpaqueValueExpr( 13692 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13693 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13694 Expr *Args[] = {LHS.get(), RHS.get()}; 13695 ReductionOp = 13696 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13697 } else { 13698 ReductionOp = S.BuildBinOp( 13699 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13700 if (ReductionOp.isUsable()) { 13701 if (BOK != BO_LT && BOK != BO_GT) { 13702 ReductionOp = 13703 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13704 BO_Assign, LHSDRE, ReductionOp.get()); 13705 } else { 13706 auto *ConditionalOp = new (Context) 13707 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13708 Type, VK_LValue, OK_Ordinary); 13709 ReductionOp = 13710 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13711 BO_Assign, LHSDRE, ConditionalOp); 13712 } 13713 if (ReductionOp.isUsable()) 13714 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13715 /*DiscardedValue*/ false); 13716 } 13717 if (!ReductionOp.isUsable()) 13718 continue; 13719 } 13720 13721 // OpenMP [2.15.4.6, Restrictions, p.2] 13722 // A list item that appears in an in_reduction clause of a task construct 13723 // must appear in a task_reduction clause of a construct associated with a 13724 // taskgroup region that includes the participating task in its taskgroup 13725 // set. The construct associated with the innermost region that meets this 13726 // condition must specify the same reduction-identifier as the in_reduction 13727 // clause. 13728 if (ClauseKind == OMPC_in_reduction) { 13729 SourceRange ParentSR; 13730 BinaryOperatorKind ParentBOK; 13731 const Expr *ParentReductionOp; 13732 Expr *ParentBOKTD, *ParentReductionOpTD; 13733 DSAStackTy::DSAVarData ParentBOKDSA = 13734 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13735 ParentBOKTD); 13736 DSAStackTy::DSAVarData ParentReductionOpDSA = 13737 Stack->getTopMostTaskgroupReductionData( 13738 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13739 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13740 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13741 if (!IsParentBOK && !IsParentReductionOp) { 13742 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13743 continue; 13744 } 13745 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13746 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13747 IsParentReductionOp) { 13748 bool EmitError = true; 13749 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13750 llvm::FoldingSetNodeID RedId, ParentRedId; 13751 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13752 DeclareReductionRef.get()->Profile(RedId, Context, 13753 /*Canonical=*/true); 13754 EmitError = RedId != ParentRedId; 13755 } 13756 if (EmitError) { 13757 S.Diag(ReductionId.getBeginLoc(), 13758 diag::err_omp_reduction_identifier_mismatch) 13759 << ReductionIdRange << RefExpr->getSourceRange(); 13760 S.Diag(ParentSR.getBegin(), 13761 diag::note_omp_previous_reduction_identifier) 13762 << ParentSR 13763 << (IsParentBOK ? ParentBOKDSA.RefExpr 13764 : ParentReductionOpDSA.RefExpr) 13765 ->getSourceRange(); 13766 continue; 13767 } 13768 } 13769 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13770 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13771 } 13772 13773 DeclRefExpr *Ref = nullptr; 13774 Expr *VarsExpr = RefExpr->IgnoreParens(); 13775 if (!VD && !S.CurContext->isDependentContext()) { 13776 if (ASE || OASE) { 13777 TransformExprToCaptures RebuildToCapture(S, D); 13778 VarsExpr = 13779 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13780 Ref = RebuildToCapture.getCapturedExpr(); 13781 } else { 13782 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13783 } 13784 if (!S.isOpenMPCapturedDecl(D)) { 13785 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13786 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13787 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13788 if (!RefRes.isUsable()) 13789 continue; 13790 ExprResult PostUpdateRes = 13791 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13792 RefRes.get()); 13793 if (!PostUpdateRes.isUsable()) 13794 continue; 13795 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13796 Stack->getCurrentDirective() == OMPD_taskgroup) { 13797 S.Diag(RefExpr->getExprLoc(), 13798 diag::err_omp_reduction_non_addressable_expression) 13799 << RefExpr->getSourceRange(); 13800 continue; 13801 } 13802 RD.ExprPostUpdates.emplace_back( 13803 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13804 } 13805 } 13806 } 13807 // All reduction items are still marked as reduction (to do not increase 13808 // code base size). 13809 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13810 if (CurrDir == OMPD_taskgroup) { 13811 if (DeclareReductionRef.isUsable()) 13812 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13813 DeclareReductionRef.get()); 13814 else 13815 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13816 } 13817 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13818 TaskgroupDescriptor); 13819 } 13820 return RD.Vars.empty(); 13821 } 13822 13823 OMPClause *Sema::ActOnOpenMPReductionClause( 13824 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13825 SourceLocation ColonLoc, SourceLocation EndLoc, 13826 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13827 ArrayRef<Expr *> UnresolvedReductions) { 13828 ReductionData RD(VarList.size()); 13829 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13830 StartLoc, LParenLoc, ColonLoc, EndLoc, 13831 ReductionIdScopeSpec, ReductionId, 13832 UnresolvedReductions, RD)) 13833 return nullptr; 13834 13835 return OMPReductionClause::Create( 13836 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13837 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13838 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13839 buildPreInits(Context, RD.ExprCaptures), 13840 buildPostUpdate(*this, RD.ExprPostUpdates)); 13841 } 13842 13843 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13844 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13845 SourceLocation ColonLoc, SourceLocation EndLoc, 13846 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13847 ArrayRef<Expr *> UnresolvedReductions) { 13848 ReductionData RD(VarList.size()); 13849 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13850 StartLoc, LParenLoc, ColonLoc, EndLoc, 13851 ReductionIdScopeSpec, ReductionId, 13852 UnresolvedReductions, RD)) 13853 return nullptr; 13854 13855 return OMPTaskReductionClause::Create( 13856 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13857 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13858 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13859 buildPreInits(Context, RD.ExprCaptures), 13860 buildPostUpdate(*this, RD.ExprPostUpdates)); 13861 } 13862 13863 OMPClause *Sema::ActOnOpenMPInReductionClause( 13864 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13865 SourceLocation ColonLoc, SourceLocation EndLoc, 13866 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13867 ArrayRef<Expr *> UnresolvedReductions) { 13868 ReductionData RD(VarList.size()); 13869 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13870 StartLoc, LParenLoc, ColonLoc, EndLoc, 13871 ReductionIdScopeSpec, ReductionId, 13872 UnresolvedReductions, RD)) 13873 return nullptr; 13874 13875 return OMPInReductionClause::Create( 13876 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13877 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13878 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13879 buildPreInits(Context, RD.ExprCaptures), 13880 buildPostUpdate(*this, RD.ExprPostUpdates)); 13881 } 13882 13883 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13884 SourceLocation LinLoc) { 13885 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13886 LinKind == OMPC_LINEAR_unknown) { 13887 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13888 return true; 13889 } 13890 return false; 13891 } 13892 13893 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13894 OpenMPLinearClauseKind LinKind, 13895 QualType Type) { 13896 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13897 // A variable must not have an incomplete type or a reference type. 13898 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13899 return true; 13900 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13901 !Type->isReferenceType()) { 13902 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13903 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13904 return true; 13905 } 13906 Type = Type.getNonReferenceType(); 13907 13908 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13909 // A variable that is privatized must not have a const-qualified type 13910 // unless it is of class type with a mutable member. This restriction does 13911 // not apply to the firstprivate clause. 13912 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13913 return true; 13914 13915 // A list item must be of integral or pointer type. 13916 Type = Type.getUnqualifiedType().getCanonicalType(); 13917 const auto *Ty = Type.getTypePtrOrNull(); 13918 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13919 !Ty->isPointerType())) { 13920 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13921 if (D) { 13922 bool IsDecl = 13923 !VD || 13924 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13925 Diag(D->getLocation(), 13926 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13927 << D; 13928 } 13929 return true; 13930 } 13931 return false; 13932 } 13933 13934 OMPClause *Sema::ActOnOpenMPLinearClause( 13935 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13936 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13937 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13938 SmallVector<Expr *, 8> Vars; 13939 SmallVector<Expr *, 8> Privates; 13940 SmallVector<Expr *, 8> Inits; 13941 SmallVector<Decl *, 4> ExprCaptures; 13942 SmallVector<Expr *, 4> ExprPostUpdates; 13943 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13944 LinKind = OMPC_LINEAR_val; 13945 for (Expr *RefExpr : VarList) { 13946 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13947 SourceLocation ELoc; 13948 SourceRange ERange; 13949 Expr *SimpleRefExpr = RefExpr; 13950 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13951 if (Res.second) { 13952 // It will be analyzed later. 13953 Vars.push_back(RefExpr); 13954 Privates.push_back(nullptr); 13955 Inits.push_back(nullptr); 13956 } 13957 ValueDecl *D = Res.first; 13958 if (!D) 13959 continue; 13960 13961 QualType Type = D->getType(); 13962 auto *VD = dyn_cast<VarDecl>(D); 13963 13964 // OpenMP [2.14.3.7, linear clause] 13965 // A list-item cannot appear in more than one linear clause. 13966 // A list-item that appears in a linear clause cannot appear in any 13967 // other data-sharing attribute clause. 13968 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13969 if (DVar.RefExpr) { 13970 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13971 << getOpenMPClauseName(OMPC_linear); 13972 reportOriginalDsa(*this, DSAStack, D, DVar); 13973 continue; 13974 } 13975 13976 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13977 continue; 13978 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13979 13980 // Build private copy of original var. 13981 VarDecl *Private = 13982 buildVarDecl(*this, ELoc, Type, D->getName(), 13983 D->hasAttrs() ? &D->getAttrs() : nullptr, 13984 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13985 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13986 // Build var to save initial value. 13987 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13988 Expr *InitExpr; 13989 DeclRefExpr *Ref = nullptr; 13990 if (!VD && !CurContext->isDependentContext()) { 13991 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13992 if (!isOpenMPCapturedDecl(D)) { 13993 ExprCaptures.push_back(Ref->getDecl()); 13994 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13995 ExprResult RefRes = DefaultLvalueConversion(Ref); 13996 if (!RefRes.isUsable()) 13997 continue; 13998 ExprResult PostUpdateRes = 13999 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14000 SimpleRefExpr, RefRes.get()); 14001 if (!PostUpdateRes.isUsable()) 14002 continue; 14003 ExprPostUpdates.push_back( 14004 IgnoredValueConversions(PostUpdateRes.get()).get()); 14005 } 14006 } 14007 } 14008 if (LinKind == OMPC_LINEAR_uval) 14009 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14010 else 14011 InitExpr = VD ? SimpleRefExpr : Ref; 14012 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14013 /*DirectInit=*/false); 14014 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14015 14016 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14017 Vars.push_back((VD || CurContext->isDependentContext()) 14018 ? RefExpr->IgnoreParens() 14019 : Ref); 14020 Privates.push_back(PrivateRef); 14021 Inits.push_back(InitRef); 14022 } 14023 14024 if (Vars.empty()) 14025 return nullptr; 14026 14027 Expr *StepExpr = Step; 14028 Expr *CalcStepExpr = nullptr; 14029 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14030 !Step->isInstantiationDependent() && 14031 !Step->containsUnexpandedParameterPack()) { 14032 SourceLocation StepLoc = Step->getBeginLoc(); 14033 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14034 if (Val.isInvalid()) 14035 return nullptr; 14036 StepExpr = Val.get(); 14037 14038 // Build var to save the step value. 14039 VarDecl *SaveVar = 14040 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14041 ExprResult SaveRef = 14042 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14043 ExprResult CalcStep = 14044 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14045 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14046 14047 // Warn about zero linear step (it would be probably better specified as 14048 // making corresponding variables 'const'). 14049 llvm::APSInt Result; 14050 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14051 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14052 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14053 << (Vars.size() > 1); 14054 if (!IsConstant && CalcStep.isUsable()) { 14055 // Calculate the step beforehand instead of doing this on each iteration. 14056 // (This is not used if the number of iterations may be kfold-ed). 14057 CalcStepExpr = CalcStep.get(); 14058 } 14059 } 14060 14061 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14062 ColonLoc, EndLoc, Vars, Privates, Inits, 14063 StepExpr, CalcStepExpr, 14064 buildPreInits(Context, ExprCaptures), 14065 buildPostUpdate(*this, ExprPostUpdates)); 14066 } 14067 14068 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14069 Expr *NumIterations, Sema &SemaRef, 14070 Scope *S, DSAStackTy *Stack) { 14071 // Walk the vars and build update/final expressions for the CodeGen. 14072 SmallVector<Expr *, 8> Updates; 14073 SmallVector<Expr *, 8> Finals; 14074 SmallVector<Expr *, 8> UsedExprs; 14075 Expr *Step = Clause.getStep(); 14076 Expr *CalcStep = Clause.getCalcStep(); 14077 // OpenMP [2.14.3.7, linear clause] 14078 // If linear-step is not specified it is assumed to be 1. 14079 if (!Step) 14080 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14081 else if (CalcStep) 14082 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14083 bool HasErrors = false; 14084 auto CurInit = Clause.inits().begin(); 14085 auto CurPrivate = Clause.privates().begin(); 14086 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14087 for (Expr *RefExpr : Clause.varlists()) { 14088 SourceLocation ELoc; 14089 SourceRange ERange; 14090 Expr *SimpleRefExpr = RefExpr; 14091 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14092 ValueDecl *D = Res.first; 14093 if (Res.second || !D) { 14094 Updates.push_back(nullptr); 14095 Finals.push_back(nullptr); 14096 HasErrors = true; 14097 continue; 14098 } 14099 auto &&Info = Stack->isLoopControlVariable(D); 14100 // OpenMP [2.15.11, distribute simd Construct] 14101 // A list item may not appear in a linear clause, unless it is the loop 14102 // iteration variable. 14103 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14104 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14105 SemaRef.Diag(ELoc, 14106 diag::err_omp_linear_distribute_var_non_loop_iteration); 14107 Updates.push_back(nullptr); 14108 Finals.push_back(nullptr); 14109 HasErrors = true; 14110 continue; 14111 } 14112 Expr *InitExpr = *CurInit; 14113 14114 // Build privatized reference to the current linear var. 14115 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14116 Expr *CapturedRef; 14117 if (LinKind == OMPC_LINEAR_uval) 14118 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14119 else 14120 CapturedRef = 14121 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14122 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14123 /*RefersToCapture=*/true); 14124 14125 // Build update: Var = InitExpr + IV * Step 14126 ExprResult Update; 14127 if (!Info.first) 14128 Update = buildCounterUpdate( 14129 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14130 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14131 else 14132 Update = *CurPrivate; 14133 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14134 /*DiscardedValue*/ false); 14135 14136 // Build final: Var = InitExpr + NumIterations * Step 14137 ExprResult Final; 14138 if (!Info.first) 14139 Final = 14140 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14141 InitExpr, NumIterations, Step, /*Subtract=*/false, 14142 /*IsNonRectangularLB=*/false); 14143 else 14144 Final = *CurPrivate; 14145 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14146 /*DiscardedValue*/ false); 14147 14148 if (!Update.isUsable() || !Final.isUsable()) { 14149 Updates.push_back(nullptr); 14150 Finals.push_back(nullptr); 14151 UsedExprs.push_back(nullptr); 14152 HasErrors = true; 14153 } else { 14154 Updates.push_back(Update.get()); 14155 Finals.push_back(Final.get()); 14156 if (!Info.first) 14157 UsedExprs.push_back(SimpleRefExpr); 14158 } 14159 ++CurInit; 14160 ++CurPrivate; 14161 } 14162 if (Expr *S = Clause.getStep()) 14163 UsedExprs.push_back(S); 14164 // Fill the remaining part with the nullptr. 14165 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14166 Clause.setUpdates(Updates); 14167 Clause.setFinals(Finals); 14168 Clause.setUsedExprs(UsedExprs); 14169 return HasErrors; 14170 } 14171 14172 OMPClause *Sema::ActOnOpenMPAlignedClause( 14173 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14174 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14175 SmallVector<Expr *, 8> Vars; 14176 for (Expr *RefExpr : VarList) { 14177 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14178 SourceLocation ELoc; 14179 SourceRange ERange; 14180 Expr *SimpleRefExpr = RefExpr; 14181 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14182 if (Res.second) { 14183 // It will be analyzed later. 14184 Vars.push_back(RefExpr); 14185 } 14186 ValueDecl *D = Res.first; 14187 if (!D) 14188 continue; 14189 14190 QualType QType = D->getType(); 14191 auto *VD = dyn_cast<VarDecl>(D); 14192 14193 // OpenMP [2.8.1, simd construct, Restrictions] 14194 // The type of list items appearing in the aligned clause must be 14195 // array, pointer, reference to array, or reference to pointer. 14196 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14197 const Type *Ty = QType.getTypePtrOrNull(); 14198 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14199 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14200 << QType << getLangOpts().CPlusPlus << ERange; 14201 bool IsDecl = 14202 !VD || 14203 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14204 Diag(D->getLocation(), 14205 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14206 << D; 14207 continue; 14208 } 14209 14210 // OpenMP [2.8.1, simd construct, Restrictions] 14211 // A list-item cannot appear in more than one aligned clause. 14212 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14213 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 14214 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14215 << getOpenMPClauseName(OMPC_aligned); 14216 continue; 14217 } 14218 14219 DeclRefExpr *Ref = nullptr; 14220 if (!VD && isOpenMPCapturedDecl(D)) 14221 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14222 Vars.push_back(DefaultFunctionArrayConversion( 14223 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14224 .get()); 14225 } 14226 14227 // OpenMP [2.8.1, simd construct, Description] 14228 // The parameter of the aligned clause, alignment, must be a constant 14229 // positive integer expression. 14230 // If no optional parameter is specified, implementation-defined default 14231 // alignments for SIMD instructions on the target platforms are assumed. 14232 if (Alignment != nullptr) { 14233 ExprResult AlignResult = 14234 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14235 if (AlignResult.isInvalid()) 14236 return nullptr; 14237 Alignment = AlignResult.get(); 14238 } 14239 if (Vars.empty()) 14240 return nullptr; 14241 14242 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14243 EndLoc, Vars, Alignment); 14244 } 14245 14246 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14247 SourceLocation StartLoc, 14248 SourceLocation LParenLoc, 14249 SourceLocation EndLoc) { 14250 SmallVector<Expr *, 8> Vars; 14251 SmallVector<Expr *, 8> SrcExprs; 14252 SmallVector<Expr *, 8> DstExprs; 14253 SmallVector<Expr *, 8> AssignmentOps; 14254 for (Expr *RefExpr : VarList) { 14255 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14256 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14257 // It will be analyzed later. 14258 Vars.push_back(RefExpr); 14259 SrcExprs.push_back(nullptr); 14260 DstExprs.push_back(nullptr); 14261 AssignmentOps.push_back(nullptr); 14262 continue; 14263 } 14264 14265 SourceLocation ELoc = RefExpr->getExprLoc(); 14266 // OpenMP [2.1, C/C++] 14267 // A list item is a variable name. 14268 // OpenMP [2.14.4.1, Restrictions, p.1] 14269 // A list item that appears in a copyin clause must be threadprivate. 14270 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14271 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14272 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14273 << 0 << RefExpr->getSourceRange(); 14274 continue; 14275 } 14276 14277 Decl *D = DE->getDecl(); 14278 auto *VD = cast<VarDecl>(D); 14279 14280 QualType Type = VD->getType(); 14281 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14282 // It will be analyzed later. 14283 Vars.push_back(DE); 14284 SrcExprs.push_back(nullptr); 14285 DstExprs.push_back(nullptr); 14286 AssignmentOps.push_back(nullptr); 14287 continue; 14288 } 14289 14290 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14291 // A list item that appears in a copyin clause must be threadprivate. 14292 if (!DSAStack->isThreadPrivate(VD)) { 14293 Diag(ELoc, diag::err_omp_required_access) 14294 << getOpenMPClauseName(OMPC_copyin) 14295 << getOpenMPDirectiveName(OMPD_threadprivate); 14296 continue; 14297 } 14298 14299 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14300 // A variable of class type (or array thereof) that appears in a 14301 // copyin clause requires an accessible, unambiguous copy assignment 14302 // operator for the class type. 14303 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14304 VarDecl *SrcVD = 14305 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14306 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14307 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14308 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14309 VarDecl *DstVD = 14310 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14311 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14312 DeclRefExpr *PseudoDstExpr = 14313 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14314 // For arrays generate assignment operation for single element and replace 14315 // it by the original array element in CodeGen. 14316 ExprResult AssignmentOp = 14317 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14318 PseudoSrcExpr); 14319 if (AssignmentOp.isInvalid()) 14320 continue; 14321 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14322 /*DiscardedValue*/ false); 14323 if (AssignmentOp.isInvalid()) 14324 continue; 14325 14326 DSAStack->addDSA(VD, DE, OMPC_copyin); 14327 Vars.push_back(DE); 14328 SrcExprs.push_back(PseudoSrcExpr); 14329 DstExprs.push_back(PseudoDstExpr); 14330 AssignmentOps.push_back(AssignmentOp.get()); 14331 } 14332 14333 if (Vars.empty()) 14334 return nullptr; 14335 14336 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14337 SrcExprs, DstExprs, AssignmentOps); 14338 } 14339 14340 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14341 SourceLocation StartLoc, 14342 SourceLocation LParenLoc, 14343 SourceLocation EndLoc) { 14344 SmallVector<Expr *, 8> Vars; 14345 SmallVector<Expr *, 8> SrcExprs; 14346 SmallVector<Expr *, 8> DstExprs; 14347 SmallVector<Expr *, 8> AssignmentOps; 14348 for (Expr *RefExpr : VarList) { 14349 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14350 SourceLocation ELoc; 14351 SourceRange ERange; 14352 Expr *SimpleRefExpr = RefExpr; 14353 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14354 if (Res.second) { 14355 // It will be analyzed later. 14356 Vars.push_back(RefExpr); 14357 SrcExprs.push_back(nullptr); 14358 DstExprs.push_back(nullptr); 14359 AssignmentOps.push_back(nullptr); 14360 } 14361 ValueDecl *D = Res.first; 14362 if (!D) 14363 continue; 14364 14365 QualType Type = D->getType(); 14366 auto *VD = dyn_cast<VarDecl>(D); 14367 14368 // OpenMP [2.14.4.2, Restrictions, p.2] 14369 // A list item that appears in a copyprivate clause may not appear in a 14370 // private or firstprivate clause on the single construct. 14371 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14372 DSAStackTy::DSAVarData DVar = 14373 DSAStack->getTopDSA(D, /*FromParent=*/false); 14374 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14375 DVar.RefExpr) { 14376 Diag(ELoc, diag::err_omp_wrong_dsa) 14377 << getOpenMPClauseName(DVar.CKind) 14378 << getOpenMPClauseName(OMPC_copyprivate); 14379 reportOriginalDsa(*this, DSAStack, D, DVar); 14380 continue; 14381 } 14382 14383 // OpenMP [2.11.4.2, Restrictions, p.1] 14384 // All list items that appear in a copyprivate clause must be either 14385 // threadprivate or private in the enclosing context. 14386 if (DVar.CKind == OMPC_unknown) { 14387 DVar = DSAStack->getImplicitDSA(D, false); 14388 if (DVar.CKind == OMPC_shared) { 14389 Diag(ELoc, diag::err_omp_required_access) 14390 << getOpenMPClauseName(OMPC_copyprivate) 14391 << "threadprivate or private in the enclosing context"; 14392 reportOriginalDsa(*this, DSAStack, D, DVar); 14393 continue; 14394 } 14395 } 14396 } 14397 14398 // Variably modified types are not supported. 14399 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14400 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14401 << getOpenMPClauseName(OMPC_copyprivate) << Type 14402 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14403 bool IsDecl = 14404 !VD || 14405 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14406 Diag(D->getLocation(), 14407 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14408 << D; 14409 continue; 14410 } 14411 14412 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14413 // A variable of class type (or array thereof) that appears in a 14414 // copyin clause requires an accessible, unambiguous copy assignment 14415 // operator for the class type. 14416 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14417 .getUnqualifiedType(); 14418 VarDecl *SrcVD = 14419 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14420 D->hasAttrs() ? &D->getAttrs() : nullptr); 14421 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14422 VarDecl *DstVD = 14423 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14424 D->hasAttrs() ? &D->getAttrs() : nullptr); 14425 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14426 ExprResult AssignmentOp = BuildBinOp( 14427 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14428 if (AssignmentOp.isInvalid()) 14429 continue; 14430 AssignmentOp = 14431 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14432 if (AssignmentOp.isInvalid()) 14433 continue; 14434 14435 // No need to mark vars as copyprivate, they are already threadprivate or 14436 // implicitly private. 14437 assert(VD || isOpenMPCapturedDecl(D)); 14438 Vars.push_back( 14439 VD ? RefExpr->IgnoreParens() 14440 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14441 SrcExprs.push_back(PseudoSrcExpr); 14442 DstExprs.push_back(PseudoDstExpr); 14443 AssignmentOps.push_back(AssignmentOp.get()); 14444 } 14445 14446 if (Vars.empty()) 14447 return nullptr; 14448 14449 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14450 Vars, SrcExprs, DstExprs, AssignmentOps); 14451 } 14452 14453 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14454 SourceLocation StartLoc, 14455 SourceLocation LParenLoc, 14456 SourceLocation EndLoc) { 14457 if (VarList.empty()) 14458 return nullptr; 14459 14460 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14461 } 14462 14463 OMPClause * 14464 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14465 SourceLocation DepLoc, SourceLocation ColonLoc, 14466 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14467 SourceLocation LParenLoc, SourceLocation EndLoc) { 14468 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14469 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14470 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14471 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14472 return nullptr; 14473 } 14474 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14475 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14476 DepKind == OMPC_DEPEND_sink)) { 14477 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14478 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14479 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14480 /*Last=*/OMPC_DEPEND_unknown, Except) 14481 << getOpenMPClauseName(OMPC_depend); 14482 return nullptr; 14483 } 14484 SmallVector<Expr *, 8> Vars; 14485 DSAStackTy::OperatorOffsetTy OpsOffs; 14486 llvm::APSInt DepCounter(/*BitWidth=*/32); 14487 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14488 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14489 if (const Expr *OrderedCountExpr = 14490 DSAStack->getParentOrderedRegionParam().first) { 14491 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14492 TotalDepCount.setIsUnsigned(/*Val=*/true); 14493 } 14494 } 14495 for (Expr *RefExpr : VarList) { 14496 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14497 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14498 // It will be analyzed later. 14499 Vars.push_back(RefExpr); 14500 continue; 14501 } 14502 14503 SourceLocation ELoc = RefExpr->getExprLoc(); 14504 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14505 if (DepKind == OMPC_DEPEND_sink) { 14506 if (DSAStack->getParentOrderedRegionParam().first && 14507 DepCounter >= TotalDepCount) { 14508 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14509 continue; 14510 } 14511 ++DepCounter; 14512 // OpenMP [2.13.9, Summary] 14513 // depend(dependence-type : vec), where dependence-type is: 14514 // 'sink' and where vec is the iteration vector, which has the form: 14515 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14516 // where n is the value specified by the ordered clause in the loop 14517 // directive, xi denotes the loop iteration variable of the i-th nested 14518 // loop associated with the loop directive, and di is a constant 14519 // non-negative integer. 14520 if (CurContext->isDependentContext()) { 14521 // It will be analyzed later. 14522 Vars.push_back(RefExpr); 14523 continue; 14524 } 14525 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14526 OverloadedOperatorKind OOK = OO_None; 14527 SourceLocation OOLoc; 14528 Expr *LHS = SimpleExpr; 14529 Expr *RHS = nullptr; 14530 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14531 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14532 OOLoc = BO->getOperatorLoc(); 14533 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14534 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14535 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14536 OOK = OCE->getOperator(); 14537 OOLoc = OCE->getOperatorLoc(); 14538 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14539 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14540 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14541 OOK = MCE->getMethodDecl() 14542 ->getNameInfo() 14543 .getName() 14544 .getCXXOverloadedOperator(); 14545 OOLoc = MCE->getCallee()->getExprLoc(); 14546 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14547 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14548 } 14549 SourceLocation ELoc; 14550 SourceRange ERange; 14551 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14552 if (Res.second) { 14553 // It will be analyzed later. 14554 Vars.push_back(RefExpr); 14555 } 14556 ValueDecl *D = Res.first; 14557 if (!D) 14558 continue; 14559 14560 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14561 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14562 continue; 14563 } 14564 if (RHS) { 14565 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14566 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14567 if (RHSRes.isInvalid()) 14568 continue; 14569 } 14570 if (!CurContext->isDependentContext() && 14571 DSAStack->getParentOrderedRegionParam().first && 14572 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14573 const ValueDecl *VD = 14574 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14575 if (VD) 14576 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14577 << 1 << VD; 14578 else 14579 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14580 continue; 14581 } 14582 OpsOffs.emplace_back(RHS, OOK); 14583 } else { 14584 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14585 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14586 (ASE && 14587 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14588 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14589 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14590 << RefExpr->getSourceRange(); 14591 continue; 14592 } 14593 14594 ExprResult Res; 14595 { 14596 Sema::TentativeAnalysisScope Trap(*this); 14597 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14598 RefExpr->IgnoreParenImpCasts()); 14599 } 14600 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14601 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14602 << RefExpr->getSourceRange(); 14603 continue; 14604 } 14605 } 14606 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14607 } 14608 14609 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14610 TotalDepCount > VarList.size() && 14611 DSAStack->getParentOrderedRegionParam().first && 14612 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14613 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14614 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14615 } 14616 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14617 Vars.empty()) 14618 return nullptr; 14619 14620 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14621 DepKind, DepLoc, ColonLoc, Vars, 14622 TotalDepCount.getZExtValue()); 14623 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14624 DSAStack->isParentOrderedRegion()) 14625 DSAStack->addDoacrossDependClause(C, OpsOffs); 14626 return C; 14627 } 14628 14629 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14630 SourceLocation LParenLoc, 14631 SourceLocation EndLoc) { 14632 Expr *ValExpr = Device; 14633 Stmt *HelperValStmt = nullptr; 14634 14635 // OpenMP [2.9.1, Restrictions] 14636 // The device expression must evaluate to a non-negative integer value. 14637 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14638 /*StrictlyPositive=*/false)) 14639 return nullptr; 14640 14641 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14642 OpenMPDirectiveKind CaptureRegion = 14643 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14644 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14645 ValExpr = MakeFullExpr(ValExpr).get(); 14646 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14647 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14648 HelperValStmt = buildPreInits(Context, Captures); 14649 } 14650 14651 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14652 StartLoc, LParenLoc, EndLoc); 14653 } 14654 14655 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14656 DSAStackTy *Stack, QualType QTy, 14657 bool FullCheck = true) { 14658 NamedDecl *ND; 14659 if (QTy->isIncompleteType(&ND)) { 14660 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14661 return false; 14662 } 14663 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14664 !QTy.isTrivialType(SemaRef.Context)) 14665 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14666 return true; 14667 } 14668 14669 /// Return true if it can be proven that the provided array expression 14670 /// (array section or array subscript) does NOT specify the whole size of the 14671 /// array whose base type is \a BaseQTy. 14672 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14673 const Expr *E, 14674 QualType BaseQTy) { 14675 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14676 14677 // If this is an array subscript, it refers to the whole size if the size of 14678 // the dimension is constant and equals 1. Also, an array section assumes the 14679 // format of an array subscript if no colon is used. 14680 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14681 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14682 return ATy->getSize().getSExtValue() != 1; 14683 // Size can't be evaluated statically. 14684 return false; 14685 } 14686 14687 assert(OASE && "Expecting array section if not an array subscript."); 14688 const Expr *LowerBound = OASE->getLowerBound(); 14689 const Expr *Length = OASE->getLength(); 14690 14691 // If there is a lower bound that does not evaluates to zero, we are not 14692 // covering the whole dimension. 14693 if (LowerBound) { 14694 Expr::EvalResult Result; 14695 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14696 return false; // Can't get the integer value as a constant. 14697 14698 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14699 if (ConstLowerBound.getSExtValue()) 14700 return true; 14701 } 14702 14703 // If we don't have a length we covering the whole dimension. 14704 if (!Length) 14705 return false; 14706 14707 // If the base is a pointer, we don't have a way to get the size of the 14708 // pointee. 14709 if (BaseQTy->isPointerType()) 14710 return false; 14711 14712 // We can only check if the length is the same as the size of the dimension 14713 // if we have a constant array. 14714 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14715 if (!CATy) 14716 return false; 14717 14718 Expr::EvalResult Result; 14719 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14720 return false; // Can't get the integer value as a constant. 14721 14722 llvm::APSInt ConstLength = Result.Val.getInt(); 14723 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14724 } 14725 14726 // Return true if it can be proven that the provided array expression (array 14727 // section or array subscript) does NOT specify a single element of the array 14728 // whose base type is \a BaseQTy. 14729 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14730 const Expr *E, 14731 QualType BaseQTy) { 14732 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14733 14734 // An array subscript always refer to a single element. Also, an array section 14735 // assumes the format of an array subscript if no colon is used. 14736 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14737 return false; 14738 14739 assert(OASE && "Expecting array section if not an array subscript."); 14740 const Expr *Length = OASE->getLength(); 14741 14742 // If we don't have a length we have to check if the array has unitary size 14743 // for this dimension. Also, we should always expect a length if the base type 14744 // is pointer. 14745 if (!Length) { 14746 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14747 return ATy->getSize().getSExtValue() != 1; 14748 // We cannot assume anything. 14749 return false; 14750 } 14751 14752 // Check if the length evaluates to 1. 14753 Expr::EvalResult Result; 14754 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14755 return false; // Can't get the integer value as a constant. 14756 14757 llvm::APSInt ConstLength = Result.Val.getInt(); 14758 return ConstLength.getSExtValue() != 1; 14759 } 14760 14761 // Return the expression of the base of the mappable expression or null if it 14762 // cannot be determined and do all the necessary checks to see if the expression 14763 // is valid as a standalone mappable expression. In the process, record all the 14764 // components of the expression. 14765 static const Expr *checkMapClauseExpressionBase( 14766 Sema &SemaRef, Expr *E, 14767 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14768 OpenMPClauseKind CKind, bool NoDiagnose) { 14769 SourceLocation ELoc = E->getExprLoc(); 14770 SourceRange ERange = E->getSourceRange(); 14771 14772 // The base of elements of list in a map clause have to be either: 14773 // - a reference to variable or field. 14774 // - a member expression. 14775 // - an array expression. 14776 // 14777 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14778 // reference to 'r'. 14779 // 14780 // If we have: 14781 // 14782 // struct SS { 14783 // Bla S; 14784 // foo() { 14785 // #pragma omp target map (S.Arr[:12]); 14786 // } 14787 // } 14788 // 14789 // We want to retrieve the member expression 'this->S'; 14790 14791 const Expr *RelevantExpr = nullptr; 14792 14793 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14794 // If a list item is an array section, it must specify contiguous storage. 14795 // 14796 // For this restriction it is sufficient that we make sure only references 14797 // to variables or fields and array expressions, and that no array sections 14798 // exist except in the rightmost expression (unless they cover the whole 14799 // dimension of the array). E.g. these would be invalid: 14800 // 14801 // r.ArrS[3:5].Arr[6:7] 14802 // 14803 // r.ArrS[3:5].x 14804 // 14805 // but these would be valid: 14806 // r.ArrS[3].Arr[6:7] 14807 // 14808 // r.ArrS[3].x 14809 14810 bool AllowUnitySizeArraySection = true; 14811 bool AllowWholeSizeArraySection = true; 14812 14813 while (!RelevantExpr) { 14814 E = E->IgnoreParenImpCasts(); 14815 14816 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14817 if (!isa<VarDecl>(CurE->getDecl())) 14818 return nullptr; 14819 14820 RelevantExpr = CurE; 14821 14822 // If we got a reference to a declaration, we should not expect any array 14823 // section before that. 14824 AllowUnitySizeArraySection = false; 14825 AllowWholeSizeArraySection = false; 14826 14827 // Record the component. 14828 CurComponents.emplace_back(CurE, CurE->getDecl()); 14829 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14830 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14831 14832 if (isa<CXXThisExpr>(BaseE)) 14833 // We found a base expression: this->Val. 14834 RelevantExpr = CurE; 14835 else 14836 E = BaseE; 14837 14838 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14839 if (!NoDiagnose) { 14840 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14841 << CurE->getSourceRange(); 14842 return nullptr; 14843 } 14844 if (RelevantExpr) 14845 return nullptr; 14846 continue; 14847 } 14848 14849 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14850 14851 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14852 // A bit-field cannot appear in a map clause. 14853 // 14854 if (FD->isBitField()) { 14855 if (!NoDiagnose) { 14856 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14857 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14858 return nullptr; 14859 } 14860 if (RelevantExpr) 14861 return nullptr; 14862 continue; 14863 } 14864 14865 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14866 // If the type of a list item is a reference to a type T then the type 14867 // will be considered to be T for all purposes of this clause. 14868 QualType CurType = BaseE->getType().getNonReferenceType(); 14869 14870 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14871 // A list item cannot be a variable that is a member of a structure with 14872 // a union type. 14873 // 14874 if (CurType->isUnionType()) { 14875 if (!NoDiagnose) { 14876 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14877 << CurE->getSourceRange(); 14878 return nullptr; 14879 } 14880 continue; 14881 } 14882 14883 // If we got a member expression, we should not expect any array section 14884 // before that: 14885 // 14886 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14887 // If a list item is an element of a structure, only the rightmost symbol 14888 // of the variable reference can be an array section. 14889 // 14890 AllowUnitySizeArraySection = false; 14891 AllowWholeSizeArraySection = false; 14892 14893 // Record the component. 14894 CurComponents.emplace_back(CurE, FD); 14895 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14896 E = CurE->getBase()->IgnoreParenImpCasts(); 14897 14898 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14899 if (!NoDiagnose) { 14900 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14901 << 0 << CurE->getSourceRange(); 14902 return nullptr; 14903 } 14904 continue; 14905 } 14906 14907 // If we got an array subscript that express the whole dimension we 14908 // can have any array expressions before. If it only expressing part of 14909 // the dimension, we can only have unitary-size array expressions. 14910 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14911 E->getType())) 14912 AllowWholeSizeArraySection = false; 14913 14914 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14915 Expr::EvalResult Result; 14916 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14917 if (!Result.Val.getInt().isNullValue()) { 14918 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14919 diag::err_omp_invalid_map_this_expr); 14920 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14921 diag::note_omp_invalid_subscript_on_this_ptr_map); 14922 } 14923 } 14924 RelevantExpr = TE; 14925 } 14926 14927 // Record the component - we don't have any declaration associated. 14928 CurComponents.emplace_back(CurE, nullptr); 14929 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14930 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14931 E = CurE->getBase()->IgnoreParenImpCasts(); 14932 14933 QualType CurType = 14934 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14935 14936 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14937 // If the type of a list item is a reference to a type T then the type 14938 // will be considered to be T for all purposes of this clause. 14939 if (CurType->isReferenceType()) 14940 CurType = CurType->getPointeeType(); 14941 14942 bool IsPointer = CurType->isAnyPointerType(); 14943 14944 if (!IsPointer && !CurType->isArrayType()) { 14945 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14946 << 0 << CurE->getSourceRange(); 14947 return nullptr; 14948 } 14949 14950 bool NotWhole = 14951 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14952 bool NotUnity = 14953 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14954 14955 if (AllowWholeSizeArraySection) { 14956 // Any array section is currently allowed. Allowing a whole size array 14957 // section implies allowing a unity array section as well. 14958 // 14959 // If this array section refers to the whole dimension we can still 14960 // accept other array sections before this one, except if the base is a 14961 // pointer. Otherwise, only unitary sections are accepted. 14962 if (NotWhole || IsPointer) 14963 AllowWholeSizeArraySection = false; 14964 } else if (AllowUnitySizeArraySection && NotUnity) { 14965 // A unity or whole array section is not allowed and that is not 14966 // compatible with the properties of the current array section. 14967 SemaRef.Diag( 14968 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14969 << CurE->getSourceRange(); 14970 return nullptr; 14971 } 14972 14973 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14974 Expr::EvalResult ResultR; 14975 Expr::EvalResult ResultL; 14976 if (CurE->getLength()->EvaluateAsInt(ResultR, 14977 SemaRef.getASTContext())) { 14978 if (!ResultR.Val.getInt().isOneValue()) { 14979 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14980 diag::err_omp_invalid_map_this_expr); 14981 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14982 diag::note_omp_invalid_length_on_this_ptr_mapping); 14983 } 14984 } 14985 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14986 ResultL, SemaRef.getASTContext())) { 14987 if (!ResultL.Val.getInt().isNullValue()) { 14988 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14989 diag::err_omp_invalid_map_this_expr); 14990 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14991 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14992 } 14993 } 14994 RelevantExpr = TE; 14995 } 14996 14997 // Record the component - we don't have any declaration associated. 14998 CurComponents.emplace_back(CurE, nullptr); 14999 } else { 15000 if (!NoDiagnose) { 15001 // If nothing else worked, this is not a valid map clause expression. 15002 SemaRef.Diag( 15003 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 15004 << ERange; 15005 } 15006 return nullptr; 15007 } 15008 } 15009 15010 return RelevantExpr; 15011 } 15012 15013 // Return true if expression E associated with value VD has conflicts with other 15014 // map information. 15015 static bool checkMapConflicts( 15016 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15017 bool CurrentRegionOnly, 15018 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15019 OpenMPClauseKind CKind) { 15020 assert(VD && E); 15021 SourceLocation ELoc = E->getExprLoc(); 15022 SourceRange ERange = E->getSourceRange(); 15023 15024 // In order to easily check the conflicts we need to match each component of 15025 // the expression under test with the components of the expressions that are 15026 // already in the stack. 15027 15028 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15029 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15030 "Map clause expression with unexpected base!"); 15031 15032 // Variables to help detecting enclosing problems in data environment nests. 15033 bool IsEnclosedByDataEnvironmentExpr = false; 15034 const Expr *EnclosingExpr = nullptr; 15035 15036 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15037 VD, CurrentRegionOnly, 15038 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15039 ERange, CKind, &EnclosingExpr, 15040 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15041 StackComponents, 15042 OpenMPClauseKind) { 15043 assert(!StackComponents.empty() && 15044 "Map clause expression with no components!"); 15045 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15046 "Map clause expression with unexpected base!"); 15047 (void)VD; 15048 15049 // The whole expression in the stack. 15050 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15051 15052 // Expressions must start from the same base. Here we detect at which 15053 // point both expressions diverge from each other and see if we can 15054 // detect if the memory referred to both expressions is contiguous and 15055 // do not overlap. 15056 auto CI = CurComponents.rbegin(); 15057 auto CE = CurComponents.rend(); 15058 auto SI = StackComponents.rbegin(); 15059 auto SE = StackComponents.rend(); 15060 for (; CI != CE && SI != SE; ++CI, ++SI) { 15061 15062 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15063 // At most one list item can be an array item derived from a given 15064 // variable in map clauses of the same construct. 15065 if (CurrentRegionOnly && 15066 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15067 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15068 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15069 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15070 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15071 diag::err_omp_multiple_array_items_in_map_clause) 15072 << CI->getAssociatedExpression()->getSourceRange(); 15073 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15074 diag::note_used_here) 15075 << SI->getAssociatedExpression()->getSourceRange(); 15076 return true; 15077 } 15078 15079 // Do both expressions have the same kind? 15080 if (CI->getAssociatedExpression()->getStmtClass() != 15081 SI->getAssociatedExpression()->getStmtClass()) 15082 break; 15083 15084 // Are we dealing with different variables/fields? 15085 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15086 break; 15087 } 15088 // Check if the extra components of the expressions in the enclosing 15089 // data environment are redundant for the current base declaration. 15090 // If they are, the maps completely overlap, which is legal. 15091 for (; SI != SE; ++SI) { 15092 QualType Type; 15093 if (const auto *ASE = 15094 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15095 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15096 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15097 SI->getAssociatedExpression())) { 15098 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15099 Type = 15100 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15101 } 15102 if (Type.isNull() || Type->isAnyPointerType() || 15103 checkArrayExpressionDoesNotReferToWholeSize( 15104 SemaRef, SI->getAssociatedExpression(), Type)) 15105 break; 15106 } 15107 15108 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15109 // List items of map clauses in the same construct must not share 15110 // original storage. 15111 // 15112 // If the expressions are exactly the same or one is a subset of the 15113 // other, it means they are sharing storage. 15114 if (CI == CE && SI == SE) { 15115 if (CurrentRegionOnly) { 15116 if (CKind == OMPC_map) { 15117 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15118 } else { 15119 assert(CKind == OMPC_to || CKind == OMPC_from); 15120 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15121 << ERange; 15122 } 15123 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15124 << RE->getSourceRange(); 15125 return true; 15126 } 15127 // If we find the same expression in the enclosing data environment, 15128 // that is legal. 15129 IsEnclosedByDataEnvironmentExpr = true; 15130 return false; 15131 } 15132 15133 QualType DerivedType = 15134 std::prev(CI)->getAssociatedDeclaration()->getType(); 15135 SourceLocation DerivedLoc = 15136 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15137 15138 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15139 // If the type of a list item is a reference to a type T then the type 15140 // will be considered to be T for all purposes of this clause. 15141 DerivedType = DerivedType.getNonReferenceType(); 15142 15143 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15144 // A variable for which the type is pointer and an array section 15145 // derived from that variable must not appear as list items of map 15146 // clauses of the same construct. 15147 // 15148 // Also, cover one of the cases in: 15149 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15150 // If any part of the original storage of a list item has corresponding 15151 // storage in the device data environment, all of the original storage 15152 // must have corresponding storage in the device data environment. 15153 // 15154 if (DerivedType->isAnyPointerType()) { 15155 if (CI == CE || SI == SE) { 15156 SemaRef.Diag( 15157 DerivedLoc, 15158 diag::err_omp_pointer_mapped_along_with_derived_section) 15159 << DerivedLoc; 15160 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15161 << RE->getSourceRange(); 15162 return true; 15163 } 15164 if (CI->getAssociatedExpression()->getStmtClass() != 15165 SI->getAssociatedExpression()->getStmtClass() || 15166 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15167 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15168 assert(CI != CE && SI != SE); 15169 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15170 << DerivedLoc; 15171 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15172 << RE->getSourceRange(); 15173 return true; 15174 } 15175 } 15176 15177 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15178 // List items of map clauses in the same construct must not share 15179 // original storage. 15180 // 15181 // An expression is a subset of the other. 15182 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15183 if (CKind == OMPC_map) { 15184 if (CI != CE || SI != SE) { 15185 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15186 // a pointer. 15187 auto Begin = 15188 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15189 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15190 auto It = Begin; 15191 while (It != End && !It->getAssociatedDeclaration()) 15192 std::advance(It, 1); 15193 assert(It != End && 15194 "Expected at least one component with the declaration."); 15195 if (It != Begin && It->getAssociatedDeclaration() 15196 ->getType() 15197 .getCanonicalType() 15198 ->isAnyPointerType()) { 15199 IsEnclosedByDataEnvironmentExpr = false; 15200 EnclosingExpr = nullptr; 15201 return false; 15202 } 15203 } 15204 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15205 } else { 15206 assert(CKind == OMPC_to || CKind == OMPC_from); 15207 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15208 << ERange; 15209 } 15210 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15211 << RE->getSourceRange(); 15212 return true; 15213 } 15214 15215 // The current expression uses the same base as other expression in the 15216 // data environment but does not contain it completely. 15217 if (!CurrentRegionOnly && SI != SE) 15218 EnclosingExpr = RE; 15219 15220 // The current expression is a subset of the expression in the data 15221 // environment. 15222 IsEnclosedByDataEnvironmentExpr |= 15223 (!CurrentRegionOnly && CI != CE && SI == SE); 15224 15225 return false; 15226 }); 15227 15228 if (CurrentRegionOnly) 15229 return FoundError; 15230 15231 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15232 // If any part of the original storage of a list item has corresponding 15233 // storage in the device data environment, all of the original storage must 15234 // have corresponding storage in the device data environment. 15235 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15236 // If a list item is an element of a structure, and a different element of 15237 // the structure has a corresponding list item in the device data environment 15238 // prior to a task encountering the construct associated with the map clause, 15239 // then the list item must also have a corresponding list item in the device 15240 // data environment prior to the task encountering the construct. 15241 // 15242 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15243 SemaRef.Diag(ELoc, 15244 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15245 << ERange; 15246 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15247 << EnclosingExpr->getSourceRange(); 15248 return true; 15249 } 15250 15251 return FoundError; 15252 } 15253 15254 // Look up the user-defined mapper given the mapper name and mapped type, and 15255 // build a reference to it. 15256 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15257 CXXScopeSpec &MapperIdScopeSpec, 15258 const DeclarationNameInfo &MapperId, 15259 QualType Type, 15260 Expr *UnresolvedMapper) { 15261 if (MapperIdScopeSpec.isInvalid()) 15262 return ExprError(); 15263 // Get the actual type for the array type. 15264 if (Type->isArrayType()) { 15265 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15266 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15267 } 15268 // Find all user-defined mappers with the given MapperId. 15269 SmallVector<UnresolvedSet<8>, 4> Lookups; 15270 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15271 Lookup.suppressDiagnostics(); 15272 if (S) { 15273 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15274 NamedDecl *D = Lookup.getRepresentativeDecl(); 15275 while (S && !S->isDeclScope(D)) 15276 S = S->getParent(); 15277 if (S) 15278 S = S->getParent(); 15279 Lookups.emplace_back(); 15280 Lookups.back().append(Lookup.begin(), Lookup.end()); 15281 Lookup.clear(); 15282 } 15283 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15284 // Extract the user-defined mappers with the given MapperId. 15285 Lookups.push_back(UnresolvedSet<8>()); 15286 for (NamedDecl *D : ULE->decls()) { 15287 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15288 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15289 Lookups.back().addDecl(DMD); 15290 } 15291 } 15292 // Defer the lookup for dependent types. The results will be passed through 15293 // UnresolvedMapper on instantiation. 15294 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15295 Type->isInstantiationDependentType() || 15296 Type->containsUnexpandedParameterPack() || 15297 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15298 return !D->isInvalidDecl() && 15299 (D->getType()->isDependentType() || 15300 D->getType()->isInstantiationDependentType() || 15301 D->getType()->containsUnexpandedParameterPack()); 15302 })) { 15303 UnresolvedSet<8> URS; 15304 for (const UnresolvedSet<8> &Set : Lookups) { 15305 if (Set.empty()) 15306 continue; 15307 URS.append(Set.begin(), Set.end()); 15308 } 15309 return UnresolvedLookupExpr::Create( 15310 SemaRef.Context, /*NamingClass=*/nullptr, 15311 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15312 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15313 } 15314 SourceLocation Loc = MapperId.getLoc(); 15315 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15316 // The type must be of struct, union or class type in C and C++ 15317 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15318 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15319 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15320 return ExprError(); 15321 } 15322 // Perform argument dependent lookup. 15323 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15324 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15325 // Return the first user-defined mapper with the desired type. 15326 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15327 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15328 if (!D->isInvalidDecl() && 15329 SemaRef.Context.hasSameType(D->getType(), Type)) 15330 return D; 15331 return nullptr; 15332 })) 15333 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15334 // Find the first user-defined mapper with a type derived from the desired 15335 // type. 15336 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15337 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15338 if (!D->isInvalidDecl() && 15339 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15340 !Type.isMoreQualifiedThan(D->getType())) 15341 return D; 15342 return nullptr; 15343 })) { 15344 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15345 /*DetectVirtual=*/false); 15346 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15347 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15348 VD->getType().getUnqualifiedType()))) { 15349 if (SemaRef.CheckBaseClassAccess( 15350 Loc, VD->getType(), Type, Paths.front(), 15351 /*DiagID=*/0) != Sema::AR_inaccessible) { 15352 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15353 } 15354 } 15355 } 15356 } 15357 // Report error if a mapper is specified, but cannot be found. 15358 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15359 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15360 << Type << MapperId.getName(); 15361 return ExprError(); 15362 } 15363 return ExprEmpty(); 15364 } 15365 15366 namespace { 15367 // Utility struct that gathers all the related lists associated with a mappable 15368 // expression. 15369 struct MappableVarListInfo { 15370 // The list of expressions. 15371 ArrayRef<Expr *> VarList; 15372 // The list of processed expressions. 15373 SmallVector<Expr *, 16> ProcessedVarList; 15374 // The mappble components for each expression. 15375 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15376 // The base declaration of the variable. 15377 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15378 // The reference to the user-defined mapper associated with every expression. 15379 SmallVector<Expr *, 16> UDMapperList; 15380 15381 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15382 // We have a list of components and base declarations for each entry in the 15383 // variable list. 15384 VarComponents.reserve(VarList.size()); 15385 VarBaseDeclarations.reserve(VarList.size()); 15386 } 15387 }; 15388 } 15389 15390 // Check the validity of the provided variable list for the provided clause kind 15391 // \a CKind. In the check process the valid expressions, mappable expression 15392 // components, variables, and user-defined mappers are extracted and used to 15393 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15394 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15395 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15396 static void checkMappableExpressionList( 15397 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15398 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15399 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15400 ArrayRef<Expr *> UnresolvedMappers, 15401 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15402 bool IsMapTypeImplicit = false) { 15403 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15404 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15405 "Unexpected clause kind with mappable expressions!"); 15406 15407 // If the identifier of user-defined mapper is not specified, it is "default". 15408 // We do not change the actual name in this clause to distinguish whether a 15409 // mapper is specified explicitly, i.e., it is not explicitly specified when 15410 // MapperId.getName() is empty. 15411 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15412 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15413 MapperId.setName(DeclNames.getIdentifier( 15414 &SemaRef.getASTContext().Idents.get("default"))); 15415 } 15416 15417 // Iterators to find the current unresolved mapper expression. 15418 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15419 bool UpdateUMIt = false; 15420 Expr *UnresolvedMapper = nullptr; 15421 15422 // Keep track of the mappable components and base declarations in this clause. 15423 // Each entry in the list is going to have a list of components associated. We 15424 // record each set of the components so that we can build the clause later on. 15425 // In the end we should have the same amount of declarations and component 15426 // lists. 15427 15428 for (Expr *RE : MVLI.VarList) { 15429 assert(RE && "Null expr in omp to/from/map clause"); 15430 SourceLocation ELoc = RE->getExprLoc(); 15431 15432 // Find the current unresolved mapper expression. 15433 if (UpdateUMIt && UMIt != UMEnd) { 15434 UMIt++; 15435 assert( 15436 UMIt != UMEnd && 15437 "Expect the size of UnresolvedMappers to match with that of VarList"); 15438 } 15439 UpdateUMIt = true; 15440 if (UMIt != UMEnd) 15441 UnresolvedMapper = *UMIt; 15442 15443 const Expr *VE = RE->IgnoreParenLValueCasts(); 15444 15445 if (VE->isValueDependent() || VE->isTypeDependent() || 15446 VE->isInstantiationDependent() || 15447 VE->containsUnexpandedParameterPack()) { 15448 // Try to find the associated user-defined mapper. 15449 ExprResult ER = buildUserDefinedMapperRef( 15450 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15451 VE->getType().getCanonicalType(), UnresolvedMapper); 15452 if (ER.isInvalid()) 15453 continue; 15454 MVLI.UDMapperList.push_back(ER.get()); 15455 // We can only analyze this information once the missing information is 15456 // resolved. 15457 MVLI.ProcessedVarList.push_back(RE); 15458 continue; 15459 } 15460 15461 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15462 15463 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15464 SemaRef.Diag(ELoc, 15465 diag::err_omp_expected_named_var_member_or_array_expression) 15466 << RE->getSourceRange(); 15467 continue; 15468 } 15469 15470 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15471 ValueDecl *CurDeclaration = nullptr; 15472 15473 // Obtain the array or member expression bases if required. Also, fill the 15474 // components array with all the components identified in the process. 15475 const Expr *BE = checkMapClauseExpressionBase( 15476 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15477 if (!BE) 15478 continue; 15479 15480 assert(!CurComponents.empty() && 15481 "Invalid mappable expression information."); 15482 15483 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15484 // Add store "this" pointer to class in DSAStackTy for future checking 15485 DSAS->addMappedClassesQualTypes(TE->getType()); 15486 // Try to find the associated user-defined mapper. 15487 ExprResult ER = buildUserDefinedMapperRef( 15488 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15489 VE->getType().getCanonicalType(), UnresolvedMapper); 15490 if (ER.isInvalid()) 15491 continue; 15492 MVLI.UDMapperList.push_back(ER.get()); 15493 // Skip restriction checking for variable or field declarations 15494 MVLI.ProcessedVarList.push_back(RE); 15495 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15496 MVLI.VarComponents.back().append(CurComponents.begin(), 15497 CurComponents.end()); 15498 MVLI.VarBaseDeclarations.push_back(nullptr); 15499 continue; 15500 } 15501 15502 // For the following checks, we rely on the base declaration which is 15503 // expected to be associated with the last component. The declaration is 15504 // expected to be a variable or a field (if 'this' is being mapped). 15505 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15506 assert(CurDeclaration && "Null decl on map clause."); 15507 assert( 15508 CurDeclaration->isCanonicalDecl() && 15509 "Expecting components to have associated only canonical declarations."); 15510 15511 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15512 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15513 15514 assert((VD || FD) && "Only variables or fields are expected here!"); 15515 (void)FD; 15516 15517 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15518 // threadprivate variables cannot appear in a map clause. 15519 // OpenMP 4.5 [2.10.5, target update Construct] 15520 // threadprivate variables cannot appear in a from clause. 15521 if (VD && DSAS->isThreadPrivate(VD)) { 15522 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15523 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15524 << getOpenMPClauseName(CKind); 15525 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15526 continue; 15527 } 15528 15529 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15530 // A list item cannot appear in both a map clause and a data-sharing 15531 // attribute clause on the same construct. 15532 15533 // Check conflicts with other map clause expressions. We check the conflicts 15534 // with the current construct separately from the enclosing data 15535 // environment, because the restrictions are different. We only have to 15536 // check conflicts across regions for the map clauses. 15537 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15538 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15539 break; 15540 if (CKind == OMPC_map && 15541 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15542 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15543 break; 15544 15545 // OpenMP 4.5 [2.10.5, target update Construct] 15546 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15547 // If the type of a list item is a reference to a type T then the type will 15548 // be considered to be T for all purposes of this clause. 15549 auto I = llvm::find_if( 15550 CurComponents, 15551 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15552 return MC.getAssociatedDeclaration(); 15553 }); 15554 assert(I != CurComponents.end() && "Null decl on map clause."); 15555 QualType Type = 15556 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15557 15558 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15559 // A list item in a to or from clause must have a mappable type. 15560 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15561 // A list item must have a mappable type. 15562 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15563 DSAS, Type)) 15564 continue; 15565 15566 if (CKind == OMPC_map) { 15567 // target enter data 15568 // OpenMP [2.10.2, Restrictions, p. 99] 15569 // A map-type must be specified in all map clauses and must be either 15570 // to or alloc. 15571 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15572 if (DKind == OMPD_target_enter_data && 15573 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15574 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15575 << (IsMapTypeImplicit ? 1 : 0) 15576 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15577 << getOpenMPDirectiveName(DKind); 15578 continue; 15579 } 15580 15581 // target exit_data 15582 // OpenMP [2.10.3, Restrictions, p. 102] 15583 // A map-type must be specified in all map clauses and must be either 15584 // from, release, or delete. 15585 if (DKind == OMPD_target_exit_data && 15586 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15587 MapType == OMPC_MAP_delete)) { 15588 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15589 << (IsMapTypeImplicit ? 1 : 0) 15590 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15591 << getOpenMPDirectiveName(DKind); 15592 continue; 15593 } 15594 15595 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15596 // A list item cannot appear in both a map clause and a data-sharing 15597 // attribute clause on the same construct 15598 // 15599 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15600 // A list item cannot appear in both a map clause and a data-sharing 15601 // attribute clause on the same construct unless the construct is a 15602 // combined construct. 15603 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15604 isOpenMPTargetExecutionDirective(DKind)) || 15605 DKind == OMPD_target)) { 15606 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15607 if (isOpenMPPrivate(DVar.CKind)) { 15608 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15609 << getOpenMPClauseName(DVar.CKind) 15610 << getOpenMPClauseName(OMPC_map) 15611 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15612 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15613 continue; 15614 } 15615 } 15616 } 15617 15618 // Try to find the associated user-defined mapper. 15619 ExprResult ER = buildUserDefinedMapperRef( 15620 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15621 Type.getCanonicalType(), UnresolvedMapper); 15622 if (ER.isInvalid()) 15623 continue; 15624 MVLI.UDMapperList.push_back(ER.get()); 15625 15626 // Save the current expression. 15627 MVLI.ProcessedVarList.push_back(RE); 15628 15629 // Store the components in the stack so that they can be used to check 15630 // against other clauses later on. 15631 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15632 /*WhereFoundClauseKind=*/OMPC_map); 15633 15634 // Save the components and declaration to create the clause. For purposes of 15635 // the clause creation, any component list that has has base 'this' uses 15636 // null as base declaration. 15637 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15638 MVLI.VarComponents.back().append(CurComponents.begin(), 15639 CurComponents.end()); 15640 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15641 : CurDeclaration); 15642 } 15643 } 15644 15645 OMPClause *Sema::ActOnOpenMPMapClause( 15646 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15647 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15648 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15649 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15650 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15651 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15652 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15653 OMPC_MAP_MODIFIER_unknown, 15654 OMPC_MAP_MODIFIER_unknown}; 15655 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15656 15657 // Process map-type-modifiers, flag errors for duplicate modifiers. 15658 unsigned Count = 0; 15659 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15660 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15661 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15662 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15663 continue; 15664 } 15665 assert(Count < OMPMapClause::NumberOfModifiers && 15666 "Modifiers exceed the allowed number of map type modifiers"); 15667 Modifiers[Count] = MapTypeModifiers[I]; 15668 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15669 ++Count; 15670 } 15671 15672 MappableVarListInfo MVLI(VarList); 15673 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15674 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15675 MapType, IsMapTypeImplicit); 15676 15677 // We need to produce a map clause even if we don't have variables so that 15678 // other diagnostics related with non-existing map clauses are accurate. 15679 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15680 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15681 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15682 MapperIdScopeSpec.getWithLocInContext(Context), 15683 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15684 } 15685 15686 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15687 TypeResult ParsedType) { 15688 assert(ParsedType.isUsable()); 15689 15690 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15691 if (ReductionType.isNull()) 15692 return QualType(); 15693 15694 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15695 // A type name in a declare reduction directive cannot be a function type, an 15696 // array type, a reference type, or a type qualified with const, volatile or 15697 // restrict. 15698 if (ReductionType.hasQualifiers()) { 15699 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15700 return QualType(); 15701 } 15702 15703 if (ReductionType->isFunctionType()) { 15704 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15705 return QualType(); 15706 } 15707 if (ReductionType->isReferenceType()) { 15708 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15709 return QualType(); 15710 } 15711 if (ReductionType->isArrayType()) { 15712 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15713 return QualType(); 15714 } 15715 return ReductionType; 15716 } 15717 15718 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15719 Scope *S, DeclContext *DC, DeclarationName Name, 15720 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15721 AccessSpecifier AS, Decl *PrevDeclInScope) { 15722 SmallVector<Decl *, 8> Decls; 15723 Decls.reserve(ReductionTypes.size()); 15724 15725 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15726 forRedeclarationInCurContext()); 15727 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15728 // A reduction-identifier may not be re-declared in the current scope for the 15729 // same type or for a type that is compatible according to the base language 15730 // rules. 15731 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15732 OMPDeclareReductionDecl *PrevDRD = nullptr; 15733 bool InCompoundScope = true; 15734 if (S != nullptr) { 15735 // Find previous declaration with the same name not referenced in other 15736 // declarations. 15737 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15738 InCompoundScope = 15739 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15740 LookupName(Lookup, S); 15741 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15742 /*AllowInlineNamespace=*/false); 15743 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15744 LookupResult::Filter Filter = Lookup.makeFilter(); 15745 while (Filter.hasNext()) { 15746 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15747 if (InCompoundScope) { 15748 auto I = UsedAsPrevious.find(PrevDecl); 15749 if (I == UsedAsPrevious.end()) 15750 UsedAsPrevious[PrevDecl] = false; 15751 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15752 UsedAsPrevious[D] = true; 15753 } 15754 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15755 PrevDecl->getLocation(); 15756 } 15757 Filter.done(); 15758 if (InCompoundScope) { 15759 for (const auto &PrevData : UsedAsPrevious) { 15760 if (!PrevData.second) { 15761 PrevDRD = PrevData.first; 15762 break; 15763 } 15764 } 15765 } 15766 } else if (PrevDeclInScope != nullptr) { 15767 auto *PrevDRDInScope = PrevDRD = 15768 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15769 do { 15770 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15771 PrevDRDInScope->getLocation(); 15772 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15773 } while (PrevDRDInScope != nullptr); 15774 } 15775 for (const auto &TyData : ReductionTypes) { 15776 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15777 bool Invalid = false; 15778 if (I != PreviousRedeclTypes.end()) { 15779 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15780 << TyData.first; 15781 Diag(I->second, diag::note_previous_definition); 15782 Invalid = true; 15783 } 15784 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15785 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15786 Name, TyData.first, PrevDRD); 15787 DC->addDecl(DRD); 15788 DRD->setAccess(AS); 15789 Decls.push_back(DRD); 15790 if (Invalid) 15791 DRD->setInvalidDecl(); 15792 else 15793 PrevDRD = DRD; 15794 } 15795 15796 return DeclGroupPtrTy::make( 15797 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15798 } 15799 15800 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15801 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15802 15803 // Enter new function scope. 15804 PushFunctionScope(); 15805 setFunctionHasBranchProtectedScope(); 15806 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15807 15808 if (S != nullptr) 15809 PushDeclContext(S, DRD); 15810 else 15811 CurContext = DRD; 15812 15813 PushExpressionEvaluationContext( 15814 ExpressionEvaluationContext::PotentiallyEvaluated); 15815 15816 QualType ReductionType = DRD->getType(); 15817 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15818 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15819 // uses semantics of argument handles by value, but it should be passed by 15820 // reference. C lang does not support references, so pass all parameters as 15821 // pointers. 15822 // Create 'T omp_in;' variable. 15823 VarDecl *OmpInParm = 15824 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15825 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15826 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15827 // uses semantics of argument handles by value, but it should be passed by 15828 // reference. C lang does not support references, so pass all parameters as 15829 // pointers. 15830 // Create 'T omp_out;' variable. 15831 VarDecl *OmpOutParm = 15832 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15833 if (S != nullptr) { 15834 PushOnScopeChains(OmpInParm, S); 15835 PushOnScopeChains(OmpOutParm, S); 15836 } else { 15837 DRD->addDecl(OmpInParm); 15838 DRD->addDecl(OmpOutParm); 15839 } 15840 Expr *InE = 15841 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15842 Expr *OutE = 15843 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15844 DRD->setCombinerData(InE, OutE); 15845 } 15846 15847 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15848 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15849 DiscardCleanupsInEvaluationContext(); 15850 PopExpressionEvaluationContext(); 15851 15852 PopDeclContext(); 15853 PopFunctionScopeInfo(); 15854 15855 if (Combiner != nullptr) 15856 DRD->setCombiner(Combiner); 15857 else 15858 DRD->setInvalidDecl(); 15859 } 15860 15861 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15862 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15863 15864 // Enter new function scope. 15865 PushFunctionScope(); 15866 setFunctionHasBranchProtectedScope(); 15867 15868 if (S != nullptr) 15869 PushDeclContext(S, DRD); 15870 else 15871 CurContext = DRD; 15872 15873 PushExpressionEvaluationContext( 15874 ExpressionEvaluationContext::PotentiallyEvaluated); 15875 15876 QualType ReductionType = DRD->getType(); 15877 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15878 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15879 // uses semantics of argument handles by value, but it should be passed by 15880 // reference. C lang does not support references, so pass all parameters as 15881 // pointers. 15882 // Create 'T omp_priv;' variable. 15883 VarDecl *OmpPrivParm = 15884 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15885 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15886 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15887 // uses semantics of argument handles by value, but it should be passed by 15888 // reference. C lang does not support references, so pass all parameters as 15889 // pointers. 15890 // Create 'T omp_orig;' variable. 15891 VarDecl *OmpOrigParm = 15892 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15893 if (S != nullptr) { 15894 PushOnScopeChains(OmpPrivParm, S); 15895 PushOnScopeChains(OmpOrigParm, S); 15896 } else { 15897 DRD->addDecl(OmpPrivParm); 15898 DRD->addDecl(OmpOrigParm); 15899 } 15900 Expr *OrigE = 15901 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15902 Expr *PrivE = 15903 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15904 DRD->setInitializerData(OrigE, PrivE); 15905 return OmpPrivParm; 15906 } 15907 15908 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15909 VarDecl *OmpPrivParm) { 15910 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15911 DiscardCleanupsInEvaluationContext(); 15912 PopExpressionEvaluationContext(); 15913 15914 PopDeclContext(); 15915 PopFunctionScopeInfo(); 15916 15917 if (Initializer != nullptr) { 15918 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15919 } else if (OmpPrivParm->hasInit()) { 15920 DRD->setInitializer(OmpPrivParm->getInit(), 15921 OmpPrivParm->isDirectInit() 15922 ? OMPDeclareReductionDecl::DirectInit 15923 : OMPDeclareReductionDecl::CopyInit); 15924 } else { 15925 DRD->setInvalidDecl(); 15926 } 15927 } 15928 15929 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15930 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15931 for (Decl *D : DeclReductions.get()) { 15932 if (IsValid) { 15933 if (S) 15934 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15935 /*AddToContext=*/false); 15936 } else { 15937 D->setInvalidDecl(); 15938 } 15939 } 15940 return DeclReductions; 15941 } 15942 15943 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15944 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15945 QualType T = TInfo->getType(); 15946 if (D.isInvalidType()) 15947 return true; 15948 15949 if (getLangOpts().CPlusPlus) { 15950 // Check that there are no default arguments (C++ only). 15951 CheckExtraCXXDefaultArguments(D); 15952 } 15953 15954 return CreateParsedType(T, TInfo); 15955 } 15956 15957 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15958 TypeResult ParsedType) { 15959 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15960 15961 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15962 assert(!MapperType.isNull() && "Expect valid mapper type"); 15963 15964 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15965 // The type must be of struct, union or class type in C and C++ 15966 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15967 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15968 return QualType(); 15969 } 15970 return MapperType; 15971 } 15972 15973 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15974 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15975 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15976 Decl *PrevDeclInScope) { 15977 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15978 forRedeclarationInCurContext()); 15979 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15980 // A mapper-identifier may not be redeclared in the current scope for the 15981 // same type or for a type that is compatible according to the base language 15982 // rules. 15983 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15984 OMPDeclareMapperDecl *PrevDMD = nullptr; 15985 bool InCompoundScope = true; 15986 if (S != nullptr) { 15987 // Find previous declaration with the same name not referenced in other 15988 // declarations. 15989 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15990 InCompoundScope = 15991 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15992 LookupName(Lookup, S); 15993 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15994 /*AllowInlineNamespace=*/false); 15995 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15996 LookupResult::Filter Filter = Lookup.makeFilter(); 15997 while (Filter.hasNext()) { 15998 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15999 if (InCompoundScope) { 16000 auto I = UsedAsPrevious.find(PrevDecl); 16001 if (I == UsedAsPrevious.end()) 16002 UsedAsPrevious[PrevDecl] = false; 16003 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16004 UsedAsPrevious[D] = true; 16005 } 16006 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16007 PrevDecl->getLocation(); 16008 } 16009 Filter.done(); 16010 if (InCompoundScope) { 16011 for (const auto &PrevData : UsedAsPrevious) { 16012 if (!PrevData.second) { 16013 PrevDMD = PrevData.first; 16014 break; 16015 } 16016 } 16017 } 16018 } else if (PrevDeclInScope) { 16019 auto *PrevDMDInScope = PrevDMD = 16020 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16021 do { 16022 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16023 PrevDMDInScope->getLocation(); 16024 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16025 } while (PrevDMDInScope != nullptr); 16026 } 16027 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16028 bool Invalid = false; 16029 if (I != PreviousRedeclTypes.end()) { 16030 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16031 << MapperType << Name; 16032 Diag(I->second, diag::note_previous_definition); 16033 Invalid = true; 16034 } 16035 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16036 MapperType, VN, PrevDMD); 16037 DC->addDecl(DMD); 16038 DMD->setAccess(AS); 16039 if (Invalid) 16040 DMD->setInvalidDecl(); 16041 16042 // Enter new function scope. 16043 PushFunctionScope(); 16044 setFunctionHasBranchProtectedScope(); 16045 16046 CurContext = DMD; 16047 16048 return DMD; 16049 } 16050 16051 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16052 Scope *S, 16053 QualType MapperType, 16054 SourceLocation StartLoc, 16055 DeclarationName VN) { 16056 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16057 if (S) 16058 PushOnScopeChains(VD, S); 16059 else 16060 DMD->addDecl(VD); 16061 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16062 DMD->setMapperVarRef(MapperVarRefExpr); 16063 } 16064 16065 Sema::DeclGroupPtrTy 16066 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16067 ArrayRef<OMPClause *> ClauseList) { 16068 PopDeclContext(); 16069 PopFunctionScopeInfo(); 16070 16071 if (D) { 16072 if (S) 16073 PushOnScopeChains(D, S, /*AddToContext=*/false); 16074 D->CreateClauses(Context, ClauseList); 16075 } 16076 16077 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16078 } 16079 16080 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16081 SourceLocation StartLoc, 16082 SourceLocation LParenLoc, 16083 SourceLocation EndLoc) { 16084 Expr *ValExpr = NumTeams; 16085 Stmt *HelperValStmt = nullptr; 16086 16087 // OpenMP [teams Constrcut, Restrictions] 16088 // The num_teams expression must evaluate to a positive integer value. 16089 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16090 /*StrictlyPositive=*/true)) 16091 return nullptr; 16092 16093 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16094 OpenMPDirectiveKind CaptureRegion = 16095 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 16096 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16097 ValExpr = MakeFullExpr(ValExpr).get(); 16098 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16099 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16100 HelperValStmt = buildPreInits(Context, Captures); 16101 } 16102 16103 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16104 StartLoc, LParenLoc, EndLoc); 16105 } 16106 16107 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16108 SourceLocation StartLoc, 16109 SourceLocation LParenLoc, 16110 SourceLocation EndLoc) { 16111 Expr *ValExpr = ThreadLimit; 16112 Stmt *HelperValStmt = nullptr; 16113 16114 // OpenMP [teams Constrcut, Restrictions] 16115 // The thread_limit expression must evaluate to a positive integer value. 16116 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16117 /*StrictlyPositive=*/true)) 16118 return nullptr; 16119 16120 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16121 OpenMPDirectiveKind CaptureRegion = 16122 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 16123 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16124 ValExpr = MakeFullExpr(ValExpr).get(); 16125 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16126 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16127 HelperValStmt = buildPreInits(Context, Captures); 16128 } 16129 16130 return new (Context) OMPThreadLimitClause( 16131 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16132 } 16133 16134 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16135 SourceLocation StartLoc, 16136 SourceLocation LParenLoc, 16137 SourceLocation EndLoc) { 16138 Expr *ValExpr = Priority; 16139 Stmt *HelperValStmt = nullptr; 16140 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16141 16142 // OpenMP [2.9.1, task Constrcut] 16143 // The priority-value is a non-negative numerical scalar expression. 16144 if (!isNonNegativeIntegerValue( 16145 ValExpr, *this, OMPC_priority, 16146 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16147 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16148 return nullptr; 16149 16150 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16151 StartLoc, LParenLoc, EndLoc); 16152 } 16153 16154 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16155 SourceLocation StartLoc, 16156 SourceLocation LParenLoc, 16157 SourceLocation EndLoc) { 16158 Expr *ValExpr = Grainsize; 16159 Stmt *HelperValStmt = nullptr; 16160 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16161 16162 // OpenMP [2.9.2, taskloop Constrcut] 16163 // The parameter of the grainsize clause must be a positive integer 16164 // expression. 16165 if (!isNonNegativeIntegerValue( 16166 ValExpr, *this, OMPC_grainsize, 16167 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16168 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16169 return nullptr; 16170 16171 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16172 StartLoc, LParenLoc, EndLoc); 16173 } 16174 16175 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16176 SourceLocation StartLoc, 16177 SourceLocation LParenLoc, 16178 SourceLocation EndLoc) { 16179 Expr *ValExpr = NumTasks; 16180 Stmt *HelperValStmt = nullptr; 16181 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16182 16183 // OpenMP [2.9.2, taskloop Constrcut] 16184 // The parameter of the num_tasks clause must be a positive integer 16185 // expression. 16186 if (!isNonNegativeIntegerValue( 16187 ValExpr, *this, OMPC_num_tasks, 16188 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16189 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16190 return nullptr; 16191 16192 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16193 StartLoc, LParenLoc, EndLoc); 16194 } 16195 16196 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16197 SourceLocation LParenLoc, 16198 SourceLocation EndLoc) { 16199 // OpenMP [2.13.2, critical construct, Description] 16200 // ... where hint-expression is an integer constant expression that evaluates 16201 // to a valid lock hint. 16202 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16203 if (HintExpr.isInvalid()) 16204 return nullptr; 16205 return new (Context) 16206 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16207 } 16208 16209 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16210 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16211 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16212 SourceLocation EndLoc) { 16213 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16214 std::string Values; 16215 Values += "'"; 16216 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16217 Values += "'"; 16218 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16219 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16220 return nullptr; 16221 } 16222 Expr *ValExpr = ChunkSize; 16223 Stmt *HelperValStmt = nullptr; 16224 if (ChunkSize) { 16225 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16226 !ChunkSize->isInstantiationDependent() && 16227 !ChunkSize->containsUnexpandedParameterPack()) { 16228 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16229 ExprResult Val = 16230 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16231 if (Val.isInvalid()) 16232 return nullptr; 16233 16234 ValExpr = Val.get(); 16235 16236 // OpenMP [2.7.1, Restrictions] 16237 // chunk_size must be a loop invariant integer expression with a positive 16238 // value. 16239 llvm::APSInt Result; 16240 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16241 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16242 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16243 << "dist_schedule" << ChunkSize->getSourceRange(); 16244 return nullptr; 16245 } 16246 } else if (getOpenMPCaptureRegionForClause( 16247 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 16248 OMPD_unknown && 16249 !CurContext->isDependentContext()) { 16250 ValExpr = MakeFullExpr(ValExpr).get(); 16251 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16252 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16253 HelperValStmt = buildPreInits(Context, Captures); 16254 } 16255 } 16256 } 16257 16258 return new (Context) 16259 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16260 Kind, ValExpr, HelperValStmt); 16261 } 16262 16263 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16264 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16265 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16266 SourceLocation KindLoc, SourceLocation EndLoc) { 16267 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 16268 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 16269 std::string Value; 16270 SourceLocation Loc; 16271 Value += "'"; 16272 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16273 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16274 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16275 Loc = MLoc; 16276 } else { 16277 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16278 OMPC_DEFAULTMAP_scalar); 16279 Loc = KindLoc; 16280 } 16281 Value += "'"; 16282 Diag(Loc, diag::err_omp_unexpected_clause_value) 16283 << Value << getOpenMPClauseName(OMPC_defaultmap); 16284 return nullptr; 16285 } 16286 DSAStack->setDefaultDMAToFromScalar(StartLoc); 16287 16288 return new (Context) 16289 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16290 } 16291 16292 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16293 DeclContext *CurLexicalContext = getCurLexicalContext(); 16294 if (!CurLexicalContext->isFileContext() && 16295 !CurLexicalContext->isExternCContext() && 16296 !CurLexicalContext->isExternCXXContext() && 16297 !isa<CXXRecordDecl>(CurLexicalContext) && 16298 !isa<ClassTemplateDecl>(CurLexicalContext) && 16299 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16300 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16301 Diag(Loc, diag::err_omp_region_not_file_context); 16302 return false; 16303 } 16304 ++DeclareTargetNestingLevel; 16305 return true; 16306 } 16307 16308 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16309 assert(DeclareTargetNestingLevel > 0 && 16310 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16311 --DeclareTargetNestingLevel; 16312 } 16313 16314 NamedDecl * 16315 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16316 const DeclarationNameInfo &Id, 16317 NamedDeclSetType &SameDirectiveDecls) { 16318 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16319 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16320 16321 if (Lookup.isAmbiguous()) 16322 return nullptr; 16323 Lookup.suppressDiagnostics(); 16324 16325 if (!Lookup.isSingleResult()) { 16326 VarOrFuncDeclFilterCCC CCC(*this); 16327 if (TypoCorrection Corrected = 16328 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16329 CTK_ErrorRecovery)) { 16330 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16331 << Id.getName()); 16332 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16333 return nullptr; 16334 } 16335 16336 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16337 return nullptr; 16338 } 16339 16340 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16341 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16342 !isa<FunctionTemplateDecl>(ND)) { 16343 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16344 return nullptr; 16345 } 16346 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16347 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16348 return ND; 16349 } 16350 16351 void Sema::ActOnOpenMPDeclareTargetName( 16352 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16353 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16354 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16355 isa<FunctionTemplateDecl>(ND)) && 16356 "Expected variable, function or function template."); 16357 16358 // Diagnose marking after use as it may lead to incorrect diagnosis and 16359 // codegen. 16360 if (LangOpts.OpenMP >= 50 && 16361 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16362 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16363 16364 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16365 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16366 if (DevTy.hasValue() && *DevTy != DT) { 16367 Diag(Loc, diag::err_omp_device_type_mismatch) 16368 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16369 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16370 return; 16371 } 16372 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16373 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16374 if (!Res) { 16375 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16376 SourceRange(Loc, Loc)); 16377 ND->addAttr(A); 16378 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16379 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16380 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16381 } else if (*Res != MT) { 16382 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16383 } 16384 } 16385 16386 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16387 Sema &SemaRef, Decl *D) { 16388 if (!D || !isa<VarDecl>(D)) 16389 return; 16390 auto *VD = cast<VarDecl>(D); 16391 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16392 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16393 if (SemaRef.LangOpts.OpenMP >= 50 && 16394 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16395 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16396 VD->hasGlobalStorage()) { 16397 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16398 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16399 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16400 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16401 // If a lambda declaration and definition appears between a 16402 // declare target directive and the matching end declare target 16403 // directive, all variables that are captured by the lambda 16404 // expression must also appear in a to clause. 16405 SemaRef.Diag(VD->getLocation(), 16406 diag::err_omp_lambda_capture_in_declare_target_not_to); 16407 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16408 << VD << 0 << SR; 16409 return; 16410 } 16411 } 16412 if (MapTy.hasValue()) 16413 return; 16414 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16415 SemaRef.Diag(SL, diag::note_used_here) << SR; 16416 } 16417 16418 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16419 Sema &SemaRef, DSAStackTy *Stack, 16420 ValueDecl *VD) { 16421 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16422 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16423 /*FullCheck=*/false); 16424 } 16425 16426 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16427 SourceLocation IdLoc) { 16428 if (!D || D->isInvalidDecl()) 16429 return; 16430 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16431 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16432 if (auto *VD = dyn_cast<VarDecl>(D)) { 16433 // Only global variables can be marked as declare target. 16434 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16435 !VD->isStaticDataMember()) 16436 return; 16437 // 2.10.6: threadprivate variable cannot appear in a declare target 16438 // directive. 16439 if (DSAStack->isThreadPrivate(VD)) { 16440 Diag(SL, diag::err_omp_threadprivate_in_target); 16441 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16442 return; 16443 } 16444 } 16445 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16446 D = FTD->getTemplatedDecl(); 16447 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16448 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16449 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16450 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16451 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16452 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16453 return; 16454 } 16455 // Mark the function as must be emitted for the device. 16456 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16457 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16458 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16459 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16460 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16461 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16462 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16463 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16464 } 16465 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16466 // Problem if any with var declared with incomplete type will be reported 16467 // as normal, so no need to check it here. 16468 if ((E || !VD->getType()->isIncompleteType()) && 16469 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16470 return; 16471 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16472 // Checking declaration inside declare target region. 16473 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16474 isa<FunctionTemplateDecl>(D)) { 16475 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16476 Context, OMPDeclareTargetDeclAttr::MT_To, 16477 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16478 D->addAttr(A); 16479 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16480 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16481 } 16482 return; 16483 } 16484 } 16485 if (!E) 16486 return; 16487 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16488 } 16489 16490 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16491 CXXScopeSpec &MapperIdScopeSpec, 16492 DeclarationNameInfo &MapperId, 16493 const OMPVarListLocTy &Locs, 16494 ArrayRef<Expr *> UnresolvedMappers) { 16495 MappableVarListInfo MVLI(VarList); 16496 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16497 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16498 if (MVLI.ProcessedVarList.empty()) 16499 return nullptr; 16500 16501 return OMPToClause::Create( 16502 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16503 MVLI.VarComponents, MVLI.UDMapperList, 16504 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16505 } 16506 16507 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16508 CXXScopeSpec &MapperIdScopeSpec, 16509 DeclarationNameInfo &MapperId, 16510 const OMPVarListLocTy &Locs, 16511 ArrayRef<Expr *> UnresolvedMappers) { 16512 MappableVarListInfo MVLI(VarList); 16513 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16514 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16515 if (MVLI.ProcessedVarList.empty()) 16516 return nullptr; 16517 16518 return OMPFromClause::Create( 16519 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16520 MVLI.VarComponents, MVLI.UDMapperList, 16521 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16522 } 16523 16524 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16525 const OMPVarListLocTy &Locs) { 16526 MappableVarListInfo MVLI(VarList); 16527 SmallVector<Expr *, 8> PrivateCopies; 16528 SmallVector<Expr *, 8> Inits; 16529 16530 for (Expr *RefExpr : VarList) { 16531 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16532 SourceLocation ELoc; 16533 SourceRange ERange; 16534 Expr *SimpleRefExpr = RefExpr; 16535 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16536 if (Res.second) { 16537 // It will be analyzed later. 16538 MVLI.ProcessedVarList.push_back(RefExpr); 16539 PrivateCopies.push_back(nullptr); 16540 Inits.push_back(nullptr); 16541 } 16542 ValueDecl *D = Res.first; 16543 if (!D) 16544 continue; 16545 16546 QualType Type = D->getType(); 16547 Type = Type.getNonReferenceType().getUnqualifiedType(); 16548 16549 auto *VD = dyn_cast<VarDecl>(D); 16550 16551 // Item should be a pointer or reference to pointer. 16552 if (!Type->isPointerType()) { 16553 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16554 << 0 << RefExpr->getSourceRange(); 16555 continue; 16556 } 16557 16558 // Build the private variable and the expression that refers to it. 16559 auto VDPrivate = 16560 buildVarDecl(*this, ELoc, Type, D->getName(), 16561 D->hasAttrs() ? &D->getAttrs() : nullptr, 16562 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16563 if (VDPrivate->isInvalidDecl()) 16564 continue; 16565 16566 CurContext->addDecl(VDPrivate); 16567 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16568 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16569 16570 // Add temporary variable to initialize the private copy of the pointer. 16571 VarDecl *VDInit = 16572 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16573 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16574 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16575 AddInitializerToDecl(VDPrivate, 16576 DefaultLvalueConversion(VDInitRefExpr).get(), 16577 /*DirectInit=*/false); 16578 16579 // If required, build a capture to implement the privatization initialized 16580 // with the current list item value. 16581 DeclRefExpr *Ref = nullptr; 16582 if (!VD) 16583 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16584 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16585 PrivateCopies.push_back(VDPrivateRefExpr); 16586 Inits.push_back(VDInitRefExpr); 16587 16588 // We need to add a data sharing attribute for this variable to make sure it 16589 // is correctly captured. A variable that shows up in a use_device_ptr has 16590 // similar properties of a first private variable. 16591 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16592 16593 // Create a mappable component for the list item. List items in this clause 16594 // only need a component. 16595 MVLI.VarBaseDeclarations.push_back(D); 16596 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16597 MVLI.VarComponents.back().push_back( 16598 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16599 } 16600 16601 if (MVLI.ProcessedVarList.empty()) 16602 return nullptr; 16603 16604 return OMPUseDevicePtrClause::Create( 16605 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16606 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16607 } 16608 16609 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16610 const OMPVarListLocTy &Locs) { 16611 MappableVarListInfo MVLI(VarList); 16612 for (Expr *RefExpr : VarList) { 16613 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16614 SourceLocation ELoc; 16615 SourceRange ERange; 16616 Expr *SimpleRefExpr = RefExpr; 16617 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16618 if (Res.second) { 16619 // It will be analyzed later. 16620 MVLI.ProcessedVarList.push_back(RefExpr); 16621 } 16622 ValueDecl *D = Res.first; 16623 if (!D) 16624 continue; 16625 16626 QualType Type = D->getType(); 16627 // item should be a pointer or array or reference to pointer or array 16628 if (!Type.getNonReferenceType()->isPointerType() && 16629 !Type.getNonReferenceType()->isArrayType()) { 16630 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16631 << 0 << RefExpr->getSourceRange(); 16632 continue; 16633 } 16634 16635 // Check if the declaration in the clause does not show up in any data 16636 // sharing attribute. 16637 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16638 if (isOpenMPPrivate(DVar.CKind)) { 16639 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16640 << getOpenMPClauseName(DVar.CKind) 16641 << getOpenMPClauseName(OMPC_is_device_ptr) 16642 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16643 reportOriginalDsa(*this, DSAStack, D, DVar); 16644 continue; 16645 } 16646 16647 const Expr *ConflictExpr; 16648 if (DSAStack->checkMappableExprComponentListsForDecl( 16649 D, /*CurrentRegionOnly=*/true, 16650 [&ConflictExpr]( 16651 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16652 OpenMPClauseKind) -> bool { 16653 ConflictExpr = R.front().getAssociatedExpression(); 16654 return true; 16655 })) { 16656 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16657 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16658 << ConflictExpr->getSourceRange(); 16659 continue; 16660 } 16661 16662 // Store the components in the stack so that they can be used to check 16663 // against other clauses later on. 16664 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16665 DSAStack->addMappableExpressionComponents( 16666 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16667 16668 // Record the expression we've just processed. 16669 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16670 16671 // Create a mappable component for the list item. List items in this clause 16672 // only need a component. We use a null declaration to signal fields in 16673 // 'this'. 16674 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16675 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16676 "Unexpected device pointer expression!"); 16677 MVLI.VarBaseDeclarations.push_back( 16678 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16679 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16680 MVLI.VarComponents.back().push_back(MC); 16681 } 16682 16683 if (MVLI.ProcessedVarList.empty()) 16684 return nullptr; 16685 16686 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16687 MVLI.VarBaseDeclarations, 16688 MVLI.VarComponents); 16689 } 16690 16691 OMPClause *Sema::ActOnOpenMPAllocateClause( 16692 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16693 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16694 if (Allocator) { 16695 // OpenMP [2.11.4 allocate Clause, Description] 16696 // allocator is an expression of omp_allocator_handle_t type. 16697 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16698 return nullptr; 16699 16700 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16701 if (AllocatorRes.isInvalid()) 16702 return nullptr; 16703 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16704 DSAStack->getOMPAllocatorHandleT(), 16705 Sema::AA_Initializing, 16706 /*AllowExplicit=*/true); 16707 if (AllocatorRes.isInvalid()) 16708 return nullptr; 16709 Allocator = AllocatorRes.get(); 16710 } else { 16711 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16712 // allocate clauses that appear on a target construct or on constructs in a 16713 // target region must specify an allocator expression unless a requires 16714 // directive with the dynamic_allocators clause is present in the same 16715 // compilation unit. 16716 if (LangOpts.OpenMPIsDevice && 16717 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16718 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16719 } 16720 // Analyze and build list of variables. 16721 SmallVector<Expr *, 8> Vars; 16722 for (Expr *RefExpr : VarList) { 16723 assert(RefExpr && "NULL expr in OpenMP private clause."); 16724 SourceLocation ELoc; 16725 SourceRange ERange; 16726 Expr *SimpleRefExpr = RefExpr; 16727 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16728 if (Res.second) { 16729 // It will be analyzed later. 16730 Vars.push_back(RefExpr); 16731 } 16732 ValueDecl *D = Res.first; 16733 if (!D) 16734 continue; 16735 16736 auto *VD = dyn_cast<VarDecl>(D); 16737 DeclRefExpr *Ref = nullptr; 16738 if (!VD && !CurContext->isDependentContext()) 16739 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16740 Vars.push_back((VD || CurContext->isDependentContext()) 16741 ? RefExpr->IgnoreParens() 16742 : Ref); 16743 } 16744 16745 if (Vars.empty()) 16746 return nullptr; 16747 16748 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16749 ColonLoc, EndLoc, Vars); 16750 } 16751