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 QualType KmpInt32Ty = 3306 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3307 .withConst(); 3308 QualType KmpUInt64Ty = 3309 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3310 .withConst(); 3311 QualType KmpInt64Ty = 3312 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3313 .withConst(); 3314 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3315 QualType KmpInt32PtrTy = 3316 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3317 Sema::CapturedParamNameType ParamsParallel[] = { 3318 std::make_pair(".global_tid.", KmpInt32PtrTy), 3319 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3320 std::make_pair(StringRef(), QualType()) // __context with shared vars 3321 }; 3322 // Start a captured region for 'parallel'. 3323 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3324 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3325 QualType Args[] = {VoidPtrTy}; 3326 FunctionProtoType::ExtProtoInfo EPI; 3327 EPI.Variadic = true; 3328 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3329 Sema::CapturedParamNameType Params[] = { 3330 std::make_pair(".global_tid.", KmpInt32Ty), 3331 std::make_pair(".part_id.", KmpInt32PtrTy), 3332 std::make_pair(".privates.", VoidPtrTy), 3333 std::make_pair( 3334 ".copy_fn.", 3335 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3336 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3337 std::make_pair(".lb.", KmpUInt64Ty), 3338 std::make_pair(".ub.", KmpUInt64Ty), 3339 std::make_pair(".st.", KmpInt64Ty), 3340 std::make_pair(".liter.", KmpInt32Ty), 3341 std::make_pair(".reductions.", VoidPtrTy), 3342 std::make_pair(StringRef(), QualType()) // __context with shared vars 3343 }; 3344 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3345 Params, /*OpenMPCaptureLevel=*/2); 3346 // Mark this captured region as inlined, because we don't use outlined 3347 // function directly. 3348 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3349 AlwaysInlineAttr::CreateImplicit( 3350 Context, {}, AttributeCommonInfo::AS_Keyword, 3351 AlwaysInlineAttr::Keyword_forceinline)); 3352 break; 3353 } 3354 case OMPD_distribute_parallel_for_simd: 3355 case OMPD_distribute_parallel_for: { 3356 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3357 QualType KmpInt32PtrTy = 3358 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3359 Sema::CapturedParamNameType Params[] = { 3360 std::make_pair(".global_tid.", KmpInt32PtrTy), 3361 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3362 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3363 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3364 std::make_pair(StringRef(), QualType()) // __context with shared vars 3365 }; 3366 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3367 Params); 3368 break; 3369 } 3370 case OMPD_target_teams_distribute_parallel_for: 3371 case OMPD_target_teams_distribute_parallel_for_simd: { 3372 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3373 QualType KmpInt32PtrTy = 3374 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3375 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3376 3377 QualType Args[] = {VoidPtrTy}; 3378 FunctionProtoType::ExtProtoInfo EPI; 3379 EPI.Variadic = true; 3380 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3381 Sema::CapturedParamNameType Params[] = { 3382 std::make_pair(".global_tid.", KmpInt32Ty), 3383 std::make_pair(".part_id.", KmpInt32PtrTy), 3384 std::make_pair(".privates.", VoidPtrTy), 3385 std::make_pair( 3386 ".copy_fn.", 3387 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3388 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3389 std::make_pair(StringRef(), QualType()) // __context with shared vars 3390 }; 3391 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3392 Params, /*OpenMPCaptureLevel=*/0); 3393 // Mark this captured region as inlined, because we don't use outlined 3394 // function directly. 3395 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3396 AlwaysInlineAttr::CreateImplicit( 3397 Context, {}, AttributeCommonInfo::AS_Keyword, 3398 AlwaysInlineAttr::Keyword_forceinline)); 3399 Sema::CapturedParamNameType ParamsTarget[] = { 3400 std::make_pair(StringRef(), QualType()) // __context with shared vars 3401 }; 3402 // Start a captured region for 'target' with no implicit parameters. 3403 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3404 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3405 3406 Sema::CapturedParamNameType ParamsTeams[] = { 3407 std::make_pair(".global_tid.", KmpInt32PtrTy), 3408 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3409 std::make_pair(StringRef(), QualType()) // __context with shared vars 3410 }; 3411 // Start a captured region for 'target' with no implicit parameters. 3412 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3413 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3414 3415 Sema::CapturedParamNameType ParamsParallel[] = { 3416 std::make_pair(".global_tid.", KmpInt32PtrTy), 3417 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3418 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3419 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3420 std::make_pair(StringRef(), QualType()) // __context with shared vars 3421 }; 3422 // Start a captured region for 'teams' or 'parallel'. Both regions have 3423 // the same implicit parameters. 3424 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3425 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3426 break; 3427 } 3428 3429 case OMPD_teams_distribute_parallel_for: 3430 case OMPD_teams_distribute_parallel_for_simd: { 3431 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3432 QualType KmpInt32PtrTy = 3433 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3434 3435 Sema::CapturedParamNameType ParamsTeams[] = { 3436 std::make_pair(".global_tid.", KmpInt32PtrTy), 3437 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3438 std::make_pair(StringRef(), QualType()) // __context with shared vars 3439 }; 3440 // Start a captured region for 'target' with no implicit parameters. 3441 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3442 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3443 3444 Sema::CapturedParamNameType ParamsParallel[] = { 3445 std::make_pair(".global_tid.", KmpInt32PtrTy), 3446 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3447 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3448 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3449 std::make_pair(StringRef(), QualType()) // __context with shared vars 3450 }; 3451 // Start a captured region for 'teams' or 'parallel'. Both regions have 3452 // the same implicit parameters. 3453 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3454 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3455 break; 3456 } 3457 case OMPD_target_update: 3458 case OMPD_target_enter_data: 3459 case OMPD_target_exit_data: { 3460 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3461 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3462 QualType KmpInt32PtrTy = 3463 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3464 QualType Args[] = {VoidPtrTy}; 3465 FunctionProtoType::ExtProtoInfo EPI; 3466 EPI.Variadic = true; 3467 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3468 Sema::CapturedParamNameType Params[] = { 3469 std::make_pair(".global_tid.", KmpInt32Ty), 3470 std::make_pair(".part_id.", KmpInt32PtrTy), 3471 std::make_pair(".privates.", VoidPtrTy), 3472 std::make_pair( 3473 ".copy_fn.", 3474 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3475 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3476 std::make_pair(StringRef(), QualType()) // __context with shared vars 3477 }; 3478 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3479 Params); 3480 // Mark this captured region as inlined, because we don't use outlined 3481 // function directly. 3482 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3483 AlwaysInlineAttr::CreateImplicit( 3484 Context, {}, AttributeCommonInfo::AS_Keyword, 3485 AlwaysInlineAttr::Keyword_forceinline)); 3486 break; 3487 } 3488 case OMPD_threadprivate: 3489 case OMPD_allocate: 3490 case OMPD_taskyield: 3491 case OMPD_barrier: 3492 case OMPD_taskwait: 3493 case OMPD_cancellation_point: 3494 case OMPD_cancel: 3495 case OMPD_flush: 3496 case OMPD_declare_reduction: 3497 case OMPD_declare_mapper: 3498 case OMPD_declare_simd: 3499 case OMPD_declare_target: 3500 case OMPD_end_declare_target: 3501 case OMPD_requires: 3502 case OMPD_declare_variant: 3503 llvm_unreachable("OpenMP Directive is not allowed"); 3504 case OMPD_unknown: 3505 llvm_unreachable("Unknown OpenMP directive"); 3506 } 3507 } 3508 3509 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3510 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3511 } 3512 3513 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3514 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3515 getOpenMPCaptureRegions(CaptureRegions, DKind); 3516 return CaptureRegions.size(); 3517 } 3518 3519 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3520 Expr *CaptureExpr, bool WithInit, 3521 bool AsExpression) { 3522 assert(CaptureExpr); 3523 ASTContext &C = S.getASTContext(); 3524 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3525 QualType Ty = Init->getType(); 3526 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3527 if (S.getLangOpts().CPlusPlus) { 3528 Ty = C.getLValueReferenceType(Ty); 3529 } else { 3530 Ty = C.getPointerType(Ty); 3531 ExprResult Res = 3532 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3533 if (!Res.isUsable()) 3534 return nullptr; 3535 Init = Res.get(); 3536 } 3537 WithInit = true; 3538 } 3539 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3540 CaptureExpr->getBeginLoc()); 3541 if (!WithInit) 3542 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3543 S.CurContext->addHiddenDecl(CED); 3544 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3545 return CED; 3546 } 3547 3548 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3549 bool WithInit) { 3550 OMPCapturedExprDecl *CD; 3551 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3552 CD = cast<OMPCapturedExprDecl>(VD); 3553 else 3554 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3555 /*AsExpression=*/false); 3556 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3557 CaptureExpr->getExprLoc()); 3558 } 3559 3560 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3561 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3562 if (!Ref) { 3563 OMPCapturedExprDecl *CD = buildCaptureDecl( 3564 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3565 /*WithInit=*/true, /*AsExpression=*/true); 3566 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3567 CaptureExpr->getExprLoc()); 3568 } 3569 ExprResult Res = Ref; 3570 if (!S.getLangOpts().CPlusPlus && 3571 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3572 Ref->getType()->isPointerType()) { 3573 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3574 if (!Res.isUsable()) 3575 return ExprError(); 3576 } 3577 return S.DefaultLvalueConversion(Res.get()); 3578 } 3579 3580 namespace { 3581 // OpenMP directives parsed in this section are represented as a 3582 // CapturedStatement with an associated statement. If a syntax error 3583 // is detected during the parsing of the associated statement, the 3584 // compiler must abort processing and close the CapturedStatement. 3585 // 3586 // Combined directives such as 'target parallel' have more than one 3587 // nested CapturedStatements. This RAII ensures that we unwind out 3588 // of all the nested CapturedStatements when an error is found. 3589 class CaptureRegionUnwinderRAII { 3590 private: 3591 Sema &S; 3592 bool &ErrorFound; 3593 OpenMPDirectiveKind DKind = OMPD_unknown; 3594 3595 public: 3596 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3597 OpenMPDirectiveKind DKind) 3598 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3599 ~CaptureRegionUnwinderRAII() { 3600 if (ErrorFound) { 3601 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3602 while (--ThisCaptureLevel >= 0) 3603 S.ActOnCapturedRegionError(); 3604 } 3605 } 3606 }; 3607 } // namespace 3608 3609 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3610 // Capture variables captured by reference in lambdas for target-based 3611 // directives. 3612 if (!CurContext->isDependentContext() && 3613 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3614 isOpenMPTargetDataManagementDirective( 3615 DSAStack->getCurrentDirective()))) { 3616 QualType Type = V->getType(); 3617 if (const auto *RD = Type.getCanonicalType() 3618 .getNonReferenceType() 3619 ->getAsCXXRecordDecl()) { 3620 bool SavedForceCaptureByReferenceInTargetExecutable = 3621 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3622 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3623 /*V=*/true); 3624 if (RD->isLambda()) { 3625 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3626 FieldDecl *ThisCapture; 3627 RD->getCaptureFields(Captures, ThisCapture); 3628 for (const LambdaCapture &LC : RD->captures()) { 3629 if (LC.getCaptureKind() == LCK_ByRef) { 3630 VarDecl *VD = LC.getCapturedVar(); 3631 DeclContext *VDC = VD->getDeclContext(); 3632 if (!VDC->Encloses(CurContext)) 3633 continue; 3634 MarkVariableReferenced(LC.getLocation(), VD); 3635 } else if (LC.getCaptureKind() == LCK_This) { 3636 QualType ThisTy = getCurrentThisType(); 3637 if (!ThisTy.isNull() && 3638 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3639 CheckCXXThisCapture(LC.getLocation()); 3640 } 3641 } 3642 } 3643 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3644 SavedForceCaptureByReferenceInTargetExecutable); 3645 } 3646 } 3647 } 3648 3649 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3650 ArrayRef<OMPClause *> Clauses) { 3651 bool ErrorFound = false; 3652 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3653 *this, ErrorFound, DSAStack->getCurrentDirective()); 3654 if (!S.isUsable()) { 3655 ErrorFound = true; 3656 return StmtError(); 3657 } 3658 3659 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3660 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3661 OMPOrderedClause *OC = nullptr; 3662 OMPScheduleClause *SC = nullptr; 3663 SmallVector<const OMPLinearClause *, 4> LCs; 3664 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3665 // This is required for proper codegen. 3666 for (OMPClause *Clause : Clauses) { 3667 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3668 Clause->getClauseKind() == OMPC_in_reduction) { 3669 // Capture taskgroup task_reduction descriptors inside the tasking regions 3670 // with the corresponding in_reduction items. 3671 auto *IRC = cast<OMPInReductionClause>(Clause); 3672 for (Expr *E : IRC->taskgroup_descriptors()) 3673 if (E) 3674 MarkDeclarationsReferencedInExpr(E); 3675 } 3676 if (isOpenMPPrivate(Clause->getClauseKind()) || 3677 Clause->getClauseKind() == OMPC_copyprivate || 3678 (getLangOpts().OpenMPUseTLS && 3679 getASTContext().getTargetInfo().isTLSSupported() && 3680 Clause->getClauseKind() == OMPC_copyin)) { 3681 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3682 // Mark all variables in private list clauses as used in inner region. 3683 for (Stmt *VarRef : Clause->children()) { 3684 if (auto *E = cast_or_null<Expr>(VarRef)) { 3685 MarkDeclarationsReferencedInExpr(E); 3686 } 3687 } 3688 DSAStack->setForceVarCapturing(/*V=*/false); 3689 } else if (CaptureRegions.size() > 1 || 3690 CaptureRegions.back() != OMPD_unknown) { 3691 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3692 PICs.push_back(C); 3693 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3694 if (Expr *E = C->getPostUpdateExpr()) 3695 MarkDeclarationsReferencedInExpr(E); 3696 } 3697 } 3698 if (Clause->getClauseKind() == OMPC_schedule) 3699 SC = cast<OMPScheduleClause>(Clause); 3700 else if (Clause->getClauseKind() == OMPC_ordered) 3701 OC = cast<OMPOrderedClause>(Clause); 3702 else if (Clause->getClauseKind() == OMPC_linear) 3703 LCs.push_back(cast<OMPLinearClause>(Clause)); 3704 } 3705 // OpenMP, 2.7.1 Loop Construct, Restrictions 3706 // The nonmonotonic modifier cannot be specified if an ordered clause is 3707 // specified. 3708 if (SC && 3709 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3710 SC->getSecondScheduleModifier() == 3711 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3712 OC) { 3713 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3714 ? SC->getFirstScheduleModifierLoc() 3715 : SC->getSecondScheduleModifierLoc(), 3716 diag::err_omp_schedule_nonmonotonic_ordered) 3717 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3718 ErrorFound = true; 3719 } 3720 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3721 for (const OMPLinearClause *C : LCs) { 3722 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3723 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3724 } 3725 ErrorFound = true; 3726 } 3727 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3728 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3729 OC->getNumForLoops()) { 3730 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3731 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3732 ErrorFound = true; 3733 } 3734 if (ErrorFound) { 3735 return StmtError(); 3736 } 3737 StmtResult SR = S; 3738 unsigned CompletedRegions = 0; 3739 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3740 // Mark all variables in private list clauses as used in inner region. 3741 // Required for proper codegen of combined directives. 3742 // TODO: add processing for other clauses. 3743 if (ThisCaptureRegion != OMPD_unknown) { 3744 for (const clang::OMPClauseWithPreInit *C : PICs) { 3745 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3746 // Find the particular capture region for the clause if the 3747 // directive is a combined one with multiple capture regions. 3748 // If the directive is not a combined one, the capture region 3749 // associated with the clause is OMPD_unknown and is generated 3750 // only once. 3751 if (CaptureRegion == ThisCaptureRegion || 3752 CaptureRegion == OMPD_unknown) { 3753 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3754 for (Decl *D : DS->decls()) 3755 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3756 } 3757 } 3758 } 3759 } 3760 if (++CompletedRegions == CaptureRegions.size()) 3761 DSAStack->setBodyComplete(); 3762 SR = ActOnCapturedRegionEnd(SR.get()); 3763 } 3764 return SR; 3765 } 3766 3767 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3768 OpenMPDirectiveKind CancelRegion, 3769 SourceLocation StartLoc) { 3770 // CancelRegion is only needed for cancel and cancellation_point. 3771 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3772 return false; 3773 3774 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3775 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3776 return false; 3777 3778 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3779 << getOpenMPDirectiveName(CancelRegion); 3780 return true; 3781 } 3782 3783 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3784 OpenMPDirectiveKind CurrentRegion, 3785 const DeclarationNameInfo &CurrentName, 3786 OpenMPDirectiveKind CancelRegion, 3787 SourceLocation StartLoc) { 3788 if (Stack->getCurScope()) { 3789 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3790 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3791 bool NestingProhibited = false; 3792 bool CloseNesting = true; 3793 bool OrphanSeen = false; 3794 enum { 3795 NoRecommend, 3796 ShouldBeInParallelRegion, 3797 ShouldBeInOrderedRegion, 3798 ShouldBeInTargetRegion, 3799 ShouldBeInTeamsRegion 3800 } Recommend = NoRecommend; 3801 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3802 // OpenMP [2.16, Nesting of Regions] 3803 // OpenMP constructs may not be nested inside a simd region. 3804 // OpenMP [2.8.1,simd Construct, Restrictions] 3805 // An ordered construct with the simd clause is the only OpenMP 3806 // construct that can appear in the simd region. 3807 // Allowing a SIMD construct nested in another SIMD construct is an 3808 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3809 // message. 3810 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3811 ? diag::err_omp_prohibited_region_simd 3812 : diag::warn_omp_nesting_simd); 3813 return CurrentRegion != OMPD_simd; 3814 } 3815 if (ParentRegion == OMPD_atomic) { 3816 // OpenMP [2.16, Nesting of Regions] 3817 // OpenMP constructs may not be nested inside an atomic region. 3818 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3819 return true; 3820 } 3821 if (CurrentRegion == OMPD_section) { 3822 // OpenMP [2.7.2, sections Construct, Restrictions] 3823 // Orphaned section directives are prohibited. That is, the section 3824 // directives must appear within the sections construct and must not be 3825 // encountered elsewhere in the sections region. 3826 if (ParentRegion != OMPD_sections && 3827 ParentRegion != OMPD_parallel_sections) { 3828 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3829 << (ParentRegion != OMPD_unknown) 3830 << getOpenMPDirectiveName(ParentRegion); 3831 return true; 3832 } 3833 return false; 3834 } 3835 // Allow some constructs (except teams and cancellation constructs) to be 3836 // orphaned (they could be used in functions, called from OpenMP regions 3837 // with the required preconditions). 3838 if (ParentRegion == OMPD_unknown && 3839 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3840 CurrentRegion != OMPD_cancellation_point && 3841 CurrentRegion != OMPD_cancel) 3842 return false; 3843 if (CurrentRegion == OMPD_cancellation_point || 3844 CurrentRegion == OMPD_cancel) { 3845 // OpenMP [2.16, Nesting of Regions] 3846 // A cancellation point construct for which construct-type-clause is 3847 // taskgroup must be nested inside a task construct. A cancellation 3848 // point construct for which construct-type-clause is not taskgroup must 3849 // be closely nested inside an OpenMP construct that matches the type 3850 // specified in construct-type-clause. 3851 // A cancel construct for which construct-type-clause is taskgroup must be 3852 // nested inside a task construct. A cancel construct for which 3853 // construct-type-clause is not taskgroup must be closely nested inside an 3854 // OpenMP construct that matches the type specified in 3855 // construct-type-clause. 3856 NestingProhibited = 3857 !((CancelRegion == OMPD_parallel && 3858 (ParentRegion == OMPD_parallel || 3859 ParentRegion == OMPD_target_parallel)) || 3860 (CancelRegion == OMPD_for && 3861 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3862 ParentRegion == OMPD_target_parallel_for || 3863 ParentRegion == OMPD_distribute_parallel_for || 3864 ParentRegion == OMPD_teams_distribute_parallel_for || 3865 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3866 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3867 (CancelRegion == OMPD_sections && 3868 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3869 ParentRegion == OMPD_parallel_sections))); 3870 OrphanSeen = ParentRegion == OMPD_unknown; 3871 } else if (CurrentRegion == OMPD_master) { 3872 // OpenMP [2.16, Nesting of Regions] 3873 // A master region may not be closely nested inside a worksharing, 3874 // atomic, or explicit task region. 3875 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3876 isOpenMPTaskingDirective(ParentRegion); 3877 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3878 // OpenMP [2.16, Nesting of Regions] 3879 // A critical region may not be nested (closely or otherwise) inside a 3880 // critical region with the same name. Note that this restriction is not 3881 // sufficient to prevent deadlock. 3882 SourceLocation PreviousCriticalLoc; 3883 bool DeadLock = Stack->hasDirective( 3884 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3885 const DeclarationNameInfo &DNI, 3886 SourceLocation Loc) { 3887 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3888 PreviousCriticalLoc = Loc; 3889 return true; 3890 } 3891 return false; 3892 }, 3893 false /* skip top directive */); 3894 if (DeadLock) { 3895 SemaRef.Diag(StartLoc, 3896 diag::err_omp_prohibited_region_critical_same_name) 3897 << CurrentName.getName(); 3898 if (PreviousCriticalLoc.isValid()) 3899 SemaRef.Diag(PreviousCriticalLoc, 3900 diag::note_omp_previous_critical_region); 3901 return true; 3902 } 3903 } else if (CurrentRegion == OMPD_barrier) { 3904 // OpenMP [2.16, Nesting of Regions] 3905 // A barrier region may not be closely nested inside a worksharing, 3906 // explicit task, critical, ordered, atomic, or master region. 3907 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3908 isOpenMPTaskingDirective(ParentRegion) || 3909 ParentRegion == OMPD_master || 3910 ParentRegion == OMPD_critical || 3911 ParentRegion == OMPD_ordered; 3912 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3913 !isOpenMPParallelDirective(CurrentRegion) && 3914 !isOpenMPTeamsDirective(CurrentRegion)) { 3915 // OpenMP [2.16, Nesting of Regions] 3916 // A worksharing region may not be closely nested inside a worksharing, 3917 // explicit task, critical, ordered, atomic, or master region. 3918 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3919 isOpenMPTaskingDirective(ParentRegion) || 3920 ParentRegion == OMPD_master || 3921 ParentRegion == OMPD_critical || 3922 ParentRegion == OMPD_ordered; 3923 Recommend = ShouldBeInParallelRegion; 3924 } else if (CurrentRegion == OMPD_ordered) { 3925 // OpenMP [2.16, Nesting of Regions] 3926 // An ordered region may not be closely nested inside a critical, 3927 // atomic, or explicit task region. 3928 // An ordered region must be closely nested inside a loop region (or 3929 // parallel loop region) with an ordered clause. 3930 // OpenMP [2.8.1,simd Construct, Restrictions] 3931 // An ordered construct with the simd clause is the only OpenMP construct 3932 // that can appear in the simd region. 3933 NestingProhibited = ParentRegion == OMPD_critical || 3934 isOpenMPTaskingDirective(ParentRegion) || 3935 !(isOpenMPSimdDirective(ParentRegion) || 3936 Stack->isParentOrderedRegion()); 3937 Recommend = ShouldBeInOrderedRegion; 3938 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3939 // OpenMP [2.16, Nesting of Regions] 3940 // If specified, a teams construct must be contained within a target 3941 // construct. 3942 NestingProhibited = 3943 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 3944 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 3945 ParentRegion != OMPD_target); 3946 OrphanSeen = ParentRegion == OMPD_unknown; 3947 Recommend = ShouldBeInTargetRegion; 3948 } 3949 if (!NestingProhibited && 3950 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3951 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3952 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3953 // OpenMP [2.16, Nesting of Regions] 3954 // distribute, parallel, parallel sections, parallel workshare, and the 3955 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3956 // constructs that can be closely nested in the teams region. 3957 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3958 !isOpenMPDistributeDirective(CurrentRegion); 3959 Recommend = ShouldBeInParallelRegion; 3960 } 3961 if (!NestingProhibited && 3962 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3963 // OpenMP 4.5 [2.17 Nesting of Regions] 3964 // The region associated with the distribute construct must be strictly 3965 // nested inside a teams region 3966 NestingProhibited = 3967 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3968 Recommend = ShouldBeInTeamsRegion; 3969 } 3970 if (!NestingProhibited && 3971 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3972 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3973 // OpenMP 4.5 [2.17 Nesting of Regions] 3974 // If a target, target update, target data, target enter data, or 3975 // target exit data construct is encountered during execution of a 3976 // target region, the behavior is unspecified. 3977 NestingProhibited = Stack->hasDirective( 3978 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3979 SourceLocation) { 3980 if (isOpenMPTargetExecutionDirective(K)) { 3981 OffendingRegion = K; 3982 return true; 3983 } 3984 return false; 3985 }, 3986 false /* don't skip top directive */); 3987 CloseNesting = false; 3988 } 3989 if (NestingProhibited) { 3990 if (OrphanSeen) { 3991 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3992 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3993 } else { 3994 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3995 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3996 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3997 } 3998 return true; 3999 } 4000 } 4001 return false; 4002 } 4003 4004 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4005 ArrayRef<OMPClause *> Clauses, 4006 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4007 bool ErrorFound = false; 4008 unsigned NamedModifiersNumber = 0; 4009 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 4010 OMPD_unknown + 1); 4011 SmallVector<SourceLocation, 4> NameModifierLoc; 4012 for (const OMPClause *C : Clauses) { 4013 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4014 // At most one if clause without a directive-name-modifier can appear on 4015 // the directive. 4016 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4017 if (FoundNameModifiers[CurNM]) { 4018 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4019 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4020 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4021 ErrorFound = true; 4022 } else if (CurNM != OMPD_unknown) { 4023 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4024 ++NamedModifiersNumber; 4025 } 4026 FoundNameModifiers[CurNM] = IC; 4027 if (CurNM == OMPD_unknown) 4028 continue; 4029 // Check if the specified name modifier is allowed for the current 4030 // directive. 4031 // At most one if clause with the particular directive-name-modifier can 4032 // appear on the directive. 4033 bool MatchFound = false; 4034 for (auto NM : AllowedNameModifiers) { 4035 if (CurNM == NM) { 4036 MatchFound = true; 4037 break; 4038 } 4039 } 4040 if (!MatchFound) { 4041 S.Diag(IC->getNameModifierLoc(), 4042 diag::err_omp_wrong_if_directive_name_modifier) 4043 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4044 ErrorFound = true; 4045 } 4046 } 4047 } 4048 // If any if clause on the directive includes a directive-name-modifier then 4049 // all if clauses on the directive must include a directive-name-modifier. 4050 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4051 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4052 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4053 diag::err_omp_no_more_if_clause); 4054 } else { 4055 std::string Values; 4056 std::string Sep(", "); 4057 unsigned AllowedCnt = 0; 4058 unsigned TotalAllowedNum = 4059 AllowedNameModifiers.size() - NamedModifiersNumber; 4060 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4061 ++Cnt) { 4062 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4063 if (!FoundNameModifiers[NM]) { 4064 Values += "'"; 4065 Values += getOpenMPDirectiveName(NM); 4066 Values += "'"; 4067 if (AllowedCnt + 2 == TotalAllowedNum) 4068 Values += " or "; 4069 else if (AllowedCnt + 1 != TotalAllowedNum) 4070 Values += Sep; 4071 ++AllowedCnt; 4072 } 4073 } 4074 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4075 diag::err_omp_unnamed_if_clause) 4076 << (TotalAllowedNum > 1) << Values; 4077 } 4078 for (SourceLocation Loc : NameModifierLoc) { 4079 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4080 } 4081 ErrorFound = true; 4082 } 4083 return ErrorFound; 4084 } 4085 4086 static std::pair<ValueDecl *, bool> 4087 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4088 SourceRange &ERange, bool AllowArraySection = false) { 4089 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4090 RefExpr->containsUnexpandedParameterPack()) 4091 return std::make_pair(nullptr, true); 4092 4093 // OpenMP [3.1, C/C++] 4094 // A list item is a variable name. 4095 // OpenMP [2.9.3.3, Restrictions, p.1] 4096 // A variable that is part of another variable (as an array or 4097 // structure element) cannot appear in a private clause. 4098 RefExpr = RefExpr->IgnoreParens(); 4099 enum { 4100 NoArrayExpr = -1, 4101 ArraySubscript = 0, 4102 OMPArraySection = 1 4103 } IsArrayExpr = NoArrayExpr; 4104 if (AllowArraySection) { 4105 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4106 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4107 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4108 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4109 RefExpr = Base; 4110 IsArrayExpr = ArraySubscript; 4111 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4112 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4113 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4114 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4115 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4116 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4117 RefExpr = Base; 4118 IsArrayExpr = OMPArraySection; 4119 } 4120 } 4121 ELoc = RefExpr->getExprLoc(); 4122 ERange = RefExpr->getSourceRange(); 4123 RefExpr = RefExpr->IgnoreParenImpCasts(); 4124 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4125 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4126 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4127 (S.getCurrentThisType().isNull() || !ME || 4128 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4129 !isa<FieldDecl>(ME->getMemberDecl()))) { 4130 if (IsArrayExpr != NoArrayExpr) { 4131 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4132 << ERange; 4133 } else { 4134 S.Diag(ELoc, 4135 AllowArraySection 4136 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4137 : diag::err_omp_expected_var_name_member_expr) 4138 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4139 } 4140 return std::make_pair(nullptr, false); 4141 } 4142 return std::make_pair( 4143 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4144 } 4145 4146 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4147 ArrayRef<OMPClause *> Clauses) { 4148 assert(!S.CurContext->isDependentContext() && 4149 "Expected non-dependent context."); 4150 auto AllocateRange = 4151 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4152 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4153 DeclToCopy; 4154 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4155 return isOpenMPPrivate(C->getClauseKind()); 4156 }); 4157 for (OMPClause *Cl : PrivateRange) { 4158 MutableArrayRef<Expr *>::iterator I, It, Et; 4159 if (Cl->getClauseKind() == OMPC_private) { 4160 auto *PC = cast<OMPPrivateClause>(Cl); 4161 I = PC->private_copies().begin(); 4162 It = PC->varlist_begin(); 4163 Et = PC->varlist_end(); 4164 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4165 auto *PC = cast<OMPFirstprivateClause>(Cl); 4166 I = PC->private_copies().begin(); 4167 It = PC->varlist_begin(); 4168 Et = PC->varlist_end(); 4169 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4170 auto *PC = cast<OMPLastprivateClause>(Cl); 4171 I = PC->private_copies().begin(); 4172 It = PC->varlist_begin(); 4173 Et = PC->varlist_end(); 4174 } else if (Cl->getClauseKind() == OMPC_linear) { 4175 auto *PC = cast<OMPLinearClause>(Cl); 4176 I = PC->privates().begin(); 4177 It = PC->varlist_begin(); 4178 Et = PC->varlist_end(); 4179 } else if (Cl->getClauseKind() == OMPC_reduction) { 4180 auto *PC = cast<OMPReductionClause>(Cl); 4181 I = PC->privates().begin(); 4182 It = PC->varlist_begin(); 4183 Et = PC->varlist_end(); 4184 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4185 auto *PC = cast<OMPTaskReductionClause>(Cl); 4186 I = PC->privates().begin(); 4187 It = PC->varlist_begin(); 4188 Et = PC->varlist_end(); 4189 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4190 auto *PC = cast<OMPInReductionClause>(Cl); 4191 I = PC->privates().begin(); 4192 It = PC->varlist_begin(); 4193 Et = PC->varlist_end(); 4194 } else { 4195 llvm_unreachable("Expected private clause."); 4196 } 4197 for (Expr *E : llvm::make_range(It, Et)) { 4198 if (!*I) { 4199 ++I; 4200 continue; 4201 } 4202 SourceLocation ELoc; 4203 SourceRange ERange; 4204 Expr *SimpleRefExpr = E; 4205 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4206 /*AllowArraySection=*/true); 4207 DeclToCopy.try_emplace(Res.first, 4208 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4209 ++I; 4210 } 4211 } 4212 for (OMPClause *C : AllocateRange) { 4213 auto *AC = cast<OMPAllocateClause>(C); 4214 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4215 getAllocatorKind(S, Stack, AC->getAllocator()); 4216 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4217 // For task, taskloop or target directives, allocation requests to memory 4218 // allocators with the trait access set to thread result in unspecified 4219 // behavior. 4220 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4221 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4222 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4223 S.Diag(AC->getAllocator()->getExprLoc(), 4224 diag::warn_omp_allocate_thread_on_task_target_directive) 4225 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4226 } 4227 for (Expr *E : AC->varlists()) { 4228 SourceLocation ELoc; 4229 SourceRange ERange; 4230 Expr *SimpleRefExpr = E; 4231 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4232 ValueDecl *VD = Res.first; 4233 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4234 if (!isOpenMPPrivate(Data.CKind)) { 4235 S.Diag(E->getExprLoc(), 4236 diag::err_omp_expected_private_copy_for_allocate); 4237 continue; 4238 } 4239 VarDecl *PrivateVD = DeclToCopy[VD]; 4240 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4241 AllocatorKind, AC->getAllocator())) 4242 continue; 4243 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4244 E->getSourceRange()); 4245 } 4246 } 4247 } 4248 4249 StmtResult Sema::ActOnOpenMPExecutableDirective( 4250 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4251 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4252 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4253 StmtResult Res = StmtError(); 4254 // First check CancelRegion which is then used in checkNestingOfRegions. 4255 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4256 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4257 StartLoc)) 4258 return StmtError(); 4259 4260 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4261 VarsWithInheritedDSAType VarsWithInheritedDSA; 4262 bool ErrorFound = false; 4263 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4264 if (AStmt && !CurContext->isDependentContext()) { 4265 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4266 4267 // Check default data sharing attributes for referenced variables. 4268 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4269 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4270 Stmt *S = AStmt; 4271 while (--ThisCaptureLevel >= 0) 4272 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4273 DSAChecker.Visit(S); 4274 if (!isOpenMPTargetDataManagementDirective(Kind) && 4275 !isOpenMPTaskingDirective(Kind)) { 4276 // Visit subcaptures to generate implicit clauses for captured vars. 4277 auto *CS = cast<CapturedStmt>(AStmt); 4278 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4279 getOpenMPCaptureRegions(CaptureRegions, Kind); 4280 // Ignore outer tasking regions for target directives. 4281 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4282 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4283 DSAChecker.visitSubCaptures(CS); 4284 } 4285 if (DSAChecker.isErrorFound()) 4286 return StmtError(); 4287 // Generate list of implicitly defined firstprivate variables. 4288 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4289 4290 SmallVector<Expr *, 4> ImplicitFirstprivates( 4291 DSAChecker.getImplicitFirstprivate().begin(), 4292 DSAChecker.getImplicitFirstprivate().end()); 4293 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4294 DSAChecker.getImplicitMap().end()); 4295 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4296 for (OMPClause *C : Clauses) { 4297 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4298 for (Expr *E : IRC->taskgroup_descriptors()) 4299 if (E) 4300 ImplicitFirstprivates.emplace_back(E); 4301 } 4302 } 4303 if (!ImplicitFirstprivates.empty()) { 4304 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4305 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4306 SourceLocation())) { 4307 ClausesWithImplicit.push_back(Implicit); 4308 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4309 ImplicitFirstprivates.size(); 4310 } else { 4311 ErrorFound = true; 4312 } 4313 } 4314 if (!ImplicitMaps.empty()) { 4315 CXXScopeSpec MapperIdScopeSpec; 4316 DeclarationNameInfo MapperId; 4317 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4318 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4319 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4320 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4321 ClausesWithImplicit.emplace_back(Implicit); 4322 ErrorFound |= 4323 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4324 } else { 4325 ErrorFound = true; 4326 } 4327 } 4328 } 4329 4330 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4331 switch (Kind) { 4332 case OMPD_parallel: 4333 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4334 EndLoc); 4335 AllowedNameModifiers.push_back(OMPD_parallel); 4336 break; 4337 case OMPD_simd: 4338 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4339 VarsWithInheritedDSA); 4340 break; 4341 case OMPD_for: 4342 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4343 VarsWithInheritedDSA); 4344 break; 4345 case OMPD_for_simd: 4346 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4347 EndLoc, VarsWithInheritedDSA); 4348 break; 4349 case OMPD_sections: 4350 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4351 EndLoc); 4352 break; 4353 case OMPD_section: 4354 assert(ClausesWithImplicit.empty() && 4355 "No clauses are allowed for 'omp section' directive"); 4356 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4357 break; 4358 case OMPD_single: 4359 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4360 EndLoc); 4361 break; 4362 case OMPD_master: 4363 assert(ClausesWithImplicit.empty() && 4364 "No clauses are allowed for 'omp master' directive"); 4365 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4366 break; 4367 case OMPD_critical: 4368 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4369 StartLoc, EndLoc); 4370 break; 4371 case OMPD_parallel_for: 4372 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4373 EndLoc, VarsWithInheritedDSA); 4374 AllowedNameModifiers.push_back(OMPD_parallel); 4375 break; 4376 case OMPD_parallel_for_simd: 4377 Res = ActOnOpenMPParallelForSimdDirective( 4378 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4379 AllowedNameModifiers.push_back(OMPD_parallel); 4380 break; 4381 case OMPD_parallel_sections: 4382 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4383 StartLoc, EndLoc); 4384 AllowedNameModifiers.push_back(OMPD_parallel); 4385 break; 4386 case OMPD_task: 4387 Res = 4388 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4389 AllowedNameModifiers.push_back(OMPD_task); 4390 break; 4391 case OMPD_taskyield: 4392 assert(ClausesWithImplicit.empty() && 4393 "No clauses are allowed for 'omp taskyield' directive"); 4394 assert(AStmt == nullptr && 4395 "No associated statement allowed for 'omp taskyield' directive"); 4396 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4397 break; 4398 case OMPD_barrier: 4399 assert(ClausesWithImplicit.empty() && 4400 "No clauses are allowed for 'omp barrier' directive"); 4401 assert(AStmt == nullptr && 4402 "No associated statement allowed for 'omp barrier' directive"); 4403 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4404 break; 4405 case OMPD_taskwait: 4406 assert(ClausesWithImplicit.empty() && 4407 "No clauses are allowed for 'omp taskwait' directive"); 4408 assert(AStmt == nullptr && 4409 "No associated statement allowed for 'omp taskwait' directive"); 4410 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4411 break; 4412 case OMPD_taskgroup: 4413 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4414 EndLoc); 4415 break; 4416 case OMPD_flush: 4417 assert(AStmt == nullptr && 4418 "No associated statement allowed for 'omp flush' directive"); 4419 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4420 break; 4421 case OMPD_ordered: 4422 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4423 EndLoc); 4424 break; 4425 case OMPD_atomic: 4426 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4427 EndLoc); 4428 break; 4429 case OMPD_teams: 4430 Res = 4431 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4432 break; 4433 case OMPD_target: 4434 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4435 EndLoc); 4436 AllowedNameModifiers.push_back(OMPD_target); 4437 break; 4438 case OMPD_target_parallel: 4439 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4440 StartLoc, EndLoc); 4441 AllowedNameModifiers.push_back(OMPD_target); 4442 AllowedNameModifiers.push_back(OMPD_parallel); 4443 break; 4444 case OMPD_target_parallel_for: 4445 Res = ActOnOpenMPTargetParallelForDirective( 4446 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4447 AllowedNameModifiers.push_back(OMPD_target); 4448 AllowedNameModifiers.push_back(OMPD_parallel); 4449 break; 4450 case OMPD_cancellation_point: 4451 assert(ClausesWithImplicit.empty() && 4452 "No clauses are allowed for 'omp cancellation point' directive"); 4453 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4454 "cancellation point' directive"); 4455 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4456 break; 4457 case OMPD_cancel: 4458 assert(AStmt == nullptr && 4459 "No associated statement allowed for 'omp cancel' directive"); 4460 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4461 CancelRegion); 4462 AllowedNameModifiers.push_back(OMPD_cancel); 4463 break; 4464 case OMPD_target_data: 4465 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4466 EndLoc); 4467 AllowedNameModifiers.push_back(OMPD_target_data); 4468 break; 4469 case OMPD_target_enter_data: 4470 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4471 EndLoc, AStmt); 4472 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4473 break; 4474 case OMPD_target_exit_data: 4475 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4476 EndLoc, AStmt); 4477 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4478 break; 4479 case OMPD_taskloop: 4480 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4481 EndLoc, VarsWithInheritedDSA); 4482 AllowedNameModifiers.push_back(OMPD_taskloop); 4483 break; 4484 case OMPD_taskloop_simd: 4485 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4486 EndLoc, VarsWithInheritedDSA); 4487 AllowedNameModifiers.push_back(OMPD_taskloop); 4488 break; 4489 case OMPD_master_taskloop: 4490 Res = ActOnOpenMPMasterTaskLoopDirective( 4491 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4492 AllowedNameModifiers.push_back(OMPD_taskloop); 4493 break; 4494 case OMPD_master_taskloop_simd: 4495 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4496 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4497 AllowedNameModifiers.push_back(OMPD_taskloop); 4498 break; 4499 case OMPD_parallel_master_taskloop: 4500 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4501 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4502 AllowedNameModifiers.push_back(OMPD_taskloop); 4503 AllowedNameModifiers.push_back(OMPD_parallel); 4504 break; 4505 case OMPD_distribute: 4506 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4507 EndLoc, VarsWithInheritedDSA); 4508 break; 4509 case OMPD_target_update: 4510 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4511 EndLoc, AStmt); 4512 AllowedNameModifiers.push_back(OMPD_target_update); 4513 break; 4514 case OMPD_distribute_parallel_for: 4515 Res = ActOnOpenMPDistributeParallelForDirective( 4516 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4517 AllowedNameModifiers.push_back(OMPD_parallel); 4518 break; 4519 case OMPD_distribute_parallel_for_simd: 4520 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4521 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4522 AllowedNameModifiers.push_back(OMPD_parallel); 4523 break; 4524 case OMPD_distribute_simd: 4525 Res = ActOnOpenMPDistributeSimdDirective( 4526 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4527 break; 4528 case OMPD_target_parallel_for_simd: 4529 Res = ActOnOpenMPTargetParallelForSimdDirective( 4530 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4531 AllowedNameModifiers.push_back(OMPD_target); 4532 AllowedNameModifiers.push_back(OMPD_parallel); 4533 break; 4534 case OMPD_target_simd: 4535 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4536 EndLoc, VarsWithInheritedDSA); 4537 AllowedNameModifiers.push_back(OMPD_target); 4538 break; 4539 case OMPD_teams_distribute: 4540 Res = ActOnOpenMPTeamsDistributeDirective( 4541 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4542 break; 4543 case OMPD_teams_distribute_simd: 4544 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4545 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4546 break; 4547 case OMPD_teams_distribute_parallel_for_simd: 4548 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4549 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4550 AllowedNameModifiers.push_back(OMPD_parallel); 4551 break; 4552 case OMPD_teams_distribute_parallel_for: 4553 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4554 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4555 AllowedNameModifiers.push_back(OMPD_parallel); 4556 break; 4557 case OMPD_target_teams: 4558 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4559 EndLoc); 4560 AllowedNameModifiers.push_back(OMPD_target); 4561 break; 4562 case OMPD_target_teams_distribute: 4563 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4564 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4565 AllowedNameModifiers.push_back(OMPD_target); 4566 break; 4567 case OMPD_target_teams_distribute_parallel_for: 4568 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4569 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4570 AllowedNameModifiers.push_back(OMPD_target); 4571 AllowedNameModifiers.push_back(OMPD_parallel); 4572 break; 4573 case OMPD_target_teams_distribute_parallel_for_simd: 4574 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4575 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4576 AllowedNameModifiers.push_back(OMPD_target); 4577 AllowedNameModifiers.push_back(OMPD_parallel); 4578 break; 4579 case OMPD_target_teams_distribute_simd: 4580 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4581 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4582 AllowedNameModifiers.push_back(OMPD_target); 4583 break; 4584 case OMPD_declare_target: 4585 case OMPD_end_declare_target: 4586 case OMPD_threadprivate: 4587 case OMPD_allocate: 4588 case OMPD_declare_reduction: 4589 case OMPD_declare_mapper: 4590 case OMPD_declare_simd: 4591 case OMPD_requires: 4592 case OMPD_declare_variant: 4593 llvm_unreachable("OpenMP Directive is not allowed"); 4594 case OMPD_unknown: 4595 llvm_unreachable("Unknown OpenMP directive"); 4596 } 4597 4598 ErrorFound = Res.isInvalid() || ErrorFound; 4599 4600 // Check variables in the clauses if default(none) was specified. 4601 if (DSAStack->getDefaultDSA() == DSA_none) { 4602 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4603 for (OMPClause *C : Clauses) { 4604 switch (C->getClauseKind()) { 4605 case OMPC_num_threads: 4606 case OMPC_dist_schedule: 4607 // Do not analyse if no parent teams directive. 4608 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4609 break; 4610 continue; 4611 case OMPC_if: 4612 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4613 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4614 break; 4615 continue; 4616 case OMPC_schedule: 4617 break; 4618 case OMPC_grainsize: 4619 case OMPC_num_tasks: 4620 case OMPC_final: 4621 case OMPC_priority: 4622 // Do not analyze if no parent parallel directive. 4623 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective())) 4624 break; 4625 continue; 4626 case OMPC_ordered: 4627 case OMPC_device: 4628 case OMPC_num_teams: 4629 case OMPC_thread_limit: 4630 case OMPC_hint: 4631 case OMPC_collapse: 4632 case OMPC_safelen: 4633 case OMPC_simdlen: 4634 case OMPC_default: 4635 case OMPC_proc_bind: 4636 case OMPC_private: 4637 case OMPC_firstprivate: 4638 case OMPC_lastprivate: 4639 case OMPC_shared: 4640 case OMPC_reduction: 4641 case OMPC_task_reduction: 4642 case OMPC_in_reduction: 4643 case OMPC_linear: 4644 case OMPC_aligned: 4645 case OMPC_copyin: 4646 case OMPC_copyprivate: 4647 case OMPC_nowait: 4648 case OMPC_untied: 4649 case OMPC_mergeable: 4650 case OMPC_allocate: 4651 case OMPC_read: 4652 case OMPC_write: 4653 case OMPC_update: 4654 case OMPC_capture: 4655 case OMPC_seq_cst: 4656 case OMPC_depend: 4657 case OMPC_threads: 4658 case OMPC_simd: 4659 case OMPC_map: 4660 case OMPC_nogroup: 4661 case OMPC_defaultmap: 4662 case OMPC_to: 4663 case OMPC_from: 4664 case OMPC_use_device_ptr: 4665 case OMPC_is_device_ptr: 4666 continue; 4667 case OMPC_allocator: 4668 case OMPC_flush: 4669 case OMPC_threadprivate: 4670 case OMPC_uniform: 4671 case OMPC_unknown: 4672 case OMPC_unified_address: 4673 case OMPC_unified_shared_memory: 4674 case OMPC_reverse_offload: 4675 case OMPC_dynamic_allocators: 4676 case OMPC_atomic_default_mem_order: 4677 case OMPC_device_type: 4678 case OMPC_match: 4679 llvm_unreachable("Unexpected clause"); 4680 } 4681 for (Stmt *CC : C->children()) { 4682 if (CC) 4683 DSAChecker.Visit(CC); 4684 } 4685 } 4686 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4687 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4688 } 4689 for (const auto &P : VarsWithInheritedDSA) { 4690 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4691 continue; 4692 ErrorFound = true; 4693 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4694 << P.first << P.second->getSourceRange(); 4695 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4696 } 4697 4698 if (!AllowedNameModifiers.empty()) 4699 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4700 ErrorFound; 4701 4702 if (ErrorFound) 4703 return StmtError(); 4704 4705 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4706 Res.getAs<OMPExecutableDirective>() 4707 ->getStructuredBlock() 4708 ->setIsOMPStructuredBlock(true); 4709 } 4710 4711 if (!CurContext->isDependentContext() && 4712 isOpenMPTargetExecutionDirective(Kind) && 4713 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4714 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4715 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4716 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4717 // Register target to DSA Stack. 4718 DSAStack->addTargetDirLocation(StartLoc); 4719 } 4720 4721 return Res; 4722 } 4723 4724 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4725 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4726 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4727 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4728 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4729 assert(Aligneds.size() == Alignments.size()); 4730 assert(Linears.size() == LinModifiers.size()); 4731 assert(Linears.size() == Steps.size()); 4732 if (!DG || DG.get().isNull()) 4733 return DeclGroupPtrTy(); 4734 4735 const int SimdId = 0; 4736 if (!DG.get().isSingleDecl()) { 4737 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4738 << SimdId; 4739 return DG; 4740 } 4741 Decl *ADecl = DG.get().getSingleDecl(); 4742 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4743 ADecl = FTD->getTemplatedDecl(); 4744 4745 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4746 if (!FD) { 4747 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4748 return DeclGroupPtrTy(); 4749 } 4750 4751 // OpenMP [2.8.2, declare simd construct, Description] 4752 // The parameter of the simdlen clause must be a constant positive integer 4753 // expression. 4754 ExprResult SL; 4755 if (Simdlen) 4756 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4757 // OpenMP [2.8.2, declare simd construct, Description] 4758 // The special this pointer can be used as if was one of the arguments to the 4759 // function in any of the linear, aligned, or uniform clauses. 4760 // The uniform clause declares one or more arguments to have an invariant 4761 // value for all concurrent invocations of the function in the execution of a 4762 // single SIMD loop. 4763 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4764 const Expr *UniformedLinearThis = nullptr; 4765 for (const Expr *E : Uniforms) { 4766 E = E->IgnoreParenImpCasts(); 4767 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4768 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4769 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4770 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4771 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4772 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4773 continue; 4774 } 4775 if (isa<CXXThisExpr>(E)) { 4776 UniformedLinearThis = E; 4777 continue; 4778 } 4779 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4780 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4781 } 4782 // OpenMP [2.8.2, declare simd construct, Description] 4783 // The aligned clause declares that the object to which each list item points 4784 // is aligned to the number of bytes expressed in the optional parameter of 4785 // the aligned clause. 4786 // The special this pointer can be used as if was one of the arguments to the 4787 // function in any of the linear, aligned, or uniform clauses. 4788 // The type of list items appearing in the aligned clause must be array, 4789 // pointer, reference to array, or reference to pointer. 4790 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4791 const Expr *AlignedThis = nullptr; 4792 for (const Expr *E : Aligneds) { 4793 E = E->IgnoreParenImpCasts(); 4794 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4795 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4796 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4797 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4798 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4799 ->getCanonicalDecl() == CanonPVD) { 4800 // OpenMP [2.8.1, simd construct, Restrictions] 4801 // A list-item cannot appear in more than one aligned clause. 4802 if (AlignedArgs.count(CanonPVD) > 0) { 4803 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4804 << 1 << E->getSourceRange(); 4805 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4806 diag::note_omp_explicit_dsa) 4807 << getOpenMPClauseName(OMPC_aligned); 4808 continue; 4809 } 4810 AlignedArgs[CanonPVD] = E; 4811 QualType QTy = PVD->getType() 4812 .getNonReferenceType() 4813 .getUnqualifiedType() 4814 .getCanonicalType(); 4815 const Type *Ty = QTy.getTypePtrOrNull(); 4816 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4817 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4818 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4819 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4820 } 4821 continue; 4822 } 4823 } 4824 if (isa<CXXThisExpr>(E)) { 4825 if (AlignedThis) { 4826 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4827 << 2 << E->getSourceRange(); 4828 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4829 << getOpenMPClauseName(OMPC_aligned); 4830 } 4831 AlignedThis = E; 4832 continue; 4833 } 4834 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4835 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4836 } 4837 // The optional parameter of the aligned clause, alignment, must be a constant 4838 // positive integer expression. If no optional parameter is specified, 4839 // implementation-defined default alignments for SIMD instructions on the 4840 // target platforms are assumed. 4841 SmallVector<const Expr *, 4> NewAligns; 4842 for (Expr *E : Alignments) { 4843 ExprResult Align; 4844 if (E) 4845 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4846 NewAligns.push_back(Align.get()); 4847 } 4848 // OpenMP [2.8.2, declare simd construct, Description] 4849 // The linear clause declares one or more list items to be private to a SIMD 4850 // lane and to have a linear relationship with respect to the iteration space 4851 // of a loop. 4852 // The special this pointer can be used as if was one of the arguments to the 4853 // function in any of the linear, aligned, or uniform clauses. 4854 // When a linear-step expression is specified in a linear clause it must be 4855 // either a constant integer expression or an integer-typed parameter that is 4856 // specified in a uniform clause on the directive. 4857 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4858 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4859 auto MI = LinModifiers.begin(); 4860 for (const Expr *E : Linears) { 4861 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4862 ++MI; 4863 E = E->IgnoreParenImpCasts(); 4864 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4865 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4866 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4867 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4868 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4869 ->getCanonicalDecl() == CanonPVD) { 4870 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4871 // A list-item cannot appear in more than one linear clause. 4872 if (LinearArgs.count(CanonPVD) > 0) { 4873 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4874 << getOpenMPClauseName(OMPC_linear) 4875 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4876 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4877 diag::note_omp_explicit_dsa) 4878 << getOpenMPClauseName(OMPC_linear); 4879 continue; 4880 } 4881 // Each argument can appear in at most one uniform or linear clause. 4882 if (UniformedArgs.count(CanonPVD) > 0) { 4883 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4884 << getOpenMPClauseName(OMPC_linear) 4885 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4886 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4887 diag::note_omp_explicit_dsa) 4888 << getOpenMPClauseName(OMPC_uniform); 4889 continue; 4890 } 4891 LinearArgs[CanonPVD] = E; 4892 if (E->isValueDependent() || E->isTypeDependent() || 4893 E->isInstantiationDependent() || 4894 E->containsUnexpandedParameterPack()) 4895 continue; 4896 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4897 PVD->getOriginalType()); 4898 continue; 4899 } 4900 } 4901 if (isa<CXXThisExpr>(E)) { 4902 if (UniformedLinearThis) { 4903 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4904 << getOpenMPClauseName(OMPC_linear) 4905 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4906 << E->getSourceRange(); 4907 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4908 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4909 : OMPC_linear); 4910 continue; 4911 } 4912 UniformedLinearThis = E; 4913 if (E->isValueDependent() || E->isTypeDependent() || 4914 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4915 continue; 4916 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4917 E->getType()); 4918 continue; 4919 } 4920 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4921 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4922 } 4923 Expr *Step = nullptr; 4924 Expr *NewStep = nullptr; 4925 SmallVector<Expr *, 4> NewSteps; 4926 for (Expr *E : Steps) { 4927 // Skip the same step expression, it was checked already. 4928 if (Step == E || !E) { 4929 NewSteps.push_back(E ? NewStep : nullptr); 4930 continue; 4931 } 4932 Step = E; 4933 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4934 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4935 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4936 if (UniformedArgs.count(CanonPVD) == 0) { 4937 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4938 << Step->getSourceRange(); 4939 } else if (E->isValueDependent() || E->isTypeDependent() || 4940 E->isInstantiationDependent() || 4941 E->containsUnexpandedParameterPack() || 4942 CanonPVD->getType()->hasIntegerRepresentation()) { 4943 NewSteps.push_back(Step); 4944 } else { 4945 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4946 << Step->getSourceRange(); 4947 } 4948 continue; 4949 } 4950 NewStep = Step; 4951 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4952 !Step->isInstantiationDependent() && 4953 !Step->containsUnexpandedParameterPack()) { 4954 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4955 .get(); 4956 if (NewStep) 4957 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4958 } 4959 NewSteps.push_back(NewStep); 4960 } 4961 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4962 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4963 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4964 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4965 const_cast<Expr **>(Linears.data()), Linears.size(), 4966 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4967 NewSteps.data(), NewSteps.size(), SR); 4968 ADecl->addAttr(NewAttr); 4969 return DG; 4970 } 4971 4972 Optional<std::pair<FunctionDecl *, Expr *>> 4973 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 4974 Expr *VariantRef, SourceRange SR) { 4975 if (!DG || DG.get().isNull()) 4976 return None; 4977 4978 const int VariantId = 1; 4979 // Must be applied only to single decl. 4980 if (!DG.get().isSingleDecl()) { 4981 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4982 << VariantId << SR; 4983 return None; 4984 } 4985 Decl *ADecl = DG.get().getSingleDecl(); 4986 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4987 ADecl = FTD->getTemplatedDecl(); 4988 4989 // Decl must be a function. 4990 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4991 if (!FD) { 4992 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 4993 << VariantId << SR; 4994 return None; 4995 } 4996 4997 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 4998 return FD->hasAttrs() && 4999 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5000 FD->hasAttr<TargetAttr>()); 5001 }; 5002 // OpenMP is not compatible with CPU-specific attributes. 5003 if (HasMultiVersionAttributes(FD)) { 5004 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5005 << SR; 5006 return None; 5007 } 5008 5009 // Allow #pragma omp declare variant only if the function is not used. 5010 if (FD->isUsed(false)) 5011 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5012 << FD->getLocation(); 5013 5014 // Check if the function was emitted already. 5015 const FunctionDecl *Definition; 5016 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5017 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5018 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5019 << FD->getLocation(); 5020 5021 // The VariantRef must point to function. 5022 if (!VariantRef) { 5023 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5024 return None; 5025 } 5026 5027 // Do not check templates, wait until instantiation. 5028 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5029 VariantRef->containsUnexpandedParameterPack() || 5030 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5031 return std::make_pair(FD, VariantRef); 5032 5033 // Convert VariantRef expression to the type of the original function to 5034 // resolve possible conflicts. 5035 ExprResult VariantRefCast; 5036 if (LangOpts.CPlusPlus) { 5037 QualType FnPtrType; 5038 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5039 if (Method && !Method->isStatic()) { 5040 const Type *ClassType = 5041 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5042 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5043 ExprResult ER; 5044 { 5045 // Build adrr_of unary op to correctly handle type checks for member 5046 // functions. 5047 Sema::TentativeAnalysisScope Trap(*this); 5048 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5049 VariantRef); 5050 } 5051 if (!ER.isUsable()) { 5052 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5053 << VariantId << VariantRef->getSourceRange(); 5054 return None; 5055 } 5056 VariantRef = ER.get(); 5057 } else { 5058 FnPtrType = Context.getPointerType(FD->getType()); 5059 } 5060 ImplicitConversionSequence ICS = 5061 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5062 /*SuppressUserConversions=*/false, 5063 /*AllowExplicit=*/false, 5064 /*InOverloadResolution=*/false, 5065 /*CStyle=*/false, 5066 /*AllowObjCWritebackConversion=*/false); 5067 if (ICS.isFailure()) { 5068 Diag(VariantRef->getExprLoc(), 5069 diag::err_omp_declare_variant_incompat_types) 5070 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 5071 return None; 5072 } 5073 VariantRefCast = PerformImplicitConversion( 5074 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5075 if (!VariantRefCast.isUsable()) 5076 return None; 5077 // Drop previously built artificial addr_of unary op for member functions. 5078 if (Method && !Method->isStatic()) { 5079 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5080 if (auto *UO = dyn_cast<UnaryOperator>( 5081 PossibleAddrOfVariantRef->IgnoreImplicit())) 5082 VariantRefCast = UO->getSubExpr(); 5083 } 5084 } else { 5085 VariantRefCast = VariantRef; 5086 } 5087 5088 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5089 if (!ER.isUsable() || 5090 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5091 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5092 << VariantId << VariantRef->getSourceRange(); 5093 return None; 5094 } 5095 5096 // The VariantRef must point to function. 5097 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5098 if (!DRE) { 5099 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5100 << VariantId << VariantRef->getSourceRange(); 5101 return None; 5102 } 5103 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5104 if (!NewFD) { 5105 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5106 << VariantId << VariantRef->getSourceRange(); 5107 return None; 5108 } 5109 5110 // Check if variant function is not marked with declare variant directive. 5111 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5112 Diag(VariantRef->getExprLoc(), 5113 diag::warn_omp_declare_variant_marked_as_declare_variant) 5114 << VariantRef->getSourceRange(); 5115 SourceRange SR = 5116 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5117 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5118 return None; 5119 } 5120 5121 enum DoesntSupport { 5122 VirtFuncs = 1, 5123 Constructors = 3, 5124 Destructors = 4, 5125 DeletedFuncs = 5, 5126 DefaultedFuncs = 6, 5127 ConstexprFuncs = 7, 5128 ConstevalFuncs = 8, 5129 }; 5130 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5131 if (CXXFD->isVirtual()) { 5132 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5133 << VirtFuncs; 5134 return None; 5135 } 5136 5137 if (isa<CXXConstructorDecl>(FD)) { 5138 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5139 << Constructors; 5140 return None; 5141 } 5142 5143 if (isa<CXXDestructorDecl>(FD)) { 5144 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5145 << Destructors; 5146 return None; 5147 } 5148 } 5149 5150 if (FD->isDeleted()) { 5151 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5152 << DeletedFuncs; 5153 return None; 5154 } 5155 5156 if (FD->isDefaulted()) { 5157 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5158 << DefaultedFuncs; 5159 return None; 5160 } 5161 5162 if (FD->isConstexpr()) { 5163 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5164 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5165 return None; 5166 } 5167 5168 // Check general compatibility. 5169 if (areMultiversionVariantFunctionsCompatible( 5170 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5171 PartialDiagnosticAt( 5172 SR.getBegin(), 5173 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5174 PartialDiagnosticAt( 5175 VariantRef->getExprLoc(), 5176 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5177 PartialDiagnosticAt(VariantRef->getExprLoc(), 5178 PDiag(diag::err_omp_declare_variant_diff) 5179 << FD->getLocation()), 5180 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5181 /*CLinkageMayDiffer=*/true)) 5182 return None; 5183 return std::make_pair(FD, cast<Expr>(DRE)); 5184 } 5185 5186 void Sema::ActOnOpenMPDeclareVariantDirective( 5187 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5188 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { 5189 if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || 5190 Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) 5191 return; 5192 Expr *Score = nullptr; 5193 OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown; 5194 if (Data.CtxScore.isUsable()) { 5195 ST = OMPDeclareVariantAttr::ScoreSpecified; 5196 Score = Data.CtxScore.get(); 5197 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5198 !Score->isInstantiationDependent() && 5199 !Score->containsUnexpandedParameterPack()) { 5200 llvm::APSInt Result; 5201 ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result); 5202 if (ICE.isInvalid()) 5203 return; 5204 } 5205 } 5206 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5207 Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, 5208 Data.ImplVendors.begin(), Data.ImplVendors.size(), SR); 5209 FD->addAttr(NewAttr); 5210 } 5211 5212 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5213 FunctionDecl *Func, 5214 bool MightBeOdrUse) { 5215 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5216 5217 if (!Func->isDependentContext() && Func->hasAttrs()) { 5218 for (OMPDeclareVariantAttr *A : 5219 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5220 // TODO: add checks for active OpenMP context where possible. 5221 Expr *VariantRef = A->getVariantFuncRef(); 5222 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5223 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5224 if (!F->isDefined() && F->isTemplateInstantiation()) 5225 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5226 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5227 } 5228 } 5229 } 5230 5231 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5232 Stmt *AStmt, 5233 SourceLocation StartLoc, 5234 SourceLocation EndLoc) { 5235 if (!AStmt) 5236 return StmtError(); 5237 5238 auto *CS = cast<CapturedStmt>(AStmt); 5239 // 1.2.2 OpenMP Language Terminology 5240 // Structured block - An executable statement with a single entry at the 5241 // top and a single exit at the bottom. 5242 // The point of exit cannot be a branch out of the structured block. 5243 // longjmp() and throw() must not violate the entry/exit criteria. 5244 CS->getCapturedDecl()->setNothrow(); 5245 5246 setFunctionHasBranchProtectedScope(); 5247 5248 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5249 DSAStack->isCancelRegion()); 5250 } 5251 5252 namespace { 5253 /// Iteration space of a single for loop. 5254 struct LoopIterationSpace final { 5255 /// True if the condition operator is the strict compare operator (<, > or 5256 /// !=). 5257 bool IsStrictCompare = false; 5258 /// Condition of the loop. 5259 Expr *PreCond = nullptr; 5260 /// This expression calculates the number of iterations in the loop. 5261 /// It is always possible to calculate it before starting the loop. 5262 Expr *NumIterations = nullptr; 5263 /// The loop counter variable. 5264 Expr *CounterVar = nullptr; 5265 /// Private loop counter variable. 5266 Expr *PrivateCounterVar = nullptr; 5267 /// This is initializer for the initial value of #CounterVar. 5268 Expr *CounterInit = nullptr; 5269 /// This is step for the #CounterVar used to generate its update: 5270 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5271 Expr *CounterStep = nullptr; 5272 /// Should step be subtracted? 5273 bool Subtract = false; 5274 /// Source range of the loop init. 5275 SourceRange InitSrcRange; 5276 /// Source range of the loop condition. 5277 SourceRange CondSrcRange; 5278 /// Source range of the loop increment. 5279 SourceRange IncSrcRange; 5280 /// Minimum value that can have the loop control variable. Used to support 5281 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5282 /// since only such variables can be used in non-loop invariant expressions. 5283 Expr *MinValue = nullptr; 5284 /// Maximum value that can have the loop control variable. Used to support 5285 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5286 /// since only such variables can be used in non-loop invariant expressions. 5287 Expr *MaxValue = nullptr; 5288 /// true, if the lower bound depends on the outer loop control var. 5289 bool IsNonRectangularLB = false; 5290 /// true, if the upper bound depends on the outer loop control var. 5291 bool IsNonRectangularUB = false; 5292 /// Index of the loop this loop depends on and forms non-rectangular loop 5293 /// nest. 5294 unsigned LoopDependentIdx = 0; 5295 /// Final condition for the non-rectangular loop nest support. It is used to 5296 /// check that the number of iterations for this particular counter must be 5297 /// finished. 5298 Expr *FinalCondition = nullptr; 5299 }; 5300 5301 /// Helper class for checking canonical form of the OpenMP loops and 5302 /// extracting iteration space of each loop in the loop nest, that will be used 5303 /// for IR generation. 5304 class OpenMPIterationSpaceChecker { 5305 /// Reference to Sema. 5306 Sema &SemaRef; 5307 /// Data-sharing stack. 5308 DSAStackTy &Stack; 5309 /// A location for diagnostics (when there is no some better location). 5310 SourceLocation DefaultLoc; 5311 /// A location for diagnostics (when increment is not compatible). 5312 SourceLocation ConditionLoc; 5313 /// A source location for referring to loop init later. 5314 SourceRange InitSrcRange; 5315 /// A source location for referring to condition later. 5316 SourceRange ConditionSrcRange; 5317 /// A source location for referring to increment later. 5318 SourceRange IncrementSrcRange; 5319 /// Loop variable. 5320 ValueDecl *LCDecl = nullptr; 5321 /// Reference to loop variable. 5322 Expr *LCRef = nullptr; 5323 /// Lower bound (initializer for the var). 5324 Expr *LB = nullptr; 5325 /// Upper bound. 5326 Expr *UB = nullptr; 5327 /// Loop step (increment). 5328 Expr *Step = nullptr; 5329 /// This flag is true when condition is one of: 5330 /// Var < UB 5331 /// Var <= UB 5332 /// UB > Var 5333 /// UB >= Var 5334 /// This will have no value when the condition is != 5335 llvm::Optional<bool> TestIsLessOp; 5336 /// This flag is true when condition is strict ( < or > ). 5337 bool TestIsStrictOp = false; 5338 /// This flag is true when step is subtracted on each iteration. 5339 bool SubtractStep = false; 5340 /// The outer loop counter this loop depends on (if any). 5341 const ValueDecl *DepDecl = nullptr; 5342 /// Contains number of loop (starts from 1) on which loop counter init 5343 /// expression of this loop depends on. 5344 Optional<unsigned> InitDependOnLC; 5345 /// Contains number of loop (starts from 1) on which loop counter condition 5346 /// expression of this loop depends on. 5347 Optional<unsigned> CondDependOnLC; 5348 /// Checks if the provide statement depends on the loop counter. 5349 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5350 /// Original condition required for checking of the exit condition for 5351 /// non-rectangular loop. 5352 Expr *Condition = nullptr; 5353 5354 public: 5355 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5356 SourceLocation DefaultLoc) 5357 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5358 ConditionLoc(DefaultLoc) {} 5359 /// Check init-expr for canonical loop form and save loop counter 5360 /// variable - #Var and its initialization value - #LB. 5361 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5362 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5363 /// for less/greater and for strict/non-strict comparison. 5364 bool checkAndSetCond(Expr *S); 5365 /// Check incr-expr for canonical loop form and return true if it 5366 /// does not conform, otherwise save loop step (#Step). 5367 bool checkAndSetInc(Expr *S); 5368 /// Return the loop counter variable. 5369 ValueDecl *getLoopDecl() const { return LCDecl; } 5370 /// Return the reference expression to loop counter variable. 5371 Expr *getLoopDeclRefExpr() const { return LCRef; } 5372 /// Source range of the loop init. 5373 SourceRange getInitSrcRange() const { return InitSrcRange; } 5374 /// Source range of the loop condition. 5375 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5376 /// Source range of the loop increment. 5377 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5378 /// True if the step should be subtracted. 5379 bool shouldSubtractStep() const { return SubtractStep; } 5380 /// True, if the compare operator is strict (<, > or !=). 5381 bool isStrictTestOp() const { return TestIsStrictOp; } 5382 /// Build the expression to calculate the number of iterations. 5383 Expr *buildNumIterations( 5384 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5385 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5386 /// Build the precondition expression for the loops. 5387 Expr * 5388 buildPreCond(Scope *S, Expr *Cond, 5389 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5390 /// Build reference expression to the counter be used for codegen. 5391 DeclRefExpr * 5392 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5393 DSAStackTy &DSA) const; 5394 /// Build reference expression to the private counter be used for 5395 /// codegen. 5396 Expr *buildPrivateCounterVar() const; 5397 /// Build initialization of the counter be used for codegen. 5398 Expr *buildCounterInit() const; 5399 /// Build step of the counter be used for codegen. 5400 Expr *buildCounterStep() const; 5401 /// Build loop data with counter value for depend clauses in ordered 5402 /// directives. 5403 Expr * 5404 buildOrderedLoopData(Scope *S, Expr *Counter, 5405 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5406 SourceLocation Loc, Expr *Inc = nullptr, 5407 OverloadedOperatorKind OOK = OO_Amp); 5408 /// Builds the minimum value for the loop counter. 5409 std::pair<Expr *, Expr *> buildMinMaxValues( 5410 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5411 /// Builds final condition for the non-rectangular loops. 5412 Expr *buildFinalCondition(Scope *S) const; 5413 /// Return true if any expression is dependent. 5414 bool dependent() const; 5415 /// Returns true if the initializer forms non-rectangular loop. 5416 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5417 /// Returns true if the condition forms non-rectangular loop. 5418 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5419 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5420 unsigned getLoopDependentIdx() const { 5421 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5422 } 5423 5424 private: 5425 /// Check the right-hand side of an assignment in the increment 5426 /// expression. 5427 bool checkAndSetIncRHS(Expr *RHS); 5428 /// Helper to set loop counter variable and its initializer. 5429 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5430 bool EmitDiags); 5431 /// Helper to set upper bound. 5432 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5433 SourceRange SR, SourceLocation SL); 5434 /// Helper to set loop increment. 5435 bool setStep(Expr *NewStep, bool Subtract); 5436 }; 5437 5438 bool OpenMPIterationSpaceChecker::dependent() const { 5439 if (!LCDecl) { 5440 assert(!LB && !UB && !Step); 5441 return false; 5442 } 5443 return LCDecl->getType()->isDependentType() || 5444 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5445 (Step && Step->isValueDependent()); 5446 } 5447 5448 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5449 Expr *NewLCRefExpr, 5450 Expr *NewLB, bool EmitDiags) { 5451 // State consistency checking to ensure correct usage. 5452 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5453 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5454 if (!NewLCDecl || !NewLB) 5455 return true; 5456 LCDecl = getCanonicalDecl(NewLCDecl); 5457 LCRef = NewLCRefExpr; 5458 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5459 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5460 if ((Ctor->isCopyOrMoveConstructor() || 5461 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5462 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5463 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5464 LB = NewLB; 5465 if (EmitDiags) 5466 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5467 return false; 5468 } 5469 5470 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5471 llvm::Optional<bool> LessOp, 5472 bool StrictOp, SourceRange SR, 5473 SourceLocation SL) { 5474 // State consistency checking to ensure correct usage. 5475 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5476 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5477 if (!NewUB) 5478 return true; 5479 UB = NewUB; 5480 if (LessOp) 5481 TestIsLessOp = LessOp; 5482 TestIsStrictOp = StrictOp; 5483 ConditionSrcRange = SR; 5484 ConditionLoc = SL; 5485 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5486 return false; 5487 } 5488 5489 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5490 // State consistency checking to ensure correct usage. 5491 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5492 if (!NewStep) 5493 return true; 5494 if (!NewStep->isValueDependent()) { 5495 // Check that the step is integer expression. 5496 SourceLocation StepLoc = NewStep->getBeginLoc(); 5497 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5498 StepLoc, getExprAsWritten(NewStep)); 5499 if (Val.isInvalid()) 5500 return true; 5501 NewStep = Val.get(); 5502 5503 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5504 // If test-expr is of form var relational-op b and relational-op is < or 5505 // <= then incr-expr must cause var to increase on each iteration of the 5506 // loop. If test-expr is of form var relational-op b and relational-op is 5507 // > or >= then incr-expr must cause var to decrease on each iteration of 5508 // the loop. 5509 // If test-expr is of form b relational-op var and relational-op is < or 5510 // <= then incr-expr must cause var to decrease on each iteration of the 5511 // loop. If test-expr is of form b relational-op var and relational-op is 5512 // > or >= then incr-expr must cause var to increase on each iteration of 5513 // the loop. 5514 llvm::APSInt Result; 5515 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5516 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5517 bool IsConstNeg = 5518 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5519 bool IsConstPos = 5520 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5521 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5522 5523 // != with increment is treated as <; != with decrement is treated as > 5524 if (!TestIsLessOp.hasValue()) 5525 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5526 if (UB && (IsConstZero || 5527 (TestIsLessOp.getValue() ? 5528 (IsConstNeg || (IsUnsigned && Subtract)) : 5529 (IsConstPos || (IsUnsigned && !Subtract))))) { 5530 SemaRef.Diag(NewStep->getExprLoc(), 5531 diag::err_omp_loop_incr_not_compatible) 5532 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5533 SemaRef.Diag(ConditionLoc, 5534 diag::note_omp_loop_cond_requres_compatible_incr) 5535 << TestIsLessOp.getValue() << ConditionSrcRange; 5536 return true; 5537 } 5538 if (TestIsLessOp.getValue() == Subtract) { 5539 NewStep = 5540 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5541 .get(); 5542 Subtract = !Subtract; 5543 } 5544 } 5545 5546 Step = NewStep; 5547 SubtractStep = Subtract; 5548 return false; 5549 } 5550 5551 namespace { 5552 /// Checker for the non-rectangular loops. Checks if the initializer or 5553 /// condition expression references loop counter variable. 5554 class LoopCounterRefChecker final 5555 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5556 Sema &SemaRef; 5557 DSAStackTy &Stack; 5558 const ValueDecl *CurLCDecl = nullptr; 5559 const ValueDecl *DepDecl = nullptr; 5560 const ValueDecl *PrevDepDecl = nullptr; 5561 bool IsInitializer = true; 5562 unsigned BaseLoopId = 0; 5563 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5564 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5565 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5566 << (IsInitializer ? 0 : 1); 5567 return false; 5568 } 5569 const auto &&Data = Stack.isLoopControlVariable(VD); 5570 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5571 // The type of the loop iterator on which we depend may not have a random 5572 // access iterator type. 5573 if (Data.first && VD->getType()->isRecordType()) { 5574 SmallString<128> Name; 5575 llvm::raw_svector_ostream OS(Name); 5576 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5577 /*Qualified=*/true); 5578 SemaRef.Diag(E->getExprLoc(), 5579 diag::err_omp_wrong_dependency_iterator_type) 5580 << OS.str(); 5581 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5582 return false; 5583 } 5584 if (Data.first && 5585 (DepDecl || (PrevDepDecl && 5586 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5587 if (!DepDecl && PrevDepDecl) 5588 DepDecl = PrevDepDecl; 5589 SmallString<128> Name; 5590 llvm::raw_svector_ostream OS(Name); 5591 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5592 /*Qualified=*/true); 5593 SemaRef.Diag(E->getExprLoc(), 5594 diag::err_omp_invariant_or_linear_dependency) 5595 << OS.str(); 5596 return false; 5597 } 5598 if (Data.first) { 5599 DepDecl = VD; 5600 BaseLoopId = Data.first; 5601 } 5602 return Data.first; 5603 } 5604 5605 public: 5606 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5607 const ValueDecl *VD = E->getDecl(); 5608 if (isa<VarDecl>(VD)) 5609 return checkDecl(E, VD); 5610 return false; 5611 } 5612 bool VisitMemberExpr(const MemberExpr *E) { 5613 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5614 const ValueDecl *VD = E->getMemberDecl(); 5615 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5616 return checkDecl(E, VD); 5617 } 5618 return false; 5619 } 5620 bool VisitStmt(const Stmt *S) { 5621 bool Res = false; 5622 for (const Stmt *Child : S->children()) 5623 Res = (Child && Visit(Child)) || Res; 5624 return Res; 5625 } 5626 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5627 const ValueDecl *CurLCDecl, bool IsInitializer, 5628 const ValueDecl *PrevDepDecl = nullptr) 5629 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5630 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5631 unsigned getBaseLoopId() const { 5632 assert(CurLCDecl && "Expected loop dependency."); 5633 return BaseLoopId; 5634 } 5635 const ValueDecl *getDepDecl() const { 5636 assert(CurLCDecl && "Expected loop dependency."); 5637 return DepDecl; 5638 } 5639 }; 5640 } // namespace 5641 5642 Optional<unsigned> 5643 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5644 bool IsInitializer) { 5645 // Check for the non-rectangular loops. 5646 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5647 DepDecl); 5648 if (LoopStmtChecker.Visit(S)) { 5649 DepDecl = LoopStmtChecker.getDepDecl(); 5650 return LoopStmtChecker.getBaseLoopId(); 5651 } 5652 return llvm::None; 5653 } 5654 5655 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5656 // Check init-expr for canonical loop form and save loop counter 5657 // variable - #Var and its initialization value - #LB. 5658 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5659 // var = lb 5660 // integer-type var = lb 5661 // random-access-iterator-type var = lb 5662 // pointer-type var = lb 5663 // 5664 if (!S) { 5665 if (EmitDiags) { 5666 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5667 } 5668 return true; 5669 } 5670 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5671 if (!ExprTemp->cleanupsHaveSideEffects()) 5672 S = ExprTemp->getSubExpr(); 5673 5674 InitSrcRange = S->getSourceRange(); 5675 if (Expr *E = dyn_cast<Expr>(S)) 5676 S = E->IgnoreParens(); 5677 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5678 if (BO->getOpcode() == BO_Assign) { 5679 Expr *LHS = BO->getLHS()->IgnoreParens(); 5680 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5681 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5682 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5683 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5684 EmitDiags); 5685 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5686 } 5687 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5688 if (ME->isArrow() && 5689 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5690 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5691 EmitDiags); 5692 } 5693 } 5694 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5695 if (DS->isSingleDecl()) { 5696 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5697 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5698 // Accept non-canonical init form here but emit ext. warning. 5699 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5700 SemaRef.Diag(S->getBeginLoc(), 5701 diag::ext_omp_loop_not_canonical_init) 5702 << S->getSourceRange(); 5703 return setLCDeclAndLB( 5704 Var, 5705 buildDeclRefExpr(SemaRef, Var, 5706 Var->getType().getNonReferenceType(), 5707 DS->getBeginLoc()), 5708 Var->getInit(), EmitDiags); 5709 } 5710 } 5711 } 5712 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5713 if (CE->getOperator() == OO_Equal) { 5714 Expr *LHS = CE->getArg(0); 5715 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5716 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5717 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5718 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5719 EmitDiags); 5720 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5721 } 5722 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5723 if (ME->isArrow() && 5724 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5725 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5726 EmitDiags); 5727 } 5728 } 5729 } 5730 5731 if (dependent() || SemaRef.CurContext->isDependentContext()) 5732 return false; 5733 if (EmitDiags) { 5734 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5735 << S->getSourceRange(); 5736 } 5737 return true; 5738 } 5739 5740 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5741 /// variable (which may be the loop variable) if possible. 5742 static const ValueDecl *getInitLCDecl(const Expr *E) { 5743 if (!E) 5744 return nullptr; 5745 E = getExprAsWritten(E); 5746 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5747 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5748 if ((Ctor->isCopyOrMoveConstructor() || 5749 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5750 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5751 E = CE->getArg(0)->IgnoreParenImpCasts(); 5752 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5753 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5754 return getCanonicalDecl(VD); 5755 } 5756 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5757 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5758 return getCanonicalDecl(ME->getMemberDecl()); 5759 return nullptr; 5760 } 5761 5762 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5763 // Check test-expr for canonical form, save upper-bound UB, flags for 5764 // less/greater and for strict/non-strict comparison. 5765 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5766 // var relational-op b 5767 // b relational-op var 5768 // 5769 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5770 if (!S) { 5771 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5772 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5773 return true; 5774 } 5775 Condition = S; 5776 S = getExprAsWritten(S); 5777 SourceLocation CondLoc = S->getBeginLoc(); 5778 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5779 if (BO->isRelationalOp()) { 5780 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5781 return setUB(BO->getRHS(), 5782 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5783 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5784 BO->getSourceRange(), BO->getOperatorLoc()); 5785 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5786 return setUB(BO->getLHS(), 5787 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5788 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5789 BO->getSourceRange(), BO->getOperatorLoc()); 5790 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5791 return setUB( 5792 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5793 /*LessOp=*/llvm::None, 5794 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5795 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5796 if (CE->getNumArgs() == 2) { 5797 auto Op = CE->getOperator(); 5798 switch (Op) { 5799 case OO_Greater: 5800 case OO_GreaterEqual: 5801 case OO_Less: 5802 case OO_LessEqual: 5803 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5804 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5805 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5806 CE->getOperatorLoc()); 5807 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5808 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5809 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5810 CE->getOperatorLoc()); 5811 break; 5812 case OO_ExclaimEqual: 5813 if (IneqCondIsCanonical) 5814 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5815 : CE->getArg(0), 5816 /*LessOp=*/llvm::None, 5817 /*StrictOp=*/true, CE->getSourceRange(), 5818 CE->getOperatorLoc()); 5819 break; 5820 default: 5821 break; 5822 } 5823 } 5824 } 5825 if (dependent() || SemaRef.CurContext->isDependentContext()) 5826 return false; 5827 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5828 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5829 return true; 5830 } 5831 5832 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5833 // RHS of canonical loop form increment can be: 5834 // var + incr 5835 // incr + var 5836 // var - incr 5837 // 5838 RHS = RHS->IgnoreParenImpCasts(); 5839 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5840 if (BO->isAdditiveOp()) { 5841 bool IsAdd = BO->getOpcode() == BO_Add; 5842 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5843 return setStep(BO->getRHS(), !IsAdd); 5844 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5845 return setStep(BO->getLHS(), /*Subtract=*/false); 5846 } 5847 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5848 bool IsAdd = CE->getOperator() == OO_Plus; 5849 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5850 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5851 return setStep(CE->getArg(1), !IsAdd); 5852 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5853 return setStep(CE->getArg(0), /*Subtract=*/false); 5854 } 5855 } 5856 if (dependent() || SemaRef.CurContext->isDependentContext()) 5857 return false; 5858 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5859 << RHS->getSourceRange() << LCDecl; 5860 return true; 5861 } 5862 5863 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5864 // Check incr-expr for canonical loop form and return true if it 5865 // does not conform. 5866 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5867 // ++var 5868 // var++ 5869 // --var 5870 // var-- 5871 // var += incr 5872 // var -= incr 5873 // var = var + incr 5874 // var = incr + var 5875 // var = var - incr 5876 // 5877 if (!S) { 5878 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5879 return true; 5880 } 5881 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5882 if (!ExprTemp->cleanupsHaveSideEffects()) 5883 S = ExprTemp->getSubExpr(); 5884 5885 IncrementSrcRange = S->getSourceRange(); 5886 S = S->IgnoreParens(); 5887 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5888 if (UO->isIncrementDecrementOp() && 5889 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5890 return setStep(SemaRef 5891 .ActOnIntegerConstant(UO->getBeginLoc(), 5892 (UO->isDecrementOp() ? -1 : 1)) 5893 .get(), 5894 /*Subtract=*/false); 5895 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5896 switch (BO->getOpcode()) { 5897 case BO_AddAssign: 5898 case BO_SubAssign: 5899 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5900 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5901 break; 5902 case BO_Assign: 5903 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5904 return checkAndSetIncRHS(BO->getRHS()); 5905 break; 5906 default: 5907 break; 5908 } 5909 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5910 switch (CE->getOperator()) { 5911 case OO_PlusPlus: 5912 case OO_MinusMinus: 5913 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5914 return setStep(SemaRef 5915 .ActOnIntegerConstant( 5916 CE->getBeginLoc(), 5917 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5918 .get(), 5919 /*Subtract=*/false); 5920 break; 5921 case OO_PlusEqual: 5922 case OO_MinusEqual: 5923 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5924 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5925 break; 5926 case OO_Equal: 5927 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5928 return checkAndSetIncRHS(CE->getArg(1)); 5929 break; 5930 default: 5931 break; 5932 } 5933 } 5934 if (dependent() || SemaRef.CurContext->isDependentContext()) 5935 return false; 5936 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5937 << S->getSourceRange() << LCDecl; 5938 return true; 5939 } 5940 5941 static ExprResult 5942 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5943 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5944 if (SemaRef.CurContext->isDependentContext()) 5945 return ExprResult(Capture); 5946 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5947 return SemaRef.PerformImplicitConversion( 5948 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5949 /*AllowExplicit=*/true); 5950 auto I = Captures.find(Capture); 5951 if (I != Captures.end()) 5952 return buildCapture(SemaRef, Capture, I->second); 5953 DeclRefExpr *Ref = nullptr; 5954 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5955 Captures[Capture] = Ref; 5956 return Res; 5957 } 5958 5959 /// Build the expression to calculate the number of iterations. 5960 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5961 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5962 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5963 ExprResult Diff; 5964 QualType VarType = LCDecl->getType().getNonReferenceType(); 5965 if (VarType->isIntegerType() || VarType->isPointerType() || 5966 SemaRef.getLangOpts().CPlusPlus) { 5967 Expr *LBVal = LB; 5968 Expr *UBVal = UB; 5969 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5970 // max(LB(MinVal), LB(MaxVal)) 5971 if (InitDependOnLC) { 5972 const LoopIterationSpace &IS = 5973 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5974 InitDependOnLC.getValueOr( 5975 CondDependOnLC.getValueOr(0))]; 5976 if (!IS.MinValue || !IS.MaxValue) 5977 return nullptr; 5978 // OuterVar = Min 5979 ExprResult MinValue = 5980 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5981 if (!MinValue.isUsable()) 5982 return nullptr; 5983 5984 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5985 IS.CounterVar, MinValue.get()); 5986 if (!LBMinVal.isUsable()) 5987 return nullptr; 5988 // OuterVar = Min, LBVal 5989 LBMinVal = 5990 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5991 if (!LBMinVal.isUsable()) 5992 return nullptr; 5993 // (OuterVar = Min, LBVal) 5994 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5995 if (!LBMinVal.isUsable()) 5996 return nullptr; 5997 5998 // OuterVar = Max 5999 ExprResult MaxValue = 6000 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6001 if (!MaxValue.isUsable()) 6002 return nullptr; 6003 6004 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6005 IS.CounterVar, MaxValue.get()); 6006 if (!LBMaxVal.isUsable()) 6007 return nullptr; 6008 // OuterVar = Max, LBVal 6009 LBMaxVal = 6010 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6011 if (!LBMaxVal.isUsable()) 6012 return nullptr; 6013 // (OuterVar = Max, LBVal) 6014 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6015 if (!LBMaxVal.isUsable()) 6016 return nullptr; 6017 6018 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6019 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6020 if (!LBMin || !LBMax) 6021 return nullptr; 6022 // LB(MinVal) < LB(MaxVal) 6023 ExprResult MinLessMaxRes = 6024 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6025 if (!MinLessMaxRes.isUsable()) 6026 return nullptr; 6027 Expr *MinLessMax = 6028 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6029 if (!MinLessMax) 6030 return nullptr; 6031 if (TestIsLessOp.getValue()) { 6032 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6033 // LB(MaxVal)) 6034 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6035 MinLessMax, LBMin, LBMax); 6036 if (!MinLB.isUsable()) 6037 return nullptr; 6038 LBVal = MinLB.get(); 6039 } else { 6040 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6041 // LB(MaxVal)) 6042 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6043 MinLessMax, LBMax, LBMin); 6044 if (!MaxLB.isUsable()) 6045 return nullptr; 6046 LBVal = MaxLB.get(); 6047 } 6048 } 6049 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6050 // min(UB(MinVal), UB(MaxVal)) 6051 if (CondDependOnLC) { 6052 const LoopIterationSpace &IS = 6053 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6054 InitDependOnLC.getValueOr( 6055 CondDependOnLC.getValueOr(0))]; 6056 if (!IS.MinValue || !IS.MaxValue) 6057 return nullptr; 6058 // OuterVar = Min 6059 ExprResult MinValue = 6060 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6061 if (!MinValue.isUsable()) 6062 return nullptr; 6063 6064 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6065 IS.CounterVar, MinValue.get()); 6066 if (!UBMinVal.isUsable()) 6067 return nullptr; 6068 // OuterVar = Min, UBVal 6069 UBMinVal = 6070 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6071 if (!UBMinVal.isUsable()) 6072 return nullptr; 6073 // (OuterVar = Min, UBVal) 6074 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6075 if (!UBMinVal.isUsable()) 6076 return nullptr; 6077 6078 // OuterVar = Max 6079 ExprResult MaxValue = 6080 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6081 if (!MaxValue.isUsable()) 6082 return nullptr; 6083 6084 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6085 IS.CounterVar, MaxValue.get()); 6086 if (!UBMaxVal.isUsable()) 6087 return nullptr; 6088 // OuterVar = Max, UBVal 6089 UBMaxVal = 6090 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6091 if (!UBMaxVal.isUsable()) 6092 return nullptr; 6093 // (OuterVar = Max, UBVal) 6094 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6095 if (!UBMaxVal.isUsable()) 6096 return nullptr; 6097 6098 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6099 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6100 if (!UBMin || !UBMax) 6101 return nullptr; 6102 // UB(MinVal) > UB(MaxVal) 6103 ExprResult MinGreaterMaxRes = 6104 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6105 if (!MinGreaterMaxRes.isUsable()) 6106 return nullptr; 6107 Expr *MinGreaterMax = 6108 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6109 if (!MinGreaterMax) 6110 return nullptr; 6111 if (TestIsLessOp.getValue()) { 6112 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6113 // UB(MaxVal)) 6114 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6115 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6116 if (!MaxUB.isUsable()) 6117 return nullptr; 6118 UBVal = MaxUB.get(); 6119 } else { 6120 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6121 // UB(MaxVal)) 6122 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6123 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6124 if (!MinUB.isUsable()) 6125 return nullptr; 6126 UBVal = MinUB.get(); 6127 } 6128 } 6129 // Upper - Lower 6130 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6131 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6132 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6133 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6134 if (!Upper || !Lower) 6135 return nullptr; 6136 6137 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6138 6139 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6140 // BuildBinOp already emitted error, this one is to point user to upper 6141 // and lower bound, and to tell what is passed to 'operator-'. 6142 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6143 << Upper->getSourceRange() << Lower->getSourceRange(); 6144 return nullptr; 6145 } 6146 } 6147 6148 if (!Diff.isUsable()) 6149 return nullptr; 6150 6151 // Upper - Lower [- 1] 6152 if (TestIsStrictOp) 6153 Diff = SemaRef.BuildBinOp( 6154 S, DefaultLoc, BO_Sub, Diff.get(), 6155 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6156 if (!Diff.isUsable()) 6157 return nullptr; 6158 6159 // Upper - Lower [- 1] + Step 6160 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6161 if (!NewStep.isUsable()) 6162 return nullptr; 6163 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6164 if (!Diff.isUsable()) 6165 return nullptr; 6166 6167 // Parentheses (for dumping/debugging purposes only). 6168 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6169 if (!Diff.isUsable()) 6170 return nullptr; 6171 6172 // (Upper - Lower [- 1] + Step) / Step 6173 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6174 if (!Diff.isUsable()) 6175 return nullptr; 6176 6177 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6178 QualType Type = Diff.get()->getType(); 6179 ASTContext &C = SemaRef.Context; 6180 bool UseVarType = VarType->hasIntegerRepresentation() && 6181 C.getTypeSize(Type) > C.getTypeSize(VarType); 6182 if (!Type->isIntegerType() || UseVarType) { 6183 unsigned NewSize = 6184 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6185 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6186 : Type->hasSignedIntegerRepresentation(); 6187 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6188 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6189 Diff = SemaRef.PerformImplicitConversion( 6190 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6191 if (!Diff.isUsable()) 6192 return nullptr; 6193 } 6194 } 6195 if (LimitedType) { 6196 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6197 if (NewSize != C.getTypeSize(Type)) { 6198 if (NewSize < C.getTypeSize(Type)) { 6199 assert(NewSize == 64 && "incorrect loop var size"); 6200 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6201 << InitSrcRange << ConditionSrcRange; 6202 } 6203 QualType NewType = C.getIntTypeForBitwidth( 6204 NewSize, Type->hasSignedIntegerRepresentation() || 6205 C.getTypeSize(Type) < NewSize); 6206 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6207 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6208 Sema::AA_Converting, true); 6209 if (!Diff.isUsable()) 6210 return nullptr; 6211 } 6212 } 6213 } 6214 6215 return Diff.get(); 6216 } 6217 6218 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6219 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6220 // Do not build for iterators, they cannot be used in non-rectangular loop 6221 // nests. 6222 if (LCDecl->getType()->isRecordType()) 6223 return std::make_pair(nullptr, nullptr); 6224 // If we subtract, the min is in the condition, otherwise the min is in the 6225 // init value. 6226 Expr *MinExpr = nullptr; 6227 Expr *MaxExpr = nullptr; 6228 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6229 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6230 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6231 : CondDependOnLC.hasValue(); 6232 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6233 : InitDependOnLC.hasValue(); 6234 Expr *Lower = 6235 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6236 Expr *Upper = 6237 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6238 if (!Upper || !Lower) 6239 return std::make_pair(nullptr, nullptr); 6240 6241 if (TestIsLessOp.getValue()) 6242 MinExpr = Lower; 6243 else 6244 MaxExpr = Upper; 6245 6246 // Build minimum/maximum value based on number of iterations. 6247 ExprResult Diff; 6248 QualType VarType = LCDecl->getType().getNonReferenceType(); 6249 6250 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6251 if (!Diff.isUsable()) 6252 return std::make_pair(nullptr, nullptr); 6253 6254 // Upper - Lower [- 1] 6255 if (TestIsStrictOp) 6256 Diff = SemaRef.BuildBinOp( 6257 S, DefaultLoc, BO_Sub, Diff.get(), 6258 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6259 if (!Diff.isUsable()) 6260 return std::make_pair(nullptr, nullptr); 6261 6262 // Upper - Lower [- 1] + Step 6263 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6264 if (!NewStep.isUsable()) 6265 return std::make_pair(nullptr, nullptr); 6266 6267 // Parentheses (for dumping/debugging purposes only). 6268 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6269 if (!Diff.isUsable()) 6270 return std::make_pair(nullptr, nullptr); 6271 6272 // (Upper - Lower [- 1]) / Step 6273 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6274 if (!Diff.isUsable()) 6275 return std::make_pair(nullptr, nullptr); 6276 6277 // ((Upper - Lower [- 1]) / Step) * Step 6278 // Parentheses (for dumping/debugging purposes only). 6279 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6280 if (!Diff.isUsable()) 6281 return std::make_pair(nullptr, nullptr); 6282 6283 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6284 if (!Diff.isUsable()) 6285 return std::make_pair(nullptr, nullptr); 6286 6287 // Convert to the original type or ptrdiff_t, if original type is pointer. 6288 if (!VarType->isAnyPointerType() && 6289 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6290 Diff = SemaRef.PerformImplicitConversion( 6291 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6292 } else if (VarType->isAnyPointerType() && 6293 !SemaRef.Context.hasSameType( 6294 Diff.get()->getType(), 6295 SemaRef.Context.getUnsignedPointerDiffType())) { 6296 Diff = SemaRef.PerformImplicitConversion( 6297 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6298 Sema::AA_Converting, /*AllowExplicit=*/true); 6299 } 6300 if (!Diff.isUsable()) 6301 return std::make_pair(nullptr, nullptr); 6302 6303 // Parentheses (for dumping/debugging purposes only). 6304 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6305 if (!Diff.isUsable()) 6306 return std::make_pair(nullptr, nullptr); 6307 6308 if (TestIsLessOp.getValue()) { 6309 // MinExpr = Lower; 6310 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6311 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6312 if (!Diff.isUsable()) 6313 return std::make_pair(nullptr, nullptr); 6314 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6315 if (!Diff.isUsable()) 6316 return std::make_pair(nullptr, nullptr); 6317 MaxExpr = Diff.get(); 6318 } else { 6319 // MaxExpr = Upper; 6320 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6321 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6322 if (!Diff.isUsable()) 6323 return std::make_pair(nullptr, nullptr); 6324 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6325 if (!Diff.isUsable()) 6326 return std::make_pair(nullptr, nullptr); 6327 MinExpr = Diff.get(); 6328 } 6329 6330 return std::make_pair(MinExpr, MaxExpr); 6331 } 6332 6333 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6334 if (InitDependOnLC || CondDependOnLC) 6335 return Condition; 6336 return nullptr; 6337 } 6338 6339 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6340 Scope *S, Expr *Cond, 6341 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6342 // Do not build a precondition when the condition/initialization is dependent 6343 // to prevent pessimistic early loop exit. 6344 // TODO: this can be improved by calculating min/max values but not sure that 6345 // it will be very effective. 6346 if (CondDependOnLC || InitDependOnLC) 6347 return SemaRef.PerformImplicitConversion( 6348 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6349 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6350 /*AllowExplicit=*/true).get(); 6351 6352 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6353 Sema::TentativeAnalysisScope Trap(SemaRef); 6354 6355 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6356 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6357 if (!NewLB.isUsable() || !NewUB.isUsable()) 6358 return nullptr; 6359 6360 ExprResult CondExpr = 6361 SemaRef.BuildBinOp(S, DefaultLoc, 6362 TestIsLessOp.getValue() ? 6363 (TestIsStrictOp ? BO_LT : BO_LE) : 6364 (TestIsStrictOp ? BO_GT : BO_GE), 6365 NewLB.get(), NewUB.get()); 6366 if (CondExpr.isUsable()) { 6367 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6368 SemaRef.Context.BoolTy)) 6369 CondExpr = SemaRef.PerformImplicitConversion( 6370 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6371 /*AllowExplicit=*/true); 6372 } 6373 6374 // Otherwise use original loop condition and evaluate it in runtime. 6375 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6376 } 6377 6378 /// Build reference expression to the counter be used for codegen. 6379 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6380 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6381 DSAStackTy &DSA) const { 6382 auto *VD = dyn_cast<VarDecl>(LCDecl); 6383 if (!VD) { 6384 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6385 DeclRefExpr *Ref = buildDeclRefExpr( 6386 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6387 const DSAStackTy::DSAVarData Data = 6388 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6389 // If the loop control decl is explicitly marked as private, do not mark it 6390 // as captured again. 6391 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6392 Captures.insert(std::make_pair(LCRef, Ref)); 6393 return Ref; 6394 } 6395 return cast<DeclRefExpr>(LCRef); 6396 } 6397 6398 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6399 if (LCDecl && !LCDecl->isInvalidDecl()) { 6400 QualType Type = LCDecl->getType().getNonReferenceType(); 6401 VarDecl *PrivateVar = buildVarDecl( 6402 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6403 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6404 isa<VarDecl>(LCDecl) 6405 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6406 : nullptr); 6407 if (PrivateVar->isInvalidDecl()) 6408 return nullptr; 6409 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6410 } 6411 return nullptr; 6412 } 6413 6414 /// Build initialization of the counter to be used for codegen. 6415 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6416 6417 /// Build step of the counter be used for codegen. 6418 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6419 6420 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6421 Scope *S, Expr *Counter, 6422 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6423 Expr *Inc, OverloadedOperatorKind OOK) { 6424 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6425 if (!Cnt) 6426 return nullptr; 6427 if (Inc) { 6428 assert((OOK == OO_Plus || OOK == OO_Minus) && 6429 "Expected only + or - operations for depend clauses."); 6430 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6431 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6432 if (!Cnt) 6433 return nullptr; 6434 } 6435 ExprResult Diff; 6436 QualType VarType = LCDecl->getType().getNonReferenceType(); 6437 if (VarType->isIntegerType() || VarType->isPointerType() || 6438 SemaRef.getLangOpts().CPlusPlus) { 6439 // Upper - Lower 6440 Expr *Upper = TestIsLessOp.getValue() 6441 ? Cnt 6442 : tryBuildCapture(SemaRef, UB, Captures).get(); 6443 Expr *Lower = TestIsLessOp.getValue() 6444 ? tryBuildCapture(SemaRef, LB, Captures).get() 6445 : Cnt; 6446 if (!Upper || !Lower) 6447 return nullptr; 6448 6449 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6450 6451 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6452 // BuildBinOp already emitted error, this one is to point user to upper 6453 // and lower bound, and to tell what is passed to 'operator-'. 6454 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6455 << Upper->getSourceRange() << Lower->getSourceRange(); 6456 return nullptr; 6457 } 6458 } 6459 6460 if (!Diff.isUsable()) 6461 return nullptr; 6462 6463 // Parentheses (for dumping/debugging purposes only). 6464 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6465 if (!Diff.isUsable()) 6466 return nullptr; 6467 6468 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6469 if (!NewStep.isUsable()) 6470 return nullptr; 6471 // (Upper - Lower) / Step 6472 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6473 if (!Diff.isUsable()) 6474 return nullptr; 6475 6476 return Diff.get(); 6477 } 6478 } // namespace 6479 6480 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6481 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6482 assert(Init && "Expected loop in canonical form."); 6483 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6484 if (AssociatedLoops > 0 && 6485 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6486 DSAStack->loopStart(); 6487 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6488 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6489 if (ValueDecl *D = ISC.getLoopDecl()) { 6490 auto *VD = dyn_cast<VarDecl>(D); 6491 DeclRefExpr *PrivateRef = nullptr; 6492 if (!VD) { 6493 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6494 VD = Private; 6495 } else { 6496 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6497 /*WithInit=*/false); 6498 VD = cast<VarDecl>(PrivateRef->getDecl()); 6499 } 6500 } 6501 DSAStack->addLoopControlVariable(D, VD); 6502 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6503 if (LD != D->getCanonicalDecl()) { 6504 DSAStack->resetPossibleLoopCounter(); 6505 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6506 MarkDeclarationsReferencedInExpr( 6507 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6508 Var->getType().getNonLValueExprType(Context), 6509 ForLoc, /*RefersToCapture=*/true)); 6510 } 6511 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6512 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6513 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6514 // associated for-loop of a simd construct with just one associated 6515 // for-loop may be listed in a linear clause with a constant-linear-step 6516 // that is the increment of the associated for-loop. The loop iteration 6517 // variable(s) in the associated for-loop(s) of a for or parallel for 6518 // construct may be listed in a private or lastprivate clause. 6519 DSAStackTy::DSAVarData DVar = 6520 DSAStack->getTopDSA(D, /*FromParent=*/false); 6521 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6522 // is declared in the loop and it is predetermined as a private. 6523 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6524 OpenMPClauseKind PredeterminedCKind = 6525 isOpenMPSimdDirective(DKind) 6526 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6527 : OMPC_private; 6528 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6529 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6530 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6531 DVar.CKind != OMPC_private))) || 6532 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6533 DKind == OMPD_master_taskloop || 6534 DKind == OMPD_parallel_master_taskloop || 6535 isOpenMPDistributeDirective(DKind)) && 6536 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6537 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6538 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6539 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6540 << getOpenMPClauseName(DVar.CKind) 6541 << getOpenMPDirectiveName(DKind) 6542 << getOpenMPClauseName(PredeterminedCKind); 6543 if (DVar.RefExpr == nullptr) 6544 DVar.CKind = PredeterminedCKind; 6545 reportOriginalDsa(*this, DSAStack, D, DVar, 6546 /*IsLoopIterVar=*/true); 6547 } else if (LoopDeclRefExpr) { 6548 // Make the loop iteration variable private (for worksharing 6549 // constructs), linear (for simd directives with the only one 6550 // associated loop) or lastprivate (for simd directives with several 6551 // collapsed or ordered loops). 6552 if (DVar.CKind == OMPC_unknown) 6553 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6554 PrivateRef); 6555 } 6556 } 6557 } 6558 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6559 } 6560 } 6561 6562 /// Called on a for stmt to check and extract its iteration space 6563 /// for further processing (such as collapsing). 6564 static bool checkOpenMPIterationSpace( 6565 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6566 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6567 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6568 Expr *OrderedLoopCountExpr, 6569 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6570 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6571 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6572 // OpenMP [2.9.1, Canonical Loop Form] 6573 // for (init-expr; test-expr; incr-expr) structured-block 6574 // for (range-decl: range-expr) structured-block 6575 auto *For = dyn_cast_or_null<ForStmt>(S); 6576 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6577 // Ranged for is supported only in OpenMP 5.0. 6578 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6579 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6580 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6581 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6582 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6583 if (TotalNestedLoopCount > 1) { 6584 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6585 SemaRef.Diag(DSA.getConstructLoc(), 6586 diag::note_omp_collapse_ordered_expr) 6587 << 2 << CollapseLoopCountExpr->getSourceRange() 6588 << OrderedLoopCountExpr->getSourceRange(); 6589 else if (CollapseLoopCountExpr) 6590 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6591 diag::note_omp_collapse_ordered_expr) 6592 << 0 << CollapseLoopCountExpr->getSourceRange(); 6593 else 6594 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6595 diag::note_omp_collapse_ordered_expr) 6596 << 1 << OrderedLoopCountExpr->getSourceRange(); 6597 } 6598 return true; 6599 } 6600 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6601 "No loop body."); 6602 6603 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6604 For ? For->getForLoc() : CXXFor->getForLoc()); 6605 6606 // Check init. 6607 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6608 if (ISC.checkAndSetInit(Init)) 6609 return true; 6610 6611 bool HasErrors = false; 6612 6613 // Check loop variable's type. 6614 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6615 // OpenMP [2.6, Canonical Loop Form] 6616 // Var is one of the following: 6617 // A variable of signed or unsigned integer type. 6618 // For C++, a variable of a random access iterator type. 6619 // For C, a variable of a pointer type. 6620 QualType VarType = LCDecl->getType().getNonReferenceType(); 6621 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6622 !VarType->isPointerType() && 6623 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6624 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6625 << SemaRef.getLangOpts().CPlusPlus; 6626 HasErrors = true; 6627 } 6628 6629 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6630 // a Construct 6631 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6632 // parallel for construct is (are) private. 6633 // The loop iteration variable in the associated for-loop of a simd 6634 // construct with just one associated for-loop is linear with a 6635 // constant-linear-step that is the increment of the associated for-loop. 6636 // Exclude loop var from the list of variables with implicitly defined data 6637 // sharing attributes. 6638 VarsWithImplicitDSA.erase(LCDecl); 6639 6640 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6641 6642 // Check test-expr. 6643 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6644 6645 // Check incr-expr. 6646 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6647 } 6648 6649 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6650 return HasErrors; 6651 6652 // Build the loop's iteration space representation. 6653 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6654 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6655 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6656 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6657 (isOpenMPWorksharingDirective(DKind) || 6658 isOpenMPTaskLoopDirective(DKind) || 6659 isOpenMPDistributeDirective(DKind)), 6660 Captures); 6661 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6662 ISC.buildCounterVar(Captures, DSA); 6663 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6664 ISC.buildPrivateCounterVar(); 6665 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6666 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6667 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6668 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6669 ISC.getConditionSrcRange(); 6670 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6671 ISC.getIncrementSrcRange(); 6672 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6673 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6674 ISC.isStrictTestOp(); 6675 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6676 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6677 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6678 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6679 ISC.buildFinalCondition(DSA.getCurScope()); 6680 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6681 ISC.doesInitDependOnLC(); 6682 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6683 ISC.doesCondDependOnLC(); 6684 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6685 ISC.getLoopDependentIdx(); 6686 6687 HasErrors |= 6688 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6689 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6690 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6691 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6692 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6693 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6694 if (!HasErrors && DSA.isOrderedRegion()) { 6695 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6696 if (CurrentNestedLoopCount < 6697 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6698 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6699 CurrentNestedLoopCount, 6700 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6701 DSA.getOrderedRegionParam().second->setLoopCounter( 6702 CurrentNestedLoopCount, 6703 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6704 } 6705 } 6706 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6707 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6708 // Erroneous case - clause has some problems. 6709 continue; 6710 } 6711 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6712 Pair.second.size() <= CurrentNestedLoopCount) { 6713 // Erroneous case - clause has some problems. 6714 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6715 continue; 6716 } 6717 Expr *CntValue; 6718 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6719 CntValue = ISC.buildOrderedLoopData( 6720 DSA.getCurScope(), 6721 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6722 Pair.first->getDependencyLoc()); 6723 else 6724 CntValue = ISC.buildOrderedLoopData( 6725 DSA.getCurScope(), 6726 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6727 Pair.first->getDependencyLoc(), 6728 Pair.second[CurrentNestedLoopCount].first, 6729 Pair.second[CurrentNestedLoopCount].second); 6730 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6731 } 6732 } 6733 6734 return HasErrors; 6735 } 6736 6737 /// Build 'VarRef = Start. 6738 static ExprResult 6739 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6740 ExprResult Start, bool IsNonRectangularLB, 6741 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6742 // Build 'VarRef = Start. 6743 ExprResult NewStart = IsNonRectangularLB 6744 ? Start.get() 6745 : tryBuildCapture(SemaRef, Start.get(), Captures); 6746 if (!NewStart.isUsable()) 6747 return ExprError(); 6748 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6749 VarRef.get()->getType())) { 6750 NewStart = SemaRef.PerformImplicitConversion( 6751 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6752 /*AllowExplicit=*/true); 6753 if (!NewStart.isUsable()) 6754 return ExprError(); 6755 } 6756 6757 ExprResult Init = 6758 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6759 return Init; 6760 } 6761 6762 /// Build 'VarRef = Start + Iter * Step'. 6763 static ExprResult buildCounterUpdate( 6764 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6765 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6766 bool IsNonRectangularLB, 6767 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6768 // Add parentheses (for debugging purposes only). 6769 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6770 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6771 !Step.isUsable()) 6772 return ExprError(); 6773 6774 ExprResult NewStep = Step; 6775 if (Captures) 6776 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6777 if (NewStep.isInvalid()) 6778 return ExprError(); 6779 ExprResult Update = 6780 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6781 if (!Update.isUsable()) 6782 return ExprError(); 6783 6784 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6785 // 'VarRef = Start (+|-) Iter * Step'. 6786 if (!Start.isUsable()) 6787 return ExprError(); 6788 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6789 if (!NewStart.isUsable()) 6790 return ExprError(); 6791 if (Captures && !IsNonRectangularLB) 6792 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6793 if (NewStart.isInvalid()) 6794 return ExprError(); 6795 6796 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6797 ExprResult SavedUpdate = Update; 6798 ExprResult UpdateVal; 6799 if (VarRef.get()->getType()->isOverloadableType() || 6800 NewStart.get()->getType()->isOverloadableType() || 6801 Update.get()->getType()->isOverloadableType()) { 6802 Sema::TentativeAnalysisScope Trap(SemaRef); 6803 6804 Update = 6805 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6806 if (Update.isUsable()) { 6807 UpdateVal = 6808 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6809 VarRef.get(), SavedUpdate.get()); 6810 if (UpdateVal.isUsable()) { 6811 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6812 UpdateVal.get()); 6813 } 6814 } 6815 } 6816 6817 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6818 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6819 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6820 NewStart.get(), SavedUpdate.get()); 6821 if (!Update.isUsable()) 6822 return ExprError(); 6823 6824 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6825 VarRef.get()->getType())) { 6826 Update = SemaRef.PerformImplicitConversion( 6827 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6828 if (!Update.isUsable()) 6829 return ExprError(); 6830 } 6831 6832 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6833 } 6834 return Update; 6835 } 6836 6837 /// Convert integer expression \a E to make it have at least \a Bits 6838 /// bits. 6839 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6840 if (E == nullptr) 6841 return ExprError(); 6842 ASTContext &C = SemaRef.Context; 6843 QualType OldType = E->getType(); 6844 unsigned HasBits = C.getTypeSize(OldType); 6845 if (HasBits >= Bits) 6846 return ExprResult(E); 6847 // OK to convert to signed, because new type has more bits than old. 6848 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6849 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6850 true); 6851 } 6852 6853 /// Check if the given expression \a E is a constant integer that fits 6854 /// into \a Bits bits. 6855 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6856 if (E == nullptr) 6857 return false; 6858 llvm::APSInt Result; 6859 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6860 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6861 return false; 6862 } 6863 6864 /// Build preinits statement for the given declarations. 6865 static Stmt *buildPreInits(ASTContext &Context, 6866 MutableArrayRef<Decl *> PreInits) { 6867 if (!PreInits.empty()) { 6868 return new (Context) DeclStmt( 6869 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6870 SourceLocation(), SourceLocation()); 6871 } 6872 return nullptr; 6873 } 6874 6875 /// Build preinits statement for the given declarations. 6876 static Stmt * 6877 buildPreInits(ASTContext &Context, 6878 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6879 if (!Captures.empty()) { 6880 SmallVector<Decl *, 16> PreInits; 6881 for (const auto &Pair : Captures) 6882 PreInits.push_back(Pair.second->getDecl()); 6883 return buildPreInits(Context, PreInits); 6884 } 6885 return nullptr; 6886 } 6887 6888 /// Build postupdate expression for the given list of postupdates expressions. 6889 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6890 Expr *PostUpdate = nullptr; 6891 if (!PostUpdates.empty()) { 6892 for (Expr *E : PostUpdates) { 6893 Expr *ConvE = S.BuildCStyleCastExpr( 6894 E->getExprLoc(), 6895 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6896 E->getExprLoc(), E) 6897 .get(); 6898 PostUpdate = PostUpdate 6899 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6900 PostUpdate, ConvE) 6901 .get() 6902 : ConvE; 6903 } 6904 } 6905 return PostUpdate; 6906 } 6907 6908 /// Called on a for stmt to check itself and nested loops (if any). 6909 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6910 /// number of collapsed loops otherwise. 6911 static unsigned 6912 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6913 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6914 DSAStackTy &DSA, 6915 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6916 OMPLoopDirective::HelperExprs &Built) { 6917 unsigned NestedLoopCount = 1; 6918 if (CollapseLoopCountExpr) { 6919 // Found 'collapse' clause - calculate collapse number. 6920 Expr::EvalResult Result; 6921 if (!CollapseLoopCountExpr->isValueDependent() && 6922 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6923 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6924 } else { 6925 Built.clear(/*Size=*/1); 6926 return 1; 6927 } 6928 } 6929 unsigned OrderedLoopCount = 1; 6930 if (OrderedLoopCountExpr) { 6931 // Found 'ordered' clause - calculate collapse number. 6932 Expr::EvalResult EVResult; 6933 if (!OrderedLoopCountExpr->isValueDependent() && 6934 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6935 SemaRef.getASTContext())) { 6936 llvm::APSInt Result = EVResult.Val.getInt(); 6937 if (Result.getLimitedValue() < NestedLoopCount) { 6938 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6939 diag::err_omp_wrong_ordered_loop_count) 6940 << OrderedLoopCountExpr->getSourceRange(); 6941 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6942 diag::note_collapse_loop_count) 6943 << CollapseLoopCountExpr->getSourceRange(); 6944 } 6945 OrderedLoopCount = Result.getLimitedValue(); 6946 } else { 6947 Built.clear(/*Size=*/1); 6948 return 1; 6949 } 6950 } 6951 // This is helper routine for loop directives (e.g., 'for', 'simd', 6952 // 'for simd', etc.). 6953 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6954 SmallVector<LoopIterationSpace, 4> IterSpaces( 6955 std::max(OrderedLoopCount, NestedLoopCount)); 6956 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6957 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6958 if (checkOpenMPIterationSpace( 6959 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6960 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6961 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6962 return 0; 6963 // Move on to the next nested for loop, or to the loop body. 6964 // OpenMP [2.8.1, simd construct, Restrictions] 6965 // All loops associated with the construct must be perfectly nested; that 6966 // is, there must be no intervening code nor any OpenMP directive between 6967 // any two loops. 6968 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6969 CurStmt = For->getBody(); 6970 } else { 6971 assert(isa<CXXForRangeStmt>(CurStmt) && 6972 "Expected canonical for or range-based for loops."); 6973 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6974 } 6975 CurStmt = CurStmt->IgnoreContainers(); 6976 } 6977 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6978 if (checkOpenMPIterationSpace( 6979 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6980 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6981 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6982 return 0; 6983 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6984 // Handle initialization of captured loop iterator variables. 6985 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6986 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6987 Captures[DRE] = DRE; 6988 } 6989 } 6990 // Move on to the next nested for loop, or to the loop body. 6991 // OpenMP [2.8.1, simd construct, Restrictions] 6992 // All loops associated with the construct must be perfectly nested; that 6993 // is, there must be no intervening code nor any OpenMP directive between 6994 // any two loops. 6995 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6996 CurStmt = For->getBody(); 6997 } else { 6998 assert(isa<CXXForRangeStmt>(CurStmt) && 6999 "Expected canonical for or range-based for loops."); 7000 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7001 } 7002 CurStmt = CurStmt->IgnoreContainers(); 7003 } 7004 7005 Built.clear(/* size */ NestedLoopCount); 7006 7007 if (SemaRef.CurContext->isDependentContext()) 7008 return NestedLoopCount; 7009 7010 // An example of what is generated for the following code: 7011 // 7012 // #pragma omp simd collapse(2) ordered(2) 7013 // for (i = 0; i < NI; ++i) 7014 // for (k = 0; k < NK; ++k) 7015 // for (j = J0; j < NJ; j+=2) { 7016 // <loop body> 7017 // } 7018 // 7019 // We generate the code below. 7020 // Note: the loop body may be outlined in CodeGen. 7021 // Note: some counters may be C++ classes, operator- is used to find number of 7022 // iterations and operator+= to calculate counter value. 7023 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7024 // or i64 is currently supported). 7025 // 7026 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7027 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7028 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7029 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7030 // // similar updates for vars in clauses (e.g. 'linear') 7031 // <loop body (using local i and j)> 7032 // } 7033 // i = NI; // assign final values of counters 7034 // j = NJ; 7035 // 7036 7037 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7038 // the iteration counts of the collapsed for loops. 7039 // Precondition tests if there is at least one iteration (all conditions are 7040 // true). 7041 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7042 Expr *N0 = IterSpaces[0].NumIterations; 7043 ExprResult LastIteration32 = 7044 widenIterationCount(/*Bits=*/32, 7045 SemaRef 7046 .PerformImplicitConversion( 7047 N0->IgnoreImpCasts(), N0->getType(), 7048 Sema::AA_Converting, /*AllowExplicit=*/true) 7049 .get(), 7050 SemaRef); 7051 ExprResult LastIteration64 = widenIterationCount( 7052 /*Bits=*/64, 7053 SemaRef 7054 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7055 Sema::AA_Converting, 7056 /*AllowExplicit=*/true) 7057 .get(), 7058 SemaRef); 7059 7060 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7061 return NestedLoopCount; 7062 7063 ASTContext &C = SemaRef.Context; 7064 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7065 7066 Scope *CurScope = DSA.getCurScope(); 7067 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7068 if (PreCond.isUsable()) { 7069 PreCond = 7070 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7071 PreCond.get(), IterSpaces[Cnt].PreCond); 7072 } 7073 Expr *N = IterSpaces[Cnt].NumIterations; 7074 SourceLocation Loc = N->getExprLoc(); 7075 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7076 if (LastIteration32.isUsable()) 7077 LastIteration32 = SemaRef.BuildBinOp( 7078 CurScope, Loc, BO_Mul, LastIteration32.get(), 7079 SemaRef 7080 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7081 Sema::AA_Converting, 7082 /*AllowExplicit=*/true) 7083 .get()); 7084 if (LastIteration64.isUsable()) 7085 LastIteration64 = SemaRef.BuildBinOp( 7086 CurScope, Loc, BO_Mul, LastIteration64.get(), 7087 SemaRef 7088 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7089 Sema::AA_Converting, 7090 /*AllowExplicit=*/true) 7091 .get()); 7092 } 7093 7094 // Choose either the 32-bit or 64-bit version. 7095 ExprResult LastIteration = LastIteration64; 7096 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7097 (LastIteration32.isUsable() && 7098 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7099 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7100 fitsInto( 7101 /*Bits=*/32, 7102 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7103 LastIteration64.get(), SemaRef)))) 7104 LastIteration = LastIteration32; 7105 QualType VType = LastIteration.get()->getType(); 7106 QualType RealVType = VType; 7107 QualType StrideVType = VType; 7108 if (isOpenMPTaskLoopDirective(DKind)) { 7109 VType = 7110 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7111 StrideVType = 7112 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7113 } 7114 7115 if (!LastIteration.isUsable()) 7116 return 0; 7117 7118 // Save the number of iterations. 7119 ExprResult NumIterations = LastIteration; 7120 { 7121 LastIteration = SemaRef.BuildBinOp( 7122 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7123 LastIteration.get(), 7124 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7125 if (!LastIteration.isUsable()) 7126 return 0; 7127 } 7128 7129 // Calculate the last iteration number beforehand instead of doing this on 7130 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7131 llvm::APSInt Result; 7132 bool IsConstant = 7133 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7134 ExprResult CalcLastIteration; 7135 if (!IsConstant) { 7136 ExprResult SaveRef = 7137 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7138 LastIteration = SaveRef; 7139 7140 // Prepare SaveRef + 1. 7141 NumIterations = SemaRef.BuildBinOp( 7142 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7143 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7144 if (!NumIterations.isUsable()) 7145 return 0; 7146 } 7147 7148 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7149 7150 // Build variables passed into runtime, necessary for worksharing directives. 7151 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7152 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7153 isOpenMPDistributeDirective(DKind)) { 7154 // Lower bound variable, initialized with zero. 7155 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7156 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7157 SemaRef.AddInitializerToDecl(LBDecl, 7158 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7159 /*DirectInit*/ false); 7160 7161 // Upper bound variable, initialized with last iteration number. 7162 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7163 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7164 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7165 /*DirectInit*/ false); 7166 7167 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7168 // This will be used to implement clause 'lastprivate'. 7169 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7170 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7171 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7172 SemaRef.AddInitializerToDecl(ILDecl, 7173 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7174 /*DirectInit*/ false); 7175 7176 // Stride variable returned by runtime (we initialize it to 1 by default). 7177 VarDecl *STDecl = 7178 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7179 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7180 SemaRef.AddInitializerToDecl(STDecl, 7181 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7182 /*DirectInit*/ false); 7183 7184 // Build expression: UB = min(UB, LastIteration) 7185 // It is necessary for CodeGen of directives with static scheduling. 7186 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7187 UB.get(), LastIteration.get()); 7188 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7189 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7190 LastIteration.get(), UB.get()); 7191 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7192 CondOp.get()); 7193 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7194 7195 // If we have a combined directive that combines 'distribute', 'for' or 7196 // 'simd' we need to be able to access the bounds of the schedule of the 7197 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7198 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7199 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7200 // Lower bound variable, initialized with zero. 7201 VarDecl *CombLBDecl = 7202 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7203 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7204 SemaRef.AddInitializerToDecl( 7205 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7206 /*DirectInit*/ false); 7207 7208 // Upper bound variable, initialized with last iteration number. 7209 VarDecl *CombUBDecl = 7210 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7211 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7212 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7213 /*DirectInit*/ false); 7214 7215 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7216 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7217 ExprResult CombCondOp = 7218 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7219 LastIteration.get(), CombUB.get()); 7220 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7221 CombCondOp.get()); 7222 CombEUB = 7223 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7224 7225 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7226 // We expect to have at least 2 more parameters than the 'parallel' 7227 // directive does - the lower and upper bounds of the previous schedule. 7228 assert(CD->getNumParams() >= 4 && 7229 "Unexpected number of parameters in loop combined directive"); 7230 7231 // Set the proper type for the bounds given what we learned from the 7232 // enclosed loops. 7233 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7234 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7235 7236 // Previous lower and upper bounds are obtained from the region 7237 // parameters. 7238 PrevLB = 7239 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7240 PrevUB = 7241 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7242 } 7243 } 7244 7245 // Build the iteration variable and its initialization before loop. 7246 ExprResult IV; 7247 ExprResult Init, CombInit; 7248 { 7249 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7250 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7251 Expr *RHS = 7252 (isOpenMPWorksharingDirective(DKind) || 7253 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7254 ? LB.get() 7255 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7256 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7257 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7258 7259 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7260 Expr *CombRHS = 7261 (isOpenMPWorksharingDirective(DKind) || 7262 isOpenMPTaskLoopDirective(DKind) || 7263 isOpenMPDistributeDirective(DKind)) 7264 ? CombLB.get() 7265 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7266 CombInit = 7267 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7268 CombInit = 7269 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7270 } 7271 } 7272 7273 bool UseStrictCompare = 7274 RealVType->hasUnsignedIntegerRepresentation() && 7275 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7276 return LIS.IsStrictCompare; 7277 }); 7278 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7279 // unsigned IV)) for worksharing loops. 7280 SourceLocation CondLoc = AStmt->getBeginLoc(); 7281 Expr *BoundUB = UB.get(); 7282 if (UseStrictCompare) { 7283 BoundUB = 7284 SemaRef 7285 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7286 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7287 .get(); 7288 BoundUB = 7289 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7290 } 7291 ExprResult Cond = 7292 (isOpenMPWorksharingDirective(DKind) || 7293 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7294 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7295 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7296 BoundUB) 7297 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7298 NumIterations.get()); 7299 ExprResult CombDistCond; 7300 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7301 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7302 NumIterations.get()); 7303 } 7304 7305 ExprResult CombCond; 7306 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7307 Expr *BoundCombUB = CombUB.get(); 7308 if (UseStrictCompare) { 7309 BoundCombUB = 7310 SemaRef 7311 .BuildBinOp( 7312 CurScope, CondLoc, BO_Add, BoundCombUB, 7313 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7314 .get(); 7315 BoundCombUB = 7316 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7317 .get(); 7318 } 7319 CombCond = 7320 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7321 IV.get(), BoundCombUB); 7322 } 7323 // Loop increment (IV = IV + 1) 7324 SourceLocation IncLoc = AStmt->getBeginLoc(); 7325 ExprResult Inc = 7326 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7327 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7328 if (!Inc.isUsable()) 7329 return 0; 7330 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7331 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7332 if (!Inc.isUsable()) 7333 return 0; 7334 7335 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7336 // Used for directives with static scheduling. 7337 // In combined construct, add combined version that use CombLB and CombUB 7338 // base variables for the update 7339 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7340 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7341 isOpenMPDistributeDirective(DKind)) { 7342 // LB + ST 7343 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7344 if (!NextLB.isUsable()) 7345 return 0; 7346 // LB = LB + ST 7347 NextLB = 7348 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7349 NextLB = 7350 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7351 if (!NextLB.isUsable()) 7352 return 0; 7353 // UB + ST 7354 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7355 if (!NextUB.isUsable()) 7356 return 0; 7357 // UB = UB + ST 7358 NextUB = 7359 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7360 NextUB = 7361 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7362 if (!NextUB.isUsable()) 7363 return 0; 7364 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7365 CombNextLB = 7366 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7367 if (!NextLB.isUsable()) 7368 return 0; 7369 // LB = LB + ST 7370 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7371 CombNextLB.get()); 7372 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7373 /*DiscardedValue*/ false); 7374 if (!CombNextLB.isUsable()) 7375 return 0; 7376 // UB + ST 7377 CombNextUB = 7378 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7379 if (!CombNextUB.isUsable()) 7380 return 0; 7381 // UB = UB + ST 7382 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7383 CombNextUB.get()); 7384 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7385 /*DiscardedValue*/ false); 7386 if (!CombNextUB.isUsable()) 7387 return 0; 7388 } 7389 } 7390 7391 // Create increment expression for distribute loop when combined in a same 7392 // directive with for as IV = IV + ST; ensure upper bound expression based 7393 // on PrevUB instead of NumIterations - used to implement 'for' when found 7394 // in combination with 'distribute', like in 'distribute parallel for' 7395 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7396 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7397 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7398 DistCond = SemaRef.BuildBinOp( 7399 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7400 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7401 7402 DistInc = 7403 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7404 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7405 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7406 DistInc.get()); 7407 DistInc = 7408 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7409 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7410 7411 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7412 // construct 7413 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7414 ExprResult IsUBGreater = 7415 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7416 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7417 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7418 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7419 CondOp.get()); 7420 PrevEUB = 7421 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7422 7423 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7424 // parallel for is in combination with a distribute directive with 7425 // schedule(static, 1) 7426 Expr *BoundPrevUB = PrevUB.get(); 7427 if (UseStrictCompare) { 7428 BoundPrevUB = 7429 SemaRef 7430 .BuildBinOp( 7431 CurScope, CondLoc, BO_Add, BoundPrevUB, 7432 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7433 .get(); 7434 BoundPrevUB = 7435 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7436 .get(); 7437 } 7438 ParForInDistCond = 7439 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7440 IV.get(), BoundPrevUB); 7441 } 7442 7443 // Build updates and final values of the loop counters. 7444 bool HasErrors = false; 7445 Built.Counters.resize(NestedLoopCount); 7446 Built.Inits.resize(NestedLoopCount); 7447 Built.Updates.resize(NestedLoopCount); 7448 Built.Finals.resize(NestedLoopCount); 7449 Built.DependentCounters.resize(NestedLoopCount); 7450 Built.DependentInits.resize(NestedLoopCount); 7451 Built.FinalsConditions.resize(NestedLoopCount); 7452 { 7453 // We implement the following algorithm for obtaining the 7454 // original loop iteration variable values based on the 7455 // value of the collapsed loop iteration variable IV. 7456 // 7457 // Let n+1 be the number of collapsed loops in the nest. 7458 // Iteration variables (I0, I1, .... In) 7459 // Iteration counts (N0, N1, ... Nn) 7460 // 7461 // Acc = IV; 7462 // 7463 // To compute Ik for loop k, 0 <= k <= n, generate: 7464 // Prod = N(k+1) * N(k+2) * ... * Nn; 7465 // Ik = Acc / Prod; 7466 // Acc -= Ik * Prod; 7467 // 7468 ExprResult Acc = IV; 7469 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7470 LoopIterationSpace &IS = IterSpaces[Cnt]; 7471 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7472 ExprResult Iter; 7473 7474 // Compute prod 7475 ExprResult Prod = 7476 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7477 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7478 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7479 IterSpaces[K].NumIterations); 7480 7481 // Iter = Acc / Prod 7482 // If there is at least one more inner loop to avoid 7483 // multiplication by 1. 7484 if (Cnt + 1 < NestedLoopCount) 7485 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7486 Acc.get(), Prod.get()); 7487 else 7488 Iter = Acc; 7489 if (!Iter.isUsable()) { 7490 HasErrors = true; 7491 break; 7492 } 7493 7494 // Update Acc: 7495 // Acc -= Iter * Prod 7496 // Check if there is at least one more inner loop to avoid 7497 // multiplication by 1. 7498 if (Cnt + 1 < NestedLoopCount) 7499 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7500 Iter.get(), Prod.get()); 7501 else 7502 Prod = Iter; 7503 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7504 Acc.get(), Prod.get()); 7505 7506 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7507 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7508 DeclRefExpr *CounterVar = buildDeclRefExpr( 7509 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7510 /*RefersToCapture=*/true); 7511 ExprResult Init = 7512 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7513 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7514 if (!Init.isUsable()) { 7515 HasErrors = true; 7516 break; 7517 } 7518 ExprResult Update = buildCounterUpdate( 7519 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7520 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7521 if (!Update.isUsable()) { 7522 HasErrors = true; 7523 break; 7524 } 7525 7526 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7527 ExprResult Final = 7528 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7529 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7530 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7531 if (!Final.isUsable()) { 7532 HasErrors = true; 7533 break; 7534 } 7535 7536 if (!Update.isUsable() || !Final.isUsable()) { 7537 HasErrors = true; 7538 break; 7539 } 7540 // Save results 7541 Built.Counters[Cnt] = IS.CounterVar; 7542 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7543 Built.Inits[Cnt] = Init.get(); 7544 Built.Updates[Cnt] = Update.get(); 7545 Built.Finals[Cnt] = Final.get(); 7546 Built.DependentCounters[Cnt] = nullptr; 7547 Built.DependentInits[Cnt] = nullptr; 7548 Built.FinalsConditions[Cnt] = nullptr; 7549 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7550 Built.DependentCounters[Cnt] = 7551 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7552 Built.DependentInits[Cnt] = 7553 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7554 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7555 } 7556 } 7557 } 7558 7559 if (HasErrors) 7560 return 0; 7561 7562 // Save results 7563 Built.IterationVarRef = IV.get(); 7564 Built.LastIteration = LastIteration.get(); 7565 Built.NumIterations = NumIterations.get(); 7566 Built.CalcLastIteration = SemaRef 7567 .ActOnFinishFullExpr(CalcLastIteration.get(), 7568 /*DiscardedValue=*/false) 7569 .get(); 7570 Built.PreCond = PreCond.get(); 7571 Built.PreInits = buildPreInits(C, Captures); 7572 Built.Cond = Cond.get(); 7573 Built.Init = Init.get(); 7574 Built.Inc = Inc.get(); 7575 Built.LB = LB.get(); 7576 Built.UB = UB.get(); 7577 Built.IL = IL.get(); 7578 Built.ST = ST.get(); 7579 Built.EUB = EUB.get(); 7580 Built.NLB = NextLB.get(); 7581 Built.NUB = NextUB.get(); 7582 Built.PrevLB = PrevLB.get(); 7583 Built.PrevUB = PrevUB.get(); 7584 Built.DistInc = DistInc.get(); 7585 Built.PrevEUB = PrevEUB.get(); 7586 Built.DistCombinedFields.LB = CombLB.get(); 7587 Built.DistCombinedFields.UB = CombUB.get(); 7588 Built.DistCombinedFields.EUB = CombEUB.get(); 7589 Built.DistCombinedFields.Init = CombInit.get(); 7590 Built.DistCombinedFields.Cond = CombCond.get(); 7591 Built.DistCombinedFields.NLB = CombNextLB.get(); 7592 Built.DistCombinedFields.NUB = CombNextUB.get(); 7593 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7594 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7595 7596 return NestedLoopCount; 7597 } 7598 7599 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7600 auto CollapseClauses = 7601 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7602 if (CollapseClauses.begin() != CollapseClauses.end()) 7603 return (*CollapseClauses.begin())->getNumForLoops(); 7604 return nullptr; 7605 } 7606 7607 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7608 auto OrderedClauses = 7609 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7610 if (OrderedClauses.begin() != OrderedClauses.end()) 7611 return (*OrderedClauses.begin())->getNumForLoops(); 7612 return nullptr; 7613 } 7614 7615 static bool checkSimdlenSafelenSpecified(Sema &S, 7616 const ArrayRef<OMPClause *> Clauses) { 7617 const OMPSafelenClause *Safelen = nullptr; 7618 const OMPSimdlenClause *Simdlen = nullptr; 7619 7620 for (const OMPClause *Clause : Clauses) { 7621 if (Clause->getClauseKind() == OMPC_safelen) 7622 Safelen = cast<OMPSafelenClause>(Clause); 7623 else if (Clause->getClauseKind() == OMPC_simdlen) 7624 Simdlen = cast<OMPSimdlenClause>(Clause); 7625 if (Safelen && Simdlen) 7626 break; 7627 } 7628 7629 if (Simdlen && Safelen) { 7630 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7631 const Expr *SafelenLength = Safelen->getSafelen(); 7632 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7633 SimdlenLength->isInstantiationDependent() || 7634 SimdlenLength->containsUnexpandedParameterPack()) 7635 return false; 7636 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7637 SafelenLength->isInstantiationDependent() || 7638 SafelenLength->containsUnexpandedParameterPack()) 7639 return false; 7640 Expr::EvalResult SimdlenResult, SafelenResult; 7641 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7642 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7643 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7644 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7645 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7646 // If both simdlen and safelen clauses are specified, the value of the 7647 // simdlen parameter must be less than or equal to the value of the safelen 7648 // parameter. 7649 if (SimdlenRes > SafelenRes) { 7650 S.Diag(SimdlenLength->getExprLoc(), 7651 diag::err_omp_wrong_simdlen_safelen_values) 7652 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7653 return true; 7654 } 7655 } 7656 return false; 7657 } 7658 7659 StmtResult 7660 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7661 SourceLocation StartLoc, SourceLocation EndLoc, 7662 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7663 if (!AStmt) 7664 return StmtError(); 7665 7666 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7667 OMPLoopDirective::HelperExprs B; 7668 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7669 // define the nested loops number. 7670 unsigned NestedLoopCount = checkOpenMPLoop( 7671 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7672 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7673 if (NestedLoopCount == 0) 7674 return StmtError(); 7675 7676 assert((CurContext->isDependentContext() || B.builtAll()) && 7677 "omp simd loop exprs were not built"); 7678 7679 if (!CurContext->isDependentContext()) { 7680 // Finalize the clauses that need pre-built expressions for CodeGen. 7681 for (OMPClause *C : Clauses) { 7682 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7683 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7684 B.NumIterations, *this, CurScope, 7685 DSAStack)) 7686 return StmtError(); 7687 } 7688 } 7689 7690 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7691 return StmtError(); 7692 7693 setFunctionHasBranchProtectedScope(); 7694 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7695 Clauses, AStmt, B); 7696 } 7697 7698 StmtResult 7699 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7700 SourceLocation StartLoc, SourceLocation EndLoc, 7701 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7702 if (!AStmt) 7703 return StmtError(); 7704 7705 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7706 OMPLoopDirective::HelperExprs B; 7707 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7708 // define the nested loops number. 7709 unsigned NestedLoopCount = checkOpenMPLoop( 7710 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7711 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7712 if (NestedLoopCount == 0) 7713 return StmtError(); 7714 7715 assert((CurContext->isDependentContext() || B.builtAll()) && 7716 "omp for loop exprs were not built"); 7717 7718 if (!CurContext->isDependentContext()) { 7719 // Finalize the clauses that need pre-built expressions for CodeGen. 7720 for (OMPClause *C : Clauses) { 7721 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7722 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7723 B.NumIterations, *this, CurScope, 7724 DSAStack)) 7725 return StmtError(); 7726 } 7727 } 7728 7729 setFunctionHasBranchProtectedScope(); 7730 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7731 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7732 } 7733 7734 StmtResult Sema::ActOnOpenMPForSimdDirective( 7735 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7736 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7737 if (!AStmt) 7738 return StmtError(); 7739 7740 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7741 OMPLoopDirective::HelperExprs B; 7742 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7743 // define the nested loops number. 7744 unsigned NestedLoopCount = 7745 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7746 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7747 VarsWithImplicitDSA, B); 7748 if (NestedLoopCount == 0) 7749 return StmtError(); 7750 7751 assert((CurContext->isDependentContext() || B.builtAll()) && 7752 "omp for simd loop exprs were not built"); 7753 7754 if (!CurContext->isDependentContext()) { 7755 // Finalize the clauses that need pre-built expressions for CodeGen. 7756 for (OMPClause *C : Clauses) { 7757 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7758 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7759 B.NumIterations, *this, CurScope, 7760 DSAStack)) 7761 return StmtError(); 7762 } 7763 } 7764 7765 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7766 return StmtError(); 7767 7768 setFunctionHasBranchProtectedScope(); 7769 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7770 Clauses, AStmt, B); 7771 } 7772 7773 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7774 Stmt *AStmt, 7775 SourceLocation StartLoc, 7776 SourceLocation EndLoc) { 7777 if (!AStmt) 7778 return StmtError(); 7779 7780 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7781 auto BaseStmt = AStmt; 7782 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7783 BaseStmt = CS->getCapturedStmt(); 7784 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7785 auto S = C->children(); 7786 if (S.begin() == S.end()) 7787 return StmtError(); 7788 // All associated statements must be '#pragma omp section' except for 7789 // the first one. 7790 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7791 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7792 if (SectionStmt) 7793 Diag(SectionStmt->getBeginLoc(), 7794 diag::err_omp_sections_substmt_not_section); 7795 return StmtError(); 7796 } 7797 cast<OMPSectionDirective>(SectionStmt) 7798 ->setHasCancel(DSAStack->isCancelRegion()); 7799 } 7800 } else { 7801 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7802 return StmtError(); 7803 } 7804 7805 setFunctionHasBranchProtectedScope(); 7806 7807 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7808 DSAStack->isCancelRegion()); 7809 } 7810 7811 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7812 SourceLocation StartLoc, 7813 SourceLocation EndLoc) { 7814 if (!AStmt) 7815 return StmtError(); 7816 7817 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7818 7819 setFunctionHasBranchProtectedScope(); 7820 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7821 7822 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7823 DSAStack->isCancelRegion()); 7824 } 7825 7826 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7827 Stmt *AStmt, 7828 SourceLocation StartLoc, 7829 SourceLocation EndLoc) { 7830 if (!AStmt) 7831 return StmtError(); 7832 7833 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7834 7835 setFunctionHasBranchProtectedScope(); 7836 7837 // OpenMP [2.7.3, single Construct, Restrictions] 7838 // The copyprivate clause must not be used with the nowait clause. 7839 const OMPClause *Nowait = nullptr; 7840 const OMPClause *Copyprivate = nullptr; 7841 for (const OMPClause *Clause : Clauses) { 7842 if (Clause->getClauseKind() == OMPC_nowait) 7843 Nowait = Clause; 7844 else if (Clause->getClauseKind() == OMPC_copyprivate) 7845 Copyprivate = Clause; 7846 if (Copyprivate && Nowait) { 7847 Diag(Copyprivate->getBeginLoc(), 7848 diag::err_omp_single_copyprivate_with_nowait); 7849 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7850 return StmtError(); 7851 } 7852 } 7853 7854 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7855 } 7856 7857 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7858 SourceLocation StartLoc, 7859 SourceLocation EndLoc) { 7860 if (!AStmt) 7861 return StmtError(); 7862 7863 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7864 7865 setFunctionHasBranchProtectedScope(); 7866 7867 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7868 } 7869 7870 StmtResult Sema::ActOnOpenMPCriticalDirective( 7871 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7872 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7873 if (!AStmt) 7874 return StmtError(); 7875 7876 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7877 7878 bool ErrorFound = false; 7879 llvm::APSInt Hint; 7880 SourceLocation HintLoc; 7881 bool DependentHint = false; 7882 for (const OMPClause *C : Clauses) { 7883 if (C->getClauseKind() == OMPC_hint) { 7884 if (!DirName.getName()) { 7885 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7886 ErrorFound = true; 7887 } 7888 Expr *E = cast<OMPHintClause>(C)->getHint(); 7889 if (E->isTypeDependent() || E->isValueDependent() || 7890 E->isInstantiationDependent()) { 7891 DependentHint = true; 7892 } else { 7893 Hint = E->EvaluateKnownConstInt(Context); 7894 HintLoc = C->getBeginLoc(); 7895 } 7896 } 7897 } 7898 if (ErrorFound) 7899 return StmtError(); 7900 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7901 if (Pair.first && DirName.getName() && !DependentHint) { 7902 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7903 Diag(StartLoc, diag::err_omp_critical_with_hint); 7904 if (HintLoc.isValid()) 7905 Diag(HintLoc, diag::note_omp_critical_hint_here) 7906 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7907 else 7908 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7909 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7910 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7911 << 1 7912 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7913 /*Radix=*/10, /*Signed=*/false); 7914 } else { 7915 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7916 } 7917 } 7918 } 7919 7920 setFunctionHasBranchProtectedScope(); 7921 7922 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7923 Clauses, AStmt); 7924 if (!Pair.first && DirName.getName() && !DependentHint) 7925 DSAStack->addCriticalWithHint(Dir, Hint); 7926 return Dir; 7927 } 7928 7929 StmtResult Sema::ActOnOpenMPParallelForDirective( 7930 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7931 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7932 if (!AStmt) 7933 return StmtError(); 7934 7935 auto *CS = cast<CapturedStmt>(AStmt); 7936 // 1.2.2 OpenMP Language Terminology 7937 // Structured block - An executable statement with a single entry at the 7938 // top and a single exit at the bottom. 7939 // The point of exit cannot be a branch out of the structured block. 7940 // longjmp() and throw() must not violate the entry/exit criteria. 7941 CS->getCapturedDecl()->setNothrow(); 7942 7943 OMPLoopDirective::HelperExprs B; 7944 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7945 // define the nested loops number. 7946 unsigned NestedLoopCount = 7947 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7948 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7949 VarsWithImplicitDSA, B); 7950 if (NestedLoopCount == 0) 7951 return StmtError(); 7952 7953 assert((CurContext->isDependentContext() || B.builtAll()) && 7954 "omp parallel for loop exprs were not built"); 7955 7956 if (!CurContext->isDependentContext()) { 7957 // Finalize the clauses that need pre-built expressions for CodeGen. 7958 for (OMPClause *C : Clauses) { 7959 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7960 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7961 B.NumIterations, *this, CurScope, 7962 DSAStack)) 7963 return StmtError(); 7964 } 7965 } 7966 7967 setFunctionHasBranchProtectedScope(); 7968 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7969 NestedLoopCount, Clauses, AStmt, B, 7970 DSAStack->isCancelRegion()); 7971 } 7972 7973 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7974 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7975 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7976 if (!AStmt) 7977 return StmtError(); 7978 7979 auto *CS = cast<CapturedStmt>(AStmt); 7980 // 1.2.2 OpenMP Language Terminology 7981 // Structured block - An executable statement with a single entry at the 7982 // top and a single exit at the bottom. 7983 // The point of exit cannot be a branch out of the structured block. 7984 // longjmp() and throw() must not violate the entry/exit criteria. 7985 CS->getCapturedDecl()->setNothrow(); 7986 7987 OMPLoopDirective::HelperExprs B; 7988 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7989 // define the nested loops number. 7990 unsigned NestedLoopCount = 7991 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7992 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7993 VarsWithImplicitDSA, B); 7994 if (NestedLoopCount == 0) 7995 return StmtError(); 7996 7997 if (!CurContext->isDependentContext()) { 7998 // Finalize the clauses that need pre-built expressions for CodeGen. 7999 for (OMPClause *C : Clauses) { 8000 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8001 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8002 B.NumIterations, *this, CurScope, 8003 DSAStack)) 8004 return StmtError(); 8005 } 8006 } 8007 8008 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8009 return StmtError(); 8010 8011 setFunctionHasBranchProtectedScope(); 8012 return OMPParallelForSimdDirective::Create( 8013 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8014 } 8015 8016 StmtResult 8017 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8018 Stmt *AStmt, SourceLocation StartLoc, 8019 SourceLocation EndLoc) { 8020 if (!AStmt) 8021 return StmtError(); 8022 8023 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8024 auto BaseStmt = AStmt; 8025 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8026 BaseStmt = CS->getCapturedStmt(); 8027 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8028 auto S = C->children(); 8029 if (S.begin() == S.end()) 8030 return StmtError(); 8031 // All associated statements must be '#pragma omp section' except for 8032 // the first one. 8033 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8034 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8035 if (SectionStmt) 8036 Diag(SectionStmt->getBeginLoc(), 8037 diag::err_omp_parallel_sections_substmt_not_section); 8038 return StmtError(); 8039 } 8040 cast<OMPSectionDirective>(SectionStmt) 8041 ->setHasCancel(DSAStack->isCancelRegion()); 8042 } 8043 } else { 8044 Diag(AStmt->getBeginLoc(), 8045 diag::err_omp_parallel_sections_not_compound_stmt); 8046 return StmtError(); 8047 } 8048 8049 setFunctionHasBranchProtectedScope(); 8050 8051 return OMPParallelSectionsDirective::Create( 8052 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8053 } 8054 8055 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8056 Stmt *AStmt, SourceLocation StartLoc, 8057 SourceLocation EndLoc) { 8058 if (!AStmt) 8059 return StmtError(); 8060 8061 auto *CS = cast<CapturedStmt>(AStmt); 8062 // 1.2.2 OpenMP Language Terminology 8063 // Structured block - An executable statement with a single entry at the 8064 // top and a single exit at the bottom. 8065 // The point of exit cannot be a branch out of the structured block. 8066 // longjmp() and throw() must not violate the entry/exit criteria. 8067 CS->getCapturedDecl()->setNothrow(); 8068 8069 setFunctionHasBranchProtectedScope(); 8070 8071 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8072 DSAStack->isCancelRegion()); 8073 } 8074 8075 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8076 SourceLocation EndLoc) { 8077 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8078 } 8079 8080 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8081 SourceLocation EndLoc) { 8082 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8083 } 8084 8085 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8086 SourceLocation EndLoc) { 8087 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8088 } 8089 8090 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8091 Stmt *AStmt, 8092 SourceLocation StartLoc, 8093 SourceLocation EndLoc) { 8094 if (!AStmt) 8095 return StmtError(); 8096 8097 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8098 8099 setFunctionHasBranchProtectedScope(); 8100 8101 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8102 AStmt, 8103 DSAStack->getTaskgroupReductionRef()); 8104 } 8105 8106 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8107 SourceLocation StartLoc, 8108 SourceLocation EndLoc) { 8109 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8110 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8111 } 8112 8113 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8114 Stmt *AStmt, 8115 SourceLocation StartLoc, 8116 SourceLocation EndLoc) { 8117 const OMPClause *DependFound = nullptr; 8118 const OMPClause *DependSourceClause = nullptr; 8119 const OMPClause *DependSinkClause = nullptr; 8120 bool ErrorFound = false; 8121 const OMPThreadsClause *TC = nullptr; 8122 const OMPSIMDClause *SC = nullptr; 8123 for (const OMPClause *C : Clauses) { 8124 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8125 DependFound = C; 8126 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8127 if (DependSourceClause) { 8128 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8129 << getOpenMPDirectiveName(OMPD_ordered) 8130 << getOpenMPClauseName(OMPC_depend) << 2; 8131 ErrorFound = true; 8132 } else { 8133 DependSourceClause = C; 8134 } 8135 if (DependSinkClause) { 8136 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8137 << 0; 8138 ErrorFound = true; 8139 } 8140 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8141 if (DependSourceClause) { 8142 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8143 << 1; 8144 ErrorFound = true; 8145 } 8146 DependSinkClause = C; 8147 } 8148 } else if (C->getClauseKind() == OMPC_threads) { 8149 TC = cast<OMPThreadsClause>(C); 8150 } else if (C->getClauseKind() == OMPC_simd) { 8151 SC = cast<OMPSIMDClause>(C); 8152 } 8153 } 8154 if (!ErrorFound && !SC && 8155 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8156 // OpenMP [2.8.1,simd Construct, Restrictions] 8157 // An ordered construct with the simd clause is the only OpenMP construct 8158 // that can appear in the simd region. 8159 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 8160 ErrorFound = true; 8161 } else if (DependFound && (TC || SC)) { 8162 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8163 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8164 ErrorFound = true; 8165 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8166 Diag(DependFound->getBeginLoc(), 8167 diag::err_omp_ordered_directive_without_param); 8168 ErrorFound = true; 8169 } else if (TC || Clauses.empty()) { 8170 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8171 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8172 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8173 << (TC != nullptr); 8174 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8175 ErrorFound = true; 8176 } 8177 } 8178 if ((!AStmt && !DependFound) || ErrorFound) 8179 return StmtError(); 8180 8181 if (AStmt) { 8182 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8183 8184 setFunctionHasBranchProtectedScope(); 8185 } 8186 8187 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8188 } 8189 8190 namespace { 8191 /// Helper class for checking expression in 'omp atomic [update]' 8192 /// construct. 8193 class OpenMPAtomicUpdateChecker { 8194 /// Error results for atomic update expressions. 8195 enum ExprAnalysisErrorCode { 8196 /// A statement is not an expression statement. 8197 NotAnExpression, 8198 /// Expression is not builtin binary or unary operation. 8199 NotABinaryOrUnaryExpression, 8200 /// Unary operation is not post-/pre- increment/decrement operation. 8201 NotAnUnaryIncDecExpression, 8202 /// An expression is not of scalar type. 8203 NotAScalarType, 8204 /// A binary operation is not an assignment operation. 8205 NotAnAssignmentOp, 8206 /// RHS part of the binary operation is not a binary expression. 8207 NotABinaryExpression, 8208 /// RHS part is not additive/multiplicative/shift/biwise binary 8209 /// expression. 8210 NotABinaryOperator, 8211 /// RHS binary operation does not have reference to the updated LHS 8212 /// part. 8213 NotAnUpdateExpression, 8214 /// No errors is found. 8215 NoError 8216 }; 8217 /// Reference to Sema. 8218 Sema &SemaRef; 8219 /// A location for note diagnostics (when error is found). 8220 SourceLocation NoteLoc; 8221 /// 'x' lvalue part of the source atomic expression. 8222 Expr *X; 8223 /// 'expr' rvalue part of the source atomic expression. 8224 Expr *E; 8225 /// Helper expression of the form 8226 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8227 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8228 Expr *UpdateExpr; 8229 /// Is 'x' a LHS in a RHS part of full update expression. It is 8230 /// important for non-associative operations. 8231 bool IsXLHSInRHSPart; 8232 BinaryOperatorKind Op; 8233 SourceLocation OpLoc; 8234 /// true if the source expression is a postfix unary operation, false 8235 /// if it is a prefix unary operation. 8236 bool IsPostfixUpdate; 8237 8238 public: 8239 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8240 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8241 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8242 /// Check specified statement that it is suitable for 'atomic update' 8243 /// constructs and extract 'x', 'expr' and Operation from the original 8244 /// expression. If DiagId and NoteId == 0, then only check is performed 8245 /// without error notification. 8246 /// \param DiagId Diagnostic which should be emitted if error is found. 8247 /// \param NoteId Diagnostic note for the main error message. 8248 /// \return true if statement is not an update expression, false otherwise. 8249 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8250 /// Return the 'x' lvalue part of the source atomic expression. 8251 Expr *getX() const { return X; } 8252 /// Return the 'expr' rvalue part of the source atomic expression. 8253 Expr *getExpr() const { return E; } 8254 /// Return the update expression used in calculation of the updated 8255 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8256 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8257 Expr *getUpdateExpr() const { return UpdateExpr; } 8258 /// Return true if 'x' is LHS in RHS part of full update expression, 8259 /// false otherwise. 8260 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8261 8262 /// true if the source expression is a postfix unary operation, false 8263 /// if it is a prefix unary operation. 8264 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8265 8266 private: 8267 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8268 unsigned NoteId = 0); 8269 }; 8270 } // namespace 8271 8272 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8273 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8274 ExprAnalysisErrorCode ErrorFound = NoError; 8275 SourceLocation ErrorLoc, NoteLoc; 8276 SourceRange ErrorRange, NoteRange; 8277 // Allowed constructs are: 8278 // x = x binop expr; 8279 // x = expr binop x; 8280 if (AtomicBinOp->getOpcode() == BO_Assign) { 8281 X = AtomicBinOp->getLHS(); 8282 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8283 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8284 if (AtomicInnerBinOp->isMultiplicativeOp() || 8285 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8286 AtomicInnerBinOp->isBitwiseOp()) { 8287 Op = AtomicInnerBinOp->getOpcode(); 8288 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8289 Expr *LHS = AtomicInnerBinOp->getLHS(); 8290 Expr *RHS = AtomicInnerBinOp->getRHS(); 8291 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8292 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8293 /*Canonical=*/true); 8294 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8295 /*Canonical=*/true); 8296 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8297 /*Canonical=*/true); 8298 if (XId == LHSId) { 8299 E = RHS; 8300 IsXLHSInRHSPart = true; 8301 } else if (XId == RHSId) { 8302 E = LHS; 8303 IsXLHSInRHSPart = false; 8304 } else { 8305 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8306 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8307 NoteLoc = X->getExprLoc(); 8308 NoteRange = X->getSourceRange(); 8309 ErrorFound = NotAnUpdateExpression; 8310 } 8311 } else { 8312 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8313 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8314 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8315 NoteRange = SourceRange(NoteLoc, NoteLoc); 8316 ErrorFound = NotABinaryOperator; 8317 } 8318 } else { 8319 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8320 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8321 ErrorFound = NotABinaryExpression; 8322 } 8323 } else { 8324 ErrorLoc = AtomicBinOp->getExprLoc(); 8325 ErrorRange = AtomicBinOp->getSourceRange(); 8326 NoteLoc = AtomicBinOp->getOperatorLoc(); 8327 NoteRange = SourceRange(NoteLoc, NoteLoc); 8328 ErrorFound = NotAnAssignmentOp; 8329 } 8330 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8331 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8332 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8333 return true; 8334 } 8335 if (SemaRef.CurContext->isDependentContext()) 8336 E = X = UpdateExpr = nullptr; 8337 return ErrorFound != NoError; 8338 } 8339 8340 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8341 unsigned NoteId) { 8342 ExprAnalysisErrorCode ErrorFound = NoError; 8343 SourceLocation ErrorLoc, NoteLoc; 8344 SourceRange ErrorRange, NoteRange; 8345 // Allowed constructs are: 8346 // x++; 8347 // x--; 8348 // ++x; 8349 // --x; 8350 // x binop= expr; 8351 // x = x binop expr; 8352 // x = expr binop x; 8353 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8354 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8355 if (AtomicBody->getType()->isScalarType() || 8356 AtomicBody->isInstantiationDependent()) { 8357 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8358 AtomicBody->IgnoreParenImpCasts())) { 8359 // Check for Compound Assignment Operation 8360 Op = BinaryOperator::getOpForCompoundAssignment( 8361 AtomicCompAssignOp->getOpcode()); 8362 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8363 E = AtomicCompAssignOp->getRHS(); 8364 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8365 IsXLHSInRHSPart = true; 8366 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8367 AtomicBody->IgnoreParenImpCasts())) { 8368 // Check for Binary Operation 8369 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8370 return true; 8371 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8372 AtomicBody->IgnoreParenImpCasts())) { 8373 // Check for Unary Operation 8374 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8375 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8376 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8377 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8378 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8379 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8380 IsXLHSInRHSPart = true; 8381 } else { 8382 ErrorFound = NotAnUnaryIncDecExpression; 8383 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8384 ErrorRange = AtomicUnaryOp->getSourceRange(); 8385 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8386 NoteRange = SourceRange(NoteLoc, NoteLoc); 8387 } 8388 } else if (!AtomicBody->isInstantiationDependent()) { 8389 ErrorFound = NotABinaryOrUnaryExpression; 8390 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8391 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8392 } 8393 } else { 8394 ErrorFound = NotAScalarType; 8395 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8396 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8397 } 8398 } else { 8399 ErrorFound = NotAnExpression; 8400 NoteLoc = ErrorLoc = S->getBeginLoc(); 8401 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8402 } 8403 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8404 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8405 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8406 return true; 8407 } 8408 if (SemaRef.CurContext->isDependentContext()) 8409 E = X = UpdateExpr = nullptr; 8410 if (ErrorFound == NoError && E && X) { 8411 // Build an update expression of form 'OpaqueValueExpr(x) binop 8412 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8413 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8414 auto *OVEX = new (SemaRef.getASTContext()) 8415 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8416 auto *OVEExpr = new (SemaRef.getASTContext()) 8417 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8418 ExprResult Update = 8419 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8420 IsXLHSInRHSPart ? OVEExpr : OVEX); 8421 if (Update.isInvalid()) 8422 return true; 8423 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8424 Sema::AA_Casting); 8425 if (Update.isInvalid()) 8426 return true; 8427 UpdateExpr = Update.get(); 8428 } 8429 return ErrorFound != NoError; 8430 } 8431 8432 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8433 Stmt *AStmt, 8434 SourceLocation StartLoc, 8435 SourceLocation EndLoc) { 8436 if (!AStmt) 8437 return StmtError(); 8438 8439 auto *CS = cast<CapturedStmt>(AStmt); 8440 // 1.2.2 OpenMP Language Terminology 8441 // Structured block - An executable statement with a single entry at the 8442 // top and a single exit at the bottom. 8443 // The point of exit cannot be a branch out of the structured block. 8444 // longjmp() and throw() must not violate the entry/exit criteria. 8445 OpenMPClauseKind AtomicKind = OMPC_unknown; 8446 SourceLocation AtomicKindLoc; 8447 for (const OMPClause *C : Clauses) { 8448 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8449 C->getClauseKind() == OMPC_update || 8450 C->getClauseKind() == OMPC_capture) { 8451 if (AtomicKind != OMPC_unknown) { 8452 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8453 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8454 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8455 << getOpenMPClauseName(AtomicKind); 8456 } else { 8457 AtomicKind = C->getClauseKind(); 8458 AtomicKindLoc = C->getBeginLoc(); 8459 } 8460 } 8461 } 8462 8463 Stmt *Body = CS->getCapturedStmt(); 8464 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8465 Body = EWC->getSubExpr(); 8466 8467 Expr *X = nullptr; 8468 Expr *V = nullptr; 8469 Expr *E = nullptr; 8470 Expr *UE = nullptr; 8471 bool IsXLHSInRHSPart = false; 8472 bool IsPostfixUpdate = false; 8473 // OpenMP [2.12.6, atomic Construct] 8474 // In the next expressions: 8475 // * x and v (as applicable) are both l-value expressions with scalar type. 8476 // * During the execution of an atomic region, multiple syntactic 8477 // occurrences of x must designate the same storage location. 8478 // * Neither of v and expr (as applicable) may access the storage location 8479 // designated by x. 8480 // * Neither of x and expr (as applicable) may access the storage location 8481 // designated by v. 8482 // * expr is an expression with scalar type. 8483 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8484 // * binop, binop=, ++, and -- are not overloaded operators. 8485 // * The expression x binop expr must be numerically equivalent to x binop 8486 // (expr). This requirement is satisfied if the operators in expr have 8487 // precedence greater than binop, or by using parentheses around expr or 8488 // subexpressions of expr. 8489 // * The expression expr binop x must be numerically equivalent to (expr) 8490 // binop x. This requirement is satisfied if the operators in expr have 8491 // precedence equal to or greater than binop, or by using parentheses around 8492 // expr or subexpressions of expr. 8493 // * For forms that allow multiple occurrences of x, the number of times 8494 // that x is evaluated is unspecified. 8495 if (AtomicKind == OMPC_read) { 8496 enum { 8497 NotAnExpression, 8498 NotAnAssignmentOp, 8499 NotAScalarType, 8500 NotAnLValue, 8501 NoError 8502 } ErrorFound = NoError; 8503 SourceLocation ErrorLoc, NoteLoc; 8504 SourceRange ErrorRange, NoteRange; 8505 // If clause is read: 8506 // v = x; 8507 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8508 const auto *AtomicBinOp = 8509 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8510 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8511 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8512 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8513 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8514 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8515 if (!X->isLValue() || !V->isLValue()) { 8516 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8517 ErrorFound = NotAnLValue; 8518 ErrorLoc = AtomicBinOp->getExprLoc(); 8519 ErrorRange = AtomicBinOp->getSourceRange(); 8520 NoteLoc = NotLValueExpr->getExprLoc(); 8521 NoteRange = NotLValueExpr->getSourceRange(); 8522 } 8523 } else if (!X->isInstantiationDependent() || 8524 !V->isInstantiationDependent()) { 8525 const Expr *NotScalarExpr = 8526 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8527 ? V 8528 : X; 8529 ErrorFound = NotAScalarType; 8530 ErrorLoc = AtomicBinOp->getExprLoc(); 8531 ErrorRange = AtomicBinOp->getSourceRange(); 8532 NoteLoc = NotScalarExpr->getExprLoc(); 8533 NoteRange = NotScalarExpr->getSourceRange(); 8534 } 8535 } else if (!AtomicBody->isInstantiationDependent()) { 8536 ErrorFound = NotAnAssignmentOp; 8537 ErrorLoc = AtomicBody->getExprLoc(); 8538 ErrorRange = AtomicBody->getSourceRange(); 8539 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8540 : AtomicBody->getExprLoc(); 8541 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8542 : AtomicBody->getSourceRange(); 8543 } 8544 } else { 8545 ErrorFound = NotAnExpression; 8546 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8547 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8548 } 8549 if (ErrorFound != NoError) { 8550 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8551 << ErrorRange; 8552 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8553 << NoteRange; 8554 return StmtError(); 8555 } 8556 if (CurContext->isDependentContext()) 8557 V = X = nullptr; 8558 } else if (AtomicKind == OMPC_write) { 8559 enum { 8560 NotAnExpression, 8561 NotAnAssignmentOp, 8562 NotAScalarType, 8563 NotAnLValue, 8564 NoError 8565 } ErrorFound = NoError; 8566 SourceLocation ErrorLoc, NoteLoc; 8567 SourceRange ErrorRange, NoteRange; 8568 // If clause is write: 8569 // x = expr; 8570 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8571 const auto *AtomicBinOp = 8572 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8573 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8574 X = AtomicBinOp->getLHS(); 8575 E = AtomicBinOp->getRHS(); 8576 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8577 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8578 if (!X->isLValue()) { 8579 ErrorFound = NotAnLValue; 8580 ErrorLoc = AtomicBinOp->getExprLoc(); 8581 ErrorRange = AtomicBinOp->getSourceRange(); 8582 NoteLoc = X->getExprLoc(); 8583 NoteRange = X->getSourceRange(); 8584 } 8585 } else if (!X->isInstantiationDependent() || 8586 !E->isInstantiationDependent()) { 8587 const Expr *NotScalarExpr = 8588 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8589 ? E 8590 : X; 8591 ErrorFound = NotAScalarType; 8592 ErrorLoc = AtomicBinOp->getExprLoc(); 8593 ErrorRange = AtomicBinOp->getSourceRange(); 8594 NoteLoc = NotScalarExpr->getExprLoc(); 8595 NoteRange = NotScalarExpr->getSourceRange(); 8596 } 8597 } else if (!AtomicBody->isInstantiationDependent()) { 8598 ErrorFound = NotAnAssignmentOp; 8599 ErrorLoc = AtomicBody->getExprLoc(); 8600 ErrorRange = AtomicBody->getSourceRange(); 8601 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8602 : AtomicBody->getExprLoc(); 8603 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8604 : AtomicBody->getSourceRange(); 8605 } 8606 } else { 8607 ErrorFound = NotAnExpression; 8608 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8609 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8610 } 8611 if (ErrorFound != NoError) { 8612 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8613 << ErrorRange; 8614 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8615 << NoteRange; 8616 return StmtError(); 8617 } 8618 if (CurContext->isDependentContext()) 8619 E = X = nullptr; 8620 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8621 // If clause is update: 8622 // x++; 8623 // x--; 8624 // ++x; 8625 // --x; 8626 // x binop= expr; 8627 // x = x binop expr; 8628 // x = expr binop x; 8629 OpenMPAtomicUpdateChecker Checker(*this); 8630 if (Checker.checkStatement( 8631 Body, (AtomicKind == OMPC_update) 8632 ? diag::err_omp_atomic_update_not_expression_statement 8633 : diag::err_omp_atomic_not_expression_statement, 8634 diag::note_omp_atomic_update)) 8635 return StmtError(); 8636 if (!CurContext->isDependentContext()) { 8637 E = Checker.getExpr(); 8638 X = Checker.getX(); 8639 UE = Checker.getUpdateExpr(); 8640 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8641 } 8642 } else if (AtomicKind == OMPC_capture) { 8643 enum { 8644 NotAnAssignmentOp, 8645 NotACompoundStatement, 8646 NotTwoSubstatements, 8647 NotASpecificExpression, 8648 NoError 8649 } ErrorFound = NoError; 8650 SourceLocation ErrorLoc, NoteLoc; 8651 SourceRange ErrorRange, NoteRange; 8652 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8653 // If clause is a capture: 8654 // v = x++; 8655 // v = x--; 8656 // v = ++x; 8657 // v = --x; 8658 // v = x binop= expr; 8659 // v = x = x binop expr; 8660 // v = x = expr binop x; 8661 const auto *AtomicBinOp = 8662 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8663 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8664 V = AtomicBinOp->getLHS(); 8665 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8666 OpenMPAtomicUpdateChecker Checker(*this); 8667 if (Checker.checkStatement( 8668 Body, diag::err_omp_atomic_capture_not_expression_statement, 8669 diag::note_omp_atomic_update)) 8670 return StmtError(); 8671 E = Checker.getExpr(); 8672 X = Checker.getX(); 8673 UE = Checker.getUpdateExpr(); 8674 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8675 IsPostfixUpdate = Checker.isPostfixUpdate(); 8676 } else if (!AtomicBody->isInstantiationDependent()) { 8677 ErrorLoc = AtomicBody->getExprLoc(); 8678 ErrorRange = AtomicBody->getSourceRange(); 8679 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8680 : AtomicBody->getExprLoc(); 8681 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8682 : AtomicBody->getSourceRange(); 8683 ErrorFound = NotAnAssignmentOp; 8684 } 8685 if (ErrorFound != NoError) { 8686 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8687 << ErrorRange; 8688 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8689 return StmtError(); 8690 } 8691 if (CurContext->isDependentContext()) 8692 UE = V = E = X = nullptr; 8693 } else { 8694 // If clause is a capture: 8695 // { v = x; x = expr; } 8696 // { v = x; x++; } 8697 // { v = x; x--; } 8698 // { v = x; ++x; } 8699 // { v = x; --x; } 8700 // { v = x; x binop= expr; } 8701 // { v = x; x = x binop expr; } 8702 // { v = x; x = expr binop x; } 8703 // { x++; v = x; } 8704 // { x--; v = x; } 8705 // { ++x; v = x; } 8706 // { --x; v = x; } 8707 // { x binop= expr; v = x; } 8708 // { x = x binop expr; v = x; } 8709 // { x = expr binop x; v = x; } 8710 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8711 // Check that this is { expr1; expr2; } 8712 if (CS->size() == 2) { 8713 Stmt *First = CS->body_front(); 8714 Stmt *Second = CS->body_back(); 8715 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8716 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8717 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8718 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8719 // Need to find what subexpression is 'v' and what is 'x'. 8720 OpenMPAtomicUpdateChecker Checker(*this); 8721 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8722 BinaryOperator *BinOp = nullptr; 8723 if (IsUpdateExprFound) { 8724 BinOp = dyn_cast<BinaryOperator>(First); 8725 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8726 } 8727 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8728 // { v = x; x++; } 8729 // { v = x; x--; } 8730 // { v = x; ++x; } 8731 // { v = x; --x; } 8732 // { v = x; x binop= expr; } 8733 // { v = x; x = x binop expr; } 8734 // { v = x; x = expr binop x; } 8735 // Check that the first expression has form v = x. 8736 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8737 llvm::FoldingSetNodeID XId, PossibleXId; 8738 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8739 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8740 IsUpdateExprFound = XId == PossibleXId; 8741 if (IsUpdateExprFound) { 8742 V = BinOp->getLHS(); 8743 X = Checker.getX(); 8744 E = Checker.getExpr(); 8745 UE = Checker.getUpdateExpr(); 8746 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8747 IsPostfixUpdate = true; 8748 } 8749 } 8750 if (!IsUpdateExprFound) { 8751 IsUpdateExprFound = !Checker.checkStatement(First); 8752 BinOp = nullptr; 8753 if (IsUpdateExprFound) { 8754 BinOp = dyn_cast<BinaryOperator>(Second); 8755 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8756 } 8757 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8758 // { x++; v = x; } 8759 // { x--; v = x; } 8760 // { ++x; v = x; } 8761 // { --x; v = x; } 8762 // { x binop= expr; v = x; } 8763 // { x = x binop expr; v = x; } 8764 // { x = expr binop x; v = x; } 8765 // Check that the second expression has form v = x. 8766 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8767 llvm::FoldingSetNodeID XId, PossibleXId; 8768 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8769 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8770 IsUpdateExprFound = XId == PossibleXId; 8771 if (IsUpdateExprFound) { 8772 V = BinOp->getLHS(); 8773 X = Checker.getX(); 8774 E = Checker.getExpr(); 8775 UE = Checker.getUpdateExpr(); 8776 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8777 IsPostfixUpdate = false; 8778 } 8779 } 8780 } 8781 if (!IsUpdateExprFound) { 8782 // { v = x; x = expr; } 8783 auto *FirstExpr = dyn_cast<Expr>(First); 8784 auto *SecondExpr = dyn_cast<Expr>(Second); 8785 if (!FirstExpr || !SecondExpr || 8786 !(FirstExpr->isInstantiationDependent() || 8787 SecondExpr->isInstantiationDependent())) { 8788 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8789 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8790 ErrorFound = NotAnAssignmentOp; 8791 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8792 : First->getBeginLoc(); 8793 NoteRange = ErrorRange = FirstBinOp 8794 ? FirstBinOp->getSourceRange() 8795 : SourceRange(ErrorLoc, ErrorLoc); 8796 } else { 8797 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8798 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8799 ErrorFound = NotAnAssignmentOp; 8800 NoteLoc = ErrorLoc = SecondBinOp 8801 ? SecondBinOp->getOperatorLoc() 8802 : Second->getBeginLoc(); 8803 NoteRange = ErrorRange = 8804 SecondBinOp ? SecondBinOp->getSourceRange() 8805 : SourceRange(ErrorLoc, ErrorLoc); 8806 } else { 8807 Expr *PossibleXRHSInFirst = 8808 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8809 Expr *PossibleXLHSInSecond = 8810 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8811 llvm::FoldingSetNodeID X1Id, X2Id; 8812 PossibleXRHSInFirst->Profile(X1Id, Context, 8813 /*Canonical=*/true); 8814 PossibleXLHSInSecond->Profile(X2Id, Context, 8815 /*Canonical=*/true); 8816 IsUpdateExprFound = X1Id == X2Id; 8817 if (IsUpdateExprFound) { 8818 V = FirstBinOp->getLHS(); 8819 X = SecondBinOp->getLHS(); 8820 E = SecondBinOp->getRHS(); 8821 UE = nullptr; 8822 IsXLHSInRHSPart = false; 8823 IsPostfixUpdate = true; 8824 } else { 8825 ErrorFound = NotASpecificExpression; 8826 ErrorLoc = FirstBinOp->getExprLoc(); 8827 ErrorRange = FirstBinOp->getSourceRange(); 8828 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8829 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8830 } 8831 } 8832 } 8833 } 8834 } 8835 } else { 8836 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8837 NoteRange = ErrorRange = 8838 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8839 ErrorFound = NotTwoSubstatements; 8840 } 8841 } else { 8842 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8843 NoteRange = ErrorRange = 8844 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8845 ErrorFound = NotACompoundStatement; 8846 } 8847 if (ErrorFound != NoError) { 8848 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8849 << ErrorRange; 8850 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8851 return StmtError(); 8852 } 8853 if (CurContext->isDependentContext()) 8854 UE = V = E = X = nullptr; 8855 } 8856 } 8857 8858 setFunctionHasBranchProtectedScope(); 8859 8860 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8861 X, V, E, UE, IsXLHSInRHSPart, 8862 IsPostfixUpdate); 8863 } 8864 8865 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8866 Stmt *AStmt, 8867 SourceLocation StartLoc, 8868 SourceLocation EndLoc) { 8869 if (!AStmt) 8870 return StmtError(); 8871 8872 auto *CS = cast<CapturedStmt>(AStmt); 8873 // 1.2.2 OpenMP Language Terminology 8874 // Structured block - An executable statement with a single entry at the 8875 // top and a single exit at the bottom. 8876 // The point of exit cannot be a branch out of the structured block. 8877 // longjmp() and throw() must not violate the entry/exit criteria. 8878 CS->getCapturedDecl()->setNothrow(); 8879 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8880 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8881 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8882 // 1.2.2 OpenMP Language Terminology 8883 // Structured block - An executable statement with a single entry at the 8884 // top and a single exit at the bottom. 8885 // The point of exit cannot be a branch out of the structured block. 8886 // longjmp() and throw() must not violate the entry/exit criteria. 8887 CS->getCapturedDecl()->setNothrow(); 8888 } 8889 8890 // OpenMP [2.16, Nesting of Regions] 8891 // If specified, a teams construct must be contained within a target 8892 // construct. That target construct must contain no statements or directives 8893 // outside of the teams construct. 8894 if (DSAStack->hasInnerTeamsRegion()) { 8895 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8896 bool OMPTeamsFound = true; 8897 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8898 auto I = CS->body_begin(); 8899 while (I != CS->body_end()) { 8900 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8901 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8902 OMPTeamsFound) { 8903 8904 OMPTeamsFound = false; 8905 break; 8906 } 8907 ++I; 8908 } 8909 assert(I != CS->body_end() && "Not found statement"); 8910 S = *I; 8911 } else { 8912 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8913 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8914 } 8915 if (!OMPTeamsFound) { 8916 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8917 Diag(DSAStack->getInnerTeamsRegionLoc(), 8918 diag::note_omp_nested_teams_construct_here); 8919 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8920 << isa<OMPExecutableDirective>(S); 8921 return StmtError(); 8922 } 8923 } 8924 8925 setFunctionHasBranchProtectedScope(); 8926 8927 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8928 } 8929 8930 StmtResult 8931 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8932 Stmt *AStmt, SourceLocation StartLoc, 8933 SourceLocation EndLoc) { 8934 if (!AStmt) 8935 return StmtError(); 8936 8937 auto *CS = cast<CapturedStmt>(AStmt); 8938 // 1.2.2 OpenMP Language Terminology 8939 // Structured block - An executable statement with a single entry at the 8940 // top and a single exit at the bottom. 8941 // The point of exit cannot be a branch out of the structured block. 8942 // longjmp() and throw() must not violate the entry/exit criteria. 8943 CS->getCapturedDecl()->setNothrow(); 8944 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8945 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8946 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8947 // 1.2.2 OpenMP Language Terminology 8948 // Structured block - An executable statement with a single entry at the 8949 // top and a single exit at the bottom. 8950 // The point of exit cannot be a branch out of the structured block. 8951 // longjmp() and throw() must not violate the entry/exit criteria. 8952 CS->getCapturedDecl()->setNothrow(); 8953 } 8954 8955 setFunctionHasBranchProtectedScope(); 8956 8957 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8958 AStmt); 8959 } 8960 8961 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8962 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8963 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8964 if (!AStmt) 8965 return StmtError(); 8966 8967 auto *CS = cast<CapturedStmt>(AStmt); 8968 // 1.2.2 OpenMP Language Terminology 8969 // Structured block - An executable statement with a single entry at the 8970 // top and a single exit at the bottom. 8971 // The point of exit cannot be a branch out of the structured block. 8972 // longjmp() and throw() must not violate the entry/exit criteria. 8973 CS->getCapturedDecl()->setNothrow(); 8974 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8975 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8976 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8977 // 1.2.2 OpenMP Language Terminology 8978 // Structured block - An executable statement with a single entry at the 8979 // top and a single exit at the bottom. 8980 // The point of exit cannot be a branch out of the structured block. 8981 // longjmp() and throw() must not violate the entry/exit criteria. 8982 CS->getCapturedDecl()->setNothrow(); 8983 } 8984 8985 OMPLoopDirective::HelperExprs B; 8986 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8987 // define the nested loops number. 8988 unsigned NestedLoopCount = 8989 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8990 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8991 VarsWithImplicitDSA, B); 8992 if (NestedLoopCount == 0) 8993 return StmtError(); 8994 8995 assert((CurContext->isDependentContext() || B.builtAll()) && 8996 "omp target parallel for loop exprs were not built"); 8997 8998 if (!CurContext->isDependentContext()) { 8999 // Finalize the clauses that need pre-built expressions for CodeGen. 9000 for (OMPClause *C : Clauses) { 9001 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9002 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9003 B.NumIterations, *this, CurScope, 9004 DSAStack)) 9005 return StmtError(); 9006 } 9007 } 9008 9009 setFunctionHasBranchProtectedScope(); 9010 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9011 NestedLoopCount, Clauses, AStmt, 9012 B, DSAStack->isCancelRegion()); 9013 } 9014 9015 /// Check for existence of a map clause in the list of clauses. 9016 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9017 const OpenMPClauseKind K) { 9018 return llvm::any_of( 9019 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9020 } 9021 9022 template <typename... Params> 9023 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9024 const Params... ClauseTypes) { 9025 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9026 } 9027 9028 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9029 Stmt *AStmt, 9030 SourceLocation StartLoc, 9031 SourceLocation EndLoc) { 9032 if (!AStmt) 9033 return StmtError(); 9034 9035 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9036 9037 // OpenMP [2.10.1, Restrictions, p. 97] 9038 // At least one map clause must appear on the directive. 9039 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9040 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9041 << "'map' or 'use_device_ptr'" 9042 << getOpenMPDirectiveName(OMPD_target_data); 9043 return StmtError(); 9044 } 9045 9046 setFunctionHasBranchProtectedScope(); 9047 9048 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9049 AStmt); 9050 } 9051 9052 StmtResult 9053 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9054 SourceLocation StartLoc, 9055 SourceLocation EndLoc, Stmt *AStmt) { 9056 if (!AStmt) 9057 return StmtError(); 9058 9059 auto *CS = cast<CapturedStmt>(AStmt); 9060 // 1.2.2 OpenMP Language Terminology 9061 // Structured block - An executable statement with a single entry at the 9062 // top and a single exit at the bottom. 9063 // The point of exit cannot be a branch out of the structured block. 9064 // longjmp() and throw() must not violate the entry/exit criteria. 9065 CS->getCapturedDecl()->setNothrow(); 9066 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9067 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9068 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9069 // 1.2.2 OpenMP Language Terminology 9070 // Structured block - An executable statement with a single entry at the 9071 // top and a single exit at the bottom. 9072 // The point of exit cannot be a branch out of the structured block. 9073 // longjmp() and throw() must not violate the entry/exit criteria. 9074 CS->getCapturedDecl()->setNothrow(); 9075 } 9076 9077 // OpenMP [2.10.2, Restrictions, p. 99] 9078 // At least one map clause must appear on the directive. 9079 if (!hasClauses(Clauses, OMPC_map)) { 9080 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9081 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9082 return StmtError(); 9083 } 9084 9085 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9086 AStmt); 9087 } 9088 9089 StmtResult 9090 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9091 SourceLocation StartLoc, 9092 SourceLocation EndLoc, Stmt *AStmt) { 9093 if (!AStmt) 9094 return StmtError(); 9095 9096 auto *CS = cast<CapturedStmt>(AStmt); 9097 // 1.2.2 OpenMP Language Terminology 9098 // Structured block - An executable statement with a single entry at the 9099 // top and a single exit at the bottom. 9100 // The point of exit cannot be a branch out of the structured block. 9101 // longjmp() and throw() must not violate the entry/exit criteria. 9102 CS->getCapturedDecl()->setNothrow(); 9103 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9104 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9105 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9106 // 1.2.2 OpenMP Language Terminology 9107 // Structured block - An executable statement with a single entry at the 9108 // top and a single exit at the bottom. 9109 // The point of exit cannot be a branch out of the structured block. 9110 // longjmp() and throw() must not violate the entry/exit criteria. 9111 CS->getCapturedDecl()->setNothrow(); 9112 } 9113 9114 // OpenMP [2.10.3, Restrictions, p. 102] 9115 // At least one map clause must appear on the directive. 9116 if (!hasClauses(Clauses, OMPC_map)) { 9117 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9118 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9119 return StmtError(); 9120 } 9121 9122 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9123 AStmt); 9124 } 9125 9126 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9127 SourceLocation StartLoc, 9128 SourceLocation EndLoc, 9129 Stmt *AStmt) { 9130 if (!AStmt) 9131 return StmtError(); 9132 9133 auto *CS = cast<CapturedStmt>(AStmt); 9134 // 1.2.2 OpenMP Language Terminology 9135 // Structured block - An executable statement with a single entry at the 9136 // top and a single exit at the bottom. 9137 // The point of exit cannot be a branch out of the structured block. 9138 // longjmp() and throw() must not violate the entry/exit criteria. 9139 CS->getCapturedDecl()->setNothrow(); 9140 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9141 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9142 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9143 // 1.2.2 OpenMP Language Terminology 9144 // Structured block - An executable statement with a single entry at the 9145 // top and a single exit at the bottom. 9146 // The point of exit cannot be a branch out of the structured block. 9147 // longjmp() and throw() must not violate the entry/exit criteria. 9148 CS->getCapturedDecl()->setNothrow(); 9149 } 9150 9151 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9152 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9153 return StmtError(); 9154 } 9155 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9156 AStmt); 9157 } 9158 9159 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9160 Stmt *AStmt, SourceLocation StartLoc, 9161 SourceLocation EndLoc) { 9162 if (!AStmt) 9163 return StmtError(); 9164 9165 auto *CS = cast<CapturedStmt>(AStmt); 9166 // 1.2.2 OpenMP Language Terminology 9167 // Structured block - An executable statement with a single entry at the 9168 // top and a single exit at the bottom. 9169 // The point of exit cannot be a branch out of the structured block. 9170 // longjmp() and throw() must not violate the entry/exit criteria. 9171 CS->getCapturedDecl()->setNothrow(); 9172 9173 setFunctionHasBranchProtectedScope(); 9174 9175 DSAStack->setParentTeamsRegionLoc(StartLoc); 9176 9177 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9178 } 9179 9180 StmtResult 9181 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9182 SourceLocation EndLoc, 9183 OpenMPDirectiveKind CancelRegion) { 9184 if (DSAStack->isParentNowaitRegion()) { 9185 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9186 return StmtError(); 9187 } 9188 if (DSAStack->isParentOrderedRegion()) { 9189 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9190 return StmtError(); 9191 } 9192 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9193 CancelRegion); 9194 } 9195 9196 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9197 SourceLocation StartLoc, 9198 SourceLocation EndLoc, 9199 OpenMPDirectiveKind CancelRegion) { 9200 if (DSAStack->isParentNowaitRegion()) { 9201 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9202 return StmtError(); 9203 } 9204 if (DSAStack->isParentOrderedRegion()) { 9205 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9206 return StmtError(); 9207 } 9208 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9209 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9210 CancelRegion); 9211 } 9212 9213 static bool checkGrainsizeNumTasksClauses(Sema &S, 9214 ArrayRef<OMPClause *> Clauses) { 9215 const OMPClause *PrevClause = nullptr; 9216 bool ErrorFound = false; 9217 for (const OMPClause *C : Clauses) { 9218 if (C->getClauseKind() == OMPC_grainsize || 9219 C->getClauseKind() == OMPC_num_tasks) { 9220 if (!PrevClause) 9221 PrevClause = C; 9222 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9223 S.Diag(C->getBeginLoc(), 9224 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9225 << getOpenMPClauseName(C->getClauseKind()) 9226 << getOpenMPClauseName(PrevClause->getClauseKind()); 9227 S.Diag(PrevClause->getBeginLoc(), 9228 diag::note_omp_previous_grainsize_num_tasks) 9229 << getOpenMPClauseName(PrevClause->getClauseKind()); 9230 ErrorFound = true; 9231 } 9232 } 9233 } 9234 return ErrorFound; 9235 } 9236 9237 static bool checkReductionClauseWithNogroup(Sema &S, 9238 ArrayRef<OMPClause *> Clauses) { 9239 const OMPClause *ReductionClause = nullptr; 9240 const OMPClause *NogroupClause = nullptr; 9241 for (const OMPClause *C : Clauses) { 9242 if (C->getClauseKind() == OMPC_reduction) { 9243 ReductionClause = C; 9244 if (NogroupClause) 9245 break; 9246 continue; 9247 } 9248 if (C->getClauseKind() == OMPC_nogroup) { 9249 NogroupClause = C; 9250 if (ReductionClause) 9251 break; 9252 continue; 9253 } 9254 } 9255 if (ReductionClause && NogroupClause) { 9256 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9257 << SourceRange(NogroupClause->getBeginLoc(), 9258 NogroupClause->getEndLoc()); 9259 return true; 9260 } 9261 return false; 9262 } 9263 9264 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9265 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9266 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9267 if (!AStmt) 9268 return StmtError(); 9269 9270 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9271 OMPLoopDirective::HelperExprs B; 9272 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9273 // define the nested loops number. 9274 unsigned NestedLoopCount = 9275 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9276 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9277 VarsWithImplicitDSA, B); 9278 if (NestedLoopCount == 0) 9279 return StmtError(); 9280 9281 assert((CurContext->isDependentContext() || B.builtAll()) && 9282 "omp for loop exprs were not built"); 9283 9284 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9285 // The grainsize clause and num_tasks clause are mutually exclusive and may 9286 // not appear on the same taskloop directive. 9287 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9288 return StmtError(); 9289 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9290 // If a reduction clause is present on the taskloop directive, the nogroup 9291 // clause must not be specified. 9292 if (checkReductionClauseWithNogroup(*this, Clauses)) 9293 return StmtError(); 9294 9295 setFunctionHasBranchProtectedScope(); 9296 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9297 NestedLoopCount, Clauses, AStmt, B); 9298 } 9299 9300 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9301 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9302 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9303 if (!AStmt) 9304 return StmtError(); 9305 9306 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9307 OMPLoopDirective::HelperExprs B; 9308 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9309 // define the nested loops number. 9310 unsigned NestedLoopCount = 9311 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9312 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9313 VarsWithImplicitDSA, B); 9314 if (NestedLoopCount == 0) 9315 return StmtError(); 9316 9317 assert((CurContext->isDependentContext() || B.builtAll()) && 9318 "omp for loop exprs were not built"); 9319 9320 if (!CurContext->isDependentContext()) { 9321 // Finalize the clauses that need pre-built expressions for CodeGen. 9322 for (OMPClause *C : Clauses) { 9323 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9324 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9325 B.NumIterations, *this, CurScope, 9326 DSAStack)) 9327 return StmtError(); 9328 } 9329 } 9330 9331 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9332 // The grainsize clause and num_tasks clause are mutually exclusive and may 9333 // not appear on the same taskloop directive. 9334 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9335 return StmtError(); 9336 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9337 // If a reduction clause is present on the taskloop directive, the nogroup 9338 // clause must not be specified. 9339 if (checkReductionClauseWithNogroup(*this, Clauses)) 9340 return StmtError(); 9341 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9342 return StmtError(); 9343 9344 setFunctionHasBranchProtectedScope(); 9345 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9346 NestedLoopCount, Clauses, AStmt, B); 9347 } 9348 9349 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 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_master_taskloop, 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 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9370 // The grainsize clause and num_tasks clause are mutually exclusive and may 9371 // not appear on the same taskloop directive. 9372 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9373 return StmtError(); 9374 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9375 // If a reduction clause is present on the taskloop directive, the nogroup 9376 // clause must not be specified. 9377 if (checkReductionClauseWithNogroup(*this, Clauses)) 9378 return StmtError(); 9379 9380 setFunctionHasBranchProtectedScope(); 9381 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9382 NestedLoopCount, Clauses, AStmt, B); 9383 } 9384 9385 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9386 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9387 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9388 if (!AStmt) 9389 return StmtError(); 9390 9391 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9392 OMPLoopDirective::HelperExprs B; 9393 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9394 // define the nested loops number. 9395 unsigned NestedLoopCount = 9396 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9397 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9398 VarsWithImplicitDSA, B); 9399 if (NestedLoopCount == 0) 9400 return StmtError(); 9401 9402 assert((CurContext->isDependentContext() || B.builtAll()) && 9403 "omp for loop exprs were not built"); 9404 9405 if (!CurContext->isDependentContext()) { 9406 // Finalize the clauses that need pre-built expressions for CodeGen. 9407 for (OMPClause *C : Clauses) { 9408 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9409 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9410 B.NumIterations, *this, CurScope, 9411 DSAStack)) 9412 return StmtError(); 9413 } 9414 } 9415 9416 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9417 // The grainsize clause and num_tasks clause are mutually exclusive and may 9418 // not appear on the same taskloop directive. 9419 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9420 return StmtError(); 9421 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9422 // If a reduction clause is present on the taskloop directive, the nogroup 9423 // clause must not be specified. 9424 if (checkReductionClauseWithNogroup(*this, Clauses)) 9425 return StmtError(); 9426 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9427 return StmtError(); 9428 9429 setFunctionHasBranchProtectedScope(); 9430 return OMPMasterTaskLoopSimdDirective::Create( 9431 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9432 } 9433 9434 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 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 auto *CS = cast<CapturedStmt>(AStmt); 9442 // 1.2.2 OpenMP Language Terminology 9443 // Structured block - An executable statement with a single entry at the 9444 // top and a single exit at the bottom. 9445 // The point of exit cannot be a branch out of the structured block. 9446 // longjmp() and throw() must not violate the entry/exit criteria. 9447 CS->getCapturedDecl()->setNothrow(); 9448 for (int ThisCaptureLevel = 9449 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9450 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9451 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9452 // 1.2.2 OpenMP Language Terminology 9453 // Structured block - An executable statement with a single entry at the 9454 // top and a single exit at the bottom. 9455 // The point of exit cannot be a branch out of the structured block. 9456 // longjmp() and throw() must not violate the entry/exit criteria. 9457 CS->getCapturedDecl()->setNothrow(); 9458 } 9459 9460 OMPLoopDirective::HelperExprs B; 9461 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9462 // define the nested loops number. 9463 unsigned NestedLoopCount = checkOpenMPLoop( 9464 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9465 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9466 VarsWithImplicitDSA, B); 9467 if (NestedLoopCount == 0) 9468 return StmtError(); 9469 9470 assert((CurContext->isDependentContext() || B.builtAll()) && 9471 "omp for loop exprs were not built"); 9472 9473 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9474 // The grainsize clause and num_tasks clause are mutually exclusive and may 9475 // not appear on the same taskloop directive. 9476 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9477 return StmtError(); 9478 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9479 // If a reduction clause is present on the taskloop directive, the nogroup 9480 // clause must not be specified. 9481 if (checkReductionClauseWithNogroup(*this, Clauses)) 9482 return StmtError(); 9483 9484 setFunctionHasBranchProtectedScope(); 9485 return OMPParallelMasterTaskLoopDirective::Create( 9486 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9487 } 9488 9489 StmtResult Sema::ActOnOpenMPDistributeDirective( 9490 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9491 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9492 if (!AStmt) 9493 return StmtError(); 9494 9495 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9496 OMPLoopDirective::HelperExprs B; 9497 // In presence of clause 'collapse' with number of loops, it will 9498 // define the nested loops number. 9499 unsigned NestedLoopCount = 9500 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9501 nullptr /*ordered not a clause on distribute*/, AStmt, 9502 *this, *DSAStack, VarsWithImplicitDSA, B); 9503 if (NestedLoopCount == 0) 9504 return StmtError(); 9505 9506 assert((CurContext->isDependentContext() || B.builtAll()) && 9507 "omp for loop exprs were not built"); 9508 9509 setFunctionHasBranchProtectedScope(); 9510 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9511 NestedLoopCount, Clauses, AStmt, B); 9512 } 9513 9514 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9515 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9516 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9517 if (!AStmt) 9518 return StmtError(); 9519 9520 auto *CS = cast<CapturedStmt>(AStmt); 9521 // 1.2.2 OpenMP Language Terminology 9522 // Structured block - An executable statement with a single entry at the 9523 // top and a single exit at the bottom. 9524 // The point of exit cannot be a branch out of the structured block. 9525 // longjmp() and throw() must not violate the entry/exit criteria. 9526 CS->getCapturedDecl()->setNothrow(); 9527 for (int ThisCaptureLevel = 9528 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9529 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9530 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9531 // 1.2.2 OpenMP Language Terminology 9532 // Structured block - An executable statement with a single entry at the 9533 // top and a single exit at the bottom. 9534 // The point of exit cannot be a branch out of the structured block. 9535 // longjmp() and throw() must not violate the entry/exit criteria. 9536 CS->getCapturedDecl()->setNothrow(); 9537 } 9538 9539 OMPLoopDirective::HelperExprs B; 9540 // In presence of clause 'collapse' with number of loops, it will 9541 // define the nested loops number. 9542 unsigned NestedLoopCount = checkOpenMPLoop( 9543 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9544 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9545 VarsWithImplicitDSA, B); 9546 if (NestedLoopCount == 0) 9547 return StmtError(); 9548 9549 assert((CurContext->isDependentContext() || B.builtAll()) && 9550 "omp for loop exprs were not built"); 9551 9552 setFunctionHasBranchProtectedScope(); 9553 return OMPDistributeParallelForDirective::Create( 9554 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9555 DSAStack->isCancelRegion()); 9556 } 9557 9558 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9559 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9560 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9561 if (!AStmt) 9562 return StmtError(); 9563 9564 auto *CS = cast<CapturedStmt>(AStmt); 9565 // 1.2.2 OpenMP Language Terminology 9566 // Structured block - An executable statement with a single entry at the 9567 // top and a single exit at the bottom. 9568 // The point of exit cannot be a branch out of the structured block. 9569 // longjmp() and throw() must not violate the entry/exit criteria. 9570 CS->getCapturedDecl()->setNothrow(); 9571 for (int ThisCaptureLevel = 9572 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9573 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9574 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9575 // 1.2.2 OpenMP Language Terminology 9576 // Structured block - An executable statement with a single entry at the 9577 // top and a single exit at the bottom. 9578 // The point of exit cannot be a branch out of the structured block. 9579 // longjmp() and throw() must not violate the entry/exit criteria. 9580 CS->getCapturedDecl()->setNothrow(); 9581 } 9582 9583 OMPLoopDirective::HelperExprs B; 9584 // In presence of clause 'collapse' with number of loops, it will 9585 // define the nested loops number. 9586 unsigned NestedLoopCount = checkOpenMPLoop( 9587 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9588 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9589 VarsWithImplicitDSA, B); 9590 if (NestedLoopCount == 0) 9591 return StmtError(); 9592 9593 assert((CurContext->isDependentContext() || B.builtAll()) && 9594 "omp for loop exprs were not built"); 9595 9596 if (!CurContext->isDependentContext()) { 9597 // Finalize the clauses that need pre-built expressions for CodeGen. 9598 for (OMPClause *C : Clauses) { 9599 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9600 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9601 B.NumIterations, *this, CurScope, 9602 DSAStack)) 9603 return StmtError(); 9604 } 9605 } 9606 9607 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9608 return StmtError(); 9609 9610 setFunctionHasBranchProtectedScope(); 9611 return OMPDistributeParallelForSimdDirective::Create( 9612 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9613 } 9614 9615 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9616 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9617 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9618 if (!AStmt) 9619 return StmtError(); 9620 9621 auto *CS = cast<CapturedStmt>(AStmt); 9622 // 1.2.2 OpenMP Language Terminology 9623 // Structured block - An executable statement with a single entry at the 9624 // top and a single exit at the bottom. 9625 // The point of exit cannot be a branch out of the structured block. 9626 // longjmp() and throw() must not violate the entry/exit criteria. 9627 CS->getCapturedDecl()->setNothrow(); 9628 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9629 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9630 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9631 // 1.2.2 OpenMP Language Terminology 9632 // Structured block - An executable statement with a single entry at the 9633 // top and a single exit at the bottom. 9634 // The point of exit cannot be a branch out of the structured block. 9635 // longjmp() and throw() must not violate the entry/exit criteria. 9636 CS->getCapturedDecl()->setNothrow(); 9637 } 9638 9639 OMPLoopDirective::HelperExprs B; 9640 // In presence of clause 'collapse' with number of loops, it will 9641 // define the nested loops number. 9642 unsigned NestedLoopCount = 9643 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9644 nullptr /*ordered not a clause on distribute*/, CS, *this, 9645 *DSAStack, VarsWithImplicitDSA, B); 9646 if (NestedLoopCount == 0) 9647 return StmtError(); 9648 9649 assert((CurContext->isDependentContext() || B.builtAll()) && 9650 "omp for loop exprs were not built"); 9651 9652 if (!CurContext->isDependentContext()) { 9653 // Finalize the clauses that need pre-built expressions for CodeGen. 9654 for (OMPClause *C : Clauses) { 9655 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9656 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9657 B.NumIterations, *this, CurScope, 9658 DSAStack)) 9659 return StmtError(); 9660 } 9661 } 9662 9663 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9664 return StmtError(); 9665 9666 setFunctionHasBranchProtectedScope(); 9667 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9668 NestedLoopCount, Clauses, AStmt, B); 9669 } 9670 9671 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9672 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9673 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9674 if (!AStmt) 9675 return StmtError(); 9676 9677 auto *CS = cast<CapturedStmt>(AStmt); 9678 // 1.2.2 OpenMP Language Terminology 9679 // Structured block - An executable statement with a single entry at the 9680 // top and a single exit at the bottom. 9681 // The point of exit cannot be a branch out of the structured block. 9682 // longjmp() and throw() must not violate the entry/exit criteria. 9683 CS->getCapturedDecl()->setNothrow(); 9684 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9685 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9686 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9687 // 1.2.2 OpenMP Language Terminology 9688 // Structured block - An executable statement with a single entry at the 9689 // top and a single exit at the bottom. 9690 // The point of exit cannot be a branch out of the structured block. 9691 // longjmp() and throw() must not violate the entry/exit criteria. 9692 CS->getCapturedDecl()->setNothrow(); 9693 } 9694 9695 OMPLoopDirective::HelperExprs B; 9696 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9697 // define the nested loops number. 9698 unsigned NestedLoopCount = checkOpenMPLoop( 9699 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9700 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9701 VarsWithImplicitDSA, B); 9702 if (NestedLoopCount == 0) 9703 return StmtError(); 9704 9705 assert((CurContext->isDependentContext() || B.builtAll()) && 9706 "omp target parallel for simd loop exprs were not built"); 9707 9708 if (!CurContext->isDependentContext()) { 9709 // Finalize the clauses that need pre-built expressions for CodeGen. 9710 for (OMPClause *C : Clauses) { 9711 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9712 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9713 B.NumIterations, *this, CurScope, 9714 DSAStack)) 9715 return StmtError(); 9716 } 9717 } 9718 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9719 return StmtError(); 9720 9721 setFunctionHasBranchProtectedScope(); 9722 return OMPTargetParallelForSimdDirective::Create( 9723 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9724 } 9725 9726 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9727 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9728 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9729 if (!AStmt) 9730 return StmtError(); 9731 9732 auto *CS = cast<CapturedStmt>(AStmt); 9733 // 1.2.2 OpenMP Language Terminology 9734 // Structured block - An executable statement with a single entry at the 9735 // top and a single exit at the bottom. 9736 // The point of exit cannot be a branch out of the structured block. 9737 // longjmp() and throw() must not violate the entry/exit criteria. 9738 CS->getCapturedDecl()->setNothrow(); 9739 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9740 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9741 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9742 // 1.2.2 OpenMP Language Terminology 9743 // Structured block - An executable statement with a single entry at the 9744 // top and a single exit at the bottom. 9745 // The point of exit cannot be a branch out of the structured block. 9746 // longjmp() and throw() must not violate the entry/exit criteria. 9747 CS->getCapturedDecl()->setNothrow(); 9748 } 9749 9750 OMPLoopDirective::HelperExprs B; 9751 // In presence of clause 'collapse' with number of loops, it will define the 9752 // nested loops number. 9753 unsigned NestedLoopCount = 9754 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9755 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9756 VarsWithImplicitDSA, B); 9757 if (NestedLoopCount == 0) 9758 return StmtError(); 9759 9760 assert((CurContext->isDependentContext() || B.builtAll()) && 9761 "omp target simd loop exprs were not built"); 9762 9763 if (!CurContext->isDependentContext()) { 9764 // Finalize the clauses that need pre-built expressions for CodeGen. 9765 for (OMPClause *C : Clauses) { 9766 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9767 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9768 B.NumIterations, *this, CurScope, 9769 DSAStack)) 9770 return StmtError(); 9771 } 9772 } 9773 9774 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9775 return StmtError(); 9776 9777 setFunctionHasBranchProtectedScope(); 9778 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9779 NestedLoopCount, Clauses, AStmt, B); 9780 } 9781 9782 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9783 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9784 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9785 if (!AStmt) 9786 return StmtError(); 9787 9788 auto *CS = cast<CapturedStmt>(AStmt); 9789 // 1.2.2 OpenMP Language Terminology 9790 // Structured block - An executable statement with a single entry at the 9791 // top and a single exit at the bottom. 9792 // The point of exit cannot be a branch out of the structured block. 9793 // longjmp() and throw() must not violate the entry/exit criteria. 9794 CS->getCapturedDecl()->setNothrow(); 9795 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9796 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9797 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9798 // 1.2.2 OpenMP Language Terminology 9799 // Structured block - An executable statement with a single entry at the 9800 // top and a single exit at the bottom. 9801 // The point of exit cannot be a branch out of the structured block. 9802 // longjmp() and throw() must not violate the entry/exit criteria. 9803 CS->getCapturedDecl()->setNothrow(); 9804 } 9805 9806 OMPLoopDirective::HelperExprs B; 9807 // In presence of clause 'collapse' with number of loops, it will 9808 // define the nested loops number. 9809 unsigned NestedLoopCount = 9810 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9811 nullptr /*ordered not a clause on distribute*/, CS, *this, 9812 *DSAStack, VarsWithImplicitDSA, B); 9813 if (NestedLoopCount == 0) 9814 return StmtError(); 9815 9816 assert((CurContext->isDependentContext() || B.builtAll()) && 9817 "omp teams distribute loop exprs were not built"); 9818 9819 setFunctionHasBranchProtectedScope(); 9820 9821 DSAStack->setParentTeamsRegionLoc(StartLoc); 9822 9823 return OMPTeamsDistributeDirective::Create( 9824 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9825 } 9826 9827 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9828 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9829 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9830 if (!AStmt) 9831 return StmtError(); 9832 9833 auto *CS = cast<CapturedStmt>(AStmt); 9834 // 1.2.2 OpenMP Language Terminology 9835 // Structured block - An executable statement with a single entry at the 9836 // top and a single exit at the bottom. 9837 // The point of exit cannot be a branch out of the structured block. 9838 // longjmp() and throw() must not violate the entry/exit criteria. 9839 CS->getCapturedDecl()->setNothrow(); 9840 for (int ThisCaptureLevel = 9841 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9842 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9843 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9844 // 1.2.2 OpenMP Language Terminology 9845 // Structured block - An executable statement with a single entry at the 9846 // top and a single exit at the bottom. 9847 // The point of exit cannot be a branch out of the structured block. 9848 // longjmp() and throw() must not violate the entry/exit criteria. 9849 CS->getCapturedDecl()->setNothrow(); 9850 } 9851 9852 9853 OMPLoopDirective::HelperExprs B; 9854 // In presence of clause 'collapse' with number of loops, it will 9855 // define the nested loops number. 9856 unsigned NestedLoopCount = checkOpenMPLoop( 9857 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9858 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9859 VarsWithImplicitDSA, B); 9860 9861 if (NestedLoopCount == 0) 9862 return StmtError(); 9863 9864 assert((CurContext->isDependentContext() || B.builtAll()) && 9865 "omp teams distribute simd loop exprs were not built"); 9866 9867 if (!CurContext->isDependentContext()) { 9868 // Finalize the clauses that need pre-built expressions for CodeGen. 9869 for (OMPClause *C : Clauses) { 9870 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9871 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9872 B.NumIterations, *this, CurScope, 9873 DSAStack)) 9874 return StmtError(); 9875 } 9876 } 9877 9878 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9879 return StmtError(); 9880 9881 setFunctionHasBranchProtectedScope(); 9882 9883 DSAStack->setParentTeamsRegionLoc(StartLoc); 9884 9885 return OMPTeamsDistributeSimdDirective::Create( 9886 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9887 } 9888 9889 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9890 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9891 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9892 if (!AStmt) 9893 return StmtError(); 9894 9895 auto *CS = cast<CapturedStmt>(AStmt); 9896 // 1.2.2 OpenMP Language Terminology 9897 // Structured block - An executable statement with a single entry at the 9898 // top and a single exit at the bottom. 9899 // The point of exit cannot be a branch out of the structured block. 9900 // longjmp() and throw() must not violate the entry/exit criteria. 9901 CS->getCapturedDecl()->setNothrow(); 9902 9903 for (int ThisCaptureLevel = 9904 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9905 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9906 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9907 // 1.2.2 OpenMP Language Terminology 9908 // Structured block - An executable statement with a single entry at the 9909 // top and a single exit at the bottom. 9910 // The point of exit cannot be a branch out of the structured block. 9911 // longjmp() and throw() must not violate the entry/exit criteria. 9912 CS->getCapturedDecl()->setNothrow(); 9913 } 9914 9915 OMPLoopDirective::HelperExprs B; 9916 // In presence of clause 'collapse' with number of loops, it will 9917 // define the nested loops number. 9918 unsigned NestedLoopCount = checkOpenMPLoop( 9919 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9920 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9921 VarsWithImplicitDSA, B); 9922 9923 if (NestedLoopCount == 0) 9924 return StmtError(); 9925 9926 assert((CurContext->isDependentContext() || B.builtAll()) && 9927 "omp for loop exprs were not built"); 9928 9929 if (!CurContext->isDependentContext()) { 9930 // Finalize the clauses that need pre-built expressions for CodeGen. 9931 for (OMPClause *C : Clauses) { 9932 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9933 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9934 B.NumIterations, *this, CurScope, 9935 DSAStack)) 9936 return StmtError(); 9937 } 9938 } 9939 9940 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9941 return StmtError(); 9942 9943 setFunctionHasBranchProtectedScope(); 9944 9945 DSAStack->setParentTeamsRegionLoc(StartLoc); 9946 9947 return OMPTeamsDistributeParallelForSimdDirective::Create( 9948 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9949 } 9950 9951 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9952 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9953 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9954 if (!AStmt) 9955 return StmtError(); 9956 9957 auto *CS = cast<CapturedStmt>(AStmt); 9958 // 1.2.2 OpenMP Language Terminology 9959 // Structured block - An executable statement with a single entry at the 9960 // top and a single exit at the bottom. 9961 // The point of exit cannot be a branch out of the structured block. 9962 // longjmp() and throw() must not violate the entry/exit criteria. 9963 CS->getCapturedDecl()->setNothrow(); 9964 9965 for (int ThisCaptureLevel = 9966 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9967 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9968 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9969 // 1.2.2 OpenMP Language Terminology 9970 // Structured block - An executable statement with a single entry at the 9971 // top and a single exit at the bottom. 9972 // The point of exit cannot be a branch out of the structured block. 9973 // longjmp() and throw() must not violate the entry/exit criteria. 9974 CS->getCapturedDecl()->setNothrow(); 9975 } 9976 9977 OMPLoopDirective::HelperExprs B; 9978 // In presence of clause 'collapse' with number of loops, it will 9979 // define the nested loops number. 9980 unsigned NestedLoopCount = checkOpenMPLoop( 9981 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9982 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9983 VarsWithImplicitDSA, B); 9984 9985 if (NestedLoopCount == 0) 9986 return StmtError(); 9987 9988 assert((CurContext->isDependentContext() || B.builtAll()) && 9989 "omp for loop exprs were not built"); 9990 9991 setFunctionHasBranchProtectedScope(); 9992 9993 DSAStack->setParentTeamsRegionLoc(StartLoc); 9994 9995 return OMPTeamsDistributeParallelForDirective::Create( 9996 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9997 DSAStack->isCancelRegion()); 9998 } 9999 10000 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10001 Stmt *AStmt, 10002 SourceLocation StartLoc, 10003 SourceLocation EndLoc) { 10004 if (!AStmt) 10005 return StmtError(); 10006 10007 auto *CS = cast<CapturedStmt>(AStmt); 10008 // 1.2.2 OpenMP Language Terminology 10009 // Structured block - An executable statement with a single entry at the 10010 // top and a single exit at the bottom. 10011 // The point of exit cannot be a branch out of the structured block. 10012 // longjmp() and throw() must not violate the entry/exit criteria. 10013 CS->getCapturedDecl()->setNothrow(); 10014 10015 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10016 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10017 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10018 // 1.2.2 OpenMP Language Terminology 10019 // Structured block - An executable statement with a single entry at the 10020 // top and a single exit at the bottom. 10021 // The point of exit cannot be a branch out of the structured block. 10022 // longjmp() and throw() must not violate the entry/exit criteria. 10023 CS->getCapturedDecl()->setNothrow(); 10024 } 10025 setFunctionHasBranchProtectedScope(); 10026 10027 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10028 AStmt); 10029 } 10030 10031 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10032 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10033 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10034 if (!AStmt) 10035 return StmtError(); 10036 10037 auto *CS = cast<CapturedStmt>(AStmt); 10038 // 1.2.2 OpenMP Language Terminology 10039 // Structured block - An executable statement with a single entry at the 10040 // top and a single exit at the bottom. 10041 // The point of exit cannot be a branch out of the structured block. 10042 // longjmp() and throw() must not violate the entry/exit criteria. 10043 CS->getCapturedDecl()->setNothrow(); 10044 for (int ThisCaptureLevel = 10045 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10046 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10047 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10048 // 1.2.2 OpenMP Language Terminology 10049 // Structured block - An executable statement with a single entry at the 10050 // top and a single exit at the bottom. 10051 // The point of exit cannot be a branch out of the structured block. 10052 // longjmp() and throw() must not violate the entry/exit criteria. 10053 CS->getCapturedDecl()->setNothrow(); 10054 } 10055 10056 OMPLoopDirective::HelperExprs B; 10057 // In presence of clause 'collapse' with number of loops, it will 10058 // define the nested loops number. 10059 unsigned NestedLoopCount = checkOpenMPLoop( 10060 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10061 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10062 VarsWithImplicitDSA, B); 10063 if (NestedLoopCount == 0) 10064 return StmtError(); 10065 10066 assert((CurContext->isDependentContext() || B.builtAll()) && 10067 "omp target teams distribute loop exprs were not built"); 10068 10069 setFunctionHasBranchProtectedScope(); 10070 return OMPTargetTeamsDistributeDirective::Create( 10071 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10072 } 10073 10074 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10075 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10076 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10077 if (!AStmt) 10078 return StmtError(); 10079 10080 auto *CS = cast<CapturedStmt>(AStmt); 10081 // 1.2.2 OpenMP Language Terminology 10082 // Structured block - An executable statement with a single entry at the 10083 // top and a single exit at the bottom. 10084 // The point of exit cannot be a branch out of the structured block. 10085 // longjmp() and throw() must not violate the entry/exit criteria. 10086 CS->getCapturedDecl()->setNothrow(); 10087 for (int ThisCaptureLevel = 10088 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10089 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10090 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10091 // 1.2.2 OpenMP Language Terminology 10092 // Structured block - An executable statement with a single entry at the 10093 // top and a single exit at the bottom. 10094 // The point of exit cannot be a branch out of the structured block. 10095 // longjmp() and throw() must not violate the entry/exit criteria. 10096 CS->getCapturedDecl()->setNothrow(); 10097 } 10098 10099 OMPLoopDirective::HelperExprs B; 10100 // In presence of clause 'collapse' with number of loops, it will 10101 // define the nested loops number. 10102 unsigned NestedLoopCount = checkOpenMPLoop( 10103 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10104 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10105 VarsWithImplicitDSA, B); 10106 if (NestedLoopCount == 0) 10107 return StmtError(); 10108 10109 assert((CurContext->isDependentContext() || B.builtAll()) && 10110 "omp target teams distribute parallel for loop exprs were not built"); 10111 10112 if (!CurContext->isDependentContext()) { 10113 // Finalize the clauses that need pre-built expressions for CodeGen. 10114 for (OMPClause *C : Clauses) { 10115 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10116 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10117 B.NumIterations, *this, CurScope, 10118 DSAStack)) 10119 return StmtError(); 10120 } 10121 } 10122 10123 setFunctionHasBranchProtectedScope(); 10124 return OMPTargetTeamsDistributeParallelForDirective::Create( 10125 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10126 DSAStack->isCancelRegion()); 10127 } 10128 10129 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10130 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10131 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10132 if (!AStmt) 10133 return StmtError(); 10134 10135 auto *CS = cast<CapturedStmt>(AStmt); 10136 // 1.2.2 OpenMP Language Terminology 10137 // Structured block - An executable statement with a single entry at the 10138 // top and a single exit at the bottom. 10139 // The point of exit cannot be a branch out of the structured block. 10140 // longjmp() and throw() must not violate the entry/exit criteria. 10141 CS->getCapturedDecl()->setNothrow(); 10142 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10143 OMPD_target_teams_distribute_parallel_for_simd); 10144 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10145 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10146 // 1.2.2 OpenMP Language Terminology 10147 // Structured block - An executable statement with a single entry at the 10148 // top and a single exit at the bottom. 10149 // The point of exit cannot be a branch out of the structured block. 10150 // longjmp() and throw() must not violate the entry/exit criteria. 10151 CS->getCapturedDecl()->setNothrow(); 10152 } 10153 10154 OMPLoopDirective::HelperExprs B; 10155 // In presence of clause 'collapse' with number of loops, it will 10156 // define the nested loops number. 10157 unsigned NestedLoopCount = 10158 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10159 getCollapseNumberExpr(Clauses), 10160 nullptr /*ordered not a clause on distribute*/, CS, *this, 10161 *DSAStack, VarsWithImplicitDSA, B); 10162 if (NestedLoopCount == 0) 10163 return StmtError(); 10164 10165 assert((CurContext->isDependentContext() || B.builtAll()) && 10166 "omp target teams distribute parallel for simd loop exprs were not " 10167 "built"); 10168 10169 if (!CurContext->isDependentContext()) { 10170 // Finalize the clauses that need pre-built expressions for CodeGen. 10171 for (OMPClause *C : Clauses) { 10172 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10173 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10174 B.NumIterations, *this, CurScope, 10175 DSAStack)) 10176 return StmtError(); 10177 } 10178 } 10179 10180 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10181 return StmtError(); 10182 10183 setFunctionHasBranchProtectedScope(); 10184 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10185 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10186 } 10187 10188 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10189 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10190 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10191 if (!AStmt) 10192 return StmtError(); 10193 10194 auto *CS = cast<CapturedStmt>(AStmt); 10195 // 1.2.2 OpenMP Language Terminology 10196 // Structured block - An executable statement with a single entry at the 10197 // top and a single exit at the bottom. 10198 // The point of exit cannot be a branch out of the structured block. 10199 // longjmp() and throw() must not violate the entry/exit criteria. 10200 CS->getCapturedDecl()->setNothrow(); 10201 for (int ThisCaptureLevel = 10202 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10203 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10204 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10205 // 1.2.2 OpenMP Language Terminology 10206 // Structured block - An executable statement with a single entry at the 10207 // top and a single exit at the bottom. 10208 // The point of exit cannot be a branch out of the structured block. 10209 // longjmp() and throw() must not violate the entry/exit criteria. 10210 CS->getCapturedDecl()->setNothrow(); 10211 } 10212 10213 OMPLoopDirective::HelperExprs B; 10214 // In presence of clause 'collapse' with number of loops, it will 10215 // define the nested loops number. 10216 unsigned NestedLoopCount = checkOpenMPLoop( 10217 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10218 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10219 VarsWithImplicitDSA, B); 10220 if (NestedLoopCount == 0) 10221 return StmtError(); 10222 10223 assert((CurContext->isDependentContext() || B.builtAll()) && 10224 "omp target teams distribute simd loop exprs were not built"); 10225 10226 if (!CurContext->isDependentContext()) { 10227 // Finalize the clauses that need pre-built expressions for CodeGen. 10228 for (OMPClause *C : Clauses) { 10229 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10230 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10231 B.NumIterations, *this, CurScope, 10232 DSAStack)) 10233 return StmtError(); 10234 } 10235 } 10236 10237 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10238 return StmtError(); 10239 10240 setFunctionHasBranchProtectedScope(); 10241 return OMPTargetTeamsDistributeSimdDirective::Create( 10242 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10243 } 10244 10245 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10246 SourceLocation StartLoc, 10247 SourceLocation LParenLoc, 10248 SourceLocation EndLoc) { 10249 OMPClause *Res = nullptr; 10250 switch (Kind) { 10251 case OMPC_final: 10252 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10253 break; 10254 case OMPC_num_threads: 10255 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10256 break; 10257 case OMPC_safelen: 10258 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10259 break; 10260 case OMPC_simdlen: 10261 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10262 break; 10263 case OMPC_allocator: 10264 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10265 break; 10266 case OMPC_collapse: 10267 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10268 break; 10269 case OMPC_ordered: 10270 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10271 break; 10272 case OMPC_device: 10273 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10274 break; 10275 case OMPC_num_teams: 10276 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10277 break; 10278 case OMPC_thread_limit: 10279 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10280 break; 10281 case OMPC_priority: 10282 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10283 break; 10284 case OMPC_grainsize: 10285 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10286 break; 10287 case OMPC_num_tasks: 10288 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10289 break; 10290 case OMPC_hint: 10291 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10292 break; 10293 case OMPC_if: 10294 case OMPC_default: 10295 case OMPC_proc_bind: 10296 case OMPC_schedule: 10297 case OMPC_private: 10298 case OMPC_firstprivate: 10299 case OMPC_lastprivate: 10300 case OMPC_shared: 10301 case OMPC_reduction: 10302 case OMPC_task_reduction: 10303 case OMPC_in_reduction: 10304 case OMPC_linear: 10305 case OMPC_aligned: 10306 case OMPC_copyin: 10307 case OMPC_copyprivate: 10308 case OMPC_nowait: 10309 case OMPC_untied: 10310 case OMPC_mergeable: 10311 case OMPC_threadprivate: 10312 case OMPC_allocate: 10313 case OMPC_flush: 10314 case OMPC_read: 10315 case OMPC_write: 10316 case OMPC_update: 10317 case OMPC_capture: 10318 case OMPC_seq_cst: 10319 case OMPC_depend: 10320 case OMPC_threads: 10321 case OMPC_simd: 10322 case OMPC_map: 10323 case OMPC_nogroup: 10324 case OMPC_dist_schedule: 10325 case OMPC_defaultmap: 10326 case OMPC_unknown: 10327 case OMPC_uniform: 10328 case OMPC_to: 10329 case OMPC_from: 10330 case OMPC_use_device_ptr: 10331 case OMPC_is_device_ptr: 10332 case OMPC_unified_address: 10333 case OMPC_unified_shared_memory: 10334 case OMPC_reverse_offload: 10335 case OMPC_dynamic_allocators: 10336 case OMPC_atomic_default_mem_order: 10337 case OMPC_device_type: 10338 case OMPC_match: 10339 llvm_unreachable("Clause is not allowed."); 10340 } 10341 return Res; 10342 } 10343 10344 // An OpenMP directive such as 'target parallel' has two captured regions: 10345 // for the 'target' and 'parallel' respectively. This function returns 10346 // the region in which to capture expressions associated with a clause. 10347 // A return value of OMPD_unknown signifies that the expression should not 10348 // be captured. 10349 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10350 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10351 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10352 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10353 switch (CKind) { 10354 case OMPC_if: 10355 switch (DKind) { 10356 case OMPD_target_parallel: 10357 case OMPD_target_parallel_for: 10358 case OMPD_target_parallel_for_simd: 10359 // If this clause applies to the nested 'parallel' region, capture within 10360 // the 'target' region, otherwise do not capture. 10361 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10362 CaptureRegion = OMPD_target; 10363 break; 10364 case OMPD_target_teams_distribute_parallel_for: 10365 case OMPD_target_teams_distribute_parallel_for_simd: 10366 // If this clause applies to the nested 'parallel' region, capture within 10367 // the 'teams' region, otherwise do not capture. 10368 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10369 CaptureRegion = OMPD_teams; 10370 break; 10371 case OMPD_teams_distribute_parallel_for: 10372 case OMPD_teams_distribute_parallel_for_simd: 10373 CaptureRegion = OMPD_teams; 10374 break; 10375 case OMPD_target_update: 10376 case OMPD_target_enter_data: 10377 case OMPD_target_exit_data: 10378 CaptureRegion = OMPD_task; 10379 break; 10380 case OMPD_parallel_master_taskloop: 10381 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10382 CaptureRegion = OMPD_parallel; 10383 break; 10384 case OMPD_cancel: 10385 case OMPD_parallel: 10386 case OMPD_parallel_sections: 10387 case OMPD_parallel_for: 10388 case OMPD_parallel_for_simd: 10389 case OMPD_target: 10390 case OMPD_target_simd: 10391 case OMPD_target_teams: 10392 case OMPD_target_teams_distribute: 10393 case OMPD_target_teams_distribute_simd: 10394 case OMPD_distribute_parallel_for: 10395 case OMPD_distribute_parallel_for_simd: 10396 case OMPD_task: 10397 case OMPD_taskloop: 10398 case OMPD_taskloop_simd: 10399 case OMPD_master_taskloop: 10400 case OMPD_master_taskloop_simd: 10401 case OMPD_target_data: 10402 // Do not capture if-clause expressions. 10403 break; 10404 case OMPD_threadprivate: 10405 case OMPD_allocate: 10406 case OMPD_taskyield: 10407 case OMPD_barrier: 10408 case OMPD_taskwait: 10409 case OMPD_cancellation_point: 10410 case OMPD_flush: 10411 case OMPD_declare_reduction: 10412 case OMPD_declare_mapper: 10413 case OMPD_declare_simd: 10414 case OMPD_declare_variant: 10415 case OMPD_declare_target: 10416 case OMPD_end_declare_target: 10417 case OMPD_teams: 10418 case OMPD_simd: 10419 case OMPD_for: 10420 case OMPD_for_simd: 10421 case OMPD_sections: 10422 case OMPD_section: 10423 case OMPD_single: 10424 case OMPD_master: 10425 case OMPD_critical: 10426 case OMPD_taskgroup: 10427 case OMPD_distribute: 10428 case OMPD_ordered: 10429 case OMPD_atomic: 10430 case OMPD_distribute_simd: 10431 case OMPD_teams_distribute: 10432 case OMPD_teams_distribute_simd: 10433 case OMPD_requires: 10434 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10435 case OMPD_unknown: 10436 llvm_unreachable("Unknown OpenMP directive"); 10437 } 10438 break; 10439 case OMPC_num_threads: 10440 switch (DKind) { 10441 case OMPD_target_parallel: 10442 case OMPD_target_parallel_for: 10443 case OMPD_target_parallel_for_simd: 10444 CaptureRegion = OMPD_target; 10445 break; 10446 case OMPD_teams_distribute_parallel_for: 10447 case OMPD_teams_distribute_parallel_for_simd: 10448 case OMPD_target_teams_distribute_parallel_for: 10449 case OMPD_target_teams_distribute_parallel_for_simd: 10450 CaptureRegion = OMPD_teams; 10451 break; 10452 case OMPD_parallel: 10453 case OMPD_parallel_sections: 10454 case OMPD_parallel_for: 10455 case OMPD_parallel_for_simd: 10456 case OMPD_distribute_parallel_for: 10457 case OMPD_distribute_parallel_for_simd: 10458 case OMPD_parallel_master_taskloop: 10459 // Do not capture num_threads-clause expressions. 10460 break; 10461 case OMPD_target_data: 10462 case OMPD_target_enter_data: 10463 case OMPD_target_exit_data: 10464 case OMPD_target_update: 10465 case OMPD_target: 10466 case OMPD_target_simd: 10467 case OMPD_target_teams: 10468 case OMPD_target_teams_distribute: 10469 case OMPD_target_teams_distribute_simd: 10470 case OMPD_cancel: 10471 case OMPD_task: 10472 case OMPD_taskloop: 10473 case OMPD_taskloop_simd: 10474 case OMPD_master_taskloop: 10475 case OMPD_master_taskloop_simd: 10476 case OMPD_threadprivate: 10477 case OMPD_allocate: 10478 case OMPD_taskyield: 10479 case OMPD_barrier: 10480 case OMPD_taskwait: 10481 case OMPD_cancellation_point: 10482 case OMPD_flush: 10483 case OMPD_declare_reduction: 10484 case OMPD_declare_mapper: 10485 case OMPD_declare_simd: 10486 case OMPD_declare_variant: 10487 case OMPD_declare_target: 10488 case OMPD_end_declare_target: 10489 case OMPD_teams: 10490 case OMPD_simd: 10491 case OMPD_for: 10492 case OMPD_for_simd: 10493 case OMPD_sections: 10494 case OMPD_section: 10495 case OMPD_single: 10496 case OMPD_master: 10497 case OMPD_critical: 10498 case OMPD_taskgroup: 10499 case OMPD_distribute: 10500 case OMPD_ordered: 10501 case OMPD_atomic: 10502 case OMPD_distribute_simd: 10503 case OMPD_teams_distribute: 10504 case OMPD_teams_distribute_simd: 10505 case OMPD_requires: 10506 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10507 case OMPD_unknown: 10508 llvm_unreachable("Unknown OpenMP directive"); 10509 } 10510 break; 10511 case OMPC_num_teams: 10512 switch (DKind) { 10513 case OMPD_target_teams: 10514 case OMPD_target_teams_distribute: 10515 case OMPD_target_teams_distribute_simd: 10516 case OMPD_target_teams_distribute_parallel_for: 10517 case OMPD_target_teams_distribute_parallel_for_simd: 10518 CaptureRegion = OMPD_target; 10519 break; 10520 case OMPD_teams_distribute_parallel_for: 10521 case OMPD_teams_distribute_parallel_for_simd: 10522 case OMPD_teams: 10523 case OMPD_teams_distribute: 10524 case OMPD_teams_distribute_simd: 10525 // Do not capture num_teams-clause expressions. 10526 break; 10527 case OMPD_distribute_parallel_for: 10528 case OMPD_distribute_parallel_for_simd: 10529 case OMPD_task: 10530 case OMPD_taskloop: 10531 case OMPD_taskloop_simd: 10532 case OMPD_master_taskloop: 10533 case OMPD_master_taskloop_simd: 10534 case OMPD_parallel_master_taskloop: 10535 case OMPD_target_data: 10536 case OMPD_target_enter_data: 10537 case OMPD_target_exit_data: 10538 case OMPD_target_update: 10539 case OMPD_cancel: 10540 case OMPD_parallel: 10541 case OMPD_parallel_sections: 10542 case OMPD_parallel_for: 10543 case OMPD_parallel_for_simd: 10544 case OMPD_target: 10545 case OMPD_target_simd: 10546 case OMPD_target_parallel: 10547 case OMPD_target_parallel_for: 10548 case OMPD_target_parallel_for_simd: 10549 case OMPD_threadprivate: 10550 case OMPD_allocate: 10551 case OMPD_taskyield: 10552 case OMPD_barrier: 10553 case OMPD_taskwait: 10554 case OMPD_cancellation_point: 10555 case OMPD_flush: 10556 case OMPD_declare_reduction: 10557 case OMPD_declare_mapper: 10558 case OMPD_declare_simd: 10559 case OMPD_declare_variant: 10560 case OMPD_declare_target: 10561 case OMPD_end_declare_target: 10562 case OMPD_simd: 10563 case OMPD_for: 10564 case OMPD_for_simd: 10565 case OMPD_sections: 10566 case OMPD_section: 10567 case OMPD_single: 10568 case OMPD_master: 10569 case OMPD_critical: 10570 case OMPD_taskgroup: 10571 case OMPD_distribute: 10572 case OMPD_ordered: 10573 case OMPD_atomic: 10574 case OMPD_distribute_simd: 10575 case OMPD_requires: 10576 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10577 case OMPD_unknown: 10578 llvm_unreachable("Unknown OpenMP directive"); 10579 } 10580 break; 10581 case OMPC_thread_limit: 10582 switch (DKind) { 10583 case OMPD_target_teams: 10584 case OMPD_target_teams_distribute: 10585 case OMPD_target_teams_distribute_simd: 10586 case OMPD_target_teams_distribute_parallel_for: 10587 case OMPD_target_teams_distribute_parallel_for_simd: 10588 CaptureRegion = OMPD_target; 10589 break; 10590 case OMPD_teams_distribute_parallel_for: 10591 case OMPD_teams_distribute_parallel_for_simd: 10592 case OMPD_teams: 10593 case OMPD_teams_distribute: 10594 case OMPD_teams_distribute_simd: 10595 // Do not capture thread_limit-clause expressions. 10596 break; 10597 case OMPD_distribute_parallel_for: 10598 case OMPD_distribute_parallel_for_simd: 10599 case OMPD_task: 10600 case OMPD_taskloop: 10601 case OMPD_taskloop_simd: 10602 case OMPD_master_taskloop: 10603 case OMPD_master_taskloop_simd: 10604 case OMPD_parallel_master_taskloop: 10605 case OMPD_target_data: 10606 case OMPD_target_enter_data: 10607 case OMPD_target_exit_data: 10608 case OMPD_target_update: 10609 case OMPD_cancel: 10610 case OMPD_parallel: 10611 case OMPD_parallel_sections: 10612 case OMPD_parallel_for: 10613 case OMPD_parallel_for_simd: 10614 case OMPD_target: 10615 case OMPD_target_simd: 10616 case OMPD_target_parallel: 10617 case OMPD_target_parallel_for: 10618 case OMPD_target_parallel_for_simd: 10619 case OMPD_threadprivate: 10620 case OMPD_allocate: 10621 case OMPD_taskyield: 10622 case OMPD_barrier: 10623 case OMPD_taskwait: 10624 case OMPD_cancellation_point: 10625 case OMPD_flush: 10626 case OMPD_declare_reduction: 10627 case OMPD_declare_mapper: 10628 case OMPD_declare_simd: 10629 case OMPD_declare_variant: 10630 case OMPD_declare_target: 10631 case OMPD_end_declare_target: 10632 case OMPD_simd: 10633 case OMPD_for: 10634 case OMPD_for_simd: 10635 case OMPD_sections: 10636 case OMPD_section: 10637 case OMPD_single: 10638 case OMPD_master: 10639 case OMPD_critical: 10640 case OMPD_taskgroup: 10641 case OMPD_distribute: 10642 case OMPD_ordered: 10643 case OMPD_atomic: 10644 case OMPD_distribute_simd: 10645 case OMPD_requires: 10646 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10647 case OMPD_unknown: 10648 llvm_unreachable("Unknown OpenMP directive"); 10649 } 10650 break; 10651 case OMPC_schedule: 10652 switch (DKind) { 10653 case OMPD_parallel_for: 10654 case OMPD_parallel_for_simd: 10655 case OMPD_distribute_parallel_for: 10656 case OMPD_distribute_parallel_for_simd: 10657 case OMPD_teams_distribute_parallel_for: 10658 case OMPD_teams_distribute_parallel_for_simd: 10659 case OMPD_target_parallel_for: 10660 case OMPD_target_parallel_for_simd: 10661 case OMPD_target_teams_distribute_parallel_for: 10662 case OMPD_target_teams_distribute_parallel_for_simd: 10663 CaptureRegion = OMPD_parallel; 10664 break; 10665 case OMPD_for: 10666 case OMPD_for_simd: 10667 // Do not capture schedule-clause expressions. 10668 break; 10669 case OMPD_task: 10670 case OMPD_taskloop: 10671 case OMPD_taskloop_simd: 10672 case OMPD_master_taskloop: 10673 case OMPD_master_taskloop_simd: 10674 case OMPD_parallel_master_taskloop: 10675 case OMPD_target_data: 10676 case OMPD_target_enter_data: 10677 case OMPD_target_exit_data: 10678 case OMPD_target_update: 10679 case OMPD_teams: 10680 case OMPD_teams_distribute: 10681 case OMPD_teams_distribute_simd: 10682 case OMPD_target_teams_distribute: 10683 case OMPD_target_teams_distribute_simd: 10684 case OMPD_target: 10685 case OMPD_target_simd: 10686 case OMPD_target_parallel: 10687 case OMPD_cancel: 10688 case OMPD_parallel: 10689 case OMPD_parallel_sections: 10690 case OMPD_threadprivate: 10691 case OMPD_allocate: 10692 case OMPD_taskyield: 10693 case OMPD_barrier: 10694 case OMPD_taskwait: 10695 case OMPD_cancellation_point: 10696 case OMPD_flush: 10697 case OMPD_declare_reduction: 10698 case OMPD_declare_mapper: 10699 case OMPD_declare_simd: 10700 case OMPD_declare_variant: 10701 case OMPD_declare_target: 10702 case OMPD_end_declare_target: 10703 case OMPD_simd: 10704 case OMPD_sections: 10705 case OMPD_section: 10706 case OMPD_single: 10707 case OMPD_master: 10708 case OMPD_critical: 10709 case OMPD_taskgroup: 10710 case OMPD_distribute: 10711 case OMPD_ordered: 10712 case OMPD_atomic: 10713 case OMPD_distribute_simd: 10714 case OMPD_target_teams: 10715 case OMPD_requires: 10716 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10717 case OMPD_unknown: 10718 llvm_unreachable("Unknown OpenMP directive"); 10719 } 10720 break; 10721 case OMPC_dist_schedule: 10722 switch (DKind) { 10723 case OMPD_teams_distribute_parallel_for: 10724 case OMPD_teams_distribute_parallel_for_simd: 10725 case OMPD_teams_distribute: 10726 case OMPD_teams_distribute_simd: 10727 case OMPD_target_teams_distribute_parallel_for: 10728 case OMPD_target_teams_distribute_parallel_for_simd: 10729 case OMPD_target_teams_distribute: 10730 case OMPD_target_teams_distribute_simd: 10731 CaptureRegion = OMPD_teams; 10732 break; 10733 case OMPD_distribute_parallel_for: 10734 case OMPD_distribute_parallel_for_simd: 10735 case OMPD_distribute: 10736 case OMPD_distribute_simd: 10737 // Do not capture thread_limit-clause expressions. 10738 break; 10739 case OMPD_parallel_for: 10740 case OMPD_parallel_for_simd: 10741 case OMPD_target_parallel_for_simd: 10742 case OMPD_target_parallel_for: 10743 case OMPD_task: 10744 case OMPD_taskloop: 10745 case OMPD_taskloop_simd: 10746 case OMPD_master_taskloop: 10747 case OMPD_master_taskloop_simd: 10748 case OMPD_parallel_master_taskloop: 10749 case OMPD_target_data: 10750 case OMPD_target_enter_data: 10751 case OMPD_target_exit_data: 10752 case OMPD_target_update: 10753 case OMPD_teams: 10754 case OMPD_target: 10755 case OMPD_target_simd: 10756 case OMPD_target_parallel: 10757 case OMPD_cancel: 10758 case OMPD_parallel: 10759 case OMPD_parallel_sections: 10760 case OMPD_threadprivate: 10761 case OMPD_allocate: 10762 case OMPD_taskyield: 10763 case OMPD_barrier: 10764 case OMPD_taskwait: 10765 case OMPD_cancellation_point: 10766 case OMPD_flush: 10767 case OMPD_declare_reduction: 10768 case OMPD_declare_mapper: 10769 case OMPD_declare_simd: 10770 case OMPD_declare_variant: 10771 case OMPD_declare_target: 10772 case OMPD_end_declare_target: 10773 case OMPD_simd: 10774 case OMPD_for: 10775 case OMPD_for_simd: 10776 case OMPD_sections: 10777 case OMPD_section: 10778 case OMPD_single: 10779 case OMPD_master: 10780 case OMPD_critical: 10781 case OMPD_taskgroup: 10782 case OMPD_ordered: 10783 case OMPD_atomic: 10784 case OMPD_target_teams: 10785 case OMPD_requires: 10786 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10787 case OMPD_unknown: 10788 llvm_unreachable("Unknown OpenMP directive"); 10789 } 10790 break; 10791 case OMPC_device: 10792 switch (DKind) { 10793 case OMPD_target_update: 10794 case OMPD_target_enter_data: 10795 case OMPD_target_exit_data: 10796 case OMPD_target: 10797 case OMPD_target_simd: 10798 case OMPD_target_teams: 10799 case OMPD_target_parallel: 10800 case OMPD_target_teams_distribute: 10801 case OMPD_target_teams_distribute_simd: 10802 case OMPD_target_parallel_for: 10803 case OMPD_target_parallel_for_simd: 10804 case OMPD_target_teams_distribute_parallel_for: 10805 case OMPD_target_teams_distribute_parallel_for_simd: 10806 CaptureRegion = OMPD_task; 10807 break; 10808 case OMPD_target_data: 10809 // Do not capture device-clause expressions. 10810 break; 10811 case OMPD_teams_distribute_parallel_for: 10812 case OMPD_teams_distribute_parallel_for_simd: 10813 case OMPD_teams: 10814 case OMPD_teams_distribute: 10815 case OMPD_teams_distribute_simd: 10816 case OMPD_distribute_parallel_for: 10817 case OMPD_distribute_parallel_for_simd: 10818 case OMPD_task: 10819 case OMPD_taskloop: 10820 case OMPD_taskloop_simd: 10821 case OMPD_master_taskloop: 10822 case OMPD_master_taskloop_simd: 10823 case OMPD_parallel_master_taskloop: 10824 case OMPD_cancel: 10825 case OMPD_parallel: 10826 case OMPD_parallel_sections: 10827 case OMPD_parallel_for: 10828 case OMPD_parallel_for_simd: 10829 case OMPD_threadprivate: 10830 case OMPD_allocate: 10831 case OMPD_taskyield: 10832 case OMPD_barrier: 10833 case OMPD_taskwait: 10834 case OMPD_cancellation_point: 10835 case OMPD_flush: 10836 case OMPD_declare_reduction: 10837 case OMPD_declare_mapper: 10838 case OMPD_declare_simd: 10839 case OMPD_declare_variant: 10840 case OMPD_declare_target: 10841 case OMPD_end_declare_target: 10842 case OMPD_simd: 10843 case OMPD_for: 10844 case OMPD_for_simd: 10845 case OMPD_sections: 10846 case OMPD_section: 10847 case OMPD_single: 10848 case OMPD_master: 10849 case OMPD_critical: 10850 case OMPD_taskgroup: 10851 case OMPD_distribute: 10852 case OMPD_ordered: 10853 case OMPD_atomic: 10854 case OMPD_distribute_simd: 10855 case OMPD_requires: 10856 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10857 case OMPD_unknown: 10858 llvm_unreachable("Unknown OpenMP directive"); 10859 } 10860 break; 10861 case OMPC_grainsize: 10862 case OMPC_num_tasks: 10863 case OMPC_final: 10864 case OMPC_priority: 10865 switch (DKind) { 10866 case OMPD_task: 10867 case OMPD_taskloop: 10868 case OMPD_taskloop_simd: 10869 case OMPD_master_taskloop: 10870 case OMPD_master_taskloop_simd: 10871 break; 10872 case OMPD_parallel_master_taskloop: 10873 CaptureRegion = OMPD_parallel; 10874 break; 10875 case OMPD_target_update: 10876 case OMPD_target_enter_data: 10877 case OMPD_target_exit_data: 10878 case OMPD_target: 10879 case OMPD_target_simd: 10880 case OMPD_target_teams: 10881 case OMPD_target_parallel: 10882 case OMPD_target_teams_distribute: 10883 case OMPD_target_teams_distribute_simd: 10884 case OMPD_target_parallel_for: 10885 case OMPD_target_parallel_for_simd: 10886 case OMPD_target_teams_distribute_parallel_for: 10887 case OMPD_target_teams_distribute_parallel_for_simd: 10888 case OMPD_target_data: 10889 case OMPD_teams_distribute_parallel_for: 10890 case OMPD_teams_distribute_parallel_for_simd: 10891 case OMPD_teams: 10892 case OMPD_teams_distribute: 10893 case OMPD_teams_distribute_simd: 10894 case OMPD_distribute_parallel_for: 10895 case OMPD_distribute_parallel_for_simd: 10896 case OMPD_cancel: 10897 case OMPD_parallel: 10898 case OMPD_parallel_sections: 10899 case OMPD_parallel_for: 10900 case OMPD_parallel_for_simd: 10901 case OMPD_threadprivate: 10902 case OMPD_allocate: 10903 case OMPD_taskyield: 10904 case OMPD_barrier: 10905 case OMPD_taskwait: 10906 case OMPD_cancellation_point: 10907 case OMPD_flush: 10908 case OMPD_declare_reduction: 10909 case OMPD_declare_mapper: 10910 case OMPD_declare_simd: 10911 case OMPD_declare_variant: 10912 case OMPD_declare_target: 10913 case OMPD_end_declare_target: 10914 case OMPD_simd: 10915 case OMPD_for: 10916 case OMPD_for_simd: 10917 case OMPD_sections: 10918 case OMPD_section: 10919 case OMPD_single: 10920 case OMPD_master: 10921 case OMPD_critical: 10922 case OMPD_taskgroup: 10923 case OMPD_distribute: 10924 case OMPD_ordered: 10925 case OMPD_atomic: 10926 case OMPD_distribute_simd: 10927 case OMPD_requires: 10928 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 10929 case OMPD_unknown: 10930 llvm_unreachable("Unknown OpenMP directive"); 10931 } 10932 break; 10933 case OMPC_firstprivate: 10934 case OMPC_lastprivate: 10935 case OMPC_reduction: 10936 case OMPC_task_reduction: 10937 case OMPC_in_reduction: 10938 case OMPC_linear: 10939 case OMPC_default: 10940 case OMPC_proc_bind: 10941 case OMPC_safelen: 10942 case OMPC_simdlen: 10943 case OMPC_allocator: 10944 case OMPC_collapse: 10945 case OMPC_private: 10946 case OMPC_shared: 10947 case OMPC_aligned: 10948 case OMPC_copyin: 10949 case OMPC_copyprivate: 10950 case OMPC_ordered: 10951 case OMPC_nowait: 10952 case OMPC_untied: 10953 case OMPC_mergeable: 10954 case OMPC_threadprivate: 10955 case OMPC_allocate: 10956 case OMPC_flush: 10957 case OMPC_read: 10958 case OMPC_write: 10959 case OMPC_update: 10960 case OMPC_capture: 10961 case OMPC_seq_cst: 10962 case OMPC_depend: 10963 case OMPC_threads: 10964 case OMPC_simd: 10965 case OMPC_map: 10966 case OMPC_nogroup: 10967 case OMPC_hint: 10968 case OMPC_defaultmap: 10969 case OMPC_unknown: 10970 case OMPC_uniform: 10971 case OMPC_to: 10972 case OMPC_from: 10973 case OMPC_use_device_ptr: 10974 case OMPC_is_device_ptr: 10975 case OMPC_unified_address: 10976 case OMPC_unified_shared_memory: 10977 case OMPC_reverse_offload: 10978 case OMPC_dynamic_allocators: 10979 case OMPC_atomic_default_mem_order: 10980 case OMPC_device_type: 10981 case OMPC_match: 10982 llvm_unreachable("Unexpected OpenMP clause."); 10983 } 10984 return CaptureRegion; 10985 } 10986 10987 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10988 Expr *Condition, SourceLocation StartLoc, 10989 SourceLocation LParenLoc, 10990 SourceLocation NameModifierLoc, 10991 SourceLocation ColonLoc, 10992 SourceLocation EndLoc) { 10993 Expr *ValExpr = Condition; 10994 Stmt *HelperValStmt = nullptr; 10995 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10996 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10997 !Condition->isInstantiationDependent() && 10998 !Condition->containsUnexpandedParameterPack()) { 10999 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11000 if (Val.isInvalid()) 11001 return nullptr; 11002 11003 ValExpr = Val.get(); 11004 11005 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11006 CaptureRegion = 11007 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 11008 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11009 ValExpr = MakeFullExpr(ValExpr).get(); 11010 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11011 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11012 HelperValStmt = buildPreInits(Context, Captures); 11013 } 11014 } 11015 11016 return new (Context) 11017 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11018 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11019 } 11020 11021 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11022 SourceLocation StartLoc, 11023 SourceLocation LParenLoc, 11024 SourceLocation EndLoc) { 11025 Expr *ValExpr = Condition; 11026 Stmt *HelperValStmt = nullptr; 11027 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11028 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11029 !Condition->isInstantiationDependent() && 11030 !Condition->containsUnexpandedParameterPack()) { 11031 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11032 if (Val.isInvalid()) 11033 return nullptr; 11034 11035 ValExpr = MakeFullExpr(Val.get()).get(); 11036 11037 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11038 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final); 11039 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11040 ValExpr = MakeFullExpr(ValExpr).get(); 11041 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11042 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11043 HelperValStmt = buildPreInits(Context, Captures); 11044 } 11045 } 11046 11047 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11048 StartLoc, LParenLoc, EndLoc); 11049 } 11050 11051 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11052 Expr *Op) { 11053 if (!Op) 11054 return ExprError(); 11055 11056 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11057 public: 11058 IntConvertDiagnoser() 11059 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11060 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11061 QualType T) override { 11062 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11063 } 11064 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11065 QualType T) override { 11066 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11067 } 11068 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11069 QualType T, 11070 QualType ConvTy) override { 11071 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11072 } 11073 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11074 QualType ConvTy) override { 11075 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11076 << ConvTy->isEnumeralType() << ConvTy; 11077 } 11078 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11079 QualType T) override { 11080 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11081 } 11082 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11083 QualType ConvTy) override { 11084 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11085 << ConvTy->isEnumeralType() << ConvTy; 11086 } 11087 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11088 QualType) override { 11089 llvm_unreachable("conversion functions are permitted"); 11090 } 11091 } ConvertDiagnoser; 11092 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11093 } 11094 11095 static bool 11096 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11097 bool StrictlyPositive, bool BuildCapture = false, 11098 OpenMPDirectiveKind DKind = OMPD_unknown, 11099 OpenMPDirectiveKind *CaptureRegion = nullptr, 11100 Stmt **HelperValStmt = nullptr) { 11101 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11102 !ValExpr->isInstantiationDependent()) { 11103 SourceLocation Loc = ValExpr->getExprLoc(); 11104 ExprResult Value = 11105 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11106 if (Value.isInvalid()) 11107 return false; 11108 11109 ValExpr = Value.get(); 11110 // The expression must evaluate to a non-negative integer value. 11111 llvm::APSInt Result; 11112 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11113 Result.isSigned() && 11114 !((!StrictlyPositive && Result.isNonNegative()) || 11115 (StrictlyPositive && Result.isStrictlyPositive()))) { 11116 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11117 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11118 << ValExpr->getSourceRange(); 11119 return false; 11120 } 11121 if (!BuildCapture) 11122 return true; 11123 *CaptureRegion = getOpenMPCaptureRegionForClause(DKind, CKind); 11124 if (*CaptureRegion != OMPD_unknown && 11125 !SemaRef.CurContext->isDependentContext()) { 11126 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11127 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11128 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11129 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11130 } 11131 } 11132 return true; 11133 } 11134 11135 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11136 SourceLocation StartLoc, 11137 SourceLocation LParenLoc, 11138 SourceLocation EndLoc) { 11139 Expr *ValExpr = NumThreads; 11140 Stmt *HelperValStmt = nullptr; 11141 11142 // OpenMP [2.5, Restrictions] 11143 // The num_threads expression must evaluate to a positive integer value. 11144 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11145 /*StrictlyPositive=*/true)) 11146 return nullptr; 11147 11148 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11149 OpenMPDirectiveKind CaptureRegion = 11150 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 11151 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11152 ValExpr = MakeFullExpr(ValExpr).get(); 11153 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11154 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11155 HelperValStmt = buildPreInits(Context, Captures); 11156 } 11157 11158 return new (Context) OMPNumThreadsClause( 11159 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11160 } 11161 11162 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11163 OpenMPClauseKind CKind, 11164 bool StrictlyPositive) { 11165 if (!E) 11166 return ExprError(); 11167 if (E->isValueDependent() || E->isTypeDependent() || 11168 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11169 return E; 11170 llvm::APSInt Result; 11171 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11172 if (ICE.isInvalid()) 11173 return ExprError(); 11174 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11175 (!StrictlyPositive && !Result.isNonNegative())) { 11176 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11177 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11178 << E->getSourceRange(); 11179 return ExprError(); 11180 } 11181 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11182 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11183 << E->getSourceRange(); 11184 return ExprError(); 11185 } 11186 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11187 DSAStack->setAssociatedLoops(Result.getExtValue()); 11188 else if (CKind == OMPC_ordered) 11189 DSAStack->setAssociatedLoops(Result.getExtValue()); 11190 return ICE; 11191 } 11192 11193 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11194 SourceLocation LParenLoc, 11195 SourceLocation EndLoc) { 11196 // OpenMP [2.8.1, simd construct, Description] 11197 // The parameter of the safelen clause must be a constant 11198 // positive integer expression. 11199 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11200 if (Safelen.isInvalid()) 11201 return nullptr; 11202 return new (Context) 11203 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11204 } 11205 11206 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11207 SourceLocation LParenLoc, 11208 SourceLocation EndLoc) { 11209 // OpenMP [2.8.1, simd construct, Description] 11210 // The parameter of the simdlen clause must be a constant 11211 // positive integer expression. 11212 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11213 if (Simdlen.isInvalid()) 11214 return nullptr; 11215 return new (Context) 11216 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11217 } 11218 11219 /// Tries to find omp_allocator_handle_t type. 11220 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11221 DSAStackTy *Stack) { 11222 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11223 if (!OMPAllocatorHandleT.isNull()) 11224 return true; 11225 // Build the predefined allocator expressions. 11226 bool ErrorFound = false; 11227 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11228 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11229 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11230 StringRef Allocator = 11231 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11232 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11233 auto *VD = dyn_cast_or_null<ValueDecl>( 11234 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11235 if (!VD) { 11236 ErrorFound = true; 11237 break; 11238 } 11239 QualType AllocatorType = 11240 VD->getType().getNonLValueExprType(S.getASTContext()); 11241 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11242 if (!Res.isUsable()) { 11243 ErrorFound = true; 11244 break; 11245 } 11246 if (OMPAllocatorHandleT.isNull()) 11247 OMPAllocatorHandleT = AllocatorType; 11248 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11249 ErrorFound = true; 11250 break; 11251 } 11252 Stack->setAllocator(AllocatorKind, Res.get()); 11253 } 11254 if (ErrorFound) { 11255 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11256 return false; 11257 } 11258 OMPAllocatorHandleT.addConst(); 11259 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11260 return true; 11261 } 11262 11263 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11264 SourceLocation LParenLoc, 11265 SourceLocation EndLoc) { 11266 // OpenMP [2.11.3, allocate Directive, Description] 11267 // allocator is an expression of omp_allocator_handle_t type. 11268 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11269 return nullptr; 11270 11271 ExprResult Allocator = DefaultLvalueConversion(A); 11272 if (Allocator.isInvalid()) 11273 return nullptr; 11274 Allocator = PerformImplicitConversion(Allocator.get(), 11275 DSAStack->getOMPAllocatorHandleT(), 11276 Sema::AA_Initializing, 11277 /*AllowExplicit=*/true); 11278 if (Allocator.isInvalid()) 11279 return nullptr; 11280 return new (Context) 11281 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11282 } 11283 11284 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11285 SourceLocation StartLoc, 11286 SourceLocation LParenLoc, 11287 SourceLocation EndLoc) { 11288 // OpenMP [2.7.1, loop construct, Description] 11289 // OpenMP [2.8.1, simd construct, Description] 11290 // OpenMP [2.9.6, distribute construct, Description] 11291 // The parameter of the collapse clause must be a constant 11292 // positive integer expression. 11293 ExprResult NumForLoopsResult = 11294 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11295 if (NumForLoopsResult.isInvalid()) 11296 return nullptr; 11297 return new (Context) 11298 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11299 } 11300 11301 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11302 SourceLocation EndLoc, 11303 SourceLocation LParenLoc, 11304 Expr *NumForLoops) { 11305 // OpenMP [2.7.1, loop construct, Description] 11306 // OpenMP [2.8.1, simd construct, Description] 11307 // OpenMP [2.9.6, distribute construct, Description] 11308 // The parameter of the ordered clause must be a constant 11309 // positive integer expression if any. 11310 if (NumForLoops && LParenLoc.isValid()) { 11311 ExprResult NumForLoopsResult = 11312 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11313 if (NumForLoopsResult.isInvalid()) 11314 return nullptr; 11315 NumForLoops = NumForLoopsResult.get(); 11316 } else { 11317 NumForLoops = nullptr; 11318 } 11319 auto *Clause = OMPOrderedClause::Create( 11320 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11321 StartLoc, LParenLoc, EndLoc); 11322 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11323 return Clause; 11324 } 11325 11326 OMPClause *Sema::ActOnOpenMPSimpleClause( 11327 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11328 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11329 OMPClause *Res = nullptr; 11330 switch (Kind) { 11331 case OMPC_default: 11332 Res = 11333 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11334 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11335 break; 11336 case OMPC_proc_bind: 11337 Res = ActOnOpenMPProcBindClause( 11338 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11339 LParenLoc, EndLoc); 11340 break; 11341 case OMPC_atomic_default_mem_order: 11342 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11343 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11344 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11345 break; 11346 case OMPC_if: 11347 case OMPC_final: 11348 case OMPC_num_threads: 11349 case OMPC_safelen: 11350 case OMPC_simdlen: 11351 case OMPC_allocator: 11352 case OMPC_collapse: 11353 case OMPC_schedule: 11354 case OMPC_private: 11355 case OMPC_firstprivate: 11356 case OMPC_lastprivate: 11357 case OMPC_shared: 11358 case OMPC_reduction: 11359 case OMPC_task_reduction: 11360 case OMPC_in_reduction: 11361 case OMPC_linear: 11362 case OMPC_aligned: 11363 case OMPC_copyin: 11364 case OMPC_copyprivate: 11365 case OMPC_ordered: 11366 case OMPC_nowait: 11367 case OMPC_untied: 11368 case OMPC_mergeable: 11369 case OMPC_threadprivate: 11370 case OMPC_allocate: 11371 case OMPC_flush: 11372 case OMPC_read: 11373 case OMPC_write: 11374 case OMPC_update: 11375 case OMPC_capture: 11376 case OMPC_seq_cst: 11377 case OMPC_depend: 11378 case OMPC_device: 11379 case OMPC_threads: 11380 case OMPC_simd: 11381 case OMPC_map: 11382 case OMPC_num_teams: 11383 case OMPC_thread_limit: 11384 case OMPC_priority: 11385 case OMPC_grainsize: 11386 case OMPC_nogroup: 11387 case OMPC_num_tasks: 11388 case OMPC_hint: 11389 case OMPC_dist_schedule: 11390 case OMPC_defaultmap: 11391 case OMPC_unknown: 11392 case OMPC_uniform: 11393 case OMPC_to: 11394 case OMPC_from: 11395 case OMPC_use_device_ptr: 11396 case OMPC_is_device_ptr: 11397 case OMPC_unified_address: 11398 case OMPC_unified_shared_memory: 11399 case OMPC_reverse_offload: 11400 case OMPC_dynamic_allocators: 11401 case OMPC_device_type: 11402 case OMPC_match: 11403 llvm_unreachable("Clause is not allowed."); 11404 } 11405 return Res; 11406 } 11407 11408 static std::string 11409 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11410 ArrayRef<unsigned> Exclude = llvm::None) { 11411 SmallString<256> Buffer; 11412 llvm::raw_svector_ostream Out(Buffer); 11413 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11414 unsigned Skipped = Exclude.size(); 11415 auto S = Exclude.begin(), E = Exclude.end(); 11416 for (unsigned I = First; I < Last; ++I) { 11417 if (std::find(S, E, I) != E) { 11418 --Skipped; 11419 continue; 11420 } 11421 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11422 if (I == Bound - Skipped) 11423 Out << " or "; 11424 else if (I != Bound + 1 - Skipped) 11425 Out << ", "; 11426 } 11427 return Out.str(); 11428 } 11429 11430 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11431 SourceLocation KindKwLoc, 11432 SourceLocation StartLoc, 11433 SourceLocation LParenLoc, 11434 SourceLocation EndLoc) { 11435 if (Kind == OMPC_DEFAULT_unknown) { 11436 static_assert(OMPC_DEFAULT_unknown > 0, 11437 "OMPC_DEFAULT_unknown not greater than 0"); 11438 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11439 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11440 /*Last=*/OMPC_DEFAULT_unknown) 11441 << getOpenMPClauseName(OMPC_default); 11442 return nullptr; 11443 } 11444 switch (Kind) { 11445 case OMPC_DEFAULT_none: 11446 DSAStack->setDefaultDSANone(KindKwLoc); 11447 break; 11448 case OMPC_DEFAULT_shared: 11449 DSAStack->setDefaultDSAShared(KindKwLoc); 11450 break; 11451 case OMPC_DEFAULT_unknown: 11452 llvm_unreachable("Clause kind is not allowed."); 11453 break; 11454 } 11455 return new (Context) 11456 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11457 } 11458 11459 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11460 SourceLocation KindKwLoc, 11461 SourceLocation StartLoc, 11462 SourceLocation LParenLoc, 11463 SourceLocation EndLoc) { 11464 if (Kind == OMPC_PROC_BIND_unknown) { 11465 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11466 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11467 /*Last=*/OMPC_PROC_BIND_unknown) 11468 << getOpenMPClauseName(OMPC_proc_bind); 11469 return nullptr; 11470 } 11471 return new (Context) 11472 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11473 } 11474 11475 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11476 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11477 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11478 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11479 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11480 << getListOfPossibleValues( 11481 OMPC_atomic_default_mem_order, /*First=*/0, 11482 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11483 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11484 return nullptr; 11485 } 11486 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11487 LParenLoc, EndLoc); 11488 } 11489 11490 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11491 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11492 SourceLocation StartLoc, SourceLocation LParenLoc, 11493 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11494 SourceLocation EndLoc) { 11495 OMPClause *Res = nullptr; 11496 switch (Kind) { 11497 case OMPC_schedule: 11498 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11499 assert(Argument.size() == NumberOfElements && 11500 ArgumentLoc.size() == NumberOfElements); 11501 Res = ActOnOpenMPScheduleClause( 11502 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11503 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11504 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11505 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11506 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11507 break; 11508 case OMPC_if: 11509 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11510 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11511 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11512 DelimLoc, EndLoc); 11513 break; 11514 case OMPC_dist_schedule: 11515 Res = ActOnOpenMPDistScheduleClause( 11516 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11517 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11518 break; 11519 case OMPC_defaultmap: 11520 enum { Modifier, DefaultmapKind }; 11521 Res = ActOnOpenMPDefaultmapClause( 11522 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11523 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11524 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11525 EndLoc); 11526 break; 11527 case OMPC_final: 11528 case OMPC_num_threads: 11529 case OMPC_safelen: 11530 case OMPC_simdlen: 11531 case OMPC_allocator: 11532 case OMPC_collapse: 11533 case OMPC_default: 11534 case OMPC_proc_bind: 11535 case OMPC_private: 11536 case OMPC_firstprivate: 11537 case OMPC_lastprivate: 11538 case OMPC_shared: 11539 case OMPC_reduction: 11540 case OMPC_task_reduction: 11541 case OMPC_in_reduction: 11542 case OMPC_linear: 11543 case OMPC_aligned: 11544 case OMPC_copyin: 11545 case OMPC_copyprivate: 11546 case OMPC_ordered: 11547 case OMPC_nowait: 11548 case OMPC_untied: 11549 case OMPC_mergeable: 11550 case OMPC_threadprivate: 11551 case OMPC_allocate: 11552 case OMPC_flush: 11553 case OMPC_read: 11554 case OMPC_write: 11555 case OMPC_update: 11556 case OMPC_capture: 11557 case OMPC_seq_cst: 11558 case OMPC_depend: 11559 case OMPC_device: 11560 case OMPC_threads: 11561 case OMPC_simd: 11562 case OMPC_map: 11563 case OMPC_num_teams: 11564 case OMPC_thread_limit: 11565 case OMPC_priority: 11566 case OMPC_grainsize: 11567 case OMPC_nogroup: 11568 case OMPC_num_tasks: 11569 case OMPC_hint: 11570 case OMPC_unknown: 11571 case OMPC_uniform: 11572 case OMPC_to: 11573 case OMPC_from: 11574 case OMPC_use_device_ptr: 11575 case OMPC_is_device_ptr: 11576 case OMPC_unified_address: 11577 case OMPC_unified_shared_memory: 11578 case OMPC_reverse_offload: 11579 case OMPC_dynamic_allocators: 11580 case OMPC_atomic_default_mem_order: 11581 case OMPC_device_type: 11582 case OMPC_match: 11583 llvm_unreachable("Clause is not allowed."); 11584 } 11585 return Res; 11586 } 11587 11588 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11589 OpenMPScheduleClauseModifier M2, 11590 SourceLocation M1Loc, SourceLocation M2Loc) { 11591 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11592 SmallVector<unsigned, 2> Excluded; 11593 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11594 Excluded.push_back(M2); 11595 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11596 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11597 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11598 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11599 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11600 << getListOfPossibleValues(OMPC_schedule, 11601 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11602 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11603 Excluded) 11604 << getOpenMPClauseName(OMPC_schedule); 11605 return true; 11606 } 11607 return false; 11608 } 11609 11610 OMPClause *Sema::ActOnOpenMPScheduleClause( 11611 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11612 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11613 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11614 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11615 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11616 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11617 return nullptr; 11618 // OpenMP, 2.7.1, Loop Construct, Restrictions 11619 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11620 // but not both. 11621 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11622 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11623 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11624 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11625 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11626 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11627 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11628 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11629 return nullptr; 11630 } 11631 if (Kind == OMPC_SCHEDULE_unknown) { 11632 std::string Values; 11633 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11634 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11635 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11636 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11637 Exclude); 11638 } else { 11639 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11640 /*Last=*/OMPC_SCHEDULE_unknown); 11641 } 11642 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11643 << Values << getOpenMPClauseName(OMPC_schedule); 11644 return nullptr; 11645 } 11646 // OpenMP, 2.7.1, Loop Construct, Restrictions 11647 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11648 // schedule(guided). 11649 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11650 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11651 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11652 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11653 diag::err_omp_schedule_nonmonotonic_static); 11654 return nullptr; 11655 } 11656 Expr *ValExpr = ChunkSize; 11657 Stmt *HelperValStmt = nullptr; 11658 if (ChunkSize) { 11659 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11660 !ChunkSize->isInstantiationDependent() && 11661 !ChunkSize->containsUnexpandedParameterPack()) { 11662 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11663 ExprResult Val = 11664 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11665 if (Val.isInvalid()) 11666 return nullptr; 11667 11668 ValExpr = Val.get(); 11669 11670 // OpenMP [2.7.1, Restrictions] 11671 // chunk_size must be a loop invariant integer expression with a positive 11672 // value. 11673 llvm::APSInt Result; 11674 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11675 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11676 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11677 << "schedule" << 1 << ChunkSize->getSourceRange(); 11678 return nullptr; 11679 } 11680 } else if (getOpenMPCaptureRegionForClause( 11681 DSAStack->getCurrentDirective(), OMPC_schedule) != 11682 OMPD_unknown && 11683 !CurContext->isDependentContext()) { 11684 ValExpr = MakeFullExpr(ValExpr).get(); 11685 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11686 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11687 HelperValStmt = buildPreInits(Context, Captures); 11688 } 11689 } 11690 } 11691 11692 return new (Context) 11693 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11694 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11695 } 11696 11697 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11698 SourceLocation StartLoc, 11699 SourceLocation EndLoc) { 11700 OMPClause *Res = nullptr; 11701 switch (Kind) { 11702 case OMPC_ordered: 11703 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11704 break; 11705 case OMPC_nowait: 11706 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11707 break; 11708 case OMPC_untied: 11709 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11710 break; 11711 case OMPC_mergeable: 11712 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11713 break; 11714 case OMPC_read: 11715 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11716 break; 11717 case OMPC_write: 11718 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11719 break; 11720 case OMPC_update: 11721 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11722 break; 11723 case OMPC_capture: 11724 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11725 break; 11726 case OMPC_seq_cst: 11727 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11728 break; 11729 case OMPC_threads: 11730 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11731 break; 11732 case OMPC_simd: 11733 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11734 break; 11735 case OMPC_nogroup: 11736 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11737 break; 11738 case OMPC_unified_address: 11739 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11740 break; 11741 case OMPC_unified_shared_memory: 11742 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11743 break; 11744 case OMPC_reverse_offload: 11745 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11746 break; 11747 case OMPC_dynamic_allocators: 11748 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11749 break; 11750 case OMPC_if: 11751 case OMPC_final: 11752 case OMPC_num_threads: 11753 case OMPC_safelen: 11754 case OMPC_simdlen: 11755 case OMPC_allocator: 11756 case OMPC_collapse: 11757 case OMPC_schedule: 11758 case OMPC_private: 11759 case OMPC_firstprivate: 11760 case OMPC_lastprivate: 11761 case OMPC_shared: 11762 case OMPC_reduction: 11763 case OMPC_task_reduction: 11764 case OMPC_in_reduction: 11765 case OMPC_linear: 11766 case OMPC_aligned: 11767 case OMPC_copyin: 11768 case OMPC_copyprivate: 11769 case OMPC_default: 11770 case OMPC_proc_bind: 11771 case OMPC_threadprivate: 11772 case OMPC_allocate: 11773 case OMPC_flush: 11774 case OMPC_depend: 11775 case OMPC_device: 11776 case OMPC_map: 11777 case OMPC_num_teams: 11778 case OMPC_thread_limit: 11779 case OMPC_priority: 11780 case OMPC_grainsize: 11781 case OMPC_num_tasks: 11782 case OMPC_hint: 11783 case OMPC_dist_schedule: 11784 case OMPC_defaultmap: 11785 case OMPC_unknown: 11786 case OMPC_uniform: 11787 case OMPC_to: 11788 case OMPC_from: 11789 case OMPC_use_device_ptr: 11790 case OMPC_is_device_ptr: 11791 case OMPC_atomic_default_mem_order: 11792 case OMPC_device_type: 11793 case OMPC_match: 11794 llvm_unreachable("Clause is not allowed."); 11795 } 11796 return Res; 11797 } 11798 11799 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11800 SourceLocation EndLoc) { 11801 DSAStack->setNowaitRegion(); 11802 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11803 } 11804 11805 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11806 SourceLocation EndLoc) { 11807 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11808 } 11809 11810 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11811 SourceLocation EndLoc) { 11812 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11813 } 11814 11815 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11816 SourceLocation EndLoc) { 11817 return new (Context) OMPReadClause(StartLoc, EndLoc); 11818 } 11819 11820 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11821 SourceLocation EndLoc) { 11822 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11823 } 11824 11825 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11826 SourceLocation EndLoc) { 11827 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11828 } 11829 11830 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11831 SourceLocation EndLoc) { 11832 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11833 } 11834 11835 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11836 SourceLocation EndLoc) { 11837 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11838 } 11839 11840 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11841 SourceLocation EndLoc) { 11842 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11843 } 11844 11845 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11846 SourceLocation EndLoc) { 11847 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11848 } 11849 11850 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11851 SourceLocation EndLoc) { 11852 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11853 } 11854 11855 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11856 SourceLocation EndLoc) { 11857 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11858 } 11859 11860 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11861 SourceLocation EndLoc) { 11862 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11863 } 11864 11865 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11866 SourceLocation EndLoc) { 11867 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11868 } 11869 11870 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11871 SourceLocation EndLoc) { 11872 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11873 } 11874 11875 OMPClause *Sema::ActOnOpenMPVarListClause( 11876 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11877 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11878 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11879 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11880 OpenMPLinearClauseKind LinKind, 11881 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11882 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11883 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11884 SourceLocation StartLoc = Locs.StartLoc; 11885 SourceLocation LParenLoc = Locs.LParenLoc; 11886 SourceLocation EndLoc = Locs.EndLoc; 11887 OMPClause *Res = nullptr; 11888 switch (Kind) { 11889 case OMPC_private: 11890 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11891 break; 11892 case OMPC_firstprivate: 11893 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11894 break; 11895 case OMPC_lastprivate: 11896 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11897 break; 11898 case OMPC_shared: 11899 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11900 break; 11901 case OMPC_reduction: 11902 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11903 EndLoc, ReductionOrMapperIdScopeSpec, 11904 ReductionOrMapperId); 11905 break; 11906 case OMPC_task_reduction: 11907 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11908 EndLoc, ReductionOrMapperIdScopeSpec, 11909 ReductionOrMapperId); 11910 break; 11911 case OMPC_in_reduction: 11912 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11913 EndLoc, ReductionOrMapperIdScopeSpec, 11914 ReductionOrMapperId); 11915 break; 11916 case OMPC_linear: 11917 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11918 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11919 break; 11920 case OMPC_aligned: 11921 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11922 ColonLoc, EndLoc); 11923 break; 11924 case OMPC_copyin: 11925 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11926 break; 11927 case OMPC_copyprivate: 11928 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11929 break; 11930 case OMPC_flush: 11931 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11932 break; 11933 case OMPC_depend: 11934 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11935 StartLoc, LParenLoc, EndLoc); 11936 break; 11937 case OMPC_map: 11938 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11939 ReductionOrMapperIdScopeSpec, 11940 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11941 DepLinMapLoc, ColonLoc, VarList, Locs); 11942 break; 11943 case OMPC_to: 11944 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11945 ReductionOrMapperId, Locs); 11946 break; 11947 case OMPC_from: 11948 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11949 ReductionOrMapperId, Locs); 11950 break; 11951 case OMPC_use_device_ptr: 11952 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11953 break; 11954 case OMPC_is_device_ptr: 11955 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11956 break; 11957 case OMPC_allocate: 11958 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11959 ColonLoc, EndLoc); 11960 break; 11961 case OMPC_if: 11962 case OMPC_final: 11963 case OMPC_num_threads: 11964 case OMPC_safelen: 11965 case OMPC_simdlen: 11966 case OMPC_allocator: 11967 case OMPC_collapse: 11968 case OMPC_default: 11969 case OMPC_proc_bind: 11970 case OMPC_schedule: 11971 case OMPC_ordered: 11972 case OMPC_nowait: 11973 case OMPC_untied: 11974 case OMPC_mergeable: 11975 case OMPC_threadprivate: 11976 case OMPC_read: 11977 case OMPC_write: 11978 case OMPC_update: 11979 case OMPC_capture: 11980 case OMPC_seq_cst: 11981 case OMPC_device: 11982 case OMPC_threads: 11983 case OMPC_simd: 11984 case OMPC_num_teams: 11985 case OMPC_thread_limit: 11986 case OMPC_priority: 11987 case OMPC_grainsize: 11988 case OMPC_nogroup: 11989 case OMPC_num_tasks: 11990 case OMPC_hint: 11991 case OMPC_dist_schedule: 11992 case OMPC_defaultmap: 11993 case OMPC_unknown: 11994 case OMPC_uniform: 11995 case OMPC_unified_address: 11996 case OMPC_unified_shared_memory: 11997 case OMPC_reverse_offload: 11998 case OMPC_dynamic_allocators: 11999 case OMPC_atomic_default_mem_order: 12000 case OMPC_device_type: 12001 case OMPC_match: 12002 llvm_unreachable("Clause is not allowed."); 12003 } 12004 return Res; 12005 } 12006 12007 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12008 ExprObjectKind OK, SourceLocation Loc) { 12009 ExprResult Res = BuildDeclRefExpr( 12010 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12011 if (!Res.isUsable()) 12012 return ExprError(); 12013 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12014 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12015 if (!Res.isUsable()) 12016 return ExprError(); 12017 } 12018 if (VK != VK_LValue && Res.get()->isGLValue()) { 12019 Res = DefaultLvalueConversion(Res.get()); 12020 if (!Res.isUsable()) 12021 return ExprError(); 12022 } 12023 return Res; 12024 } 12025 12026 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12027 SourceLocation StartLoc, 12028 SourceLocation LParenLoc, 12029 SourceLocation EndLoc) { 12030 SmallVector<Expr *, 8> Vars; 12031 SmallVector<Expr *, 8> PrivateCopies; 12032 for (Expr *RefExpr : VarList) { 12033 assert(RefExpr && "NULL expr in OpenMP private clause."); 12034 SourceLocation ELoc; 12035 SourceRange ERange; 12036 Expr *SimpleRefExpr = RefExpr; 12037 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12038 if (Res.second) { 12039 // It will be analyzed later. 12040 Vars.push_back(RefExpr); 12041 PrivateCopies.push_back(nullptr); 12042 } 12043 ValueDecl *D = Res.first; 12044 if (!D) 12045 continue; 12046 12047 QualType Type = D->getType(); 12048 auto *VD = dyn_cast<VarDecl>(D); 12049 12050 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12051 // A variable that appears in a private clause must not have an incomplete 12052 // type or a reference type. 12053 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12054 continue; 12055 Type = Type.getNonReferenceType(); 12056 12057 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12058 // A variable that is privatized must not have a const-qualified type 12059 // unless it is of class type with a mutable member. This restriction does 12060 // not apply to the firstprivate clause. 12061 // 12062 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12063 // A variable that appears in a private clause must not have a 12064 // const-qualified type unless it is of class type with a mutable member. 12065 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12066 continue; 12067 12068 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12069 // in a Construct] 12070 // Variables with the predetermined data-sharing attributes may not be 12071 // listed in data-sharing attributes clauses, except for the cases 12072 // listed below. For these exceptions only, listing a predetermined 12073 // variable in a data-sharing attribute clause is allowed and overrides 12074 // the variable's predetermined data-sharing attributes. 12075 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12076 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12077 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12078 << getOpenMPClauseName(OMPC_private); 12079 reportOriginalDsa(*this, DSAStack, D, DVar); 12080 continue; 12081 } 12082 12083 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12084 // Variably modified types are not supported for tasks. 12085 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12086 isOpenMPTaskingDirective(CurrDir)) { 12087 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12088 << getOpenMPClauseName(OMPC_private) << Type 12089 << getOpenMPDirectiveName(CurrDir); 12090 bool IsDecl = 12091 !VD || 12092 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12093 Diag(D->getLocation(), 12094 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12095 << D; 12096 continue; 12097 } 12098 12099 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12100 // A list item cannot appear in both a map clause and a data-sharing 12101 // attribute clause on the same construct 12102 // 12103 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12104 // A list item cannot appear in both a map clause and a data-sharing 12105 // attribute clause on the same construct unless the construct is a 12106 // combined construct. 12107 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12108 CurrDir == OMPD_target) { 12109 OpenMPClauseKind ConflictKind; 12110 if (DSAStack->checkMappableExprComponentListsForDecl( 12111 VD, /*CurrentRegionOnly=*/true, 12112 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12113 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12114 ConflictKind = WhereFoundClauseKind; 12115 return true; 12116 })) { 12117 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12118 << getOpenMPClauseName(OMPC_private) 12119 << getOpenMPClauseName(ConflictKind) 12120 << getOpenMPDirectiveName(CurrDir); 12121 reportOriginalDsa(*this, DSAStack, D, DVar); 12122 continue; 12123 } 12124 } 12125 12126 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12127 // A variable of class type (or array thereof) that appears in a private 12128 // clause requires an accessible, unambiguous default constructor for the 12129 // class type. 12130 // Generate helper private variable and initialize it with the default 12131 // value. The address of the original variable is replaced by the address of 12132 // the new private variable in CodeGen. This new variable is not added to 12133 // IdResolver, so the code in the OpenMP region uses original variable for 12134 // proper diagnostics. 12135 Type = Type.getUnqualifiedType(); 12136 VarDecl *VDPrivate = 12137 buildVarDecl(*this, ELoc, Type, D->getName(), 12138 D->hasAttrs() ? &D->getAttrs() : nullptr, 12139 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12140 ActOnUninitializedDecl(VDPrivate); 12141 if (VDPrivate->isInvalidDecl()) 12142 continue; 12143 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12144 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12145 12146 DeclRefExpr *Ref = nullptr; 12147 if (!VD && !CurContext->isDependentContext()) 12148 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12149 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12150 Vars.push_back((VD || CurContext->isDependentContext()) 12151 ? RefExpr->IgnoreParens() 12152 : Ref); 12153 PrivateCopies.push_back(VDPrivateRefExpr); 12154 } 12155 12156 if (Vars.empty()) 12157 return nullptr; 12158 12159 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12160 PrivateCopies); 12161 } 12162 12163 namespace { 12164 class DiagsUninitializedSeveretyRAII { 12165 private: 12166 DiagnosticsEngine &Diags; 12167 SourceLocation SavedLoc; 12168 bool IsIgnored = false; 12169 12170 public: 12171 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12172 bool IsIgnored) 12173 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12174 if (!IsIgnored) { 12175 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12176 /*Map*/ diag::Severity::Ignored, Loc); 12177 } 12178 } 12179 ~DiagsUninitializedSeveretyRAII() { 12180 if (!IsIgnored) 12181 Diags.popMappings(SavedLoc); 12182 } 12183 }; 12184 } 12185 12186 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12187 SourceLocation StartLoc, 12188 SourceLocation LParenLoc, 12189 SourceLocation EndLoc) { 12190 SmallVector<Expr *, 8> Vars; 12191 SmallVector<Expr *, 8> PrivateCopies; 12192 SmallVector<Expr *, 8> Inits; 12193 SmallVector<Decl *, 4> ExprCaptures; 12194 bool IsImplicitClause = 12195 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12196 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12197 12198 for (Expr *RefExpr : VarList) { 12199 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12200 SourceLocation ELoc; 12201 SourceRange ERange; 12202 Expr *SimpleRefExpr = RefExpr; 12203 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12204 if (Res.second) { 12205 // It will be analyzed later. 12206 Vars.push_back(RefExpr); 12207 PrivateCopies.push_back(nullptr); 12208 Inits.push_back(nullptr); 12209 } 12210 ValueDecl *D = Res.first; 12211 if (!D) 12212 continue; 12213 12214 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12215 QualType Type = D->getType(); 12216 auto *VD = dyn_cast<VarDecl>(D); 12217 12218 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12219 // A variable that appears in a private clause must not have an incomplete 12220 // type or a reference type. 12221 if (RequireCompleteType(ELoc, Type, 12222 diag::err_omp_firstprivate_incomplete_type)) 12223 continue; 12224 Type = Type.getNonReferenceType(); 12225 12226 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12227 // A variable of class type (or array thereof) that appears in a private 12228 // clause requires an accessible, unambiguous copy constructor for the 12229 // class type. 12230 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12231 12232 // If an implicit firstprivate variable found it was checked already. 12233 DSAStackTy::DSAVarData TopDVar; 12234 if (!IsImplicitClause) { 12235 DSAStackTy::DSAVarData DVar = 12236 DSAStack->getTopDSA(D, /*FromParent=*/false); 12237 TopDVar = DVar; 12238 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12239 bool IsConstant = ElemType.isConstant(Context); 12240 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12241 // A list item that specifies a given variable may not appear in more 12242 // than one clause on the same directive, except that a variable may be 12243 // specified in both firstprivate and lastprivate clauses. 12244 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12245 // A list item may appear in a firstprivate or lastprivate clause but not 12246 // both. 12247 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12248 (isOpenMPDistributeDirective(CurrDir) || 12249 DVar.CKind != OMPC_lastprivate) && 12250 DVar.RefExpr) { 12251 Diag(ELoc, diag::err_omp_wrong_dsa) 12252 << getOpenMPClauseName(DVar.CKind) 12253 << getOpenMPClauseName(OMPC_firstprivate); 12254 reportOriginalDsa(*this, DSAStack, D, DVar); 12255 continue; 12256 } 12257 12258 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12259 // in a Construct] 12260 // Variables with the predetermined data-sharing attributes may not be 12261 // listed in data-sharing attributes clauses, except for the cases 12262 // listed below. For these exceptions only, listing a predetermined 12263 // variable in a data-sharing attribute clause is allowed and overrides 12264 // the variable's predetermined data-sharing attributes. 12265 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12266 // in a Construct, C/C++, p.2] 12267 // Variables with const-qualified type having no mutable member may be 12268 // listed in a firstprivate clause, even if they are static data members. 12269 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12270 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12271 Diag(ELoc, diag::err_omp_wrong_dsa) 12272 << getOpenMPClauseName(DVar.CKind) 12273 << getOpenMPClauseName(OMPC_firstprivate); 12274 reportOriginalDsa(*this, DSAStack, D, DVar); 12275 continue; 12276 } 12277 12278 // OpenMP [2.9.3.4, Restrictions, p.2] 12279 // A list item that is private within a parallel region must not appear 12280 // in a firstprivate clause on a worksharing construct if any of the 12281 // worksharing regions arising from the worksharing construct ever bind 12282 // to any of the parallel regions arising from the parallel construct. 12283 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12284 // A list item that is private within a teams region must not appear in a 12285 // firstprivate clause on a distribute construct if any of the distribute 12286 // regions arising from the distribute construct ever bind to any of the 12287 // teams regions arising from the teams construct. 12288 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12289 // A list item that appears in a reduction clause of a teams construct 12290 // must not appear in a firstprivate clause on a distribute construct if 12291 // any of the distribute regions arising from the distribute construct 12292 // ever bind to any of the teams regions arising from the teams construct. 12293 if ((isOpenMPWorksharingDirective(CurrDir) || 12294 isOpenMPDistributeDirective(CurrDir)) && 12295 !isOpenMPParallelDirective(CurrDir) && 12296 !isOpenMPTeamsDirective(CurrDir)) { 12297 DVar = DSAStack->getImplicitDSA(D, true); 12298 if (DVar.CKind != OMPC_shared && 12299 (isOpenMPParallelDirective(DVar.DKind) || 12300 isOpenMPTeamsDirective(DVar.DKind) || 12301 DVar.DKind == OMPD_unknown)) { 12302 Diag(ELoc, diag::err_omp_required_access) 12303 << getOpenMPClauseName(OMPC_firstprivate) 12304 << getOpenMPClauseName(OMPC_shared); 12305 reportOriginalDsa(*this, DSAStack, D, DVar); 12306 continue; 12307 } 12308 } 12309 // OpenMP [2.9.3.4, Restrictions, p.3] 12310 // A list item that appears in a reduction clause of a parallel construct 12311 // must not appear in a firstprivate clause on a worksharing or task 12312 // construct if any of the worksharing or task regions arising from the 12313 // worksharing or task construct ever bind to any of the parallel regions 12314 // arising from the parallel construct. 12315 // OpenMP [2.9.3.4, Restrictions, p.4] 12316 // A list item that appears in a reduction clause in worksharing 12317 // construct must not appear in a firstprivate clause in a task construct 12318 // encountered during execution of any of the worksharing regions arising 12319 // from the worksharing construct. 12320 if (isOpenMPTaskingDirective(CurrDir)) { 12321 DVar = DSAStack->hasInnermostDSA( 12322 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12323 [](OpenMPDirectiveKind K) { 12324 return isOpenMPParallelDirective(K) || 12325 isOpenMPWorksharingDirective(K) || 12326 isOpenMPTeamsDirective(K); 12327 }, 12328 /*FromParent=*/true); 12329 if (DVar.CKind == OMPC_reduction && 12330 (isOpenMPParallelDirective(DVar.DKind) || 12331 isOpenMPWorksharingDirective(DVar.DKind) || 12332 isOpenMPTeamsDirective(DVar.DKind))) { 12333 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12334 << getOpenMPDirectiveName(DVar.DKind); 12335 reportOriginalDsa(*this, DSAStack, D, DVar); 12336 continue; 12337 } 12338 } 12339 12340 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12341 // A list item cannot appear in both a map clause and a data-sharing 12342 // attribute clause on the same construct 12343 // 12344 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12345 // A list item cannot appear in both a map clause and a data-sharing 12346 // attribute clause on the same construct unless the construct is a 12347 // combined construct. 12348 if ((LangOpts.OpenMP <= 45 && 12349 isOpenMPTargetExecutionDirective(CurrDir)) || 12350 CurrDir == OMPD_target) { 12351 OpenMPClauseKind ConflictKind; 12352 if (DSAStack->checkMappableExprComponentListsForDecl( 12353 VD, /*CurrentRegionOnly=*/true, 12354 [&ConflictKind]( 12355 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12356 OpenMPClauseKind WhereFoundClauseKind) { 12357 ConflictKind = WhereFoundClauseKind; 12358 return true; 12359 })) { 12360 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12361 << getOpenMPClauseName(OMPC_firstprivate) 12362 << getOpenMPClauseName(ConflictKind) 12363 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12364 reportOriginalDsa(*this, DSAStack, D, DVar); 12365 continue; 12366 } 12367 } 12368 } 12369 12370 // Variably modified types are not supported for tasks. 12371 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12372 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12373 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12374 << getOpenMPClauseName(OMPC_firstprivate) << Type 12375 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12376 bool IsDecl = 12377 !VD || 12378 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12379 Diag(D->getLocation(), 12380 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12381 << D; 12382 continue; 12383 } 12384 12385 Type = Type.getUnqualifiedType(); 12386 VarDecl *VDPrivate = 12387 buildVarDecl(*this, ELoc, Type, D->getName(), 12388 D->hasAttrs() ? &D->getAttrs() : nullptr, 12389 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12390 // Generate helper private variable and initialize it with the value of the 12391 // original variable. The address of the original variable is replaced by 12392 // the address of the new private variable in the CodeGen. This new variable 12393 // is not added to IdResolver, so the code in the OpenMP region uses 12394 // original variable for proper diagnostics and variable capturing. 12395 Expr *VDInitRefExpr = nullptr; 12396 // For arrays generate initializer for single element and replace it by the 12397 // original array element in CodeGen. 12398 if (Type->isArrayType()) { 12399 VarDecl *VDInit = 12400 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12401 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12402 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12403 ElemType = ElemType.getUnqualifiedType(); 12404 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12405 ".firstprivate.temp"); 12406 InitializedEntity Entity = 12407 InitializedEntity::InitializeVariable(VDInitTemp); 12408 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12409 12410 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12411 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12412 if (Result.isInvalid()) 12413 VDPrivate->setInvalidDecl(); 12414 else 12415 VDPrivate->setInit(Result.getAs<Expr>()); 12416 // Remove temp variable declaration. 12417 Context.Deallocate(VDInitTemp); 12418 } else { 12419 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12420 ".firstprivate.temp"); 12421 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12422 RefExpr->getExprLoc()); 12423 AddInitializerToDecl(VDPrivate, 12424 DefaultLvalueConversion(VDInitRefExpr).get(), 12425 /*DirectInit=*/false); 12426 } 12427 if (VDPrivate->isInvalidDecl()) { 12428 if (IsImplicitClause) { 12429 Diag(RefExpr->getExprLoc(), 12430 diag::note_omp_task_predetermined_firstprivate_here); 12431 } 12432 continue; 12433 } 12434 CurContext->addDecl(VDPrivate); 12435 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12436 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12437 RefExpr->getExprLoc()); 12438 DeclRefExpr *Ref = nullptr; 12439 if (!VD && !CurContext->isDependentContext()) { 12440 if (TopDVar.CKind == OMPC_lastprivate) { 12441 Ref = TopDVar.PrivateCopy; 12442 } else { 12443 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12444 if (!isOpenMPCapturedDecl(D)) 12445 ExprCaptures.push_back(Ref->getDecl()); 12446 } 12447 } 12448 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12449 Vars.push_back((VD || CurContext->isDependentContext()) 12450 ? RefExpr->IgnoreParens() 12451 : Ref); 12452 PrivateCopies.push_back(VDPrivateRefExpr); 12453 Inits.push_back(VDInitRefExpr); 12454 } 12455 12456 if (Vars.empty()) 12457 return nullptr; 12458 12459 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12460 Vars, PrivateCopies, Inits, 12461 buildPreInits(Context, ExprCaptures)); 12462 } 12463 12464 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12465 SourceLocation StartLoc, 12466 SourceLocation LParenLoc, 12467 SourceLocation EndLoc) { 12468 SmallVector<Expr *, 8> Vars; 12469 SmallVector<Expr *, 8> SrcExprs; 12470 SmallVector<Expr *, 8> DstExprs; 12471 SmallVector<Expr *, 8> AssignmentOps; 12472 SmallVector<Decl *, 4> ExprCaptures; 12473 SmallVector<Expr *, 4> ExprPostUpdates; 12474 for (Expr *RefExpr : VarList) { 12475 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12476 SourceLocation ELoc; 12477 SourceRange ERange; 12478 Expr *SimpleRefExpr = RefExpr; 12479 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12480 if (Res.second) { 12481 // It will be analyzed later. 12482 Vars.push_back(RefExpr); 12483 SrcExprs.push_back(nullptr); 12484 DstExprs.push_back(nullptr); 12485 AssignmentOps.push_back(nullptr); 12486 } 12487 ValueDecl *D = Res.first; 12488 if (!D) 12489 continue; 12490 12491 QualType Type = D->getType(); 12492 auto *VD = dyn_cast<VarDecl>(D); 12493 12494 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12495 // A variable that appears in a lastprivate clause must not have an 12496 // incomplete type or a reference type. 12497 if (RequireCompleteType(ELoc, Type, 12498 diag::err_omp_lastprivate_incomplete_type)) 12499 continue; 12500 Type = Type.getNonReferenceType(); 12501 12502 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12503 // A variable that is privatized must not have a const-qualified type 12504 // unless it is of class type with a mutable member. This restriction does 12505 // not apply to the firstprivate clause. 12506 // 12507 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12508 // A variable that appears in a lastprivate clause must not have a 12509 // const-qualified type unless it is of class type with a mutable member. 12510 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12511 continue; 12512 12513 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12514 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12515 // in a Construct] 12516 // Variables with the predetermined data-sharing attributes may not be 12517 // listed in data-sharing attributes clauses, except for the cases 12518 // listed below. 12519 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12520 // A list item may appear in a firstprivate or lastprivate clause but not 12521 // both. 12522 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12523 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12524 (isOpenMPDistributeDirective(CurrDir) || 12525 DVar.CKind != OMPC_firstprivate) && 12526 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12527 Diag(ELoc, diag::err_omp_wrong_dsa) 12528 << getOpenMPClauseName(DVar.CKind) 12529 << getOpenMPClauseName(OMPC_lastprivate); 12530 reportOriginalDsa(*this, DSAStack, D, DVar); 12531 continue; 12532 } 12533 12534 // OpenMP [2.14.3.5, Restrictions, p.2] 12535 // A list item that is private within a parallel region, or that appears in 12536 // the reduction clause of a parallel construct, must not appear in a 12537 // lastprivate clause on a worksharing construct if any of the corresponding 12538 // worksharing regions ever binds to any of the corresponding parallel 12539 // regions. 12540 DSAStackTy::DSAVarData TopDVar = DVar; 12541 if (isOpenMPWorksharingDirective(CurrDir) && 12542 !isOpenMPParallelDirective(CurrDir) && 12543 !isOpenMPTeamsDirective(CurrDir)) { 12544 DVar = DSAStack->getImplicitDSA(D, true); 12545 if (DVar.CKind != OMPC_shared) { 12546 Diag(ELoc, diag::err_omp_required_access) 12547 << getOpenMPClauseName(OMPC_lastprivate) 12548 << getOpenMPClauseName(OMPC_shared); 12549 reportOriginalDsa(*this, DSAStack, D, DVar); 12550 continue; 12551 } 12552 } 12553 12554 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12555 // A variable of class type (or array thereof) that appears in a 12556 // lastprivate clause requires an accessible, unambiguous default 12557 // constructor for the class type, unless the list item is also specified 12558 // in a firstprivate clause. 12559 // A variable of class type (or array thereof) that appears in a 12560 // lastprivate clause requires an accessible, unambiguous copy assignment 12561 // operator for the class type. 12562 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12563 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12564 Type.getUnqualifiedType(), ".lastprivate.src", 12565 D->hasAttrs() ? &D->getAttrs() : nullptr); 12566 DeclRefExpr *PseudoSrcExpr = 12567 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12568 VarDecl *DstVD = 12569 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12570 D->hasAttrs() ? &D->getAttrs() : nullptr); 12571 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12572 // For arrays generate assignment operation for single element and replace 12573 // it by the original array element in CodeGen. 12574 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12575 PseudoDstExpr, PseudoSrcExpr); 12576 if (AssignmentOp.isInvalid()) 12577 continue; 12578 AssignmentOp = 12579 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12580 if (AssignmentOp.isInvalid()) 12581 continue; 12582 12583 DeclRefExpr *Ref = nullptr; 12584 if (!VD && !CurContext->isDependentContext()) { 12585 if (TopDVar.CKind == OMPC_firstprivate) { 12586 Ref = TopDVar.PrivateCopy; 12587 } else { 12588 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12589 if (!isOpenMPCapturedDecl(D)) 12590 ExprCaptures.push_back(Ref->getDecl()); 12591 } 12592 if (TopDVar.CKind == OMPC_firstprivate || 12593 (!isOpenMPCapturedDecl(D) && 12594 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12595 ExprResult RefRes = DefaultLvalueConversion(Ref); 12596 if (!RefRes.isUsable()) 12597 continue; 12598 ExprResult PostUpdateRes = 12599 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12600 RefRes.get()); 12601 if (!PostUpdateRes.isUsable()) 12602 continue; 12603 ExprPostUpdates.push_back( 12604 IgnoredValueConversions(PostUpdateRes.get()).get()); 12605 } 12606 } 12607 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12608 Vars.push_back((VD || CurContext->isDependentContext()) 12609 ? RefExpr->IgnoreParens() 12610 : Ref); 12611 SrcExprs.push_back(PseudoSrcExpr); 12612 DstExprs.push_back(PseudoDstExpr); 12613 AssignmentOps.push_back(AssignmentOp.get()); 12614 } 12615 12616 if (Vars.empty()) 12617 return nullptr; 12618 12619 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12620 Vars, SrcExprs, DstExprs, AssignmentOps, 12621 buildPreInits(Context, ExprCaptures), 12622 buildPostUpdate(*this, ExprPostUpdates)); 12623 } 12624 12625 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12626 SourceLocation StartLoc, 12627 SourceLocation LParenLoc, 12628 SourceLocation EndLoc) { 12629 SmallVector<Expr *, 8> Vars; 12630 for (Expr *RefExpr : VarList) { 12631 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12632 SourceLocation ELoc; 12633 SourceRange ERange; 12634 Expr *SimpleRefExpr = RefExpr; 12635 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12636 if (Res.second) { 12637 // It will be analyzed later. 12638 Vars.push_back(RefExpr); 12639 } 12640 ValueDecl *D = Res.first; 12641 if (!D) 12642 continue; 12643 12644 auto *VD = dyn_cast<VarDecl>(D); 12645 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12646 // in a Construct] 12647 // Variables with the predetermined data-sharing attributes may not be 12648 // listed in data-sharing attributes clauses, except for the cases 12649 // listed below. For these exceptions only, listing a predetermined 12650 // variable in a data-sharing attribute clause is allowed and overrides 12651 // the variable's predetermined data-sharing attributes. 12652 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12653 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12654 DVar.RefExpr) { 12655 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12656 << getOpenMPClauseName(OMPC_shared); 12657 reportOriginalDsa(*this, DSAStack, D, DVar); 12658 continue; 12659 } 12660 12661 DeclRefExpr *Ref = nullptr; 12662 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12663 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12664 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12665 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12666 ? RefExpr->IgnoreParens() 12667 : Ref); 12668 } 12669 12670 if (Vars.empty()) 12671 return nullptr; 12672 12673 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12674 } 12675 12676 namespace { 12677 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12678 DSAStackTy *Stack; 12679 12680 public: 12681 bool VisitDeclRefExpr(DeclRefExpr *E) { 12682 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12683 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12684 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12685 return false; 12686 if (DVar.CKind != OMPC_unknown) 12687 return true; 12688 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12689 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12690 /*FromParent=*/true); 12691 return DVarPrivate.CKind != OMPC_unknown; 12692 } 12693 return false; 12694 } 12695 bool VisitStmt(Stmt *S) { 12696 for (Stmt *Child : S->children()) { 12697 if (Child && Visit(Child)) 12698 return true; 12699 } 12700 return false; 12701 } 12702 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12703 }; 12704 } // namespace 12705 12706 namespace { 12707 // Transform MemberExpression for specified FieldDecl of current class to 12708 // DeclRefExpr to specified OMPCapturedExprDecl. 12709 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12710 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12711 ValueDecl *Field = nullptr; 12712 DeclRefExpr *CapturedExpr = nullptr; 12713 12714 public: 12715 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12716 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12717 12718 ExprResult TransformMemberExpr(MemberExpr *E) { 12719 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12720 E->getMemberDecl() == Field) { 12721 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12722 return CapturedExpr; 12723 } 12724 return BaseTransform::TransformMemberExpr(E); 12725 } 12726 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12727 }; 12728 } // namespace 12729 12730 template <typename T, typename U> 12731 static T filterLookupForUDReductionAndMapper( 12732 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12733 for (U &Set : Lookups) { 12734 for (auto *D : Set) { 12735 if (T Res = Gen(cast<ValueDecl>(D))) 12736 return Res; 12737 } 12738 } 12739 return T(); 12740 } 12741 12742 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12743 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12744 12745 for (auto RD : D->redecls()) { 12746 // Don't bother with extra checks if we already know this one isn't visible. 12747 if (RD == D) 12748 continue; 12749 12750 auto ND = cast<NamedDecl>(RD); 12751 if (LookupResult::isVisible(SemaRef, ND)) 12752 return ND; 12753 } 12754 12755 return nullptr; 12756 } 12757 12758 static void 12759 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12760 SourceLocation Loc, QualType Ty, 12761 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12762 // Find all of the associated namespaces and classes based on the 12763 // arguments we have. 12764 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12765 Sema::AssociatedClassSet AssociatedClasses; 12766 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12767 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12768 AssociatedClasses); 12769 12770 // C++ [basic.lookup.argdep]p3: 12771 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12772 // and let Y be the lookup set produced by argument dependent 12773 // lookup (defined as follows). If X contains [...] then Y is 12774 // empty. Otherwise Y is the set of declarations found in the 12775 // namespaces associated with the argument types as described 12776 // below. The set of declarations found by the lookup of the name 12777 // is the union of X and Y. 12778 // 12779 // Here, we compute Y and add its members to the overloaded 12780 // candidate set. 12781 for (auto *NS : AssociatedNamespaces) { 12782 // When considering an associated namespace, the lookup is the 12783 // same as the lookup performed when the associated namespace is 12784 // used as a qualifier (3.4.3.2) except that: 12785 // 12786 // -- Any using-directives in the associated namespace are 12787 // ignored. 12788 // 12789 // -- Any namespace-scope friend functions declared in 12790 // associated classes are visible within their respective 12791 // namespaces even if they are not visible during an ordinary 12792 // lookup (11.4). 12793 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12794 for (auto *D : R) { 12795 auto *Underlying = D; 12796 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12797 Underlying = USD->getTargetDecl(); 12798 12799 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12800 !isa<OMPDeclareMapperDecl>(Underlying)) 12801 continue; 12802 12803 if (!SemaRef.isVisible(D)) { 12804 D = findAcceptableDecl(SemaRef, D); 12805 if (!D) 12806 continue; 12807 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12808 Underlying = USD->getTargetDecl(); 12809 } 12810 Lookups.emplace_back(); 12811 Lookups.back().addDecl(Underlying); 12812 } 12813 } 12814 } 12815 12816 static ExprResult 12817 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12818 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12819 const DeclarationNameInfo &ReductionId, QualType Ty, 12820 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12821 if (ReductionIdScopeSpec.isInvalid()) 12822 return ExprError(); 12823 SmallVector<UnresolvedSet<8>, 4> Lookups; 12824 if (S) { 12825 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12826 Lookup.suppressDiagnostics(); 12827 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12828 NamedDecl *D = Lookup.getRepresentativeDecl(); 12829 do { 12830 S = S->getParent(); 12831 } while (S && !S->isDeclScope(D)); 12832 if (S) 12833 S = S->getParent(); 12834 Lookups.emplace_back(); 12835 Lookups.back().append(Lookup.begin(), Lookup.end()); 12836 Lookup.clear(); 12837 } 12838 } else if (auto *ULE = 12839 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12840 Lookups.push_back(UnresolvedSet<8>()); 12841 Decl *PrevD = nullptr; 12842 for (NamedDecl *D : ULE->decls()) { 12843 if (D == PrevD) 12844 Lookups.push_back(UnresolvedSet<8>()); 12845 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12846 Lookups.back().addDecl(DRD); 12847 PrevD = D; 12848 } 12849 } 12850 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12851 Ty->isInstantiationDependentType() || 12852 Ty->containsUnexpandedParameterPack() || 12853 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12854 return !D->isInvalidDecl() && 12855 (D->getType()->isDependentType() || 12856 D->getType()->isInstantiationDependentType() || 12857 D->getType()->containsUnexpandedParameterPack()); 12858 })) { 12859 UnresolvedSet<8> ResSet; 12860 for (const UnresolvedSet<8> &Set : Lookups) { 12861 if (Set.empty()) 12862 continue; 12863 ResSet.append(Set.begin(), Set.end()); 12864 // The last item marks the end of all declarations at the specified scope. 12865 ResSet.addDecl(Set[Set.size() - 1]); 12866 } 12867 return UnresolvedLookupExpr::Create( 12868 SemaRef.Context, /*NamingClass=*/nullptr, 12869 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12870 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12871 } 12872 // Lookup inside the classes. 12873 // C++ [over.match.oper]p3: 12874 // For a unary operator @ with an operand of a type whose 12875 // cv-unqualified version is T1, and for a binary operator @ with 12876 // a left operand of a type whose cv-unqualified version is T1 and 12877 // a right operand of a type whose cv-unqualified version is T2, 12878 // three sets of candidate functions, designated member 12879 // candidates, non-member candidates and built-in candidates, are 12880 // constructed as follows: 12881 // -- If T1 is a complete class type or a class currently being 12882 // defined, the set of member candidates is the result of the 12883 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12884 // the set of member candidates is empty. 12885 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12886 Lookup.suppressDiagnostics(); 12887 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12888 // Complete the type if it can be completed. 12889 // If the type is neither complete nor being defined, bail out now. 12890 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12891 TyRec->getDecl()->getDefinition()) { 12892 Lookup.clear(); 12893 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12894 if (Lookup.empty()) { 12895 Lookups.emplace_back(); 12896 Lookups.back().append(Lookup.begin(), Lookup.end()); 12897 } 12898 } 12899 } 12900 // Perform ADL. 12901 if (SemaRef.getLangOpts().CPlusPlus) 12902 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12903 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12904 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12905 if (!D->isInvalidDecl() && 12906 SemaRef.Context.hasSameType(D->getType(), Ty)) 12907 return D; 12908 return nullptr; 12909 })) 12910 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12911 VK_LValue, Loc); 12912 if (SemaRef.getLangOpts().CPlusPlus) { 12913 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12914 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12915 if (!D->isInvalidDecl() && 12916 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12917 !Ty.isMoreQualifiedThan(D->getType())) 12918 return D; 12919 return nullptr; 12920 })) { 12921 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12922 /*DetectVirtual=*/false); 12923 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12924 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12925 VD->getType().getUnqualifiedType()))) { 12926 if (SemaRef.CheckBaseClassAccess( 12927 Loc, VD->getType(), Ty, Paths.front(), 12928 /*DiagID=*/0) != Sema::AR_inaccessible) { 12929 SemaRef.BuildBasePathArray(Paths, BasePath); 12930 return SemaRef.BuildDeclRefExpr( 12931 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12932 } 12933 } 12934 } 12935 } 12936 } 12937 if (ReductionIdScopeSpec.isSet()) { 12938 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12939 return ExprError(); 12940 } 12941 return ExprEmpty(); 12942 } 12943 12944 namespace { 12945 /// Data for the reduction-based clauses. 12946 struct ReductionData { 12947 /// List of original reduction items. 12948 SmallVector<Expr *, 8> Vars; 12949 /// List of private copies of the reduction items. 12950 SmallVector<Expr *, 8> Privates; 12951 /// LHS expressions for the reduction_op expressions. 12952 SmallVector<Expr *, 8> LHSs; 12953 /// RHS expressions for the reduction_op expressions. 12954 SmallVector<Expr *, 8> RHSs; 12955 /// Reduction operation expression. 12956 SmallVector<Expr *, 8> ReductionOps; 12957 /// Taskgroup descriptors for the corresponding reduction items in 12958 /// in_reduction clauses. 12959 SmallVector<Expr *, 8> TaskgroupDescriptors; 12960 /// List of captures for clause. 12961 SmallVector<Decl *, 4> ExprCaptures; 12962 /// List of postupdate expressions. 12963 SmallVector<Expr *, 4> ExprPostUpdates; 12964 ReductionData() = delete; 12965 /// Reserves required memory for the reduction data. 12966 ReductionData(unsigned Size) { 12967 Vars.reserve(Size); 12968 Privates.reserve(Size); 12969 LHSs.reserve(Size); 12970 RHSs.reserve(Size); 12971 ReductionOps.reserve(Size); 12972 TaskgroupDescriptors.reserve(Size); 12973 ExprCaptures.reserve(Size); 12974 ExprPostUpdates.reserve(Size); 12975 } 12976 /// Stores reduction item and reduction operation only (required for dependent 12977 /// reduction item). 12978 void push(Expr *Item, Expr *ReductionOp) { 12979 Vars.emplace_back(Item); 12980 Privates.emplace_back(nullptr); 12981 LHSs.emplace_back(nullptr); 12982 RHSs.emplace_back(nullptr); 12983 ReductionOps.emplace_back(ReductionOp); 12984 TaskgroupDescriptors.emplace_back(nullptr); 12985 } 12986 /// Stores reduction data. 12987 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12988 Expr *TaskgroupDescriptor) { 12989 Vars.emplace_back(Item); 12990 Privates.emplace_back(Private); 12991 LHSs.emplace_back(LHS); 12992 RHSs.emplace_back(RHS); 12993 ReductionOps.emplace_back(ReductionOp); 12994 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12995 } 12996 }; 12997 } // namespace 12998 12999 static bool checkOMPArraySectionConstantForReduction( 13000 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13001 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13002 const Expr *Length = OASE->getLength(); 13003 if (Length == nullptr) { 13004 // For array sections of the form [1:] or [:], we would need to analyze 13005 // the lower bound... 13006 if (OASE->getColonLoc().isValid()) 13007 return false; 13008 13009 // This is an array subscript which has implicit length 1! 13010 SingleElement = true; 13011 ArraySizes.push_back(llvm::APSInt::get(1)); 13012 } else { 13013 Expr::EvalResult Result; 13014 if (!Length->EvaluateAsInt(Result, Context)) 13015 return false; 13016 13017 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13018 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13019 ArraySizes.push_back(ConstantLengthValue); 13020 } 13021 13022 // Get the base of this array section and walk up from there. 13023 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13024 13025 // We require length = 1 for all array sections except the right-most to 13026 // guarantee that the memory region is contiguous and has no holes in it. 13027 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13028 Length = TempOASE->getLength(); 13029 if (Length == nullptr) { 13030 // For array sections of the form [1:] or [:], we would need to analyze 13031 // the lower bound... 13032 if (OASE->getColonLoc().isValid()) 13033 return false; 13034 13035 // This is an array subscript which has implicit length 1! 13036 ArraySizes.push_back(llvm::APSInt::get(1)); 13037 } else { 13038 Expr::EvalResult Result; 13039 if (!Length->EvaluateAsInt(Result, Context)) 13040 return false; 13041 13042 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13043 if (ConstantLengthValue.getSExtValue() != 1) 13044 return false; 13045 13046 ArraySizes.push_back(ConstantLengthValue); 13047 } 13048 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13049 } 13050 13051 // If we have a single element, we don't need to add the implicit lengths. 13052 if (!SingleElement) { 13053 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13054 // Has implicit length 1! 13055 ArraySizes.push_back(llvm::APSInt::get(1)); 13056 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13057 } 13058 } 13059 13060 // This array section can be privatized as a single value or as a constant 13061 // sized array. 13062 return true; 13063 } 13064 13065 static bool actOnOMPReductionKindClause( 13066 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13067 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13068 SourceLocation ColonLoc, SourceLocation EndLoc, 13069 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13070 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13071 DeclarationName DN = ReductionId.getName(); 13072 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13073 BinaryOperatorKind BOK = BO_Comma; 13074 13075 ASTContext &Context = S.Context; 13076 // OpenMP [2.14.3.6, reduction clause] 13077 // C 13078 // reduction-identifier is either an identifier or one of the following 13079 // operators: +, -, *, &, |, ^, && and || 13080 // C++ 13081 // reduction-identifier is either an id-expression or one of the following 13082 // operators: +, -, *, &, |, ^, && and || 13083 switch (OOK) { 13084 case OO_Plus: 13085 case OO_Minus: 13086 BOK = BO_Add; 13087 break; 13088 case OO_Star: 13089 BOK = BO_Mul; 13090 break; 13091 case OO_Amp: 13092 BOK = BO_And; 13093 break; 13094 case OO_Pipe: 13095 BOK = BO_Or; 13096 break; 13097 case OO_Caret: 13098 BOK = BO_Xor; 13099 break; 13100 case OO_AmpAmp: 13101 BOK = BO_LAnd; 13102 break; 13103 case OO_PipePipe: 13104 BOK = BO_LOr; 13105 break; 13106 case OO_New: 13107 case OO_Delete: 13108 case OO_Array_New: 13109 case OO_Array_Delete: 13110 case OO_Slash: 13111 case OO_Percent: 13112 case OO_Tilde: 13113 case OO_Exclaim: 13114 case OO_Equal: 13115 case OO_Less: 13116 case OO_Greater: 13117 case OO_LessEqual: 13118 case OO_GreaterEqual: 13119 case OO_PlusEqual: 13120 case OO_MinusEqual: 13121 case OO_StarEqual: 13122 case OO_SlashEqual: 13123 case OO_PercentEqual: 13124 case OO_CaretEqual: 13125 case OO_AmpEqual: 13126 case OO_PipeEqual: 13127 case OO_LessLess: 13128 case OO_GreaterGreater: 13129 case OO_LessLessEqual: 13130 case OO_GreaterGreaterEqual: 13131 case OO_EqualEqual: 13132 case OO_ExclaimEqual: 13133 case OO_Spaceship: 13134 case OO_PlusPlus: 13135 case OO_MinusMinus: 13136 case OO_Comma: 13137 case OO_ArrowStar: 13138 case OO_Arrow: 13139 case OO_Call: 13140 case OO_Subscript: 13141 case OO_Conditional: 13142 case OO_Coawait: 13143 case NUM_OVERLOADED_OPERATORS: 13144 llvm_unreachable("Unexpected reduction identifier"); 13145 case OO_None: 13146 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13147 if (II->isStr("max")) 13148 BOK = BO_GT; 13149 else if (II->isStr("min")) 13150 BOK = BO_LT; 13151 } 13152 break; 13153 } 13154 SourceRange ReductionIdRange; 13155 if (ReductionIdScopeSpec.isValid()) 13156 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13157 else 13158 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13159 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13160 13161 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13162 bool FirstIter = true; 13163 for (Expr *RefExpr : VarList) { 13164 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13165 // OpenMP [2.1, C/C++] 13166 // A list item is a variable or array section, subject to the restrictions 13167 // specified in Section 2.4 on page 42 and in each of the sections 13168 // describing clauses and directives for which a list appears. 13169 // OpenMP [2.14.3.3, Restrictions, p.1] 13170 // A variable that is part of another variable (as an array or 13171 // structure element) cannot appear in a private clause. 13172 if (!FirstIter && IR != ER) 13173 ++IR; 13174 FirstIter = false; 13175 SourceLocation ELoc; 13176 SourceRange ERange; 13177 Expr *SimpleRefExpr = RefExpr; 13178 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13179 /*AllowArraySection=*/true); 13180 if (Res.second) { 13181 // Try to find 'declare reduction' corresponding construct before using 13182 // builtin/overloaded operators. 13183 QualType Type = Context.DependentTy; 13184 CXXCastPath BasePath; 13185 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13186 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13187 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13188 Expr *ReductionOp = nullptr; 13189 if (S.CurContext->isDependentContext() && 13190 (DeclareReductionRef.isUnset() || 13191 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13192 ReductionOp = DeclareReductionRef.get(); 13193 // It will be analyzed later. 13194 RD.push(RefExpr, ReductionOp); 13195 } 13196 ValueDecl *D = Res.first; 13197 if (!D) 13198 continue; 13199 13200 Expr *TaskgroupDescriptor = nullptr; 13201 QualType Type; 13202 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13203 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13204 if (ASE) { 13205 Type = ASE->getType().getNonReferenceType(); 13206 } else if (OASE) { 13207 QualType BaseType = 13208 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13209 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13210 Type = ATy->getElementType(); 13211 else 13212 Type = BaseType->getPointeeType(); 13213 Type = Type.getNonReferenceType(); 13214 } else { 13215 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13216 } 13217 auto *VD = dyn_cast<VarDecl>(D); 13218 13219 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13220 // A variable that appears in a private clause must not have an incomplete 13221 // type or a reference type. 13222 if (S.RequireCompleteType(ELoc, D->getType(), 13223 diag::err_omp_reduction_incomplete_type)) 13224 continue; 13225 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13226 // A list item that appears in a reduction clause must not be 13227 // const-qualified. 13228 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13229 /*AcceptIfMutable*/ false, ASE || OASE)) 13230 continue; 13231 13232 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13233 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13234 // If a list-item is a reference type then it must bind to the same object 13235 // for all threads of the team. 13236 if (!ASE && !OASE) { 13237 if (VD) { 13238 VarDecl *VDDef = VD->getDefinition(); 13239 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13240 DSARefChecker Check(Stack); 13241 if (Check.Visit(VDDef->getInit())) { 13242 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13243 << getOpenMPClauseName(ClauseKind) << ERange; 13244 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13245 continue; 13246 } 13247 } 13248 } 13249 13250 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13251 // in a Construct] 13252 // Variables with the predetermined data-sharing attributes may not be 13253 // listed in data-sharing attributes clauses, except for the cases 13254 // listed below. For these exceptions only, listing a predetermined 13255 // variable in a data-sharing attribute clause is allowed and overrides 13256 // the variable's predetermined data-sharing attributes. 13257 // OpenMP [2.14.3.6, Restrictions, p.3] 13258 // Any number of reduction clauses can be specified on the directive, 13259 // but a list item can appear only once in the reduction clauses for that 13260 // directive. 13261 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13262 if (DVar.CKind == OMPC_reduction) { 13263 S.Diag(ELoc, diag::err_omp_once_referenced) 13264 << getOpenMPClauseName(ClauseKind); 13265 if (DVar.RefExpr) 13266 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13267 continue; 13268 } 13269 if (DVar.CKind != OMPC_unknown) { 13270 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13271 << getOpenMPClauseName(DVar.CKind) 13272 << getOpenMPClauseName(OMPC_reduction); 13273 reportOriginalDsa(S, Stack, D, DVar); 13274 continue; 13275 } 13276 13277 // OpenMP [2.14.3.6, Restrictions, p.1] 13278 // A list item that appears in a reduction clause of a worksharing 13279 // construct must be shared in the parallel regions to which any of the 13280 // worksharing regions arising from the worksharing construct bind. 13281 if (isOpenMPWorksharingDirective(CurrDir) && 13282 !isOpenMPParallelDirective(CurrDir) && 13283 !isOpenMPTeamsDirective(CurrDir)) { 13284 DVar = Stack->getImplicitDSA(D, true); 13285 if (DVar.CKind != OMPC_shared) { 13286 S.Diag(ELoc, diag::err_omp_required_access) 13287 << getOpenMPClauseName(OMPC_reduction) 13288 << getOpenMPClauseName(OMPC_shared); 13289 reportOriginalDsa(S, Stack, D, DVar); 13290 continue; 13291 } 13292 } 13293 } 13294 13295 // Try to find 'declare reduction' corresponding construct before using 13296 // builtin/overloaded operators. 13297 CXXCastPath BasePath; 13298 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13299 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13300 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13301 if (DeclareReductionRef.isInvalid()) 13302 continue; 13303 if (S.CurContext->isDependentContext() && 13304 (DeclareReductionRef.isUnset() || 13305 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13306 RD.push(RefExpr, DeclareReductionRef.get()); 13307 continue; 13308 } 13309 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13310 // Not allowed reduction identifier is found. 13311 S.Diag(ReductionId.getBeginLoc(), 13312 diag::err_omp_unknown_reduction_identifier) 13313 << Type << ReductionIdRange; 13314 continue; 13315 } 13316 13317 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13318 // The type of a list item that appears in a reduction clause must be valid 13319 // for the reduction-identifier. For a max or min reduction in C, the type 13320 // of the list item must be an allowed arithmetic data type: char, int, 13321 // float, double, or _Bool, possibly modified with long, short, signed, or 13322 // unsigned. For a max or min reduction in C++, the type of the list item 13323 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13324 // double, or bool, possibly modified with long, short, signed, or unsigned. 13325 if (DeclareReductionRef.isUnset()) { 13326 if ((BOK == BO_GT || BOK == BO_LT) && 13327 !(Type->isScalarType() || 13328 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13329 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13330 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13331 if (!ASE && !OASE) { 13332 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13333 VarDecl::DeclarationOnly; 13334 S.Diag(D->getLocation(), 13335 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13336 << D; 13337 } 13338 continue; 13339 } 13340 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13341 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13342 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13343 << getOpenMPClauseName(ClauseKind); 13344 if (!ASE && !OASE) { 13345 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13346 VarDecl::DeclarationOnly; 13347 S.Diag(D->getLocation(), 13348 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13349 << D; 13350 } 13351 continue; 13352 } 13353 } 13354 13355 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13356 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13357 D->hasAttrs() ? &D->getAttrs() : nullptr); 13358 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13359 D->hasAttrs() ? &D->getAttrs() : nullptr); 13360 QualType PrivateTy = Type; 13361 13362 // Try if we can determine constant lengths for all array sections and avoid 13363 // the VLA. 13364 bool ConstantLengthOASE = false; 13365 if (OASE) { 13366 bool SingleElement; 13367 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13368 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13369 Context, OASE, SingleElement, ArraySizes); 13370 13371 // If we don't have a single element, we must emit a constant array type. 13372 if (ConstantLengthOASE && !SingleElement) { 13373 for (llvm::APSInt &Size : ArraySizes) 13374 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13375 ArrayType::Normal, 13376 /*IndexTypeQuals=*/0); 13377 } 13378 } 13379 13380 if ((OASE && !ConstantLengthOASE) || 13381 (!OASE && !ASE && 13382 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13383 if (!Context.getTargetInfo().isVLASupported()) { 13384 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13385 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13386 S.Diag(ELoc, diag::note_vla_unsupported); 13387 } else { 13388 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13389 S.targetDiag(ELoc, diag::note_vla_unsupported); 13390 } 13391 continue; 13392 } 13393 // For arrays/array sections only: 13394 // Create pseudo array type for private copy. The size for this array will 13395 // be generated during codegen. 13396 // For array subscripts or single variables Private Ty is the same as Type 13397 // (type of the variable or single array element). 13398 PrivateTy = Context.getVariableArrayType( 13399 Type, 13400 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13401 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13402 } else if (!ASE && !OASE && 13403 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13404 PrivateTy = D->getType().getNonReferenceType(); 13405 } 13406 // Private copy. 13407 VarDecl *PrivateVD = 13408 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13409 D->hasAttrs() ? &D->getAttrs() : nullptr, 13410 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13411 // Add initializer for private variable. 13412 Expr *Init = nullptr; 13413 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13414 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13415 if (DeclareReductionRef.isUsable()) { 13416 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13417 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13418 if (DRD->getInitializer()) { 13419 Init = DRDRef; 13420 RHSVD->setInit(DRDRef); 13421 RHSVD->setInitStyle(VarDecl::CallInit); 13422 } 13423 } else { 13424 switch (BOK) { 13425 case BO_Add: 13426 case BO_Xor: 13427 case BO_Or: 13428 case BO_LOr: 13429 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13430 if (Type->isScalarType() || Type->isAnyComplexType()) 13431 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13432 break; 13433 case BO_Mul: 13434 case BO_LAnd: 13435 if (Type->isScalarType() || Type->isAnyComplexType()) { 13436 // '*' and '&&' reduction ops - initializer is '1'. 13437 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13438 } 13439 break; 13440 case BO_And: { 13441 // '&' reduction op - initializer is '~0'. 13442 QualType OrigType = Type; 13443 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13444 Type = ComplexTy->getElementType(); 13445 if (Type->isRealFloatingType()) { 13446 llvm::APFloat InitValue = 13447 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13448 /*isIEEE=*/true); 13449 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13450 Type, ELoc); 13451 } else if (Type->isScalarType()) { 13452 uint64_t Size = Context.getTypeSize(Type); 13453 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13454 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13455 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13456 } 13457 if (Init && OrigType->isAnyComplexType()) { 13458 // Init = 0xFFFF + 0xFFFFi; 13459 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13460 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13461 } 13462 Type = OrigType; 13463 break; 13464 } 13465 case BO_LT: 13466 case BO_GT: { 13467 // 'min' reduction op - initializer is 'Largest representable number in 13468 // the reduction list item type'. 13469 // 'max' reduction op - initializer is 'Least representable number in 13470 // the reduction list item type'. 13471 if (Type->isIntegerType() || Type->isPointerType()) { 13472 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13473 uint64_t Size = Context.getTypeSize(Type); 13474 QualType IntTy = 13475 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13476 llvm::APInt InitValue = 13477 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13478 : llvm::APInt::getMinValue(Size) 13479 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13480 : llvm::APInt::getMaxValue(Size); 13481 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13482 if (Type->isPointerType()) { 13483 // Cast to pointer type. 13484 ExprResult CastExpr = S.BuildCStyleCastExpr( 13485 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13486 if (CastExpr.isInvalid()) 13487 continue; 13488 Init = CastExpr.get(); 13489 } 13490 } else if (Type->isRealFloatingType()) { 13491 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13492 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13493 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13494 Type, ELoc); 13495 } 13496 break; 13497 } 13498 case BO_PtrMemD: 13499 case BO_PtrMemI: 13500 case BO_MulAssign: 13501 case BO_Div: 13502 case BO_Rem: 13503 case BO_Sub: 13504 case BO_Shl: 13505 case BO_Shr: 13506 case BO_LE: 13507 case BO_GE: 13508 case BO_EQ: 13509 case BO_NE: 13510 case BO_Cmp: 13511 case BO_AndAssign: 13512 case BO_XorAssign: 13513 case BO_OrAssign: 13514 case BO_Assign: 13515 case BO_AddAssign: 13516 case BO_SubAssign: 13517 case BO_DivAssign: 13518 case BO_RemAssign: 13519 case BO_ShlAssign: 13520 case BO_ShrAssign: 13521 case BO_Comma: 13522 llvm_unreachable("Unexpected reduction operation"); 13523 } 13524 } 13525 if (Init && DeclareReductionRef.isUnset()) 13526 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13527 else if (!Init) 13528 S.ActOnUninitializedDecl(RHSVD); 13529 if (RHSVD->isInvalidDecl()) 13530 continue; 13531 if (!RHSVD->hasInit() && 13532 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13533 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13534 << Type << ReductionIdRange; 13535 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13536 VarDecl::DeclarationOnly; 13537 S.Diag(D->getLocation(), 13538 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13539 << D; 13540 continue; 13541 } 13542 // Store initializer for single element in private copy. Will be used during 13543 // codegen. 13544 PrivateVD->setInit(RHSVD->getInit()); 13545 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13546 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13547 ExprResult ReductionOp; 13548 if (DeclareReductionRef.isUsable()) { 13549 QualType RedTy = DeclareReductionRef.get()->getType(); 13550 QualType PtrRedTy = Context.getPointerType(RedTy); 13551 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13552 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13553 if (!BasePath.empty()) { 13554 LHS = S.DefaultLvalueConversion(LHS.get()); 13555 RHS = S.DefaultLvalueConversion(RHS.get()); 13556 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13557 CK_UncheckedDerivedToBase, LHS.get(), 13558 &BasePath, LHS.get()->getValueKind()); 13559 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13560 CK_UncheckedDerivedToBase, RHS.get(), 13561 &BasePath, RHS.get()->getValueKind()); 13562 } 13563 FunctionProtoType::ExtProtoInfo EPI; 13564 QualType Params[] = {PtrRedTy, PtrRedTy}; 13565 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13566 auto *OVE = new (Context) OpaqueValueExpr( 13567 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13568 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13569 Expr *Args[] = {LHS.get(), RHS.get()}; 13570 ReductionOp = 13571 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13572 } else { 13573 ReductionOp = S.BuildBinOp( 13574 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13575 if (ReductionOp.isUsable()) { 13576 if (BOK != BO_LT && BOK != BO_GT) { 13577 ReductionOp = 13578 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13579 BO_Assign, LHSDRE, ReductionOp.get()); 13580 } else { 13581 auto *ConditionalOp = new (Context) 13582 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13583 Type, VK_LValue, OK_Ordinary); 13584 ReductionOp = 13585 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13586 BO_Assign, LHSDRE, ConditionalOp); 13587 } 13588 if (ReductionOp.isUsable()) 13589 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13590 /*DiscardedValue*/ false); 13591 } 13592 if (!ReductionOp.isUsable()) 13593 continue; 13594 } 13595 13596 // OpenMP [2.15.4.6, Restrictions, p.2] 13597 // A list item that appears in an in_reduction clause of a task construct 13598 // must appear in a task_reduction clause of a construct associated with a 13599 // taskgroup region that includes the participating task in its taskgroup 13600 // set. The construct associated with the innermost region that meets this 13601 // condition must specify the same reduction-identifier as the in_reduction 13602 // clause. 13603 if (ClauseKind == OMPC_in_reduction) { 13604 SourceRange ParentSR; 13605 BinaryOperatorKind ParentBOK; 13606 const Expr *ParentReductionOp; 13607 Expr *ParentBOKTD, *ParentReductionOpTD; 13608 DSAStackTy::DSAVarData ParentBOKDSA = 13609 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13610 ParentBOKTD); 13611 DSAStackTy::DSAVarData ParentReductionOpDSA = 13612 Stack->getTopMostTaskgroupReductionData( 13613 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13614 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13615 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13616 if (!IsParentBOK && !IsParentReductionOp) { 13617 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13618 continue; 13619 } 13620 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13621 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13622 IsParentReductionOp) { 13623 bool EmitError = true; 13624 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13625 llvm::FoldingSetNodeID RedId, ParentRedId; 13626 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13627 DeclareReductionRef.get()->Profile(RedId, Context, 13628 /*Canonical=*/true); 13629 EmitError = RedId != ParentRedId; 13630 } 13631 if (EmitError) { 13632 S.Diag(ReductionId.getBeginLoc(), 13633 diag::err_omp_reduction_identifier_mismatch) 13634 << ReductionIdRange << RefExpr->getSourceRange(); 13635 S.Diag(ParentSR.getBegin(), 13636 diag::note_omp_previous_reduction_identifier) 13637 << ParentSR 13638 << (IsParentBOK ? ParentBOKDSA.RefExpr 13639 : ParentReductionOpDSA.RefExpr) 13640 ->getSourceRange(); 13641 continue; 13642 } 13643 } 13644 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13645 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13646 } 13647 13648 DeclRefExpr *Ref = nullptr; 13649 Expr *VarsExpr = RefExpr->IgnoreParens(); 13650 if (!VD && !S.CurContext->isDependentContext()) { 13651 if (ASE || OASE) { 13652 TransformExprToCaptures RebuildToCapture(S, D); 13653 VarsExpr = 13654 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13655 Ref = RebuildToCapture.getCapturedExpr(); 13656 } else { 13657 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13658 } 13659 if (!S.isOpenMPCapturedDecl(D)) { 13660 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13661 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13662 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13663 if (!RefRes.isUsable()) 13664 continue; 13665 ExprResult PostUpdateRes = 13666 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13667 RefRes.get()); 13668 if (!PostUpdateRes.isUsable()) 13669 continue; 13670 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13671 Stack->getCurrentDirective() == OMPD_taskgroup) { 13672 S.Diag(RefExpr->getExprLoc(), 13673 diag::err_omp_reduction_non_addressable_expression) 13674 << RefExpr->getSourceRange(); 13675 continue; 13676 } 13677 RD.ExprPostUpdates.emplace_back( 13678 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13679 } 13680 } 13681 } 13682 // All reduction items are still marked as reduction (to do not increase 13683 // code base size). 13684 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13685 if (CurrDir == OMPD_taskgroup) { 13686 if (DeclareReductionRef.isUsable()) 13687 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13688 DeclareReductionRef.get()); 13689 else 13690 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13691 } 13692 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13693 TaskgroupDescriptor); 13694 } 13695 return RD.Vars.empty(); 13696 } 13697 13698 OMPClause *Sema::ActOnOpenMPReductionClause( 13699 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13700 SourceLocation ColonLoc, SourceLocation EndLoc, 13701 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13702 ArrayRef<Expr *> UnresolvedReductions) { 13703 ReductionData RD(VarList.size()); 13704 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13705 StartLoc, LParenLoc, ColonLoc, EndLoc, 13706 ReductionIdScopeSpec, ReductionId, 13707 UnresolvedReductions, RD)) 13708 return nullptr; 13709 13710 return OMPReductionClause::Create( 13711 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13712 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13713 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13714 buildPreInits(Context, RD.ExprCaptures), 13715 buildPostUpdate(*this, RD.ExprPostUpdates)); 13716 } 13717 13718 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13719 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13720 SourceLocation ColonLoc, SourceLocation EndLoc, 13721 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13722 ArrayRef<Expr *> UnresolvedReductions) { 13723 ReductionData RD(VarList.size()); 13724 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13725 StartLoc, LParenLoc, ColonLoc, EndLoc, 13726 ReductionIdScopeSpec, ReductionId, 13727 UnresolvedReductions, RD)) 13728 return nullptr; 13729 13730 return OMPTaskReductionClause::Create( 13731 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13732 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13733 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13734 buildPreInits(Context, RD.ExprCaptures), 13735 buildPostUpdate(*this, RD.ExprPostUpdates)); 13736 } 13737 13738 OMPClause *Sema::ActOnOpenMPInReductionClause( 13739 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13740 SourceLocation ColonLoc, SourceLocation EndLoc, 13741 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13742 ArrayRef<Expr *> UnresolvedReductions) { 13743 ReductionData RD(VarList.size()); 13744 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13745 StartLoc, LParenLoc, ColonLoc, EndLoc, 13746 ReductionIdScopeSpec, ReductionId, 13747 UnresolvedReductions, RD)) 13748 return nullptr; 13749 13750 return OMPInReductionClause::Create( 13751 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13752 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13753 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13754 buildPreInits(Context, RD.ExprCaptures), 13755 buildPostUpdate(*this, RD.ExprPostUpdates)); 13756 } 13757 13758 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13759 SourceLocation LinLoc) { 13760 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13761 LinKind == OMPC_LINEAR_unknown) { 13762 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13763 return true; 13764 } 13765 return false; 13766 } 13767 13768 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13769 OpenMPLinearClauseKind LinKind, 13770 QualType Type) { 13771 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13772 // A variable must not have an incomplete type or a reference type. 13773 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13774 return true; 13775 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13776 !Type->isReferenceType()) { 13777 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13778 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13779 return true; 13780 } 13781 Type = Type.getNonReferenceType(); 13782 13783 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13784 // A variable that is privatized must not have a const-qualified type 13785 // unless it is of class type with a mutable member. This restriction does 13786 // not apply to the firstprivate clause. 13787 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13788 return true; 13789 13790 // A list item must be of integral or pointer type. 13791 Type = Type.getUnqualifiedType().getCanonicalType(); 13792 const auto *Ty = Type.getTypePtrOrNull(); 13793 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13794 !Ty->isPointerType())) { 13795 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13796 if (D) { 13797 bool IsDecl = 13798 !VD || 13799 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13800 Diag(D->getLocation(), 13801 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13802 << D; 13803 } 13804 return true; 13805 } 13806 return false; 13807 } 13808 13809 OMPClause *Sema::ActOnOpenMPLinearClause( 13810 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13811 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13812 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13813 SmallVector<Expr *, 8> Vars; 13814 SmallVector<Expr *, 8> Privates; 13815 SmallVector<Expr *, 8> Inits; 13816 SmallVector<Decl *, 4> ExprCaptures; 13817 SmallVector<Expr *, 4> ExprPostUpdates; 13818 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13819 LinKind = OMPC_LINEAR_val; 13820 for (Expr *RefExpr : VarList) { 13821 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13822 SourceLocation ELoc; 13823 SourceRange ERange; 13824 Expr *SimpleRefExpr = RefExpr; 13825 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13826 if (Res.second) { 13827 // It will be analyzed later. 13828 Vars.push_back(RefExpr); 13829 Privates.push_back(nullptr); 13830 Inits.push_back(nullptr); 13831 } 13832 ValueDecl *D = Res.first; 13833 if (!D) 13834 continue; 13835 13836 QualType Type = D->getType(); 13837 auto *VD = dyn_cast<VarDecl>(D); 13838 13839 // OpenMP [2.14.3.7, linear clause] 13840 // A list-item cannot appear in more than one linear clause. 13841 // A list-item that appears in a linear clause cannot appear in any 13842 // other data-sharing attribute clause. 13843 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13844 if (DVar.RefExpr) { 13845 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13846 << getOpenMPClauseName(OMPC_linear); 13847 reportOriginalDsa(*this, DSAStack, D, DVar); 13848 continue; 13849 } 13850 13851 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13852 continue; 13853 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13854 13855 // Build private copy of original var. 13856 VarDecl *Private = 13857 buildVarDecl(*this, ELoc, Type, D->getName(), 13858 D->hasAttrs() ? &D->getAttrs() : nullptr, 13859 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13860 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13861 // Build var to save initial value. 13862 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13863 Expr *InitExpr; 13864 DeclRefExpr *Ref = nullptr; 13865 if (!VD && !CurContext->isDependentContext()) { 13866 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13867 if (!isOpenMPCapturedDecl(D)) { 13868 ExprCaptures.push_back(Ref->getDecl()); 13869 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13870 ExprResult RefRes = DefaultLvalueConversion(Ref); 13871 if (!RefRes.isUsable()) 13872 continue; 13873 ExprResult PostUpdateRes = 13874 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13875 SimpleRefExpr, RefRes.get()); 13876 if (!PostUpdateRes.isUsable()) 13877 continue; 13878 ExprPostUpdates.push_back( 13879 IgnoredValueConversions(PostUpdateRes.get()).get()); 13880 } 13881 } 13882 } 13883 if (LinKind == OMPC_LINEAR_uval) 13884 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13885 else 13886 InitExpr = VD ? SimpleRefExpr : Ref; 13887 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13888 /*DirectInit=*/false); 13889 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13890 13891 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13892 Vars.push_back((VD || CurContext->isDependentContext()) 13893 ? RefExpr->IgnoreParens() 13894 : Ref); 13895 Privates.push_back(PrivateRef); 13896 Inits.push_back(InitRef); 13897 } 13898 13899 if (Vars.empty()) 13900 return nullptr; 13901 13902 Expr *StepExpr = Step; 13903 Expr *CalcStepExpr = nullptr; 13904 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13905 !Step->isInstantiationDependent() && 13906 !Step->containsUnexpandedParameterPack()) { 13907 SourceLocation StepLoc = Step->getBeginLoc(); 13908 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13909 if (Val.isInvalid()) 13910 return nullptr; 13911 StepExpr = Val.get(); 13912 13913 // Build var to save the step value. 13914 VarDecl *SaveVar = 13915 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13916 ExprResult SaveRef = 13917 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13918 ExprResult CalcStep = 13919 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13920 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13921 13922 // Warn about zero linear step (it would be probably better specified as 13923 // making corresponding variables 'const'). 13924 llvm::APSInt Result; 13925 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13926 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13927 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13928 << (Vars.size() > 1); 13929 if (!IsConstant && CalcStep.isUsable()) { 13930 // Calculate the step beforehand instead of doing this on each iteration. 13931 // (This is not used if the number of iterations may be kfold-ed). 13932 CalcStepExpr = CalcStep.get(); 13933 } 13934 } 13935 13936 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13937 ColonLoc, EndLoc, Vars, Privates, Inits, 13938 StepExpr, CalcStepExpr, 13939 buildPreInits(Context, ExprCaptures), 13940 buildPostUpdate(*this, ExprPostUpdates)); 13941 } 13942 13943 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13944 Expr *NumIterations, Sema &SemaRef, 13945 Scope *S, DSAStackTy *Stack) { 13946 // Walk the vars and build update/final expressions for the CodeGen. 13947 SmallVector<Expr *, 8> Updates; 13948 SmallVector<Expr *, 8> Finals; 13949 SmallVector<Expr *, 8> UsedExprs; 13950 Expr *Step = Clause.getStep(); 13951 Expr *CalcStep = Clause.getCalcStep(); 13952 // OpenMP [2.14.3.7, linear clause] 13953 // If linear-step is not specified it is assumed to be 1. 13954 if (!Step) 13955 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13956 else if (CalcStep) 13957 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13958 bool HasErrors = false; 13959 auto CurInit = Clause.inits().begin(); 13960 auto CurPrivate = Clause.privates().begin(); 13961 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13962 for (Expr *RefExpr : Clause.varlists()) { 13963 SourceLocation ELoc; 13964 SourceRange ERange; 13965 Expr *SimpleRefExpr = RefExpr; 13966 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13967 ValueDecl *D = Res.first; 13968 if (Res.second || !D) { 13969 Updates.push_back(nullptr); 13970 Finals.push_back(nullptr); 13971 HasErrors = true; 13972 continue; 13973 } 13974 auto &&Info = Stack->isLoopControlVariable(D); 13975 // OpenMP [2.15.11, distribute simd Construct] 13976 // A list item may not appear in a linear clause, unless it is the loop 13977 // iteration variable. 13978 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13979 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13980 SemaRef.Diag(ELoc, 13981 diag::err_omp_linear_distribute_var_non_loop_iteration); 13982 Updates.push_back(nullptr); 13983 Finals.push_back(nullptr); 13984 HasErrors = true; 13985 continue; 13986 } 13987 Expr *InitExpr = *CurInit; 13988 13989 // Build privatized reference to the current linear var. 13990 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13991 Expr *CapturedRef; 13992 if (LinKind == OMPC_LINEAR_uval) 13993 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13994 else 13995 CapturedRef = 13996 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13997 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13998 /*RefersToCapture=*/true); 13999 14000 // Build update: Var = InitExpr + IV * Step 14001 ExprResult Update; 14002 if (!Info.first) 14003 Update = buildCounterUpdate( 14004 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14005 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14006 else 14007 Update = *CurPrivate; 14008 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14009 /*DiscardedValue*/ false); 14010 14011 // Build final: Var = InitExpr + NumIterations * Step 14012 ExprResult Final; 14013 if (!Info.first) 14014 Final = 14015 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14016 InitExpr, NumIterations, Step, /*Subtract=*/false, 14017 /*IsNonRectangularLB=*/false); 14018 else 14019 Final = *CurPrivate; 14020 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14021 /*DiscardedValue*/ false); 14022 14023 if (!Update.isUsable() || !Final.isUsable()) { 14024 Updates.push_back(nullptr); 14025 Finals.push_back(nullptr); 14026 UsedExprs.push_back(nullptr); 14027 HasErrors = true; 14028 } else { 14029 Updates.push_back(Update.get()); 14030 Finals.push_back(Final.get()); 14031 if (!Info.first) 14032 UsedExprs.push_back(SimpleRefExpr); 14033 } 14034 ++CurInit; 14035 ++CurPrivate; 14036 } 14037 if (Expr *S = Clause.getStep()) 14038 UsedExprs.push_back(S); 14039 // Fill the remaining part with the nullptr. 14040 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14041 Clause.setUpdates(Updates); 14042 Clause.setFinals(Finals); 14043 Clause.setUsedExprs(UsedExprs); 14044 return HasErrors; 14045 } 14046 14047 OMPClause *Sema::ActOnOpenMPAlignedClause( 14048 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14049 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14050 SmallVector<Expr *, 8> Vars; 14051 for (Expr *RefExpr : VarList) { 14052 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14053 SourceLocation ELoc; 14054 SourceRange ERange; 14055 Expr *SimpleRefExpr = RefExpr; 14056 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14057 if (Res.second) { 14058 // It will be analyzed later. 14059 Vars.push_back(RefExpr); 14060 } 14061 ValueDecl *D = Res.first; 14062 if (!D) 14063 continue; 14064 14065 QualType QType = D->getType(); 14066 auto *VD = dyn_cast<VarDecl>(D); 14067 14068 // OpenMP [2.8.1, simd construct, Restrictions] 14069 // The type of list items appearing in the aligned clause must be 14070 // array, pointer, reference to array, or reference to pointer. 14071 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14072 const Type *Ty = QType.getTypePtrOrNull(); 14073 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14074 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14075 << QType << getLangOpts().CPlusPlus << ERange; 14076 bool IsDecl = 14077 !VD || 14078 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14079 Diag(D->getLocation(), 14080 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14081 << D; 14082 continue; 14083 } 14084 14085 // OpenMP [2.8.1, simd construct, Restrictions] 14086 // A list-item cannot appear in more than one aligned clause. 14087 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14088 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 14089 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14090 << getOpenMPClauseName(OMPC_aligned); 14091 continue; 14092 } 14093 14094 DeclRefExpr *Ref = nullptr; 14095 if (!VD && isOpenMPCapturedDecl(D)) 14096 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14097 Vars.push_back(DefaultFunctionArrayConversion( 14098 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14099 .get()); 14100 } 14101 14102 // OpenMP [2.8.1, simd construct, Description] 14103 // The parameter of the aligned clause, alignment, must be a constant 14104 // positive integer expression. 14105 // If no optional parameter is specified, implementation-defined default 14106 // alignments for SIMD instructions on the target platforms are assumed. 14107 if (Alignment != nullptr) { 14108 ExprResult AlignResult = 14109 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14110 if (AlignResult.isInvalid()) 14111 return nullptr; 14112 Alignment = AlignResult.get(); 14113 } 14114 if (Vars.empty()) 14115 return nullptr; 14116 14117 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14118 EndLoc, Vars, Alignment); 14119 } 14120 14121 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14122 SourceLocation StartLoc, 14123 SourceLocation LParenLoc, 14124 SourceLocation EndLoc) { 14125 SmallVector<Expr *, 8> Vars; 14126 SmallVector<Expr *, 8> SrcExprs; 14127 SmallVector<Expr *, 8> DstExprs; 14128 SmallVector<Expr *, 8> AssignmentOps; 14129 for (Expr *RefExpr : VarList) { 14130 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14131 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14132 // It will be analyzed later. 14133 Vars.push_back(RefExpr); 14134 SrcExprs.push_back(nullptr); 14135 DstExprs.push_back(nullptr); 14136 AssignmentOps.push_back(nullptr); 14137 continue; 14138 } 14139 14140 SourceLocation ELoc = RefExpr->getExprLoc(); 14141 // OpenMP [2.1, C/C++] 14142 // A list item is a variable name. 14143 // OpenMP [2.14.4.1, Restrictions, p.1] 14144 // A list item that appears in a copyin clause must be threadprivate. 14145 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14146 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14147 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14148 << 0 << RefExpr->getSourceRange(); 14149 continue; 14150 } 14151 14152 Decl *D = DE->getDecl(); 14153 auto *VD = cast<VarDecl>(D); 14154 14155 QualType Type = VD->getType(); 14156 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14157 // It will be analyzed later. 14158 Vars.push_back(DE); 14159 SrcExprs.push_back(nullptr); 14160 DstExprs.push_back(nullptr); 14161 AssignmentOps.push_back(nullptr); 14162 continue; 14163 } 14164 14165 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14166 // A list item that appears in a copyin clause must be threadprivate. 14167 if (!DSAStack->isThreadPrivate(VD)) { 14168 Diag(ELoc, diag::err_omp_required_access) 14169 << getOpenMPClauseName(OMPC_copyin) 14170 << getOpenMPDirectiveName(OMPD_threadprivate); 14171 continue; 14172 } 14173 14174 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14175 // A variable of class type (or array thereof) that appears in a 14176 // copyin clause requires an accessible, unambiguous copy assignment 14177 // operator for the class type. 14178 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14179 VarDecl *SrcVD = 14180 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14181 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14182 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14183 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14184 VarDecl *DstVD = 14185 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14186 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14187 DeclRefExpr *PseudoDstExpr = 14188 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14189 // For arrays generate assignment operation for single element and replace 14190 // it by the original array element in CodeGen. 14191 ExprResult AssignmentOp = 14192 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14193 PseudoSrcExpr); 14194 if (AssignmentOp.isInvalid()) 14195 continue; 14196 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14197 /*DiscardedValue*/ false); 14198 if (AssignmentOp.isInvalid()) 14199 continue; 14200 14201 DSAStack->addDSA(VD, DE, OMPC_copyin); 14202 Vars.push_back(DE); 14203 SrcExprs.push_back(PseudoSrcExpr); 14204 DstExprs.push_back(PseudoDstExpr); 14205 AssignmentOps.push_back(AssignmentOp.get()); 14206 } 14207 14208 if (Vars.empty()) 14209 return nullptr; 14210 14211 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14212 SrcExprs, DstExprs, AssignmentOps); 14213 } 14214 14215 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14216 SourceLocation StartLoc, 14217 SourceLocation LParenLoc, 14218 SourceLocation EndLoc) { 14219 SmallVector<Expr *, 8> Vars; 14220 SmallVector<Expr *, 8> SrcExprs; 14221 SmallVector<Expr *, 8> DstExprs; 14222 SmallVector<Expr *, 8> AssignmentOps; 14223 for (Expr *RefExpr : VarList) { 14224 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14225 SourceLocation ELoc; 14226 SourceRange ERange; 14227 Expr *SimpleRefExpr = RefExpr; 14228 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14229 if (Res.second) { 14230 // It will be analyzed later. 14231 Vars.push_back(RefExpr); 14232 SrcExprs.push_back(nullptr); 14233 DstExprs.push_back(nullptr); 14234 AssignmentOps.push_back(nullptr); 14235 } 14236 ValueDecl *D = Res.first; 14237 if (!D) 14238 continue; 14239 14240 QualType Type = D->getType(); 14241 auto *VD = dyn_cast<VarDecl>(D); 14242 14243 // OpenMP [2.14.4.2, Restrictions, p.2] 14244 // A list item that appears in a copyprivate clause may not appear in a 14245 // private or firstprivate clause on the single construct. 14246 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14247 DSAStackTy::DSAVarData DVar = 14248 DSAStack->getTopDSA(D, /*FromParent=*/false); 14249 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14250 DVar.RefExpr) { 14251 Diag(ELoc, diag::err_omp_wrong_dsa) 14252 << getOpenMPClauseName(DVar.CKind) 14253 << getOpenMPClauseName(OMPC_copyprivate); 14254 reportOriginalDsa(*this, DSAStack, D, DVar); 14255 continue; 14256 } 14257 14258 // OpenMP [2.11.4.2, Restrictions, p.1] 14259 // All list items that appear in a copyprivate clause must be either 14260 // threadprivate or private in the enclosing context. 14261 if (DVar.CKind == OMPC_unknown) { 14262 DVar = DSAStack->getImplicitDSA(D, false); 14263 if (DVar.CKind == OMPC_shared) { 14264 Diag(ELoc, diag::err_omp_required_access) 14265 << getOpenMPClauseName(OMPC_copyprivate) 14266 << "threadprivate or private in the enclosing context"; 14267 reportOriginalDsa(*this, DSAStack, D, DVar); 14268 continue; 14269 } 14270 } 14271 } 14272 14273 // Variably modified types are not supported. 14274 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14275 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14276 << getOpenMPClauseName(OMPC_copyprivate) << Type 14277 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14278 bool IsDecl = 14279 !VD || 14280 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14281 Diag(D->getLocation(), 14282 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14283 << D; 14284 continue; 14285 } 14286 14287 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14288 // A variable of class type (or array thereof) that appears in a 14289 // copyin clause requires an accessible, unambiguous copy assignment 14290 // operator for the class type. 14291 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14292 .getUnqualifiedType(); 14293 VarDecl *SrcVD = 14294 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14295 D->hasAttrs() ? &D->getAttrs() : nullptr); 14296 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14297 VarDecl *DstVD = 14298 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14299 D->hasAttrs() ? &D->getAttrs() : nullptr); 14300 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14301 ExprResult AssignmentOp = BuildBinOp( 14302 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14303 if (AssignmentOp.isInvalid()) 14304 continue; 14305 AssignmentOp = 14306 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14307 if (AssignmentOp.isInvalid()) 14308 continue; 14309 14310 // No need to mark vars as copyprivate, they are already threadprivate or 14311 // implicitly private. 14312 assert(VD || isOpenMPCapturedDecl(D)); 14313 Vars.push_back( 14314 VD ? RefExpr->IgnoreParens() 14315 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14316 SrcExprs.push_back(PseudoSrcExpr); 14317 DstExprs.push_back(PseudoDstExpr); 14318 AssignmentOps.push_back(AssignmentOp.get()); 14319 } 14320 14321 if (Vars.empty()) 14322 return nullptr; 14323 14324 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14325 Vars, SrcExprs, DstExprs, AssignmentOps); 14326 } 14327 14328 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14329 SourceLocation StartLoc, 14330 SourceLocation LParenLoc, 14331 SourceLocation EndLoc) { 14332 if (VarList.empty()) 14333 return nullptr; 14334 14335 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14336 } 14337 14338 OMPClause * 14339 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14340 SourceLocation DepLoc, SourceLocation ColonLoc, 14341 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14342 SourceLocation LParenLoc, SourceLocation EndLoc) { 14343 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14344 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14345 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14346 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14347 return nullptr; 14348 } 14349 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14350 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14351 DepKind == OMPC_DEPEND_sink)) { 14352 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14353 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14354 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14355 /*Last=*/OMPC_DEPEND_unknown, Except) 14356 << getOpenMPClauseName(OMPC_depend); 14357 return nullptr; 14358 } 14359 SmallVector<Expr *, 8> Vars; 14360 DSAStackTy::OperatorOffsetTy OpsOffs; 14361 llvm::APSInt DepCounter(/*BitWidth=*/32); 14362 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14363 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14364 if (const Expr *OrderedCountExpr = 14365 DSAStack->getParentOrderedRegionParam().first) { 14366 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14367 TotalDepCount.setIsUnsigned(/*Val=*/true); 14368 } 14369 } 14370 for (Expr *RefExpr : VarList) { 14371 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14372 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14373 // It will be analyzed later. 14374 Vars.push_back(RefExpr); 14375 continue; 14376 } 14377 14378 SourceLocation ELoc = RefExpr->getExprLoc(); 14379 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14380 if (DepKind == OMPC_DEPEND_sink) { 14381 if (DSAStack->getParentOrderedRegionParam().first && 14382 DepCounter >= TotalDepCount) { 14383 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14384 continue; 14385 } 14386 ++DepCounter; 14387 // OpenMP [2.13.9, Summary] 14388 // depend(dependence-type : vec), where dependence-type is: 14389 // 'sink' and where vec is the iteration vector, which has the form: 14390 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14391 // where n is the value specified by the ordered clause in the loop 14392 // directive, xi denotes the loop iteration variable of the i-th nested 14393 // loop associated with the loop directive, and di is a constant 14394 // non-negative integer. 14395 if (CurContext->isDependentContext()) { 14396 // It will be analyzed later. 14397 Vars.push_back(RefExpr); 14398 continue; 14399 } 14400 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14401 OverloadedOperatorKind OOK = OO_None; 14402 SourceLocation OOLoc; 14403 Expr *LHS = SimpleExpr; 14404 Expr *RHS = nullptr; 14405 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14406 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14407 OOLoc = BO->getOperatorLoc(); 14408 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14409 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14410 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14411 OOK = OCE->getOperator(); 14412 OOLoc = OCE->getOperatorLoc(); 14413 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14414 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14415 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14416 OOK = MCE->getMethodDecl() 14417 ->getNameInfo() 14418 .getName() 14419 .getCXXOverloadedOperator(); 14420 OOLoc = MCE->getCallee()->getExprLoc(); 14421 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14422 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14423 } 14424 SourceLocation ELoc; 14425 SourceRange ERange; 14426 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14427 if (Res.second) { 14428 // It will be analyzed later. 14429 Vars.push_back(RefExpr); 14430 } 14431 ValueDecl *D = Res.first; 14432 if (!D) 14433 continue; 14434 14435 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14436 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14437 continue; 14438 } 14439 if (RHS) { 14440 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14441 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14442 if (RHSRes.isInvalid()) 14443 continue; 14444 } 14445 if (!CurContext->isDependentContext() && 14446 DSAStack->getParentOrderedRegionParam().first && 14447 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14448 const ValueDecl *VD = 14449 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14450 if (VD) 14451 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14452 << 1 << VD; 14453 else 14454 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14455 continue; 14456 } 14457 OpsOffs.emplace_back(RHS, OOK); 14458 } else { 14459 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14460 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14461 (ASE && 14462 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14463 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14464 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14465 << RefExpr->getSourceRange(); 14466 continue; 14467 } 14468 14469 ExprResult Res; 14470 { 14471 Sema::TentativeAnalysisScope Trap(*this); 14472 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14473 RefExpr->IgnoreParenImpCasts()); 14474 } 14475 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14476 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14477 << RefExpr->getSourceRange(); 14478 continue; 14479 } 14480 } 14481 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14482 } 14483 14484 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14485 TotalDepCount > VarList.size() && 14486 DSAStack->getParentOrderedRegionParam().first && 14487 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14488 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14489 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14490 } 14491 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14492 Vars.empty()) 14493 return nullptr; 14494 14495 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14496 DepKind, DepLoc, ColonLoc, Vars, 14497 TotalDepCount.getZExtValue()); 14498 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14499 DSAStack->isParentOrderedRegion()) 14500 DSAStack->addDoacrossDependClause(C, OpsOffs); 14501 return C; 14502 } 14503 14504 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14505 SourceLocation LParenLoc, 14506 SourceLocation EndLoc) { 14507 Expr *ValExpr = Device; 14508 Stmt *HelperValStmt = nullptr; 14509 14510 // OpenMP [2.9.1, Restrictions] 14511 // The device expression must evaluate to a non-negative integer value. 14512 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14513 /*StrictlyPositive=*/false)) 14514 return nullptr; 14515 14516 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14517 OpenMPDirectiveKind CaptureRegion = 14518 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14519 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14520 ValExpr = MakeFullExpr(ValExpr).get(); 14521 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14522 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14523 HelperValStmt = buildPreInits(Context, Captures); 14524 } 14525 14526 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14527 StartLoc, LParenLoc, EndLoc); 14528 } 14529 14530 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14531 DSAStackTy *Stack, QualType QTy, 14532 bool FullCheck = true) { 14533 NamedDecl *ND; 14534 if (QTy->isIncompleteType(&ND)) { 14535 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14536 return false; 14537 } 14538 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14539 !QTy.isTrivialType(SemaRef.Context)) 14540 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14541 return true; 14542 } 14543 14544 /// Return true if it can be proven that the provided array expression 14545 /// (array section or array subscript) does NOT specify the whole size of the 14546 /// array whose base type is \a BaseQTy. 14547 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14548 const Expr *E, 14549 QualType BaseQTy) { 14550 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14551 14552 // If this is an array subscript, it refers to the whole size if the size of 14553 // the dimension is constant and equals 1. Also, an array section assumes the 14554 // format of an array subscript if no colon is used. 14555 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14556 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14557 return ATy->getSize().getSExtValue() != 1; 14558 // Size can't be evaluated statically. 14559 return false; 14560 } 14561 14562 assert(OASE && "Expecting array section if not an array subscript."); 14563 const Expr *LowerBound = OASE->getLowerBound(); 14564 const Expr *Length = OASE->getLength(); 14565 14566 // If there is a lower bound that does not evaluates to zero, we are not 14567 // covering the whole dimension. 14568 if (LowerBound) { 14569 Expr::EvalResult Result; 14570 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14571 return false; // Can't get the integer value as a constant. 14572 14573 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14574 if (ConstLowerBound.getSExtValue()) 14575 return true; 14576 } 14577 14578 // If we don't have a length we covering the whole dimension. 14579 if (!Length) 14580 return false; 14581 14582 // If the base is a pointer, we don't have a way to get the size of the 14583 // pointee. 14584 if (BaseQTy->isPointerType()) 14585 return false; 14586 14587 // We can only check if the length is the same as the size of the dimension 14588 // if we have a constant array. 14589 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14590 if (!CATy) 14591 return false; 14592 14593 Expr::EvalResult Result; 14594 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14595 return false; // Can't get the integer value as a constant. 14596 14597 llvm::APSInt ConstLength = Result.Val.getInt(); 14598 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14599 } 14600 14601 // Return true if it can be proven that the provided array expression (array 14602 // section or array subscript) does NOT specify a single element of the array 14603 // whose base type is \a BaseQTy. 14604 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14605 const Expr *E, 14606 QualType BaseQTy) { 14607 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14608 14609 // An array subscript always refer to a single element. Also, an array section 14610 // assumes the format of an array subscript if no colon is used. 14611 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14612 return false; 14613 14614 assert(OASE && "Expecting array section if not an array subscript."); 14615 const Expr *Length = OASE->getLength(); 14616 14617 // If we don't have a length we have to check if the array has unitary size 14618 // for this dimension. Also, we should always expect a length if the base type 14619 // is pointer. 14620 if (!Length) { 14621 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14622 return ATy->getSize().getSExtValue() != 1; 14623 // We cannot assume anything. 14624 return false; 14625 } 14626 14627 // Check if the length evaluates to 1. 14628 Expr::EvalResult Result; 14629 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14630 return false; // Can't get the integer value as a constant. 14631 14632 llvm::APSInt ConstLength = Result.Val.getInt(); 14633 return ConstLength.getSExtValue() != 1; 14634 } 14635 14636 // Return the expression of the base of the mappable expression or null if it 14637 // cannot be determined and do all the necessary checks to see if the expression 14638 // is valid as a standalone mappable expression. In the process, record all the 14639 // components of the expression. 14640 static const Expr *checkMapClauseExpressionBase( 14641 Sema &SemaRef, Expr *E, 14642 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14643 OpenMPClauseKind CKind, bool NoDiagnose) { 14644 SourceLocation ELoc = E->getExprLoc(); 14645 SourceRange ERange = E->getSourceRange(); 14646 14647 // The base of elements of list in a map clause have to be either: 14648 // - a reference to variable or field. 14649 // - a member expression. 14650 // - an array expression. 14651 // 14652 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14653 // reference to 'r'. 14654 // 14655 // If we have: 14656 // 14657 // struct SS { 14658 // Bla S; 14659 // foo() { 14660 // #pragma omp target map (S.Arr[:12]); 14661 // } 14662 // } 14663 // 14664 // We want to retrieve the member expression 'this->S'; 14665 14666 const Expr *RelevantExpr = nullptr; 14667 14668 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14669 // If a list item is an array section, it must specify contiguous storage. 14670 // 14671 // For this restriction it is sufficient that we make sure only references 14672 // to variables or fields and array expressions, and that no array sections 14673 // exist except in the rightmost expression (unless they cover the whole 14674 // dimension of the array). E.g. these would be invalid: 14675 // 14676 // r.ArrS[3:5].Arr[6:7] 14677 // 14678 // r.ArrS[3:5].x 14679 // 14680 // but these would be valid: 14681 // r.ArrS[3].Arr[6:7] 14682 // 14683 // r.ArrS[3].x 14684 14685 bool AllowUnitySizeArraySection = true; 14686 bool AllowWholeSizeArraySection = true; 14687 14688 while (!RelevantExpr) { 14689 E = E->IgnoreParenImpCasts(); 14690 14691 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14692 if (!isa<VarDecl>(CurE->getDecl())) 14693 return nullptr; 14694 14695 RelevantExpr = CurE; 14696 14697 // If we got a reference to a declaration, we should not expect any array 14698 // section before that. 14699 AllowUnitySizeArraySection = false; 14700 AllowWholeSizeArraySection = false; 14701 14702 // Record the component. 14703 CurComponents.emplace_back(CurE, CurE->getDecl()); 14704 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14705 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14706 14707 if (isa<CXXThisExpr>(BaseE)) 14708 // We found a base expression: this->Val. 14709 RelevantExpr = CurE; 14710 else 14711 E = BaseE; 14712 14713 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14714 if (!NoDiagnose) { 14715 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14716 << CurE->getSourceRange(); 14717 return nullptr; 14718 } 14719 if (RelevantExpr) 14720 return nullptr; 14721 continue; 14722 } 14723 14724 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14725 14726 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14727 // A bit-field cannot appear in a map clause. 14728 // 14729 if (FD->isBitField()) { 14730 if (!NoDiagnose) { 14731 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14732 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14733 return nullptr; 14734 } 14735 if (RelevantExpr) 14736 return nullptr; 14737 continue; 14738 } 14739 14740 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14741 // If the type of a list item is a reference to a type T then the type 14742 // will be considered to be T for all purposes of this clause. 14743 QualType CurType = BaseE->getType().getNonReferenceType(); 14744 14745 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14746 // A list item cannot be a variable that is a member of a structure with 14747 // a union type. 14748 // 14749 if (CurType->isUnionType()) { 14750 if (!NoDiagnose) { 14751 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14752 << CurE->getSourceRange(); 14753 return nullptr; 14754 } 14755 continue; 14756 } 14757 14758 // If we got a member expression, we should not expect any array section 14759 // before that: 14760 // 14761 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14762 // If a list item is an element of a structure, only the rightmost symbol 14763 // of the variable reference can be an array section. 14764 // 14765 AllowUnitySizeArraySection = false; 14766 AllowWholeSizeArraySection = false; 14767 14768 // Record the component. 14769 CurComponents.emplace_back(CurE, FD); 14770 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14771 E = CurE->getBase()->IgnoreParenImpCasts(); 14772 14773 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14774 if (!NoDiagnose) { 14775 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14776 << 0 << CurE->getSourceRange(); 14777 return nullptr; 14778 } 14779 continue; 14780 } 14781 14782 // If we got an array subscript that express the whole dimension we 14783 // can have any array expressions before. If it only expressing part of 14784 // the dimension, we can only have unitary-size array expressions. 14785 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14786 E->getType())) 14787 AllowWholeSizeArraySection = false; 14788 14789 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14790 Expr::EvalResult Result; 14791 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14792 if (!Result.Val.getInt().isNullValue()) { 14793 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14794 diag::err_omp_invalid_map_this_expr); 14795 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14796 diag::note_omp_invalid_subscript_on_this_ptr_map); 14797 } 14798 } 14799 RelevantExpr = TE; 14800 } 14801 14802 // Record the component - we don't have any declaration associated. 14803 CurComponents.emplace_back(CurE, nullptr); 14804 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14805 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14806 E = CurE->getBase()->IgnoreParenImpCasts(); 14807 14808 QualType CurType = 14809 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14810 14811 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14812 // If the type of a list item is a reference to a type T then the type 14813 // will be considered to be T for all purposes of this clause. 14814 if (CurType->isReferenceType()) 14815 CurType = CurType->getPointeeType(); 14816 14817 bool IsPointer = CurType->isAnyPointerType(); 14818 14819 if (!IsPointer && !CurType->isArrayType()) { 14820 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14821 << 0 << CurE->getSourceRange(); 14822 return nullptr; 14823 } 14824 14825 bool NotWhole = 14826 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14827 bool NotUnity = 14828 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14829 14830 if (AllowWholeSizeArraySection) { 14831 // Any array section is currently allowed. Allowing a whole size array 14832 // section implies allowing a unity array section as well. 14833 // 14834 // If this array section refers to the whole dimension we can still 14835 // accept other array sections before this one, except if the base is a 14836 // pointer. Otherwise, only unitary sections are accepted. 14837 if (NotWhole || IsPointer) 14838 AllowWholeSizeArraySection = false; 14839 } else if (AllowUnitySizeArraySection && NotUnity) { 14840 // A unity or whole array section is not allowed and that is not 14841 // compatible with the properties of the current array section. 14842 SemaRef.Diag( 14843 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14844 << CurE->getSourceRange(); 14845 return nullptr; 14846 } 14847 14848 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14849 Expr::EvalResult ResultR; 14850 Expr::EvalResult ResultL; 14851 if (CurE->getLength()->EvaluateAsInt(ResultR, 14852 SemaRef.getASTContext())) { 14853 if (!ResultR.Val.getInt().isOneValue()) { 14854 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14855 diag::err_omp_invalid_map_this_expr); 14856 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14857 diag::note_omp_invalid_length_on_this_ptr_mapping); 14858 } 14859 } 14860 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14861 ResultL, SemaRef.getASTContext())) { 14862 if (!ResultL.Val.getInt().isNullValue()) { 14863 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14864 diag::err_omp_invalid_map_this_expr); 14865 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14866 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14867 } 14868 } 14869 RelevantExpr = TE; 14870 } 14871 14872 // Record the component - we don't have any declaration associated. 14873 CurComponents.emplace_back(CurE, nullptr); 14874 } else { 14875 if (!NoDiagnose) { 14876 // If nothing else worked, this is not a valid map clause expression. 14877 SemaRef.Diag( 14878 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14879 << ERange; 14880 } 14881 return nullptr; 14882 } 14883 } 14884 14885 return RelevantExpr; 14886 } 14887 14888 // Return true if expression E associated with value VD has conflicts with other 14889 // map information. 14890 static bool checkMapConflicts( 14891 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14892 bool CurrentRegionOnly, 14893 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14894 OpenMPClauseKind CKind) { 14895 assert(VD && E); 14896 SourceLocation ELoc = E->getExprLoc(); 14897 SourceRange ERange = E->getSourceRange(); 14898 14899 // In order to easily check the conflicts we need to match each component of 14900 // the expression under test with the components of the expressions that are 14901 // already in the stack. 14902 14903 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14904 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14905 "Map clause expression with unexpected base!"); 14906 14907 // Variables to help detecting enclosing problems in data environment nests. 14908 bool IsEnclosedByDataEnvironmentExpr = false; 14909 const Expr *EnclosingExpr = nullptr; 14910 14911 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14912 VD, CurrentRegionOnly, 14913 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14914 ERange, CKind, &EnclosingExpr, 14915 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14916 StackComponents, 14917 OpenMPClauseKind) { 14918 assert(!StackComponents.empty() && 14919 "Map clause expression with no components!"); 14920 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14921 "Map clause expression with unexpected base!"); 14922 (void)VD; 14923 14924 // The whole expression in the stack. 14925 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14926 14927 // Expressions must start from the same base. Here we detect at which 14928 // point both expressions diverge from each other and see if we can 14929 // detect if the memory referred to both expressions is contiguous and 14930 // do not overlap. 14931 auto CI = CurComponents.rbegin(); 14932 auto CE = CurComponents.rend(); 14933 auto SI = StackComponents.rbegin(); 14934 auto SE = StackComponents.rend(); 14935 for (; CI != CE && SI != SE; ++CI, ++SI) { 14936 14937 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14938 // At most one list item can be an array item derived from a given 14939 // variable in map clauses of the same construct. 14940 if (CurrentRegionOnly && 14941 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14942 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14943 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14944 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14945 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14946 diag::err_omp_multiple_array_items_in_map_clause) 14947 << CI->getAssociatedExpression()->getSourceRange(); 14948 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14949 diag::note_used_here) 14950 << SI->getAssociatedExpression()->getSourceRange(); 14951 return true; 14952 } 14953 14954 // Do both expressions have the same kind? 14955 if (CI->getAssociatedExpression()->getStmtClass() != 14956 SI->getAssociatedExpression()->getStmtClass()) 14957 break; 14958 14959 // Are we dealing with different variables/fields? 14960 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14961 break; 14962 } 14963 // Check if the extra components of the expressions in the enclosing 14964 // data environment are redundant for the current base declaration. 14965 // If they are, the maps completely overlap, which is legal. 14966 for (; SI != SE; ++SI) { 14967 QualType Type; 14968 if (const auto *ASE = 14969 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14970 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14971 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14972 SI->getAssociatedExpression())) { 14973 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14974 Type = 14975 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14976 } 14977 if (Type.isNull() || Type->isAnyPointerType() || 14978 checkArrayExpressionDoesNotReferToWholeSize( 14979 SemaRef, SI->getAssociatedExpression(), Type)) 14980 break; 14981 } 14982 14983 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14984 // List items of map clauses in the same construct must not share 14985 // original storage. 14986 // 14987 // If the expressions are exactly the same or one is a subset of the 14988 // other, it means they are sharing storage. 14989 if (CI == CE && SI == SE) { 14990 if (CurrentRegionOnly) { 14991 if (CKind == OMPC_map) { 14992 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14993 } else { 14994 assert(CKind == OMPC_to || CKind == OMPC_from); 14995 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14996 << ERange; 14997 } 14998 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14999 << RE->getSourceRange(); 15000 return true; 15001 } 15002 // If we find the same expression in the enclosing data environment, 15003 // that is legal. 15004 IsEnclosedByDataEnvironmentExpr = true; 15005 return false; 15006 } 15007 15008 QualType DerivedType = 15009 std::prev(CI)->getAssociatedDeclaration()->getType(); 15010 SourceLocation DerivedLoc = 15011 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15012 15013 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15014 // If the type of a list item is a reference to a type T then the type 15015 // will be considered to be T for all purposes of this clause. 15016 DerivedType = DerivedType.getNonReferenceType(); 15017 15018 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15019 // A variable for which the type is pointer and an array section 15020 // derived from that variable must not appear as list items of map 15021 // clauses of the same construct. 15022 // 15023 // Also, cover one of the cases in: 15024 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15025 // If any part of the original storage of a list item has corresponding 15026 // storage in the device data environment, all of the original storage 15027 // must have corresponding storage in the device data environment. 15028 // 15029 if (DerivedType->isAnyPointerType()) { 15030 if (CI == CE || SI == SE) { 15031 SemaRef.Diag( 15032 DerivedLoc, 15033 diag::err_omp_pointer_mapped_along_with_derived_section) 15034 << DerivedLoc; 15035 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15036 << RE->getSourceRange(); 15037 return true; 15038 } 15039 if (CI->getAssociatedExpression()->getStmtClass() != 15040 SI->getAssociatedExpression()->getStmtClass() || 15041 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15042 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15043 assert(CI != CE && SI != SE); 15044 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15045 << DerivedLoc; 15046 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15047 << RE->getSourceRange(); 15048 return true; 15049 } 15050 } 15051 15052 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15053 // List items of map clauses in the same construct must not share 15054 // original storage. 15055 // 15056 // An expression is a subset of the other. 15057 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15058 if (CKind == OMPC_map) { 15059 if (CI != CE || SI != SE) { 15060 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15061 // a pointer. 15062 auto Begin = 15063 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15064 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15065 auto It = Begin; 15066 while (It != End && !It->getAssociatedDeclaration()) 15067 std::advance(It, 1); 15068 assert(It != End && 15069 "Expected at least one component with the declaration."); 15070 if (It != Begin && It->getAssociatedDeclaration() 15071 ->getType() 15072 .getCanonicalType() 15073 ->isAnyPointerType()) { 15074 IsEnclosedByDataEnvironmentExpr = false; 15075 EnclosingExpr = nullptr; 15076 return false; 15077 } 15078 } 15079 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15080 } else { 15081 assert(CKind == OMPC_to || CKind == OMPC_from); 15082 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15083 << ERange; 15084 } 15085 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15086 << RE->getSourceRange(); 15087 return true; 15088 } 15089 15090 // The current expression uses the same base as other expression in the 15091 // data environment but does not contain it completely. 15092 if (!CurrentRegionOnly && SI != SE) 15093 EnclosingExpr = RE; 15094 15095 // The current expression is a subset of the expression in the data 15096 // environment. 15097 IsEnclosedByDataEnvironmentExpr |= 15098 (!CurrentRegionOnly && CI != CE && SI == SE); 15099 15100 return false; 15101 }); 15102 15103 if (CurrentRegionOnly) 15104 return FoundError; 15105 15106 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15107 // If any part of the original storage of a list item has corresponding 15108 // storage in the device data environment, all of the original storage must 15109 // have corresponding storage in the device data environment. 15110 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15111 // If a list item is an element of a structure, and a different element of 15112 // the structure has a corresponding list item in the device data environment 15113 // prior to a task encountering the construct associated with the map clause, 15114 // then the list item must also have a corresponding list item in the device 15115 // data environment prior to the task encountering the construct. 15116 // 15117 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15118 SemaRef.Diag(ELoc, 15119 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15120 << ERange; 15121 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15122 << EnclosingExpr->getSourceRange(); 15123 return true; 15124 } 15125 15126 return FoundError; 15127 } 15128 15129 // Look up the user-defined mapper given the mapper name and mapped type, and 15130 // build a reference to it. 15131 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15132 CXXScopeSpec &MapperIdScopeSpec, 15133 const DeclarationNameInfo &MapperId, 15134 QualType Type, 15135 Expr *UnresolvedMapper) { 15136 if (MapperIdScopeSpec.isInvalid()) 15137 return ExprError(); 15138 // Get the actual type for the array type. 15139 if (Type->isArrayType()) { 15140 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15141 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15142 } 15143 // Find all user-defined mappers with the given MapperId. 15144 SmallVector<UnresolvedSet<8>, 4> Lookups; 15145 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15146 Lookup.suppressDiagnostics(); 15147 if (S) { 15148 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15149 NamedDecl *D = Lookup.getRepresentativeDecl(); 15150 while (S && !S->isDeclScope(D)) 15151 S = S->getParent(); 15152 if (S) 15153 S = S->getParent(); 15154 Lookups.emplace_back(); 15155 Lookups.back().append(Lookup.begin(), Lookup.end()); 15156 Lookup.clear(); 15157 } 15158 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15159 // Extract the user-defined mappers with the given MapperId. 15160 Lookups.push_back(UnresolvedSet<8>()); 15161 for (NamedDecl *D : ULE->decls()) { 15162 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15163 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15164 Lookups.back().addDecl(DMD); 15165 } 15166 } 15167 // Defer the lookup for dependent types. The results will be passed through 15168 // UnresolvedMapper on instantiation. 15169 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15170 Type->isInstantiationDependentType() || 15171 Type->containsUnexpandedParameterPack() || 15172 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15173 return !D->isInvalidDecl() && 15174 (D->getType()->isDependentType() || 15175 D->getType()->isInstantiationDependentType() || 15176 D->getType()->containsUnexpandedParameterPack()); 15177 })) { 15178 UnresolvedSet<8> URS; 15179 for (const UnresolvedSet<8> &Set : Lookups) { 15180 if (Set.empty()) 15181 continue; 15182 URS.append(Set.begin(), Set.end()); 15183 } 15184 return UnresolvedLookupExpr::Create( 15185 SemaRef.Context, /*NamingClass=*/nullptr, 15186 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15187 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15188 } 15189 SourceLocation Loc = MapperId.getLoc(); 15190 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15191 // The type must be of struct, union or class type in C and C++ 15192 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15193 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15194 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15195 return ExprError(); 15196 } 15197 // Perform argument dependent lookup. 15198 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15199 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15200 // Return the first user-defined mapper with the desired type. 15201 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15202 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15203 if (!D->isInvalidDecl() && 15204 SemaRef.Context.hasSameType(D->getType(), Type)) 15205 return D; 15206 return nullptr; 15207 })) 15208 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15209 // Find the first user-defined mapper with a type derived from the desired 15210 // type. 15211 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15212 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15213 if (!D->isInvalidDecl() && 15214 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15215 !Type.isMoreQualifiedThan(D->getType())) 15216 return D; 15217 return nullptr; 15218 })) { 15219 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15220 /*DetectVirtual=*/false); 15221 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15222 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15223 VD->getType().getUnqualifiedType()))) { 15224 if (SemaRef.CheckBaseClassAccess( 15225 Loc, VD->getType(), Type, Paths.front(), 15226 /*DiagID=*/0) != Sema::AR_inaccessible) { 15227 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15228 } 15229 } 15230 } 15231 } 15232 // Report error if a mapper is specified, but cannot be found. 15233 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15234 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15235 << Type << MapperId.getName(); 15236 return ExprError(); 15237 } 15238 return ExprEmpty(); 15239 } 15240 15241 namespace { 15242 // Utility struct that gathers all the related lists associated with a mappable 15243 // expression. 15244 struct MappableVarListInfo { 15245 // The list of expressions. 15246 ArrayRef<Expr *> VarList; 15247 // The list of processed expressions. 15248 SmallVector<Expr *, 16> ProcessedVarList; 15249 // The mappble components for each expression. 15250 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15251 // The base declaration of the variable. 15252 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15253 // The reference to the user-defined mapper associated with every expression. 15254 SmallVector<Expr *, 16> UDMapperList; 15255 15256 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15257 // We have a list of components and base declarations for each entry in the 15258 // variable list. 15259 VarComponents.reserve(VarList.size()); 15260 VarBaseDeclarations.reserve(VarList.size()); 15261 } 15262 }; 15263 } 15264 15265 // Check the validity of the provided variable list for the provided clause kind 15266 // \a CKind. In the check process the valid expressions, mappable expression 15267 // components, variables, and user-defined mappers are extracted and used to 15268 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15269 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15270 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15271 static void checkMappableExpressionList( 15272 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15273 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15274 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15275 ArrayRef<Expr *> UnresolvedMappers, 15276 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15277 bool IsMapTypeImplicit = false) { 15278 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15279 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15280 "Unexpected clause kind with mappable expressions!"); 15281 15282 // If the identifier of user-defined mapper is not specified, it is "default". 15283 // We do not change the actual name in this clause to distinguish whether a 15284 // mapper is specified explicitly, i.e., it is not explicitly specified when 15285 // MapperId.getName() is empty. 15286 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15287 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15288 MapperId.setName(DeclNames.getIdentifier( 15289 &SemaRef.getASTContext().Idents.get("default"))); 15290 } 15291 15292 // Iterators to find the current unresolved mapper expression. 15293 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15294 bool UpdateUMIt = false; 15295 Expr *UnresolvedMapper = nullptr; 15296 15297 // Keep track of the mappable components and base declarations in this clause. 15298 // Each entry in the list is going to have a list of components associated. We 15299 // record each set of the components so that we can build the clause later on. 15300 // In the end we should have the same amount of declarations and component 15301 // lists. 15302 15303 for (Expr *RE : MVLI.VarList) { 15304 assert(RE && "Null expr in omp to/from/map clause"); 15305 SourceLocation ELoc = RE->getExprLoc(); 15306 15307 // Find the current unresolved mapper expression. 15308 if (UpdateUMIt && UMIt != UMEnd) { 15309 UMIt++; 15310 assert( 15311 UMIt != UMEnd && 15312 "Expect the size of UnresolvedMappers to match with that of VarList"); 15313 } 15314 UpdateUMIt = true; 15315 if (UMIt != UMEnd) 15316 UnresolvedMapper = *UMIt; 15317 15318 const Expr *VE = RE->IgnoreParenLValueCasts(); 15319 15320 if (VE->isValueDependent() || VE->isTypeDependent() || 15321 VE->isInstantiationDependent() || 15322 VE->containsUnexpandedParameterPack()) { 15323 // Try to find the associated user-defined mapper. 15324 ExprResult ER = buildUserDefinedMapperRef( 15325 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15326 VE->getType().getCanonicalType(), UnresolvedMapper); 15327 if (ER.isInvalid()) 15328 continue; 15329 MVLI.UDMapperList.push_back(ER.get()); 15330 // We can only analyze this information once the missing information is 15331 // resolved. 15332 MVLI.ProcessedVarList.push_back(RE); 15333 continue; 15334 } 15335 15336 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15337 15338 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15339 SemaRef.Diag(ELoc, 15340 diag::err_omp_expected_named_var_member_or_array_expression) 15341 << RE->getSourceRange(); 15342 continue; 15343 } 15344 15345 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15346 ValueDecl *CurDeclaration = nullptr; 15347 15348 // Obtain the array or member expression bases if required. Also, fill the 15349 // components array with all the components identified in the process. 15350 const Expr *BE = checkMapClauseExpressionBase( 15351 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15352 if (!BE) 15353 continue; 15354 15355 assert(!CurComponents.empty() && 15356 "Invalid mappable expression information."); 15357 15358 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15359 // Add store "this" pointer to class in DSAStackTy for future checking 15360 DSAS->addMappedClassesQualTypes(TE->getType()); 15361 // Try to find the associated user-defined mapper. 15362 ExprResult ER = buildUserDefinedMapperRef( 15363 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15364 VE->getType().getCanonicalType(), UnresolvedMapper); 15365 if (ER.isInvalid()) 15366 continue; 15367 MVLI.UDMapperList.push_back(ER.get()); 15368 // Skip restriction checking for variable or field declarations 15369 MVLI.ProcessedVarList.push_back(RE); 15370 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15371 MVLI.VarComponents.back().append(CurComponents.begin(), 15372 CurComponents.end()); 15373 MVLI.VarBaseDeclarations.push_back(nullptr); 15374 continue; 15375 } 15376 15377 // For the following checks, we rely on the base declaration which is 15378 // expected to be associated with the last component. The declaration is 15379 // expected to be a variable or a field (if 'this' is being mapped). 15380 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15381 assert(CurDeclaration && "Null decl on map clause."); 15382 assert( 15383 CurDeclaration->isCanonicalDecl() && 15384 "Expecting components to have associated only canonical declarations."); 15385 15386 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15387 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15388 15389 assert((VD || FD) && "Only variables or fields are expected here!"); 15390 (void)FD; 15391 15392 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15393 // threadprivate variables cannot appear in a map clause. 15394 // OpenMP 4.5 [2.10.5, target update Construct] 15395 // threadprivate variables cannot appear in a from clause. 15396 if (VD && DSAS->isThreadPrivate(VD)) { 15397 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15398 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15399 << getOpenMPClauseName(CKind); 15400 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15401 continue; 15402 } 15403 15404 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15405 // A list item cannot appear in both a map clause and a data-sharing 15406 // attribute clause on the same construct. 15407 15408 // Check conflicts with other map clause expressions. We check the conflicts 15409 // with the current construct separately from the enclosing data 15410 // environment, because the restrictions are different. We only have to 15411 // check conflicts across regions for the map clauses. 15412 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15413 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15414 break; 15415 if (CKind == OMPC_map && 15416 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15417 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15418 break; 15419 15420 // OpenMP 4.5 [2.10.5, target update Construct] 15421 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15422 // If the type of a list item is a reference to a type T then the type will 15423 // be considered to be T for all purposes of this clause. 15424 auto I = llvm::find_if( 15425 CurComponents, 15426 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15427 return MC.getAssociatedDeclaration(); 15428 }); 15429 assert(I != CurComponents.end() && "Null decl on map clause."); 15430 QualType Type = 15431 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15432 15433 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15434 // A list item in a to or from clause must have a mappable type. 15435 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15436 // A list item must have a mappable type. 15437 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15438 DSAS, Type)) 15439 continue; 15440 15441 if (CKind == OMPC_map) { 15442 // target enter data 15443 // OpenMP [2.10.2, Restrictions, p. 99] 15444 // A map-type must be specified in all map clauses and must be either 15445 // to or alloc. 15446 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15447 if (DKind == OMPD_target_enter_data && 15448 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15449 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15450 << (IsMapTypeImplicit ? 1 : 0) 15451 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15452 << getOpenMPDirectiveName(DKind); 15453 continue; 15454 } 15455 15456 // target exit_data 15457 // OpenMP [2.10.3, Restrictions, p. 102] 15458 // A map-type must be specified in all map clauses and must be either 15459 // from, release, or delete. 15460 if (DKind == OMPD_target_exit_data && 15461 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15462 MapType == OMPC_MAP_delete)) { 15463 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15464 << (IsMapTypeImplicit ? 1 : 0) 15465 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15466 << getOpenMPDirectiveName(DKind); 15467 continue; 15468 } 15469 15470 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15471 // A list item cannot appear in both a map clause and a data-sharing 15472 // attribute clause on the same construct 15473 // 15474 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15475 // A list item cannot appear in both a map clause and a data-sharing 15476 // attribute clause on the same construct unless the construct is a 15477 // combined construct. 15478 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15479 isOpenMPTargetExecutionDirective(DKind)) || 15480 DKind == OMPD_target)) { 15481 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15482 if (isOpenMPPrivate(DVar.CKind)) { 15483 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15484 << getOpenMPClauseName(DVar.CKind) 15485 << getOpenMPClauseName(OMPC_map) 15486 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15487 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15488 continue; 15489 } 15490 } 15491 } 15492 15493 // Try to find the associated user-defined mapper. 15494 ExprResult ER = buildUserDefinedMapperRef( 15495 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15496 Type.getCanonicalType(), UnresolvedMapper); 15497 if (ER.isInvalid()) 15498 continue; 15499 MVLI.UDMapperList.push_back(ER.get()); 15500 15501 // Save the current expression. 15502 MVLI.ProcessedVarList.push_back(RE); 15503 15504 // Store the components in the stack so that they can be used to check 15505 // against other clauses later on. 15506 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15507 /*WhereFoundClauseKind=*/OMPC_map); 15508 15509 // Save the components and declaration to create the clause. For purposes of 15510 // the clause creation, any component list that has has base 'this' uses 15511 // null as base declaration. 15512 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15513 MVLI.VarComponents.back().append(CurComponents.begin(), 15514 CurComponents.end()); 15515 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15516 : CurDeclaration); 15517 } 15518 } 15519 15520 OMPClause *Sema::ActOnOpenMPMapClause( 15521 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15522 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15523 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15524 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15525 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15526 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15527 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15528 OMPC_MAP_MODIFIER_unknown, 15529 OMPC_MAP_MODIFIER_unknown}; 15530 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15531 15532 // Process map-type-modifiers, flag errors for duplicate modifiers. 15533 unsigned Count = 0; 15534 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15535 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15536 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15537 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15538 continue; 15539 } 15540 assert(Count < OMPMapClause::NumberOfModifiers && 15541 "Modifiers exceed the allowed number of map type modifiers"); 15542 Modifiers[Count] = MapTypeModifiers[I]; 15543 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15544 ++Count; 15545 } 15546 15547 MappableVarListInfo MVLI(VarList); 15548 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15549 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15550 MapType, IsMapTypeImplicit); 15551 15552 // We need to produce a map clause even if we don't have variables so that 15553 // other diagnostics related with non-existing map clauses are accurate. 15554 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15555 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15556 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15557 MapperIdScopeSpec.getWithLocInContext(Context), 15558 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15559 } 15560 15561 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15562 TypeResult ParsedType) { 15563 assert(ParsedType.isUsable()); 15564 15565 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15566 if (ReductionType.isNull()) 15567 return QualType(); 15568 15569 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15570 // A type name in a declare reduction directive cannot be a function type, an 15571 // array type, a reference type, or a type qualified with const, volatile or 15572 // restrict. 15573 if (ReductionType.hasQualifiers()) { 15574 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15575 return QualType(); 15576 } 15577 15578 if (ReductionType->isFunctionType()) { 15579 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15580 return QualType(); 15581 } 15582 if (ReductionType->isReferenceType()) { 15583 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15584 return QualType(); 15585 } 15586 if (ReductionType->isArrayType()) { 15587 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15588 return QualType(); 15589 } 15590 return ReductionType; 15591 } 15592 15593 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15594 Scope *S, DeclContext *DC, DeclarationName Name, 15595 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15596 AccessSpecifier AS, Decl *PrevDeclInScope) { 15597 SmallVector<Decl *, 8> Decls; 15598 Decls.reserve(ReductionTypes.size()); 15599 15600 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15601 forRedeclarationInCurContext()); 15602 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15603 // A reduction-identifier may not be re-declared in the current scope for the 15604 // same type or for a type that is compatible according to the base language 15605 // rules. 15606 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15607 OMPDeclareReductionDecl *PrevDRD = nullptr; 15608 bool InCompoundScope = true; 15609 if (S != nullptr) { 15610 // Find previous declaration with the same name not referenced in other 15611 // declarations. 15612 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15613 InCompoundScope = 15614 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15615 LookupName(Lookup, S); 15616 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15617 /*AllowInlineNamespace=*/false); 15618 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15619 LookupResult::Filter Filter = Lookup.makeFilter(); 15620 while (Filter.hasNext()) { 15621 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15622 if (InCompoundScope) { 15623 auto I = UsedAsPrevious.find(PrevDecl); 15624 if (I == UsedAsPrevious.end()) 15625 UsedAsPrevious[PrevDecl] = false; 15626 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15627 UsedAsPrevious[D] = true; 15628 } 15629 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15630 PrevDecl->getLocation(); 15631 } 15632 Filter.done(); 15633 if (InCompoundScope) { 15634 for (const auto &PrevData : UsedAsPrevious) { 15635 if (!PrevData.second) { 15636 PrevDRD = PrevData.first; 15637 break; 15638 } 15639 } 15640 } 15641 } else if (PrevDeclInScope != nullptr) { 15642 auto *PrevDRDInScope = PrevDRD = 15643 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15644 do { 15645 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15646 PrevDRDInScope->getLocation(); 15647 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15648 } while (PrevDRDInScope != nullptr); 15649 } 15650 for (const auto &TyData : ReductionTypes) { 15651 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15652 bool Invalid = false; 15653 if (I != PreviousRedeclTypes.end()) { 15654 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15655 << TyData.first; 15656 Diag(I->second, diag::note_previous_definition); 15657 Invalid = true; 15658 } 15659 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15660 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15661 Name, TyData.first, PrevDRD); 15662 DC->addDecl(DRD); 15663 DRD->setAccess(AS); 15664 Decls.push_back(DRD); 15665 if (Invalid) 15666 DRD->setInvalidDecl(); 15667 else 15668 PrevDRD = DRD; 15669 } 15670 15671 return DeclGroupPtrTy::make( 15672 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15673 } 15674 15675 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15676 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15677 15678 // Enter new function scope. 15679 PushFunctionScope(); 15680 setFunctionHasBranchProtectedScope(); 15681 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15682 15683 if (S != nullptr) 15684 PushDeclContext(S, DRD); 15685 else 15686 CurContext = DRD; 15687 15688 PushExpressionEvaluationContext( 15689 ExpressionEvaluationContext::PotentiallyEvaluated); 15690 15691 QualType ReductionType = DRD->getType(); 15692 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15693 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15694 // uses semantics of argument handles by value, but it should be passed by 15695 // reference. C lang does not support references, so pass all parameters as 15696 // pointers. 15697 // Create 'T omp_in;' variable. 15698 VarDecl *OmpInParm = 15699 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15700 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15701 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15702 // uses semantics of argument handles by value, but it should be passed by 15703 // reference. C lang does not support references, so pass all parameters as 15704 // pointers. 15705 // Create 'T omp_out;' variable. 15706 VarDecl *OmpOutParm = 15707 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15708 if (S != nullptr) { 15709 PushOnScopeChains(OmpInParm, S); 15710 PushOnScopeChains(OmpOutParm, S); 15711 } else { 15712 DRD->addDecl(OmpInParm); 15713 DRD->addDecl(OmpOutParm); 15714 } 15715 Expr *InE = 15716 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15717 Expr *OutE = 15718 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15719 DRD->setCombinerData(InE, OutE); 15720 } 15721 15722 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15723 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15724 DiscardCleanupsInEvaluationContext(); 15725 PopExpressionEvaluationContext(); 15726 15727 PopDeclContext(); 15728 PopFunctionScopeInfo(); 15729 15730 if (Combiner != nullptr) 15731 DRD->setCombiner(Combiner); 15732 else 15733 DRD->setInvalidDecl(); 15734 } 15735 15736 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15737 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15738 15739 // Enter new function scope. 15740 PushFunctionScope(); 15741 setFunctionHasBranchProtectedScope(); 15742 15743 if (S != nullptr) 15744 PushDeclContext(S, DRD); 15745 else 15746 CurContext = DRD; 15747 15748 PushExpressionEvaluationContext( 15749 ExpressionEvaluationContext::PotentiallyEvaluated); 15750 15751 QualType ReductionType = DRD->getType(); 15752 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15753 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15754 // uses semantics of argument handles by value, but it should be passed by 15755 // reference. C lang does not support references, so pass all parameters as 15756 // pointers. 15757 // Create 'T omp_priv;' variable. 15758 VarDecl *OmpPrivParm = 15759 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15760 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15761 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15762 // uses semantics of argument handles by value, but it should be passed by 15763 // reference. C lang does not support references, so pass all parameters as 15764 // pointers. 15765 // Create 'T omp_orig;' variable. 15766 VarDecl *OmpOrigParm = 15767 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15768 if (S != nullptr) { 15769 PushOnScopeChains(OmpPrivParm, S); 15770 PushOnScopeChains(OmpOrigParm, S); 15771 } else { 15772 DRD->addDecl(OmpPrivParm); 15773 DRD->addDecl(OmpOrigParm); 15774 } 15775 Expr *OrigE = 15776 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15777 Expr *PrivE = 15778 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15779 DRD->setInitializerData(OrigE, PrivE); 15780 return OmpPrivParm; 15781 } 15782 15783 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15784 VarDecl *OmpPrivParm) { 15785 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15786 DiscardCleanupsInEvaluationContext(); 15787 PopExpressionEvaluationContext(); 15788 15789 PopDeclContext(); 15790 PopFunctionScopeInfo(); 15791 15792 if (Initializer != nullptr) { 15793 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15794 } else if (OmpPrivParm->hasInit()) { 15795 DRD->setInitializer(OmpPrivParm->getInit(), 15796 OmpPrivParm->isDirectInit() 15797 ? OMPDeclareReductionDecl::DirectInit 15798 : OMPDeclareReductionDecl::CopyInit); 15799 } else { 15800 DRD->setInvalidDecl(); 15801 } 15802 } 15803 15804 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15805 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15806 for (Decl *D : DeclReductions.get()) { 15807 if (IsValid) { 15808 if (S) 15809 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15810 /*AddToContext=*/false); 15811 } else { 15812 D->setInvalidDecl(); 15813 } 15814 } 15815 return DeclReductions; 15816 } 15817 15818 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15819 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15820 QualType T = TInfo->getType(); 15821 if (D.isInvalidType()) 15822 return true; 15823 15824 if (getLangOpts().CPlusPlus) { 15825 // Check that there are no default arguments (C++ only). 15826 CheckExtraCXXDefaultArguments(D); 15827 } 15828 15829 return CreateParsedType(T, TInfo); 15830 } 15831 15832 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15833 TypeResult ParsedType) { 15834 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15835 15836 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15837 assert(!MapperType.isNull() && "Expect valid mapper type"); 15838 15839 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15840 // The type must be of struct, union or class type in C and C++ 15841 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15842 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15843 return QualType(); 15844 } 15845 return MapperType; 15846 } 15847 15848 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15849 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15850 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15851 Decl *PrevDeclInScope) { 15852 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15853 forRedeclarationInCurContext()); 15854 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15855 // A mapper-identifier may not be redeclared in the current scope for the 15856 // same type or for a type that is compatible according to the base language 15857 // rules. 15858 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15859 OMPDeclareMapperDecl *PrevDMD = nullptr; 15860 bool InCompoundScope = true; 15861 if (S != nullptr) { 15862 // Find previous declaration with the same name not referenced in other 15863 // declarations. 15864 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15865 InCompoundScope = 15866 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15867 LookupName(Lookup, S); 15868 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15869 /*AllowInlineNamespace=*/false); 15870 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15871 LookupResult::Filter Filter = Lookup.makeFilter(); 15872 while (Filter.hasNext()) { 15873 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15874 if (InCompoundScope) { 15875 auto I = UsedAsPrevious.find(PrevDecl); 15876 if (I == UsedAsPrevious.end()) 15877 UsedAsPrevious[PrevDecl] = false; 15878 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15879 UsedAsPrevious[D] = true; 15880 } 15881 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15882 PrevDecl->getLocation(); 15883 } 15884 Filter.done(); 15885 if (InCompoundScope) { 15886 for (const auto &PrevData : UsedAsPrevious) { 15887 if (!PrevData.second) { 15888 PrevDMD = PrevData.first; 15889 break; 15890 } 15891 } 15892 } 15893 } else if (PrevDeclInScope) { 15894 auto *PrevDMDInScope = PrevDMD = 15895 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15896 do { 15897 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15898 PrevDMDInScope->getLocation(); 15899 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15900 } while (PrevDMDInScope != nullptr); 15901 } 15902 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15903 bool Invalid = false; 15904 if (I != PreviousRedeclTypes.end()) { 15905 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15906 << MapperType << Name; 15907 Diag(I->second, diag::note_previous_definition); 15908 Invalid = true; 15909 } 15910 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15911 MapperType, VN, PrevDMD); 15912 DC->addDecl(DMD); 15913 DMD->setAccess(AS); 15914 if (Invalid) 15915 DMD->setInvalidDecl(); 15916 15917 // Enter new function scope. 15918 PushFunctionScope(); 15919 setFunctionHasBranchProtectedScope(); 15920 15921 CurContext = DMD; 15922 15923 return DMD; 15924 } 15925 15926 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15927 Scope *S, 15928 QualType MapperType, 15929 SourceLocation StartLoc, 15930 DeclarationName VN) { 15931 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15932 if (S) 15933 PushOnScopeChains(VD, S); 15934 else 15935 DMD->addDecl(VD); 15936 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15937 DMD->setMapperVarRef(MapperVarRefExpr); 15938 } 15939 15940 Sema::DeclGroupPtrTy 15941 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15942 ArrayRef<OMPClause *> ClauseList) { 15943 PopDeclContext(); 15944 PopFunctionScopeInfo(); 15945 15946 if (D) { 15947 if (S) 15948 PushOnScopeChains(D, S, /*AddToContext=*/false); 15949 D->CreateClauses(Context, ClauseList); 15950 } 15951 15952 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15953 } 15954 15955 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15956 SourceLocation StartLoc, 15957 SourceLocation LParenLoc, 15958 SourceLocation EndLoc) { 15959 Expr *ValExpr = NumTeams; 15960 Stmt *HelperValStmt = nullptr; 15961 15962 // OpenMP [teams Constrcut, Restrictions] 15963 // The num_teams expression must evaluate to a positive integer value. 15964 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15965 /*StrictlyPositive=*/true)) 15966 return nullptr; 15967 15968 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15969 OpenMPDirectiveKind CaptureRegion = 15970 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15971 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15972 ValExpr = MakeFullExpr(ValExpr).get(); 15973 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15974 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15975 HelperValStmt = buildPreInits(Context, Captures); 15976 } 15977 15978 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15979 StartLoc, LParenLoc, EndLoc); 15980 } 15981 15982 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15983 SourceLocation StartLoc, 15984 SourceLocation LParenLoc, 15985 SourceLocation EndLoc) { 15986 Expr *ValExpr = ThreadLimit; 15987 Stmt *HelperValStmt = nullptr; 15988 15989 // OpenMP [teams Constrcut, Restrictions] 15990 // The thread_limit expression must evaluate to a positive integer value. 15991 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15992 /*StrictlyPositive=*/true)) 15993 return nullptr; 15994 15995 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15996 OpenMPDirectiveKind CaptureRegion = 15997 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15998 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15999 ValExpr = MakeFullExpr(ValExpr).get(); 16000 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16001 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16002 HelperValStmt = buildPreInits(Context, Captures); 16003 } 16004 16005 return new (Context) OMPThreadLimitClause( 16006 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16007 } 16008 16009 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16010 SourceLocation StartLoc, 16011 SourceLocation LParenLoc, 16012 SourceLocation EndLoc) { 16013 Expr *ValExpr = Priority; 16014 Stmt *HelperValStmt = nullptr; 16015 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16016 16017 // OpenMP [2.9.1, task Constrcut] 16018 // The priority-value is a non-negative numerical scalar expression. 16019 if (!isNonNegativeIntegerValue( 16020 ValExpr, *this, OMPC_priority, 16021 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16022 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16023 return nullptr; 16024 16025 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16026 StartLoc, LParenLoc, EndLoc); 16027 } 16028 16029 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16030 SourceLocation StartLoc, 16031 SourceLocation LParenLoc, 16032 SourceLocation EndLoc) { 16033 Expr *ValExpr = Grainsize; 16034 Stmt *HelperValStmt = nullptr; 16035 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16036 16037 // OpenMP [2.9.2, taskloop Constrcut] 16038 // The parameter of the grainsize clause must be a positive integer 16039 // expression. 16040 if (!isNonNegativeIntegerValue( 16041 ValExpr, *this, OMPC_grainsize, 16042 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16043 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16044 return nullptr; 16045 16046 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16047 StartLoc, LParenLoc, EndLoc); 16048 } 16049 16050 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16051 SourceLocation StartLoc, 16052 SourceLocation LParenLoc, 16053 SourceLocation EndLoc) { 16054 Expr *ValExpr = NumTasks; 16055 Stmt *HelperValStmt = nullptr; 16056 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16057 16058 // OpenMP [2.9.2, taskloop Constrcut] 16059 // The parameter of the num_tasks clause must be a positive integer 16060 // expression. 16061 if (!isNonNegativeIntegerValue( 16062 ValExpr, *this, OMPC_num_tasks, 16063 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16064 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16065 return nullptr; 16066 16067 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16068 StartLoc, LParenLoc, EndLoc); 16069 } 16070 16071 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16072 SourceLocation LParenLoc, 16073 SourceLocation EndLoc) { 16074 // OpenMP [2.13.2, critical construct, Description] 16075 // ... where hint-expression is an integer constant expression that evaluates 16076 // to a valid lock hint. 16077 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16078 if (HintExpr.isInvalid()) 16079 return nullptr; 16080 return new (Context) 16081 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16082 } 16083 16084 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16085 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16086 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16087 SourceLocation EndLoc) { 16088 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16089 std::string Values; 16090 Values += "'"; 16091 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16092 Values += "'"; 16093 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16094 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16095 return nullptr; 16096 } 16097 Expr *ValExpr = ChunkSize; 16098 Stmt *HelperValStmt = nullptr; 16099 if (ChunkSize) { 16100 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16101 !ChunkSize->isInstantiationDependent() && 16102 !ChunkSize->containsUnexpandedParameterPack()) { 16103 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16104 ExprResult Val = 16105 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16106 if (Val.isInvalid()) 16107 return nullptr; 16108 16109 ValExpr = Val.get(); 16110 16111 // OpenMP [2.7.1, Restrictions] 16112 // chunk_size must be a loop invariant integer expression with a positive 16113 // value. 16114 llvm::APSInt Result; 16115 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16116 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16117 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16118 << "dist_schedule" << ChunkSize->getSourceRange(); 16119 return nullptr; 16120 } 16121 } else if (getOpenMPCaptureRegionForClause( 16122 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 16123 OMPD_unknown && 16124 !CurContext->isDependentContext()) { 16125 ValExpr = MakeFullExpr(ValExpr).get(); 16126 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16127 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16128 HelperValStmt = buildPreInits(Context, Captures); 16129 } 16130 } 16131 } 16132 16133 return new (Context) 16134 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16135 Kind, ValExpr, HelperValStmt); 16136 } 16137 16138 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16139 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16140 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16141 SourceLocation KindLoc, SourceLocation EndLoc) { 16142 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 16143 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 16144 std::string Value; 16145 SourceLocation Loc; 16146 Value += "'"; 16147 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16148 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16149 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16150 Loc = MLoc; 16151 } else { 16152 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16153 OMPC_DEFAULTMAP_scalar); 16154 Loc = KindLoc; 16155 } 16156 Value += "'"; 16157 Diag(Loc, diag::err_omp_unexpected_clause_value) 16158 << Value << getOpenMPClauseName(OMPC_defaultmap); 16159 return nullptr; 16160 } 16161 DSAStack->setDefaultDMAToFromScalar(StartLoc); 16162 16163 return new (Context) 16164 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16165 } 16166 16167 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16168 DeclContext *CurLexicalContext = getCurLexicalContext(); 16169 if (!CurLexicalContext->isFileContext() && 16170 !CurLexicalContext->isExternCContext() && 16171 !CurLexicalContext->isExternCXXContext() && 16172 !isa<CXXRecordDecl>(CurLexicalContext) && 16173 !isa<ClassTemplateDecl>(CurLexicalContext) && 16174 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16175 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16176 Diag(Loc, diag::err_omp_region_not_file_context); 16177 return false; 16178 } 16179 ++DeclareTargetNestingLevel; 16180 return true; 16181 } 16182 16183 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16184 assert(DeclareTargetNestingLevel > 0 && 16185 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16186 --DeclareTargetNestingLevel; 16187 } 16188 16189 NamedDecl * 16190 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16191 const DeclarationNameInfo &Id, 16192 NamedDeclSetType &SameDirectiveDecls) { 16193 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16194 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16195 16196 if (Lookup.isAmbiguous()) 16197 return nullptr; 16198 Lookup.suppressDiagnostics(); 16199 16200 if (!Lookup.isSingleResult()) { 16201 VarOrFuncDeclFilterCCC CCC(*this); 16202 if (TypoCorrection Corrected = 16203 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16204 CTK_ErrorRecovery)) { 16205 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16206 << Id.getName()); 16207 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16208 return nullptr; 16209 } 16210 16211 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16212 return nullptr; 16213 } 16214 16215 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16216 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16217 !isa<FunctionTemplateDecl>(ND)) { 16218 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16219 return nullptr; 16220 } 16221 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16222 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16223 return ND; 16224 } 16225 16226 void Sema::ActOnOpenMPDeclareTargetName( 16227 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16228 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16229 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16230 isa<FunctionTemplateDecl>(ND)) && 16231 "Expected variable, function or function template."); 16232 16233 // Diagnose marking after use as it may lead to incorrect diagnosis and 16234 // codegen. 16235 if (LangOpts.OpenMP >= 50 && 16236 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16237 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16238 16239 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16240 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16241 if (DevTy.hasValue() && *DevTy != DT) { 16242 Diag(Loc, diag::err_omp_device_type_mismatch) 16243 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16244 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16245 return; 16246 } 16247 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16248 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16249 if (!Res) { 16250 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16251 SourceRange(Loc, Loc)); 16252 ND->addAttr(A); 16253 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16254 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16255 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16256 } else if (*Res != MT) { 16257 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16258 } 16259 } 16260 16261 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16262 Sema &SemaRef, Decl *D) { 16263 if (!D || !isa<VarDecl>(D)) 16264 return; 16265 auto *VD = cast<VarDecl>(D); 16266 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16267 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16268 if (SemaRef.LangOpts.OpenMP >= 50 && 16269 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16270 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16271 VD->hasGlobalStorage()) { 16272 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16273 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16274 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16275 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16276 // If a lambda declaration and definition appears between a 16277 // declare target directive and the matching end declare target 16278 // directive, all variables that are captured by the lambda 16279 // expression must also appear in a to clause. 16280 SemaRef.Diag(VD->getLocation(), 16281 diag::err_omp_lambda_capture_in_declare_target_not_to); 16282 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16283 << VD << 0 << SR; 16284 return; 16285 } 16286 } 16287 if (MapTy.hasValue()) 16288 return; 16289 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16290 SemaRef.Diag(SL, diag::note_used_here) << SR; 16291 } 16292 16293 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16294 Sema &SemaRef, DSAStackTy *Stack, 16295 ValueDecl *VD) { 16296 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16297 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16298 /*FullCheck=*/false); 16299 } 16300 16301 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16302 SourceLocation IdLoc) { 16303 if (!D || D->isInvalidDecl()) 16304 return; 16305 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16306 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16307 if (auto *VD = dyn_cast<VarDecl>(D)) { 16308 // Only global variables can be marked as declare target. 16309 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16310 !VD->isStaticDataMember()) 16311 return; 16312 // 2.10.6: threadprivate variable cannot appear in a declare target 16313 // directive. 16314 if (DSAStack->isThreadPrivate(VD)) { 16315 Diag(SL, diag::err_omp_threadprivate_in_target); 16316 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16317 return; 16318 } 16319 } 16320 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16321 D = FTD->getTemplatedDecl(); 16322 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16323 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16324 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16325 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16326 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16327 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16328 return; 16329 } 16330 // Mark the function as must be emitted for the device. 16331 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16332 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16333 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16334 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16335 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16336 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16337 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16338 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16339 } 16340 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16341 // Problem if any with var declared with incomplete type will be reported 16342 // as normal, so no need to check it here. 16343 if ((E || !VD->getType()->isIncompleteType()) && 16344 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16345 return; 16346 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16347 // Checking declaration inside declare target region. 16348 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16349 isa<FunctionTemplateDecl>(D)) { 16350 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16351 Context, OMPDeclareTargetDeclAttr::MT_To, 16352 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16353 D->addAttr(A); 16354 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16355 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16356 } 16357 return; 16358 } 16359 } 16360 if (!E) 16361 return; 16362 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16363 } 16364 16365 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16366 CXXScopeSpec &MapperIdScopeSpec, 16367 DeclarationNameInfo &MapperId, 16368 const OMPVarListLocTy &Locs, 16369 ArrayRef<Expr *> UnresolvedMappers) { 16370 MappableVarListInfo MVLI(VarList); 16371 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16372 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16373 if (MVLI.ProcessedVarList.empty()) 16374 return nullptr; 16375 16376 return OMPToClause::Create( 16377 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16378 MVLI.VarComponents, MVLI.UDMapperList, 16379 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16380 } 16381 16382 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16383 CXXScopeSpec &MapperIdScopeSpec, 16384 DeclarationNameInfo &MapperId, 16385 const OMPVarListLocTy &Locs, 16386 ArrayRef<Expr *> UnresolvedMappers) { 16387 MappableVarListInfo MVLI(VarList); 16388 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16389 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16390 if (MVLI.ProcessedVarList.empty()) 16391 return nullptr; 16392 16393 return OMPFromClause::Create( 16394 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16395 MVLI.VarComponents, MVLI.UDMapperList, 16396 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16397 } 16398 16399 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16400 const OMPVarListLocTy &Locs) { 16401 MappableVarListInfo MVLI(VarList); 16402 SmallVector<Expr *, 8> PrivateCopies; 16403 SmallVector<Expr *, 8> Inits; 16404 16405 for (Expr *RefExpr : VarList) { 16406 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16407 SourceLocation ELoc; 16408 SourceRange ERange; 16409 Expr *SimpleRefExpr = RefExpr; 16410 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16411 if (Res.second) { 16412 // It will be analyzed later. 16413 MVLI.ProcessedVarList.push_back(RefExpr); 16414 PrivateCopies.push_back(nullptr); 16415 Inits.push_back(nullptr); 16416 } 16417 ValueDecl *D = Res.first; 16418 if (!D) 16419 continue; 16420 16421 QualType Type = D->getType(); 16422 Type = Type.getNonReferenceType().getUnqualifiedType(); 16423 16424 auto *VD = dyn_cast<VarDecl>(D); 16425 16426 // Item should be a pointer or reference to pointer. 16427 if (!Type->isPointerType()) { 16428 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16429 << 0 << RefExpr->getSourceRange(); 16430 continue; 16431 } 16432 16433 // Build the private variable and the expression that refers to it. 16434 auto VDPrivate = 16435 buildVarDecl(*this, ELoc, Type, D->getName(), 16436 D->hasAttrs() ? &D->getAttrs() : nullptr, 16437 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16438 if (VDPrivate->isInvalidDecl()) 16439 continue; 16440 16441 CurContext->addDecl(VDPrivate); 16442 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16443 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16444 16445 // Add temporary variable to initialize the private copy of the pointer. 16446 VarDecl *VDInit = 16447 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16448 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16449 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16450 AddInitializerToDecl(VDPrivate, 16451 DefaultLvalueConversion(VDInitRefExpr).get(), 16452 /*DirectInit=*/false); 16453 16454 // If required, build a capture to implement the privatization initialized 16455 // with the current list item value. 16456 DeclRefExpr *Ref = nullptr; 16457 if (!VD) 16458 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16459 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16460 PrivateCopies.push_back(VDPrivateRefExpr); 16461 Inits.push_back(VDInitRefExpr); 16462 16463 // We need to add a data sharing attribute for this variable to make sure it 16464 // is correctly captured. A variable that shows up in a use_device_ptr has 16465 // similar properties of a first private variable. 16466 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16467 16468 // Create a mappable component for the list item. List items in this clause 16469 // only need a component. 16470 MVLI.VarBaseDeclarations.push_back(D); 16471 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16472 MVLI.VarComponents.back().push_back( 16473 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16474 } 16475 16476 if (MVLI.ProcessedVarList.empty()) 16477 return nullptr; 16478 16479 return OMPUseDevicePtrClause::Create( 16480 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16481 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16482 } 16483 16484 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16485 const OMPVarListLocTy &Locs) { 16486 MappableVarListInfo MVLI(VarList); 16487 for (Expr *RefExpr : VarList) { 16488 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16489 SourceLocation ELoc; 16490 SourceRange ERange; 16491 Expr *SimpleRefExpr = RefExpr; 16492 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16493 if (Res.second) { 16494 // It will be analyzed later. 16495 MVLI.ProcessedVarList.push_back(RefExpr); 16496 } 16497 ValueDecl *D = Res.first; 16498 if (!D) 16499 continue; 16500 16501 QualType Type = D->getType(); 16502 // item should be a pointer or array or reference to pointer or array 16503 if (!Type.getNonReferenceType()->isPointerType() && 16504 !Type.getNonReferenceType()->isArrayType()) { 16505 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16506 << 0 << RefExpr->getSourceRange(); 16507 continue; 16508 } 16509 16510 // Check if the declaration in the clause does not show up in any data 16511 // sharing attribute. 16512 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16513 if (isOpenMPPrivate(DVar.CKind)) { 16514 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16515 << getOpenMPClauseName(DVar.CKind) 16516 << getOpenMPClauseName(OMPC_is_device_ptr) 16517 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16518 reportOriginalDsa(*this, DSAStack, D, DVar); 16519 continue; 16520 } 16521 16522 const Expr *ConflictExpr; 16523 if (DSAStack->checkMappableExprComponentListsForDecl( 16524 D, /*CurrentRegionOnly=*/true, 16525 [&ConflictExpr]( 16526 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16527 OpenMPClauseKind) -> bool { 16528 ConflictExpr = R.front().getAssociatedExpression(); 16529 return true; 16530 })) { 16531 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16532 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16533 << ConflictExpr->getSourceRange(); 16534 continue; 16535 } 16536 16537 // Store the components in the stack so that they can be used to check 16538 // against other clauses later on. 16539 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16540 DSAStack->addMappableExpressionComponents( 16541 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16542 16543 // Record the expression we've just processed. 16544 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16545 16546 // Create a mappable component for the list item. List items in this clause 16547 // only need a component. We use a null declaration to signal fields in 16548 // 'this'. 16549 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16550 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16551 "Unexpected device pointer expression!"); 16552 MVLI.VarBaseDeclarations.push_back( 16553 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16554 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16555 MVLI.VarComponents.back().push_back(MC); 16556 } 16557 16558 if (MVLI.ProcessedVarList.empty()) 16559 return nullptr; 16560 16561 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16562 MVLI.VarBaseDeclarations, 16563 MVLI.VarComponents); 16564 } 16565 16566 OMPClause *Sema::ActOnOpenMPAllocateClause( 16567 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16568 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16569 if (Allocator) { 16570 // OpenMP [2.11.4 allocate Clause, Description] 16571 // allocator is an expression of omp_allocator_handle_t type. 16572 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16573 return nullptr; 16574 16575 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16576 if (AllocatorRes.isInvalid()) 16577 return nullptr; 16578 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16579 DSAStack->getOMPAllocatorHandleT(), 16580 Sema::AA_Initializing, 16581 /*AllowExplicit=*/true); 16582 if (AllocatorRes.isInvalid()) 16583 return nullptr; 16584 Allocator = AllocatorRes.get(); 16585 } else { 16586 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16587 // allocate clauses that appear on a target construct or on constructs in a 16588 // target region must specify an allocator expression unless a requires 16589 // directive with the dynamic_allocators clause is present in the same 16590 // compilation unit. 16591 if (LangOpts.OpenMPIsDevice && 16592 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16593 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16594 } 16595 // Analyze and build list of variables. 16596 SmallVector<Expr *, 8> Vars; 16597 for (Expr *RefExpr : VarList) { 16598 assert(RefExpr && "NULL expr in OpenMP private clause."); 16599 SourceLocation ELoc; 16600 SourceRange ERange; 16601 Expr *SimpleRefExpr = RefExpr; 16602 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16603 if (Res.second) { 16604 // It will be analyzed later. 16605 Vars.push_back(RefExpr); 16606 } 16607 ValueDecl *D = Res.first; 16608 if (!D) 16609 continue; 16610 16611 auto *VD = dyn_cast<VarDecl>(D); 16612 DeclRefExpr *Ref = nullptr; 16613 if (!VD && !CurContext->isDependentContext()) 16614 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16615 Vars.push_back((VD || CurContext->isDependentContext()) 16616 ? RefExpr->IgnoreParens() 16617 : Ref); 16618 } 16619 16620 if (Vars.empty()) 16621 return nullptr; 16622 16623 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16624 ColonLoc, EndLoc, Vars); 16625 } 16626