1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 bool HasMutipleLoops = false; 143 const Decl *PossiblyLoopCounter = nullptr; 144 bool NowaitRegion = false; 145 bool CancelRegion = false; 146 bool LoopStart = false; 147 bool BodyComplete = false; 148 SourceLocation InnerTeamsRegionLoc; 149 /// Reference to the taskgroup task_reduction reference expression. 150 Expr *TaskgroupReductionRef = nullptr; 151 llvm::DenseSet<QualType> MappedClassesQualTypes; 152 /// List of globals marked as declare target link in this target region 153 /// (isOpenMPTargetExecutionDirective(Directive) == true). 154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 156 Scope *CurScope, SourceLocation Loc) 157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 158 ConstructLoc(Loc) {} 159 SharingMapTy() = default; 160 }; 161 162 using StackTy = SmallVector<SharingMapTy, 4>; 163 164 /// Stack of used declaration and their data-sharing attributes. 165 DeclSAMapTy Threadprivates; 166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 168 /// true, if check for DSA must be from parent directive, false, if 169 /// from current directive. 170 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 171 Sema &SemaRef; 172 bool ForceCapturing = false; 173 /// true if all the variables in the target executable directives must be 174 /// captured by reference. 175 bool ForceCaptureByReferenceInTargetExecutable = false; 176 CriticalsWithHintsTy Criticals; 177 unsigned IgnoredStackElements = 0; 178 179 /// Iterators over the stack iterate in order from innermost to outermost 180 /// directive. 181 using const_iterator = StackTy::const_reverse_iterator; 182 const_iterator begin() const { 183 return Stack.empty() ? const_iterator() 184 : Stack.back().first.rbegin() + IgnoredStackElements; 185 } 186 const_iterator end() const { 187 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 188 } 189 using iterator = StackTy::reverse_iterator; 190 iterator begin() { 191 return Stack.empty() ? iterator() 192 : Stack.back().first.rbegin() + IgnoredStackElements; 193 } 194 iterator end() { 195 return Stack.empty() ? iterator() : Stack.back().first.rend(); 196 } 197 198 // Convenience operations to get at the elements of the stack. 199 200 bool isStackEmpty() const { 201 return Stack.empty() || 202 Stack.back().second != CurrentNonCapturingFunctionScope || 203 Stack.back().first.size() <= IgnoredStackElements; 204 } 205 size_t getStackSize() const { 206 return isStackEmpty() ? 0 207 : Stack.back().first.size() - IgnoredStackElements; 208 } 209 210 SharingMapTy *getTopOfStackOrNull() { 211 size_t Size = getStackSize(); 212 if (Size == 0) 213 return nullptr; 214 return &Stack.back().first[Size - 1]; 215 } 216 const SharingMapTy *getTopOfStackOrNull() const { 217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 218 } 219 SharingMapTy &getTopOfStack() { 220 assert(!isStackEmpty() && "no current directive"); 221 return *getTopOfStackOrNull(); 222 } 223 const SharingMapTy &getTopOfStack() const { 224 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 225 } 226 227 SharingMapTy *getSecondOnStackOrNull() { 228 size_t Size = getStackSize(); 229 if (Size <= 1) 230 return nullptr; 231 return &Stack.back().first[Size - 2]; 232 } 233 const SharingMapTy *getSecondOnStackOrNull() const { 234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 235 } 236 237 /// Get the stack element at a certain level (previously returned by 238 /// \c getNestingLevel). 239 /// 240 /// Note that nesting levels count from outermost to innermost, and this is 241 /// the reverse of our iteration order where new inner levels are pushed at 242 /// the front of the stack. 243 SharingMapTy &getStackElemAtLevel(unsigned Level) { 244 assert(Level < getStackSize() && "no such stack element"); 245 return Stack.back().first[Level]; 246 } 247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 249 } 250 251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 252 253 /// Checks if the variable is a local for OpenMP region. 254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 255 256 /// Vector of previously declared requires directives 257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 258 /// omp_allocator_handle_t type. 259 QualType OMPAllocatorHandleT; 260 /// Expression for the predefined allocators. 261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 262 nullptr}; 263 /// Vector of previously encountered target directives 264 SmallVector<SourceLocation, 2> TargetLocations; 265 266 public: 267 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 268 269 /// Sets omp_allocator_handle_t type. 270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 271 /// Gets omp_allocator_handle_t type. 272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 273 /// Sets the given default allocator. 274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 275 Expr *Allocator) { 276 OMPPredefinedAllocators[AllocatorKind] = Allocator; 277 } 278 /// Returns the specified default allocator. 279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 280 return OMPPredefinedAllocators[AllocatorKind]; 281 } 282 283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 284 OpenMPClauseKind getClauseParsingMode() const { 285 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 286 return ClauseKindMode; 287 } 288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 289 290 bool isBodyComplete() const { 291 const SharingMapTy *Top = getTopOfStackOrNull(); 292 return Top && Top->BodyComplete; 293 } 294 void setBodyComplete() { 295 getTopOfStack().BodyComplete = true; 296 } 297 298 bool isForceVarCapturing() const { return ForceCapturing; } 299 void setForceVarCapturing(bool V) { ForceCapturing = V; } 300 301 void setForceCaptureByReferenceInTargetExecutable(bool V) { 302 ForceCaptureByReferenceInTargetExecutable = V; 303 } 304 bool isForceCaptureByReferenceInTargetExecutable() const { 305 return ForceCaptureByReferenceInTargetExecutable; 306 } 307 308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 309 Scope *CurScope, SourceLocation Loc) { 310 assert(!IgnoredStackElements && 311 "cannot change stack while ignoring elements"); 312 if (Stack.empty() || 313 Stack.back().second != CurrentNonCapturingFunctionScope) 314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 316 Stack.back().first.back().DefaultAttrLoc = Loc; 317 } 318 319 void pop() { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 assert(!Stack.back().first.empty() && 323 "Data-sharing attributes stack is empty!"); 324 Stack.back().first.pop_back(); 325 } 326 327 /// RAII object to temporarily leave the scope of a directive when we want to 328 /// logically operate in its parent. 329 class ParentDirectiveScope { 330 DSAStackTy &Self; 331 bool Active; 332 public: 333 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 334 : Self(Self), Active(false) { 335 if (Activate) 336 enable(); 337 } 338 ~ParentDirectiveScope() { disable(); } 339 void disable() { 340 if (Active) { 341 --Self.IgnoredStackElements; 342 Active = false; 343 } 344 } 345 void enable() { 346 if (!Active) { 347 ++Self.IgnoredStackElements; 348 Active = true; 349 } 350 } 351 }; 352 353 /// Marks that we're started loop parsing. 354 void loopInit() { 355 assert(isOpenMPLoopDirective(getCurrentDirective()) && 356 "Expected loop-based directive."); 357 getTopOfStack().LoopStart = true; 358 } 359 /// Start capturing of the variables in the loop context. 360 void loopStart() { 361 assert(isOpenMPLoopDirective(getCurrentDirective()) && 362 "Expected loop-based directive."); 363 getTopOfStack().LoopStart = false; 364 } 365 /// true, if variables are captured, false otherwise. 366 bool isLoopStarted() const { 367 assert(isOpenMPLoopDirective(getCurrentDirective()) && 368 "Expected loop-based directive."); 369 return !getTopOfStack().LoopStart; 370 } 371 /// Marks (or clears) declaration as possibly loop counter. 372 void resetPossibleLoopCounter(const Decl *D = nullptr) { 373 getTopOfStack().PossiblyLoopCounter = 374 D ? D->getCanonicalDecl() : D; 375 } 376 /// Gets the possible loop counter decl. 377 const Decl *getPossiblyLoopCunter() const { 378 return getTopOfStack().PossiblyLoopCounter; 379 } 380 /// Start new OpenMP region stack in new non-capturing function. 381 void pushFunction() { 382 assert(!IgnoredStackElements && 383 "cannot change stack while ignoring elements"); 384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 385 assert(!isa<CapturingScopeInfo>(CurFnScope)); 386 CurrentNonCapturingFunctionScope = CurFnScope; 387 } 388 /// Pop region stack for non-capturing function. 389 void popFunction(const FunctionScopeInfo *OldFSI) { 390 assert(!IgnoredStackElements && 391 "cannot change stack while ignoring elements"); 392 if (!Stack.empty() && Stack.back().second == OldFSI) { 393 assert(Stack.back().first.empty()); 394 Stack.pop_back(); 395 } 396 CurrentNonCapturingFunctionScope = nullptr; 397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 398 if (!isa<CapturingScopeInfo>(FSI)) { 399 CurrentNonCapturingFunctionScope = FSI; 400 break; 401 } 402 } 403 } 404 405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 407 } 408 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 409 getCriticalWithHint(const DeclarationNameInfo &Name) const { 410 auto I = Criticals.find(Name.getAsString()); 411 if (I != Criticals.end()) 412 return I->second; 413 return std::make_pair(nullptr, llvm::APSInt()); 414 } 415 /// If 'aligned' declaration for given variable \a D was not seen yet, 416 /// add it and return NULL; otherwise return previous occurrence's expression 417 /// for diagnostics. 418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 419 420 /// Register specified variable as loop control variable. 421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 422 /// Check if the specified variable is a loop control variable for 423 /// current region. 424 /// \return The index of the loop control variable in the list of associated 425 /// for-loops (from outer to inner). 426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 427 /// Check if the specified variable is a loop control variable for 428 /// parent region. 429 /// \return The index of the loop control variable in the list of associated 430 /// for-loops (from outer to inner). 431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 432 /// Get the loop control variable for the I-th loop (or nullptr) in 433 /// parent directive. 434 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 435 436 /// Adds explicit data sharing attribute to the specified declaration. 437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 438 DeclRefExpr *PrivateCopy = nullptr); 439 440 /// Adds additional information for the reduction items with the reduction id 441 /// represented as an operator. 442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 443 BinaryOperatorKind BOK); 444 /// Adds additional information for the reduction items with the reduction id 445 /// represented as reduction identifier. 446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 447 const Expr *ReductionRef); 448 /// Returns the location and reduction operation from the innermost parent 449 /// region for the given \p D. 450 const DSAVarData 451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 452 BinaryOperatorKind &BOK, 453 Expr *&TaskgroupDescriptor) const; 454 /// Returns the location and reduction operation from the innermost parent 455 /// region for the given \p D. 456 const DSAVarData 457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 458 const Expr *&ReductionRef, 459 Expr *&TaskgroupDescriptor) const; 460 /// Return reduction reference expression for the current taskgroup. 461 Expr *getTaskgroupReductionRef() const { 462 assert(getTopOfStack().Directive == OMPD_taskgroup && 463 "taskgroup reference expression requested for non taskgroup " 464 "directive."); 465 return getTopOfStack().TaskgroupReductionRef; 466 } 467 /// Checks if the given \p VD declaration is actually a taskgroup reduction 468 /// descriptor variable at the \p Level of OpenMP regions. 469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 470 return getStackElemAtLevel(Level).TaskgroupReductionRef && 471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 472 ->getDecl() == VD; 473 } 474 475 /// Returns data sharing attributes from top of the stack for the 476 /// specified declaration. 477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 478 /// Returns data-sharing attributes for the specified declaration. 479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 480 /// Checks if the specified variables has data-sharing attributes which 481 /// match specified \a CPred predicate in any directive which matches \a DPred 482 /// predicate. 483 const DSAVarData 484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 486 bool FromParent) const; 487 /// Checks if the specified variables has data-sharing attributes which 488 /// match specified \a CPred predicate in any innermost directive which 489 /// matches \a DPred predicate. 490 const DSAVarData 491 hasInnermostDSA(ValueDecl *D, 492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 494 bool FromParent) const; 495 /// Checks if the specified variables has explicit data-sharing 496 /// attributes which match specified \a CPred predicate at the specified 497 /// OpenMP region. 498 bool hasExplicitDSA(const ValueDecl *D, 499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 500 unsigned Level, bool NotLastprivate = false) const; 501 502 /// Returns true if the directive at level \Level matches in the 503 /// specified \a DPred predicate. 504 bool hasExplicitDirective( 505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 506 unsigned Level) const; 507 508 /// Finds a directive which matches specified \a DPred predicate. 509 bool hasDirective( 510 const llvm::function_ref<bool( 511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 512 DPred, 513 bool FromParent) const; 514 515 /// Returns currently analyzed directive. 516 OpenMPDirectiveKind getCurrentDirective() const { 517 const SharingMapTy *Top = getTopOfStackOrNull(); 518 return Top ? Top->Directive : OMPD_unknown; 519 } 520 /// Returns directive kind at specified level. 521 OpenMPDirectiveKind getDirective(unsigned Level) const { 522 assert(!isStackEmpty() && "No directive at specified level."); 523 return getStackElemAtLevel(Level).Directive; 524 } 525 /// Returns the capture region at the specified level. 526 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 527 unsigned OpenMPCaptureLevel) const { 528 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 529 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 530 return CaptureRegions[OpenMPCaptureLevel]; 531 } 532 /// Returns parent directive. 533 OpenMPDirectiveKind getParentDirective() const { 534 const SharingMapTy *Parent = getSecondOnStackOrNull(); 535 return Parent ? Parent->Directive : OMPD_unknown; 536 } 537 538 /// Add requires decl to internal vector 539 void addRequiresDecl(OMPRequiresDecl *RD) { 540 RequiresDecls.push_back(RD); 541 } 542 543 /// Checks if the defined 'requires' directive has specified type of clause. 544 template <typename ClauseType> 545 bool hasRequiresDeclWithClause() { 546 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 547 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 548 return isa<ClauseType>(C); 549 }); 550 }); 551 } 552 553 /// Checks for a duplicate clause amongst previously declared requires 554 /// directives 555 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 556 bool IsDuplicate = false; 557 for (OMPClause *CNew : ClauseList) { 558 for (const OMPRequiresDecl *D : RequiresDecls) { 559 for (const OMPClause *CPrev : D->clauselists()) { 560 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 561 SemaRef.Diag(CNew->getBeginLoc(), 562 diag::err_omp_requires_clause_redeclaration) 563 << getOpenMPClauseName(CNew->getClauseKind()); 564 SemaRef.Diag(CPrev->getBeginLoc(), 565 diag::note_omp_requires_previous_clause) 566 << getOpenMPClauseName(CPrev->getClauseKind()); 567 IsDuplicate = true; 568 } 569 } 570 } 571 } 572 return IsDuplicate; 573 } 574 575 /// Add location of previously encountered target to internal vector 576 void addTargetDirLocation(SourceLocation LocStart) { 577 TargetLocations.push_back(LocStart); 578 } 579 580 // Return previously encountered target region locations. 581 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 582 return TargetLocations; 583 } 584 585 /// Set default data sharing attribute to none. 586 void setDefaultDSANone(SourceLocation Loc) { 587 getTopOfStack().DefaultAttr = DSA_none; 588 getTopOfStack().DefaultAttrLoc = Loc; 589 } 590 /// Set default data sharing attribute to shared. 591 void setDefaultDSAShared(SourceLocation Loc) { 592 getTopOfStack().DefaultAttr = DSA_shared; 593 getTopOfStack().DefaultAttrLoc = Loc; 594 } 595 /// Set default data mapping attribute to 'tofrom:scalar'. 596 void setDefaultDMAToFromScalar(SourceLocation Loc) { 597 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 598 getTopOfStack().DefaultMapAttrLoc = Loc; 599 } 600 601 DefaultDataSharingAttributes getDefaultDSA() const { 602 return isStackEmpty() ? DSA_unspecified 603 : getTopOfStack().DefaultAttr; 604 } 605 SourceLocation getDefaultDSALocation() const { 606 return isStackEmpty() ? SourceLocation() 607 : getTopOfStack().DefaultAttrLoc; 608 } 609 DefaultMapAttributes getDefaultDMA() const { 610 return isStackEmpty() ? DMA_unspecified 611 : getTopOfStack().DefaultMapAttr; 612 } 613 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 614 return getStackElemAtLevel(Level).DefaultMapAttr; 615 } 616 SourceLocation getDefaultDMALocation() const { 617 return isStackEmpty() ? SourceLocation() 618 : getTopOfStack().DefaultMapAttrLoc; 619 } 620 621 /// Checks if the specified variable is a threadprivate. 622 bool isThreadPrivate(VarDecl *D) { 623 const DSAVarData DVar = getTopDSA(D, false); 624 return isOpenMPThreadPrivate(DVar.CKind); 625 } 626 627 /// Marks current region as ordered (it has an 'ordered' clause). 628 void setOrderedRegion(bool IsOrdered, const Expr *Param, 629 OMPOrderedClause *Clause) { 630 if (IsOrdered) 631 getTopOfStack().OrderedRegion.emplace(Param, Clause); 632 else 633 getTopOfStack().OrderedRegion.reset(); 634 } 635 /// Returns true, if region is ordered (has associated 'ordered' clause), 636 /// false - otherwise. 637 bool isOrderedRegion() const { 638 if (const SharingMapTy *Top = getTopOfStackOrNull()) 639 return Top->OrderedRegion.hasValue(); 640 return false; 641 } 642 /// Returns optional parameter for the ordered region. 643 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 644 if (const SharingMapTy *Top = getTopOfStackOrNull()) 645 if (Top->OrderedRegion.hasValue()) 646 return Top->OrderedRegion.getValue(); 647 return std::make_pair(nullptr, nullptr); 648 } 649 /// Returns true, if parent region is ordered (has associated 650 /// 'ordered' clause), false - otherwise. 651 bool isParentOrderedRegion() const { 652 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 653 return Parent->OrderedRegion.hasValue(); 654 return false; 655 } 656 /// Returns optional parameter for the ordered region. 657 std::pair<const Expr *, OMPOrderedClause *> 658 getParentOrderedRegionParam() const { 659 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 660 if (Parent->OrderedRegion.hasValue()) 661 return Parent->OrderedRegion.getValue(); 662 return std::make_pair(nullptr, nullptr); 663 } 664 /// Marks current region as nowait (it has a 'nowait' clause). 665 void setNowaitRegion(bool IsNowait = true) { 666 getTopOfStack().NowaitRegion = IsNowait; 667 } 668 /// Returns true, if parent region is nowait (has associated 669 /// 'nowait' clause), false - otherwise. 670 bool isParentNowaitRegion() const { 671 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 672 return Parent->NowaitRegion; 673 return false; 674 } 675 /// Marks parent region as cancel region. 676 void setParentCancelRegion(bool Cancel = true) { 677 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 678 Parent->CancelRegion |= Cancel; 679 } 680 /// Return true if current region has inner cancel construct. 681 bool isCancelRegion() const { 682 const SharingMapTy *Top = getTopOfStackOrNull(); 683 return Top ? Top->CancelRegion : false; 684 } 685 686 /// Set collapse value for the region. 687 void setAssociatedLoops(unsigned Val) { 688 getTopOfStack().AssociatedLoops = Val; 689 if (Val > 1) 690 getTopOfStack().HasMutipleLoops = true; 691 } 692 /// Return collapse value for region. 693 unsigned getAssociatedLoops() const { 694 const SharingMapTy *Top = getTopOfStackOrNull(); 695 return Top ? Top->AssociatedLoops : 0; 696 } 697 /// Returns true if the construct is associated with multiple loops. 698 bool hasMutipleLoops() const { 699 const SharingMapTy *Top = getTopOfStackOrNull(); 700 return Top ? Top->HasMutipleLoops : false; 701 } 702 703 /// Marks current target region as one with closely nested teams 704 /// region. 705 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 706 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 707 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 708 } 709 /// Returns true, if current region has closely nested teams region. 710 bool hasInnerTeamsRegion() const { 711 return getInnerTeamsRegionLoc().isValid(); 712 } 713 /// Returns location of the nested teams region (if any). 714 SourceLocation getInnerTeamsRegionLoc() const { 715 const SharingMapTy *Top = getTopOfStackOrNull(); 716 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 717 } 718 719 Scope *getCurScope() const { 720 const SharingMapTy *Top = getTopOfStackOrNull(); 721 return Top ? Top->CurScope : nullptr; 722 } 723 SourceLocation getConstructLoc() const { 724 const SharingMapTy *Top = getTopOfStackOrNull(); 725 return Top ? Top->ConstructLoc : SourceLocation(); 726 } 727 728 /// Do the check specified in \a Check to all component lists and return true 729 /// if any issue is found. 730 bool checkMappableExprComponentListsForDecl( 731 const ValueDecl *VD, bool CurrentRegionOnly, 732 const llvm::function_ref< 733 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 734 OpenMPClauseKind)> 735 Check) const { 736 if (isStackEmpty()) 737 return false; 738 auto SI = begin(); 739 auto SE = end(); 740 741 if (SI == SE) 742 return false; 743 744 if (CurrentRegionOnly) 745 SE = std::next(SI); 746 else 747 std::advance(SI, 1); 748 749 for (; SI != SE; ++SI) { 750 auto MI = SI->MappedExprComponents.find(VD); 751 if (MI != SI->MappedExprComponents.end()) 752 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 753 MI->second.Components) 754 if (Check(L, MI->second.Kind)) 755 return true; 756 } 757 return false; 758 } 759 760 /// Do the check specified in \a Check to all component lists at a given level 761 /// and return true if any issue is found. 762 bool checkMappableExprComponentListsForDeclAtLevel( 763 const ValueDecl *VD, unsigned Level, 764 const llvm::function_ref< 765 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 766 OpenMPClauseKind)> 767 Check) const { 768 if (getStackSize() <= Level) 769 return false; 770 771 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 772 auto MI = StackElem.MappedExprComponents.find(VD); 773 if (MI != StackElem.MappedExprComponents.end()) 774 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 775 MI->second.Components) 776 if (Check(L, MI->second.Kind)) 777 return true; 778 return false; 779 } 780 781 /// Create a new mappable expression component list associated with a given 782 /// declaration and initialize it with the provided list of components. 783 void addMappableExpressionComponents( 784 const ValueDecl *VD, 785 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 786 OpenMPClauseKind WhereFoundClauseKind) { 787 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 788 // Create new entry and append the new components there. 789 MEC.Components.resize(MEC.Components.size() + 1); 790 MEC.Components.back().append(Components.begin(), Components.end()); 791 MEC.Kind = WhereFoundClauseKind; 792 } 793 794 unsigned getNestingLevel() const { 795 assert(!isStackEmpty()); 796 return getStackSize() - 1; 797 } 798 void addDoacrossDependClause(OMPDependClause *C, 799 const OperatorOffsetTy &OpsOffs) { 800 SharingMapTy *Parent = getSecondOnStackOrNull(); 801 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 802 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 803 } 804 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 805 getDoacrossDependClauses() const { 806 const SharingMapTy &StackElem = getTopOfStack(); 807 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 808 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 809 return llvm::make_range(Ref.begin(), Ref.end()); 810 } 811 return llvm::make_range(StackElem.DoacrossDepends.end(), 812 StackElem.DoacrossDepends.end()); 813 } 814 815 // Store types of classes which have been explicitly mapped 816 void addMappedClassesQualTypes(QualType QT) { 817 SharingMapTy &StackElem = getTopOfStack(); 818 StackElem.MappedClassesQualTypes.insert(QT); 819 } 820 821 // Return set of mapped classes types 822 bool isClassPreviouslyMapped(QualType QT) const { 823 const SharingMapTy &StackElem = getTopOfStack(); 824 return StackElem.MappedClassesQualTypes.count(QT) != 0; 825 } 826 827 /// Adds global declare target to the parent target region. 828 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 829 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 830 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 831 "Expected declare target link global."); 832 for (auto &Elem : *this) { 833 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 834 Elem.DeclareTargetLinkVarDecls.push_back(E); 835 return; 836 } 837 } 838 } 839 840 /// Returns the list of globals with declare target link if current directive 841 /// is target. 842 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 843 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 844 "Expected target executable directive."); 845 return getTopOfStack().DeclareTargetLinkVarDecls; 846 } 847 }; 848 849 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 850 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 851 } 852 853 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 854 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 855 DKind == OMPD_unknown; 856 } 857 858 } // namespace 859 860 static const Expr *getExprAsWritten(const Expr *E) { 861 if (const auto *FE = dyn_cast<FullExpr>(E)) 862 E = FE->getSubExpr(); 863 864 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 865 E = MTE->GetTemporaryExpr(); 866 867 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 868 E = Binder->getSubExpr(); 869 870 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 871 E = ICE->getSubExprAsWritten(); 872 return E->IgnoreParens(); 873 } 874 875 static Expr *getExprAsWritten(Expr *E) { 876 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 877 } 878 879 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 880 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 881 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 882 D = ME->getMemberDecl(); 883 const auto *VD = dyn_cast<VarDecl>(D); 884 const auto *FD = dyn_cast<FieldDecl>(D); 885 if (VD != nullptr) { 886 VD = VD->getCanonicalDecl(); 887 D = VD; 888 } else { 889 assert(FD); 890 FD = FD->getCanonicalDecl(); 891 D = FD; 892 } 893 return D; 894 } 895 896 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 897 return const_cast<ValueDecl *>( 898 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 899 } 900 901 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 902 ValueDecl *D) const { 903 D = getCanonicalDecl(D); 904 auto *VD = dyn_cast<VarDecl>(D); 905 const auto *FD = dyn_cast<FieldDecl>(D); 906 DSAVarData DVar; 907 if (Iter == end()) { 908 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 909 // in a region but not in construct] 910 // File-scope or namespace-scope variables referenced in called routines 911 // in the region are shared unless they appear in a threadprivate 912 // directive. 913 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 914 DVar.CKind = OMPC_shared; 915 916 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 917 // in a region but not in construct] 918 // Variables with static storage duration that are declared in called 919 // routines in the region are shared. 920 if (VD && VD->hasGlobalStorage()) 921 DVar.CKind = OMPC_shared; 922 923 // Non-static data members are shared by default. 924 if (FD) 925 DVar.CKind = OMPC_shared; 926 927 return DVar; 928 } 929 930 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 931 // in a Construct, C/C++, predetermined, p.1] 932 // Variables with automatic storage duration that are declared in a scope 933 // inside the construct are private. 934 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 935 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 936 DVar.CKind = OMPC_private; 937 return DVar; 938 } 939 940 DVar.DKind = Iter->Directive; 941 // Explicitly specified attributes and local variables with predetermined 942 // attributes. 943 if (Iter->SharingMap.count(D)) { 944 const DSAInfo &Data = Iter->SharingMap.lookup(D); 945 DVar.RefExpr = Data.RefExpr.getPointer(); 946 DVar.PrivateCopy = Data.PrivateCopy; 947 DVar.CKind = Data.Attributes; 948 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 949 return DVar; 950 } 951 952 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 953 // in a Construct, C/C++, implicitly determined, p.1] 954 // In a parallel or task construct, the data-sharing attributes of these 955 // variables are determined by the default clause, if present. 956 switch (Iter->DefaultAttr) { 957 case DSA_shared: 958 DVar.CKind = OMPC_shared; 959 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 960 return DVar; 961 case DSA_none: 962 return DVar; 963 case DSA_unspecified: 964 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 965 // in a Construct, implicitly determined, p.2] 966 // In a parallel construct, if no default clause is present, these 967 // variables are shared. 968 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 969 if ((isOpenMPParallelDirective(DVar.DKind) && 970 !isOpenMPTaskLoopDirective(DVar.DKind)) || 971 isOpenMPTeamsDirective(DVar.DKind)) { 972 DVar.CKind = OMPC_shared; 973 return DVar; 974 } 975 976 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 977 // in a Construct, implicitly determined, p.4] 978 // In a task construct, if no default clause is present, a variable that in 979 // the enclosing context is determined to be shared by all implicit tasks 980 // bound to the current team is shared. 981 if (isOpenMPTaskingDirective(DVar.DKind)) { 982 DSAVarData DVarTemp; 983 const_iterator I = Iter, E = end(); 984 do { 985 ++I; 986 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 987 // Referenced in a Construct, implicitly determined, p.6] 988 // In a task construct, if no default clause is present, a variable 989 // whose data-sharing attribute is not determined by the rules above is 990 // firstprivate. 991 DVarTemp = getDSA(I, D); 992 if (DVarTemp.CKind != OMPC_shared) { 993 DVar.RefExpr = nullptr; 994 DVar.CKind = OMPC_firstprivate; 995 return DVar; 996 } 997 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 998 DVar.CKind = 999 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1000 return DVar; 1001 } 1002 } 1003 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1004 // in a Construct, implicitly determined, p.3] 1005 // For constructs other than task, if no default clause is present, these 1006 // variables inherit their data-sharing attributes from the enclosing 1007 // context. 1008 return getDSA(++Iter, D); 1009 } 1010 1011 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1012 const Expr *NewDE) { 1013 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1014 D = getCanonicalDecl(D); 1015 SharingMapTy &StackElem = getTopOfStack(); 1016 auto It = StackElem.AlignedMap.find(D); 1017 if (It == StackElem.AlignedMap.end()) { 1018 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1019 StackElem.AlignedMap[D] = NewDE; 1020 return nullptr; 1021 } 1022 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1023 return It->second; 1024 } 1025 1026 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1027 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1028 D = getCanonicalDecl(D); 1029 SharingMapTy &StackElem = getTopOfStack(); 1030 StackElem.LCVMap.try_emplace( 1031 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1032 } 1033 1034 const DSAStackTy::LCDeclInfo 1035 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1036 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1037 D = getCanonicalDecl(D); 1038 const SharingMapTy &StackElem = getTopOfStack(); 1039 auto It = StackElem.LCVMap.find(D); 1040 if (It != StackElem.LCVMap.end()) 1041 return It->second; 1042 return {0, nullptr}; 1043 } 1044 1045 const DSAStackTy::LCDeclInfo 1046 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1047 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1048 assert(Parent && "Data-sharing attributes stack is empty"); 1049 D = getCanonicalDecl(D); 1050 auto It = Parent->LCVMap.find(D); 1051 if (It != Parent->LCVMap.end()) 1052 return It->second; 1053 return {0, nullptr}; 1054 } 1055 1056 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1057 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1058 assert(Parent && "Data-sharing attributes stack is empty"); 1059 if (Parent->LCVMap.size() < I) 1060 return nullptr; 1061 for (const auto &Pair : Parent->LCVMap) 1062 if (Pair.second.first == I) 1063 return Pair.first; 1064 return nullptr; 1065 } 1066 1067 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1068 DeclRefExpr *PrivateCopy) { 1069 D = getCanonicalDecl(D); 1070 if (A == OMPC_threadprivate) { 1071 DSAInfo &Data = Threadprivates[D]; 1072 Data.Attributes = A; 1073 Data.RefExpr.setPointer(E); 1074 Data.PrivateCopy = nullptr; 1075 } else { 1076 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1077 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1078 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1079 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1080 (isLoopControlVariable(D).first && A == OMPC_private)); 1081 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1082 Data.RefExpr.setInt(/*IntVal=*/true); 1083 return; 1084 } 1085 const bool IsLastprivate = 1086 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1087 Data.Attributes = A; 1088 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1089 Data.PrivateCopy = PrivateCopy; 1090 if (PrivateCopy) { 1091 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1092 Data.Attributes = A; 1093 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1094 Data.PrivateCopy = nullptr; 1095 } 1096 } 1097 } 1098 1099 /// Build a variable declaration for OpenMP loop iteration variable. 1100 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1101 StringRef Name, const AttrVec *Attrs = nullptr, 1102 DeclRefExpr *OrigRef = nullptr) { 1103 DeclContext *DC = SemaRef.CurContext; 1104 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1105 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1106 auto *Decl = 1107 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1108 if (Attrs) { 1109 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1110 I != E; ++I) 1111 Decl->addAttr(*I); 1112 } 1113 Decl->setImplicit(); 1114 if (OrigRef) { 1115 Decl->addAttr( 1116 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1117 } 1118 return Decl; 1119 } 1120 1121 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1122 SourceLocation Loc, 1123 bool RefersToCapture = false) { 1124 D->setReferenced(); 1125 D->markUsed(S.Context); 1126 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1127 SourceLocation(), D, RefersToCapture, Loc, Ty, 1128 VK_LValue); 1129 } 1130 1131 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1132 BinaryOperatorKind BOK) { 1133 D = getCanonicalDecl(D); 1134 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1135 assert( 1136 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1137 "Additional reduction info may be specified only for reduction items."); 1138 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1139 assert(ReductionData.ReductionRange.isInvalid() && 1140 getTopOfStack().Directive == OMPD_taskgroup && 1141 "Additional reduction info may be specified only once for reduction " 1142 "items."); 1143 ReductionData.set(BOK, SR); 1144 Expr *&TaskgroupReductionRef = 1145 getTopOfStack().TaskgroupReductionRef; 1146 if (!TaskgroupReductionRef) { 1147 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1148 SemaRef.Context.VoidPtrTy, ".task_red."); 1149 TaskgroupReductionRef = 1150 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1151 } 1152 } 1153 1154 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1155 const Expr *ReductionRef) { 1156 D = getCanonicalDecl(D); 1157 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1158 assert( 1159 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1160 "Additional reduction info may be specified only for reduction items."); 1161 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1162 assert(ReductionData.ReductionRange.isInvalid() && 1163 getTopOfStack().Directive == OMPD_taskgroup && 1164 "Additional reduction info may be specified only once for reduction " 1165 "items."); 1166 ReductionData.set(ReductionRef, SR); 1167 Expr *&TaskgroupReductionRef = 1168 getTopOfStack().TaskgroupReductionRef; 1169 if (!TaskgroupReductionRef) { 1170 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1171 SemaRef.Context.VoidPtrTy, ".task_red."); 1172 TaskgroupReductionRef = 1173 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1174 } 1175 } 1176 1177 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1178 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1179 Expr *&TaskgroupDescriptor) const { 1180 D = getCanonicalDecl(D); 1181 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1182 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1183 const DSAInfo &Data = I->SharingMap.lookup(D); 1184 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1185 continue; 1186 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1187 if (!ReductionData.ReductionOp || 1188 ReductionData.ReductionOp.is<const Expr *>()) 1189 return DSAVarData(); 1190 SR = ReductionData.ReductionRange; 1191 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1192 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1193 "expression for the descriptor is not " 1194 "set."); 1195 TaskgroupDescriptor = I->TaskgroupReductionRef; 1196 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1197 Data.PrivateCopy, I->DefaultAttrLoc); 1198 } 1199 return DSAVarData(); 1200 } 1201 1202 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1203 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1204 Expr *&TaskgroupDescriptor) const { 1205 D = getCanonicalDecl(D); 1206 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1207 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1208 const DSAInfo &Data = I->SharingMap.lookup(D); 1209 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1210 continue; 1211 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1212 if (!ReductionData.ReductionOp || 1213 !ReductionData.ReductionOp.is<const Expr *>()) 1214 return DSAVarData(); 1215 SR = ReductionData.ReductionRange; 1216 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1217 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1218 "expression for the descriptor is not " 1219 "set."); 1220 TaskgroupDescriptor = I->TaskgroupReductionRef; 1221 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1222 Data.PrivateCopy, I->DefaultAttrLoc); 1223 } 1224 return DSAVarData(); 1225 } 1226 1227 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1228 D = D->getCanonicalDecl(); 1229 for (const_iterator E = end(); I != E; ++I) { 1230 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1231 isOpenMPTargetExecutionDirective(I->Directive)) { 1232 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1233 Scope *CurScope = getCurScope(); 1234 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1235 CurScope = CurScope->getParent(); 1236 return CurScope != TopScope; 1237 } 1238 } 1239 return false; 1240 } 1241 1242 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1243 bool AcceptIfMutable = true, 1244 bool *IsClassType = nullptr) { 1245 ASTContext &Context = SemaRef.getASTContext(); 1246 Type = Type.getNonReferenceType().getCanonicalType(); 1247 bool IsConstant = Type.isConstant(Context); 1248 Type = Context.getBaseElementType(Type); 1249 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1250 ? Type->getAsCXXRecordDecl() 1251 : nullptr; 1252 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1253 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1254 RD = CTD->getTemplatedDecl(); 1255 if (IsClassType) 1256 *IsClassType = RD; 1257 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1258 RD->hasDefinition() && RD->hasMutableFields()); 1259 } 1260 1261 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1262 QualType Type, OpenMPClauseKind CKind, 1263 SourceLocation ELoc, 1264 bool AcceptIfMutable = true, 1265 bool ListItemNotVar = false) { 1266 ASTContext &Context = SemaRef.getASTContext(); 1267 bool IsClassType; 1268 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1269 unsigned Diag = ListItemNotVar 1270 ? diag::err_omp_const_list_item 1271 : IsClassType ? diag::err_omp_const_not_mutable_variable 1272 : diag::err_omp_const_variable; 1273 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1274 if (!ListItemNotVar && D) { 1275 const VarDecl *VD = dyn_cast<VarDecl>(D); 1276 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1277 VarDecl::DeclarationOnly; 1278 SemaRef.Diag(D->getLocation(), 1279 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1280 << D; 1281 } 1282 return true; 1283 } 1284 return false; 1285 } 1286 1287 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1288 bool FromParent) { 1289 D = getCanonicalDecl(D); 1290 DSAVarData DVar; 1291 1292 auto *VD = dyn_cast<VarDecl>(D); 1293 auto TI = Threadprivates.find(D); 1294 if (TI != Threadprivates.end()) { 1295 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1296 DVar.CKind = OMPC_threadprivate; 1297 return DVar; 1298 } 1299 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1300 DVar.RefExpr = buildDeclRefExpr( 1301 SemaRef, VD, D->getType().getNonReferenceType(), 1302 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1303 DVar.CKind = OMPC_threadprivate; 1304 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1305 return DVar; 1306 } 1307 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1308 // in a Construct, C/C++, predetermined, p.1] 1309 // Variables appearing in threadprivate directives are threadprivate. 1310 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1311 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1312 SemaRef.getLangOpts().OpenMPUseTLS && 1313 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1314 (VD && VD->getStorageClass() == SC_Register && 1315 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1316 DVar.RefExpr = buildDeclRefExpr( 1317 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1318 DVar.CKind = OMPC_threadprivate; 1319 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1320 return DVar; 1321 } 1322 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1323 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1324 !isLoopControlVariable(D).first) { 1325 const_iterator IterTarget = 1326 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1327 return isOpenMPTargetExecutionDirective(Data.Directive); 1328 }); 1329 if (IterTarget != end()) { 1330 const_iterator ParentIterTarget = IterTarget + 1; 1331 for (const_iterator Iter = begin(); 1332 Iter != ParentIterTarget; ++Iter) { 1333 if (isOpenMPLocal(VD, Iter)) { 1334 DVar.RefExpr = 1335 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1336 D->getLocation()); 1337 DVar.CKind = OMPC_threadprivate; 1338 return DVar; 1339 } 1340 } 1341 if (!isClauseParsingMode() || IterTarget != begin()) { 1342 auto DSAIter = IterTarget->SharingMap.find(D); 1343 if (DSAIter != IterTarget->SharingMap.end() && 1344 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1345 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1346 DVar.CKind = OMPC_threadprivate; 1347 return DVar; 1348 } 1349 const_iterator End = end(); 1350 if (!SemaRef.isOpenMPCapturedByRef( 1351 D, std::distance(ParentIterTarget, End), 1352 /*OpenMPCaptureLevel=*/0)) { 1353 DVar.RefExpr = 1354 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1355 IterTarget->ConstructLoc); 1356 DVar.CKind = OMPC_threadprivate; 1357 return DVar; 1358 } 1359 } 1360 } 1361 } 1362 1363 if (isStackEmpty()) 1364 // Not in OpenMP execution region and top scope was already checked. 1365 return DVar; 1366 1367 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1368 // in a Construct, C/C++, predetermined, p.4] 1369 // Static data members are shared. 1370 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1371 // in a Construct, C/C++, predetermined, p.7] 1372 // Variables with static storage duration that are declared in a scope 1373 // inside the construct are shared. 1374 if (VD && VD->isStaticDataMember()) { 1375 // Check for explicitly specified attributes. 1376 const_iterator I = begin(); 1377 const_iterator EndI = end(); 1378 if (FromParent && I != EndI) 1379 ++I; 1380 auto It = I->SharingMap.find(D); 1381 if (It != I->SharingMap.end()) { 1382 const DSAInfo &Data = It->getSecond(); 1383 DVar.RefExpr = Data.RefExpr.getPointer(); 1384 DVar.PrivateCopy = Data.PrivateCopy; 1385 DVar.CKind = Data.Attributes; 1386 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1387 DVar.DKind = I->Directive; 1388 return DVar; 1389 } 1390 1391 DVar.CKind = OMPC_shared; 1392 return DVar; 1393 } 1394 1395 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1396 // The predetermined shared attribute for const-qualified types having no 1397 // mutable members was removed after OpenMP 3.1. 1398 if (SemaRef.LangOpts.OpenMP <= 31) { 1399 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1400 // in a Construct, C/C++, predetermined, p.6] 1401 // Variables with const qualified type having no mutable member are 1402 // shared. 1403 if (isConstNotMutableType(SemaRef, D->getType())) { 1404 // Variables with const-qualified type having no mutable member may be 1405 // listed in a firstprivate clause, even if they are static data members. 1406 DSAVarData DVarTemp = hasInnermostDSA( 1407 D, 1408 [](OpenMPClauseKind C) { 1409 return C == OMPC_firstprivate || C == OMPC_shared; 1410 }, 1411 MatchesAlways, FromParent); 1412 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1413 return DVarTemp; 1414 1415 DVar.CKind = OMPC_shared; 1416 return DVar; 1417 } 1418 } 1419 1420 // Explicitly specified attributes and local variables with predetermined 1421 // attributes. 1422 const_iterator I = begin(); 1423 const_iterator EndI = end(); 1424 if (FromParent && I != EndI) 1425 ++I; 1426 auto It = I->SharingMap.find(D); 1427 if (It != I->SharingMap.end()) { 1428 const DSAInfo &Data = It->getSecond(); 1429 DVar.RefExpr = Data.RefExpr.getPointer(); 1430 DVar.PrivateCopy = Data.PrivateCopy; 1431 DVar.CKind = Data.Attributes; 1432 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1433 DVar.DKind = I->Directive; 1434 } 1435 1436 return DVar; 1437 } 1438 1439 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1440 bool FromParent) const { 1441 if (isStackEmpty()) { 1442 const_iterator I; 1443 return getDSA(I, D); 1444 } 1445 D = getCanonicalDecl(D); 1446 const_iterator StartI = begin(); 1447 const_iterator EndI = end(); 1448 if (FromParent && StartI != EndI) 1449 ++StartI; 1450 return getDSA(StartI, D); 1451 } 1452 1453 const DSAStackTy::DSAVarData 1454 DSAStackTy::hasDSA(ValueDecl *D, 1455 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1456 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1457 bool FromParent) const { 1458 if (isStackEmpty()) 1459 return {}; 1460 D = getCanonicalDecl(D); 1461 const_iterator I = begin(); 1462 const_iterator EndI = end(); 1463 if (FromParent && I != EndI) 1464 ++I; 1465 for (; I != EndI; ++I) { 1466 if (!DPred(I->Directive) && 1467 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1468 continue; 1469 const_iterator NewI = I; 1470 DSAVarData DVar = getDSA(NewI, D); 1471 if (I == NewI && CPred(DVar.CKind)) 1472 return DVar; 1473 } 1474 return {}; 1475 } 1476 1477 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1478 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1479 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1480 bool FromParent) const { 1481 if (isStackEmpty()) 1482 return {}; 1483 D = getCanonicalDecl(D); 1484 const_iterator StartI = begin(); 1485 const_iterator EndI = end(); 1486 if (FromParent && StartI != EndI) 1487 ++StartI; 1488 if (StartI == EndI || !DPred(StartI->Directive)) 1489 return {}; 1490 const_iterator NewI = StartI; 1491 DSAVarData DVar = getDSA(NewI, D); 1492 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1493 } 1494 1495 bool DSAStackTy::hasExplicitDSA( 1496 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1497 unsigned Level, bool NotLastprivate) const { 1498 if (getStackSize() <= Level) 1499 return false; 1500 D = getCanonicalDecl(D); 1501 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1502 auto I = StackElem.SharingMap.find(D); 1503 if (I != StackElem.SharingMap.end() && 1504 I->getSecond().RefExpr.getPointer() && 1505 CPred(I->getSecond().Attributes) && 1506 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1507 return true; 1508 // Check predetermined rules for the loop control variables. 1509 auto LI = StackElem.LCVMap.find(D); 1510 if (LI != StackElem.LCVMap.end()) 1511 return CPred(OMPC_private); 1512 return false; 1513 } 1514 1515 bool DSAStackTy::hasExplicitDirective( 1516 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1517 unsigned Level) const { 1518 if (getStackSize() <= Level) 1519 return false; 1520 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1521 return DPred(StackElem.Directive); 1522 } 1523 1524 bool DSAStackTy::hasDirective( 1525 const llvm::function_ref<bool(OpenMPDirectiveKind, 1526 const DeclarationNameInfo &, SourceLocation)> 1527 DPred, 1528 bool FromParent) const { 1529 // We look only in the enclosing region. 1530 size_t Skip = FromParent ? 2 : 1; 1531 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1532 I != E; ++I) { 1533 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1534 return true; 1535 } 1536 return false; 1537 } 1538 1539 void Sema::InitDataSharingAttributesStack() { 1540 VarDataSharingAttributesStack = new DSAStackTy(*this); 1541 } 1542 1543 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1544 1545 void Sema::pushOpenMPFunctionRegion() { 1546 DSAStack->pushFunction(); 1547 } 1548 1549 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1550 DSAStack->popFunction(OldFSI); 1551 } 1552 1553 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1554 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1555 "Expected OpenMP device compilation."); 1556 return !S.isInOpenMPTargetExecutionDirective() && 1557 !S.isInOpenMPDeclareTargetContext(); 1558 } 1559 1560 namespace { 1561 /// Status of the function emission on the host/device. 1562 enum class FunctionEmissionStatus { 1563 Emitted, 1564 Discarded, 1565 Unknown, 1566 }; 1567 } // anonymous namespace 1568 1569 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1570 unsigned DiagID) { 1571 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1572 "Expected OpenMP device compilation."); 1573 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1574 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1575 switch (FES) { 1576 case FunctionEmissionStatus::Emitted: 1577 Kind = DeviceDiagBuilder::K_Immediate; 1578 break; 1579 case FunctionEmissionStatus::Unknown: 1580 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1581 : DeviceDiagBuilder::K_Immediate; 1582 break; 1583 case FunctionEmissionStatus::TemplateDiscarded: 1584 case FunctionEmissionStatus::OMPDiscarded: 1585 Kind = DeviceDiagBuilder::K_Nop; 1586 break; 1587 case FunctionEmissionStatus::CUDADiscarded: 1588 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1589 break; 1590 } 1591 1592 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1593 } 1594 1595 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1596 unsigned DiagID) { 1597 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1598 "Expected OpenMP host compilation."); 1599 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1600 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1601 switch (FES) { 1602 case FunctionEmissionStatus::Emitted: 1603 Kind = DeviceDiagBuilder::K_Immediate; 1604 break; 1605 case FunctionEmissionStatus::Unknown: 1606 Kind = DeviceDiagBuilder::K_Deferred; 1607 break; 1608 case FunctionEmissionStatus::TemplateDiscarded: 1609 case FunctionEmissionStatus::OMPDiscarded: 1610 case FunctionEmissionStatus::CUDADiscarded: 1611 Kind = DeviceDiagBuilder::K_Nop; 1612 break; 1613 } 1614 1615 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1616 } 1617 1618 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1619 bool CheckForDelayedContext) { 1620 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1621 "Expected OpenMP device compilation."); 1622 assert(Callee && "Callee may not be null."); 1623 Callee = Callee->getMostRecentDecl(); 1624 FunctionDecl *Caller = getCurFunctionDecl(); 1625 1626 // host only function are not available on the device. 1627 if (Caller) { 1628 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1629 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1630 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1631 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1632 "CUDADiscarded unexpected in OpenMP device function check"); 1633 if ((CallerS == FunctionEmissionStatus::Emitted || 1634 (!isOpenMPDeviceDelayedContext(*this) && 1635 CallerS == FunctionEmissionStatus::Unknown)) && 1636 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1637 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1638 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1639 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1640 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1641 diag::note_omp_marked_device_type_here) 1642 << HostDevTy; 1643 return; 1644 } 1645 } 1646 // If the caller is known-emitted, mark the callee as known-emitted. 1647 // Otherwise, mark the call in our call graph so we can traverse it later. 1648 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1649 (!Caller && !CheckForDelayedContext) || 1650 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1651 markKnownEmitted(*this, Caller, Callee, Loc, 1652 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1653 return CheckForDelayedContext && 1654 S.getEmissionStatus(FD) == 1655 FunctionEmissionStatus::Emitted; 1656 }); 1657 else if (Caller) 1658 DeviceCallGraph[Caller].insert({Callee, Loc}); 1659 } 1660 1661 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1662 bool CheckCaller) { 1663 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1664 "Expected OpenMP host compilation."); 1665 assert(Callee && "Callee may not be null."); 1666 Callee = Callee->getMostRecentDecl(); 1667 FunctionDecl *Caller = getCurFunctionDecl(); 1668 1669 // device only function are not available on the host. 1670 if (Caller) { 1671 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1672 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1673 assert( 1674 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1675 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1676 "CUDADiscarded unexpected in OpenMP host function check"); 1677 if (CallerS == FunctionEmissionStatus::Emitted && 1678 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1679 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1680 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1681 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1682 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1683 diag::note_omp_marked_device_type_here) 1684 << NoHostDevTy; 1685 return; 1686 } 1687 } 1688 // If the caller is known-emitted, mark the callee as known-emitted. 1689 // Otherwise, mark the call in our call graph so we can traverse it later. 1690 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1691 if ((!CheckCaller && !Caller) || 1692 (Caller && 1693 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1694 markKnownEmitted( 1695 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1696 return CheckCaller && 1697 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1698 }); 1699 else if (Caller) 1700 DeviceCallGraph[Caller].insert({Callee, Loc}); 1701 } 1702 } 1703 1704 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1705 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1706 "OpenMP device compilation mode is expected."); 1707 QualType Ty = E->getType(); 1708 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1709 ((Ty->isFloat128Type() || 1710 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1711 !Context.getTargetInfo().hasFloat128Type()) || 1712 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1713 !Context.getTargetInfo().hasInt128Type())) 1714 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1715 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1716 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1717 } 1718 1719 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1720 unsigned OpenMPCaptureLevel) const { 1721 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1722 1723 ASTContext &Ctx = getASTContext(); 1724 bool IsByRef = true; 1725 1726 // Find the directive that is associated with the provided scope. 1727 D = cast<ValueDecl>(D->getCanonicalDecl()); 1728 QualType Ty = D->getType(); 1729 1730 bool IsVariableUsedInMapClause = false; 1731 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1732 // This table summarizes how a given variable should be passed to the device 1733 // given its type and the clauses where it appears. This table is based on 1734 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1735 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1736 // 1737 // ========================================================================= 1738 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1739 // | |(tofrom:scalar)| | pvt | | | | 1740 // ========================================================================= 1741 // | scl | | | | - | | bycopy| 1742 // | scl | | - | x | - | - | bycopy| 1743 // | scl | | x | - | - | - | null | 1744 // | scl | x | | | - | | byref | 1745 // | scl | x | - | x | - | - | bycopy| 1746 // | scl | x | x | - | - | - | null | 1747 // | scl | | - | - | - | x | byref | 1748 // | scl | x | - | - | - | x | byref | 1749 // 1750 // | agg | n.a. | | | - | | byref | 1751 // | agg | n.a. | - | x | - | - | byref | 1752 // | agg | n.a. | x | - | - | - | null | 1753 // | agg | n.a. | - | - | - | x | byref | 1754 // | agg | n.a. | - | - | - | x[] | byref | 1755 // 1756 // | ptr | n.a. | | | - | | bycopy| 1757 // | ptr | n.a. | - | x | - | - | bycopy| 1758 // | ptr | n.a. | x | - | - | - | null | 1759 // | ptr | n.a. | - | - | - | x | byref | 1760 // | ptr | n.a. | - | - | - | x[] | bycopy| 1761 // | ptr | n.a. | - | - | x | | bycopy| 1762 // | ptr | n.a. | - | - | x | x | bycopy| 1763 // | ptr | n.a. | - | - | x | x[] | bycopy| 1764 // ========================================================================= 1765 // Legend: 1766 // scl - scalar 1767 // ptr - pointer 1768 // agg - aggregate 1769 // x - applies 1770 // - - invalid in this combination 1771 // [] - mapped with an array section 1772 // byref - should be mapped by reference 1773 // byval - should be mapped by value 1774 // null - initialize a local variable to null on the device 1775 // 1776 // Observations: 1777 // - All scalar declarations that show up in a map clause have to be passed 1778 // by reference, because they may have been mapped in the enclosing data 1779 // environment. 1780 // - If the scalar value does not fit the size of uintptr, it has to be 1781 // passed by reference, regardless the result in the table above. 1782 // - For pointers mapped by value that have either an implicit map or an 1783 // array section, the runtime library may pass the NULL value to the 1784 // device instead of the value passed to it by the compiler. 1785 1786 if (Ty->isReferenceType()) 1787 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1788 1789 // Locate map clauses and see if the variable being captured is referred to 1790 // in any of those clauses. Here we only care about variables, not fields, 1791 // because fields are part of aggregates. 1792 bool IsVariableAssociatedWithSection = false; 1793 1794 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1795 D, Level, 1796 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1797 OMPClauseMappableExprCommon::MappableExprComponentListRef 1798 MapExprComponents, 1799 OpenMPClauseKind WhereFoundClauseKind) { 1800 // Only the map clause information influences how a variable is 1801 // captured. E.g. is_device_ptr does not require changing the default 1802 // behavior. 1803 if (WhereFoundClauseKind != OMPC_map) 1804 return false; 1805 1806 auto EI = MapExprComponents.rbegin(); 1807 auto EE = MapExprComponents.rend(); 1808 1809 assert(EI != EE && "Invalid map expression!"); 1810 1811 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1812 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1813 1814 ++EI; 1815 if (EI == EE) 1816 return false; 1817 1818 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1819 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1820 isa<MemberExpr>(EI->getAssociatedExpression())) { 1821 IsVariableAssociatedWithSection = true; 1822 // There is nothing more we need to know about this variable. 1823 return true; 1824 } 1825 1826 // Keep looking for more map info. 1827 return false; 1828 }); 1829 1830 if (IsVariableUsedInMapClause) { 1831 // If variable is identified in a map clause it is always captured by 1832 // reference except if it is a pointer that is dereferenced somehow. 1833 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1834 } else { 1835 // By default, all the data that has a scalar type is mapped by copy 1836 // (except for reduction variables). 1837 IsByRef = 1838 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1839 !Ty->isAnyPointerType()) || 1840 !Ty->isScalarType() || 1841 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1842 DSAStack->hasExplicitDSA( 1843 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1844 } 1845 } 1846 1847 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1848 IsByRef = 1849 ((IsVariableUsedInMapClause && 1850 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1851 OMPD_target) || 1852 !DSAStack->hasExplicitDSA( 1853 D, 1854 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1855 Level, /*NotLastprivate=*/true)) && 1856 // If the variable is artificial and must be captured by value - try to 1857 // capture by value. 1858 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1859 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1860 } 1861 1862 // When passing data by copy, we need to make sure it fits the uintptr size 1863 // and alignment, because the runtime library only deals with uintptr types. 1864 // If it does not fit the uintptr size, we need to pass the data by reference 1865 // instead. 1866 if (!IsByRef && 1867 (Ctx.getTypeSizeInChars(Ty) > 1868 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1869 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1870 IsByRef = true; 1871 } 1872 1873 return IsByRef; 1874 } 1875 1876 unsigned Sema::getOpenMPNestingLevel() const { 1877 assert(getLangOpts().OpenMP); 1878 return DSAStack->getNestingLevel(); 1879 } 1880 1881 bool Sema::isInOpenMPTargetExecutionDirective() const { 1882 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1883 !DSAStack->isClauseParsingMode()) || 1884 DSAStack->hasDirective( 1885 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1886 SourceLocation) -> bool { 1887 return isOpenMPTargetExecutionDirective(K); 1888 }, 1889 false); 1890 } 1891 1892 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1893 unsigned StopAt) { 1894 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1895 D = getCanonicalDecl(D); 1896 1897 auto *VD = dyn_cast<VarDecl>(D); 1898 // Do not capture constexpr variables. 1899 if (VD && VD->isConstexpr()) 1900 return nullptr; 1901 1902 // If we want to determine whether the variable should be captured from the 1903 // perspective of the current capturing scope, and we've already left all the 1904 // capturing scopes of the top directive on the stack, check from the 1905 // perspective of its parent directive (if any) instead. 1906 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1907 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1908 1909 // If we are attempting to capture a global variable in a directive with 1910 // 'target' we return true so that this global is also mapped to the device. 1911 // 1912 if (VD && !VD->hasLocalStorage() && 1913 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1914 if (isInOpenMPDeclareTargetContext()) { 1915 // Try to mark variable as declare target if it is used in capturing 1916 // regions. 1917 if (LangOpts.OpenMP <= 45 && 1918 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1919 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1920 return nullptr; 1921 } else if (isInOpenMPTargetExecutionDirective()) { 1922 // If the declaration is enclosed in a 'declare target' directive, 1923 // then it should not be captured. 1924 // 1925 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1926 return nullptr; 1927 return VD; 1928 } 1929 } 1930 1931 if (CheckScopeInfo) { 1932 bool OpenMPFound = false; 1933 for (unsigned I = StopAt + 1; I > 0; --I) { 1934 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1935 if(!isa<CapturingScopeInfo>(FSI)) 1936 return nullptr; 1937 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1938 if (RSI->CapRegionKind == CR_OpenMP) { 1939 OpenMPFound = true; 1940 break; 1941 } 1942 } 1943 if (!OpenMPFound) 1944 return nullptr; 1945 } 1946 1947 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1948 (!DSAStack->isClauseParsingMode() || 1949 DSAStack->getParentDirective() != OMPD_unknown)) { 1950 auto &&Info = DSAStack->isLoopControlVariable(D); 1951 if (Info.first || 1952 (VD && VD->hasLocalStorage() && 1953 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1954 (VD && DSAStack->isForceVarCapturing())) 1955 return VD ? VD : Info.second; 1956 DSAStackTy::DSAVarData DVarPrivate = 1957 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1958 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1959 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1960 // Threadprivate variables must not be captured. 1961 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1962 return nullptr; 1963 // The variable is not private or it is the variable in the directive with 1964 // default(none) clause and not used in any clause. 1965 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1966 [](OpenMPDirectiveKind) { return true; }, 1967 DSAStack->isClauseParsingMode()); 1968 if (DVarPrivate.CKind != OMPC_unknown || 1969 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1970 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1971 } 1972 return nullptr; 1973 } 1974 1975 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1976 unsigned Level) const { 1977 SmallVector<OpenMPDirectiveKind, 4> Regions; 1978 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1979 FunctionScopesIndex -= Regions.size(); 1980 } 1981 1982 void Sema::startOpenMPLoop() { 1983 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1984 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1985 DSAStack->loopInit(); 1986 } 1987 1988 void Sema::startOpenMPCXXRangeFor() { 1989 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1990 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1991 DSAStack->resetPossibleLoopCounter(); 1992 DSAStack->loopStart(); 1993 } 1994 } 1995 1996 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1997 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1998 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1999 if (DSAStack->getAssociatedLoops() > 0 && 2000 !DSAStack->isLoopStarted()) { 2001 DSAStack->resetPossibleLoopCounter(D); 2002 DSAStack->loopStart(); 2003 return true; 2004 } 2005 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2006 DSAStack->isLoopControlVariable(D).first) && 2007 !DSAStack->hasExplicitDSA( 2008 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2009 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2010 return true; 2011 } 2012 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2013 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2014 DSAStack->isForceVarCapturing() && 2015 !DSAStack->hasExplicitDSA( 2016 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2017 return true; 2018 } 2019 return DSAStack->hasExplicitDSA( 2020 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2021 (DSAStack->isClauseParsingMode() && 2022 DSAStack->getClauseParsingMode() == OMPC_private) || 2023 // Consider taskgroup reduction descriptor variable a private to avoid 2024 // possible capture in the region. 2025 (DSAStack->hasExplicitDirective( 2026 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2027 Level) && 2028 DSAStack->isTaskgroupReductionRef(D, Level)); 2029 } 2030 2031 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2032 unsigned Level) { 2033 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2034 D = getCanonicalDecl(D); 2035 OpenMPClauseKind OMPC = OMPC_unknown; 2036 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2037 const unsigned NewLevel = I - 1; 2038 if (DSAStack->hasExplicitDSA(D, 2039 [&OMPC](const OpenMPClauseKind K) { 2040 if (isOpenMPPrivate(K)) { 2041 OMPC = K; 2042 return true; 2043 } 2044 return false; 2045 }, 2046 NewLevel)) 2047 break; 2048 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2049 D, NewLevel, 2050 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2051 OpenMPClauseKind) { return true; })) { 2052 OMPC = OMPC_map; 2053 break; 2054 } 2055 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2056 NewLevel)) { 2057 OMPC = OMPC_map; 2058 if (D->getType()->isScalarType() && 2059 DSAStack->getDefaultDMAAtLevel(NewLevel) != 2060 DefaultMapAttributes::DMA_tofrom_scalar) 2061 OMPC = OMPC_firstprivate; 2062 break; 2063 } 2064 } 2065 if (OMPC != OMPC_unknown) 2066 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2067 } 2068 2069 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2070 unsigned Level) const { 2071 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2072 // Return true if the current level is no longer enclosed in a target region. 2073 2074 const auto *VD = dyn_cast<VarDecl>(D); 2075 return VD && !VD->hasLocalStorage() && 2076 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2077 Level); 2078 } 2079 2080 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2081 2082 void Sema::finalizeOpenMPDelayedAnalysis() { 2083 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2084 // Diagnose implicit declare target functions and their callees. 2085 for (const auto &CallerCallees : DeviceCallGraph) { 2086 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2087 OMPDeclareTargetDeclAttr::getDeviceType( 2088 CallerCallees.getFirst()->getMostRecentDecl()); 2089 // Ignore host functions during device analyzis. 2090 if (LangOpts.OpenMPIsDevice && DevTy && 2091 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2092 continue; 2093 // Ignore nohost functions during host analyzis. 2094 if (!LangOpts.OpenMPIsDevice && DevTy && 2095 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2096 continue; 2097 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2098 &Callee : CallerCallees.getSecond()) { 2099 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2100 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2101 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2102 if (LangOpts.OpenMPIsDevice && DevTy && 2103 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2104 // Diagnose host function called during device codegen. 2105 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2106 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2107 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2108 << HostDevTy << 0; 2109 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2110 diag::note_omp_marked_device_type_here) 2111 << HostDevTy; 2112 continue; 2113 } 2114 if (!LangOpts.OpenMPIsDevice && DevTy && 2115 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2116 // Diagnose nohost function called during host codegen. 2117 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2118 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2119 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2120 << NoHostDevTy << 1; 2121 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2122 diag::note_omp_marked_device_type_here) 2123 << NoHostDevTy; 2124 continue; 2125 } 2126 } 2127 } 2128 } 2129 2130 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2131 const DeclarationNameInfo &DirName, 2132 Scope *CurScope, SourceLocation Loc) { 2133 DSAStack->push(DKind, DirName, CurScope, Loc); 2134 PushExpressionEvaluationContext( 2135 ExpressionEvaluationContext::PotentiallyEvaluated); 2136 } 2137 2138 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2139 DSAStack->setClauseParsingMode(K); 2140 } 2141 2142 void Sema::EndOpenMPClause() { 2143 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2144 } 2145 2146 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2147 ArrayRef<OMPClause *> Clauses); 2148 2149 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2150 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2151 // A variable of class type (or array thereof) that appears in a lastprivate 2152 // clause requires an accessible, unambiguous default constructor for the 2153 // class type, unless the list item is also specified in a firstprivate 2154 // clause. 2155 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2156 for (OMPClause *C : D->clauses()) { 2157 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2158 SmallVector<Expr *, 8> PrivateCopies; 2159 for (Expr *DE : Clause->varlists()) { 2160 if (DE->isValueDependent() || DE->isTypeDependent()) { 2161 PrivateCopies.push_back(nullptr); 2162 continue; 2163 } 2164 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2165 auto *VD = cast<VarDecl>(DRE->getDecl()); 2166 QualType Type = VD->getType().getNonReferenceType(); 2167 const DSAStackTy::DSAVarData DVar = 2168 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2169 if (DVar.CKind == OMPC_lastprivate) { 2170 // Generate helper private variable and initialize it with the 2171 // default value. The address of the original variable is replaced 2172 // by the address of the new private variable in CodeGen. This new 2173 // variable is not added to IdResolver, so the code in the OpenMP 2174 // region uses original variable for proper diagnostics. 2175 VarDecl *VDPrivate = buildVarDecl( 2176 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2177 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2178 ActOnUninitializedDecl(VDPrivate); 2179 if (VDPrivate->isInvalidDecl()) { 2180 PrivateCopies.push_back(nullptr); 2181 continue; 2182 } 2183 PrivateCopies.push_back(buildDeclRefExpr( 2184 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2185 } else { 2186 // The variable is also a firstprivate, so initialization sequence 2187 // for private copy is generated already. 2188 PrivateCopies.push_back(nullptr); 2189 } 2190 } 2191 Clause->setPrivateCopies(PrivateCopies); 2192 } 2193 } 2194 // Check allocate clauses. 2195 if (!CurContext->isDependentContext()) 2196 checkAllocateClauses(*this, DSAStack, D->clauses()); 2197 } 2198 2199 DSAStack->pop(); 2200 DiscardCleanupsInEvaluationContext(); 2201 PopExpressionEvaluationContext(); 2202 } 2203 2204 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2205 Expr *NumIterations, Sema &SemaRef, 2206 Scope *S, DSAStackTy *Stack); 2207 2208 namespace { 2209 2210 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2211 private: 2212 Sema &SemaRef; 2213 2214 public: 2215 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2216 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2217 NamedDecl *ND = Candidate.getCorrectionDecl(); 2218 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2219 return VD->hasGlobalStorage() && 2220 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2221 SemaRef.getCurScope()); 2222 } 2223 return false; 2224 } 2225 2226 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2227 return std::make_unique<VarDeclFilterCCC>(*this); 2228 } 2229 2230 }; 2231 2232 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2233 private: 2234 Sema &SemaRef; 2235 2236 public: 2237 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2238 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2239 NamedDecl *ND = Candidate.getCorrectionDecl(); 2240 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2241 isa<FunctionDecl>(ND))) { 2242 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2243 SemaRef.getCurScope()); 2244 } 2245 return false; 2246 } 2247 2248 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2249 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2250 } 2251 }; 2252 2253 } // namespace 2254 2255 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2256 CXXScopeSpec &ScopeSpec, 2257 const DeclarationNameInfo &Id, 2258 OpenMPDirectiveKind Kind) { 2259 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2260 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2261 2262 if (Lookup.isAmbiguous()) 2263 return ExprError(); 2264 2265 VarDecl *VD; 2266 if (!Lookup.isSingleResult()) { 2267 VarDeclFilterCCC CCC(*this); 2268 if (TypoCorrection Corrected = 2269 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2270 CTK_ErrorRecovery)) { 2271 diagnoseTypo(Corrected, 2272 PDiag(Lookup.empty() 2273 ? diag::err_undeclared_var_use_suggest 2274 : diag::err_omp_expected_var_arg_suggest) 2275 << Id.getName()); 2276 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2277 } else { 2278 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2279 : diag::err_omp_expected_var_arg) 2280 << Id.getName(); 2281 return ExprError(); 2282 } 2283 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2284 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2285 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2286 return ExprError(); 2287 } 2288 Lookup.suppressDiagnostics(); 2289 2290 // OpenMP [2.9.2, Syntax, C/C++] 2291 // Variables must be file-scope, namespace-scope, or static block-scope. 2292 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2293 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2294 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2295 bool IsDecl = 2296 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2297 Diag(VD->getLocation(), 2298 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2299 << VD; 2300 return ExprError(); 2301 } 2302 2303 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2304 NamedDecl *ND = CanonicalVD; 2305 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2306 // A threadprivate directive for file-scope variables must appear outside 2307 // any definition or declaration. 2308 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2309 !getCurLexicalContext()->isTranslationUnit()) { 2310 Diag(Id.getLoc(), diag::err_omp_var_scope) 2311 << getOpenMPDirectiveName(Kind) << VD; 2312 bool IsDecl = 2313 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2314 Diag(VD->getLocation(), 2315 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2316 << VD; 2317 return ExprError(); 2318 } 2319 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2320 // A threadprivate directive for static class member variables must appear 2321 // in the class definition, in the same scope in which the member 2322 // variables are declared. 2323 if (CanonicalVD->isStaticDataMember() && 2324 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2325 Diag(Id.getLoc(), diag::err_omp_var_scope) 2326 << getOpenMPDirectiveName(Kind) << VD; 2327 bool IsDecl = 2328 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2329 Diag(VD->getLocation(), 2330 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2331 << VD; 2332 return ExprError(); 2333 } 2334 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2335 // A threadprivate directive for namespace-scope variables must appear 2336 // outside any definition or declaration other than the namespace 2337 // definition itself. 2338 if (CanonicalVD->getDeclContext()->isNamespace() && 2339 (!getCurLexicalContext()->isFileContext() || 2340 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2341 Diag(Id.getLoc(), diag::err_omp_var_scope) 2342 << getOpenMPDirectiveName(Kind) << VD; 2343 bool IsDecl = 2344 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2345 Diag(VD->getLocation(), 2346 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2347 << VD; 2348 return ExprError(); 2349 } 2350 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2351 // A threadprivate directive for static block-scope variables must appear 2352 // in the scope of the variable and not in a nested scope. 2353 if (CanonicalVD->isLocalVarDecl() && CurScope && 2354 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2355 Diag(Id.getLoc(), diag::err_omp_var_scope) 2356 << getOpenMPDirectiveName(Kind) << VD; 2357 bool IsDecl = 2358 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2359 Diag(VD->getLocation(), 2360 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2361 << VD; 2362 return ExprError(); 2363 } 2364 2365 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2366 // A threadprivate directive must lexically precede all references to any 2367 // of the variables in its list. 2368 if (Kind == OMPD_threadprivate && VD->isUsed() && 2369 !DSAStack->isThreadPrivate(VD)) { 2370 Diag(Id.getLoc(), diag::err_omp_var_used) 2371 << getOpenMPDirectiveName(Kind) << VD; 2372 return ExprError(); 2373 } 2374 2375 QualType ExprType = VD->getType().getNonReferenceType(); 2376 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2377 SourceLocation(), VD, 2378 /*RefersToEnclosingVariableOrCapture=*/false, 2379 Id.getLoc(), ExprType, VK_LValue); 2380 } 2381 2382 Sema::DeclGroupPtrTy 2383 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2384 ArrayRef<Expr *> VarList) { 2385 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2386 CurContext->addDecl(D); 2387 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2388 } 2389 return nullptr; 2390 } 2391 2392 namespace { 2393 class LocalVarRefChecker final 2394 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2395 Sema &SemaRef; 2396 2397 public: 2398 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2399 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2400 if (VD->hasLocalStorage()) { 2401 SemaRef.Diag(E->getBeginLoc(), 2402 diag::err_omp_local_var_in_threadprivate_init) 2403 << E->getSourceRange(); 2404 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2405 << VD << VD->getSourceRange(); 2406 return true; 2407 } 2408 } 2409 return false; 2410 } 2411 bool VisitStmt(const Stmt *S) { 2412 for (const Stmt *Child : S->children()) { 2413 if (Child && Visit(Child)) 2414 return true; 2415 } 2416 return false; 2417 } 2418 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2419 }; 2420 } // namespace 2421 2422 OMPThreadPrivateDecl * 2423 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2424 SmallVector<Expr *, 8> Vars; 2425 for (Expr *RefExpr : VarList) { 2426 auto *DE = cast<DeclRefExpr>(RefExpr); 2427 auto *VD = cast<VarDecl>(DE->getDecl()); 2428 SourceLocation ILoc = DE->getExprLoc(); 2429 2430 // Mark variable as used. 2431 VD->setReferenced(); 2432 VD->markUsed(Context); 2433 2434 QualType QType = VD->getType(); 2435 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2436 // It will be analyzed later. 2437 Vars.push_back(DE); 2438 continue; 2439 } 2440 2441 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2442 // A threadprivate variable must not have an incomplete type. 2443 if (RequireCompleteType(ILoc, VD->getType(), 2444 diag::err_omp_threadprivate_incomplete_type)) { 2445 continue; 2446 } 2447 2448 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2449 // A threadprivate variable must not have a reference type. 2450 if (VD->getType()->isReferenceType()) { 2451 Diag(ILoc, diag::err_omp_ref_type_arg) 2452 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2453 bool IsDecl = 2454 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2455 Diag(VD->getLocation(), 2456 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2457 << VD; 2458 continue; 2459 } 2460 2461 // Check if this is a TLS variable. If TLS is not being supported, produce 2462 // the corresponding diagnostic. 2463 if ((VD->getTLSKind() != VarDecl::TLS_None && 2464 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2465 getLangOpts().OpenMPUseTLS && 2466 getASTContext().getTargetInfo().isTLSSupported())) || 2467 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2468 !VD->isLocalVarDecl())) { 2469 Diag(ILoc, diag::err_omp_var_thread_local) 2470 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2471 bool IsDecl = 2472 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2473 Diag(VD->getLocation(), 2474 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2475 << VD; 2476 continue; 2477 } 2478 2479 // Check if initial value of threadprivate variable reference variable with 2480 // local storage (it is not supported by runtime). 2481 if (const Expr *Init = VD->getAnyInitializer()) { 2482 LocalVarRefChecker Checker(*this); 2483 if (Checker.Visit(Init)) 2484 continue; 2485 } 2486 2487 Vars.push_back(RefExpr); 2488 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2489 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2490 Context, SourceRange(Loc, Loc))); 2491 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2492 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2493 } 2494 OMPThreadPrivateDecl *D = nullptr; 2495 if (!Vars.empty()) { 2496 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2497 Vars); 2498 D->setAccess(AS_public); 2499 } 2500 return D; 2501 } 2502 2503 static OMPAllocateDeclAttr::AllocatorTypeTy 2504 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2505 if (!Allocator) 2506 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2507 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2508 Allocator->isInstantiationDependent() || 2509 Allocator->containsUnexpandedParameterPack()) 2510 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2511 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2512 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2513 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2514 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2515 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2516 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2517 llvm::FoldingSetNodeID AEId, DAEId; 2518 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2519 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2520 if (AEId == DAEId) { 2521 AllocatorKindRes = AllocatorKind; 2522 break; 2523 } 2524 } 2525 return AllocatorKindRes; 2526 } 2527 2528 static bool checkPreviousOMPAllocateAttribute( 2529 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2530 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2531 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2532 return false; 2533 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2534 Expr *PrevAllocator = A->getAllocator(); 2535 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2536 getAllocatorKind(S, Stack, PrevAllocator); 2537 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2538 if (AllocatorsMatch && 2539 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2540 Allocator && PrevAllocator) { 2541 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2542 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2543 llvm::FoldingSetNodeID AEId, PAEId; 2544 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2545 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2546 AllocatorsMatch = AEId == PAEId; 2547 } 2548 if (!AllocatorsMatch) { 2549 SmallString<256> AllocatorBuffer; 2550 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2551 if (Allocator) 2552 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2553 SmallString<256> PrevAllocatorBuffer; 2554 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2555 if (PrevAllocator) 2556 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2557 S.getPrintingPolicy()); 2558 2559 SourceLocation AllocatorLoc = 2560 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2561 SourceRange AllocatorRange = 2562 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2563 SourceLocation PrevAllocatorLoc = 2564 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2565 SourceRange PrevAllocatorRange = 2566 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2567 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2568 << (Allocator ? 1 : 0) << AllocatorStream.str() 2569 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2570 << AllocatorRange; 2571 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2572 << PrevAllocatorRange; 2573 return true; 2574 } 2575 return false; 2576 } 2577 2578 static void 2579 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2580 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2581 Expr *Allocator, SourceRange SR) { 2582 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2583 return; 2584 if (Allocator && 2585 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2586 Allocator->isInstantiationDependent() || 2587 Allocator->containsUnexpandedParameterPack())) 2588 return; 2589 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2590 Allocator, SR); 2591 VD->addAttr(A); 2592 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2593 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2594 } 2595 2596 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2597 SourceLocation Loc, ArrayRef<Expr *> VarList, 2598 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2599 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2600 Expr *Allocator = nullptr; 2601 if (Clauses.empty()) { 2602 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2603 // allocate directives that appear in a target region must specify an 2604 // allocator clause unless a requires directive with the dynamic_allocators 2605 // clause is present in the same compilation unit. 2606 if (LangOpts.OpenMPIsDevice && 2607 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2608 targetDiag(Loc, diag::err_expected_allocator_clause); 2609 } else { 2610 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2611 } 2612 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2613 getAllocatorKind(*this, DSAStack, Allocator); 2614 SmallVector<Expr *, 8> Vars; 2615 for (Expr *RefExpr : VarList) { 2616 auto *DE = cast<DeclRefExpr>(RefExpr); 2617 auto *VD = cast<VarDecl>(DE->getDecl()); 2618 2619 // Check if this is a TLS variable or global register. 2620 if (VD->getTLSKind() != VarDecl::TLS_None || 2621 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2622 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2623 !VD->isLocalVarDecl())) 2624 continue; 2625 2626 // If the used several times in the allocate directive, the same allocator 2627 // must be used. 2628 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2629 AllocatorKind, Allocator)) 2630 continue; 2631 2632 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2633 // If a list item has a static storage type, the allocator expression in the 2634 // allocator clause must be a constant expression that evaluates to one of 2635 // the predefined memory allocator values. 2636 if (Allocator && VD->hasGlobalStorage()) { 2637 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2638 Diag(Allocator->getExprLoc(), 2639 diag::err_omp_expected_predefined_allocator) 2640 << Allocator->getSourceRange(); 2641 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2642 VarDecl::DeclarationOnly; 2643 Diag(VD->getLocation(), 2644 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2645 << VD; 2646 continue; 2647 } 2648 } 2649 2650 Vars.push_back(RefExpr); 2651 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2652 DE->getSourceRange()); 2653 } 2654 if (Vars.empty()) 2655 return nullptr; 2656 if (!Owner) 2657 Owner = getCurLexicalContext(); 2658 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2659 D->setAccess(AS_public); 2660 Owner->addDecl(D); 2661 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2662 } 2663 2664 Sema::DeclGroupPtrTy 2665 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2666 ArrayRef<OMPClause *> ClauseList) { 2667 OMPRequiresDecl *D = nullptr; 2668 if (!CurContext->isFileContext()) { 2669 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2670 } else { 2671 D = CheckOMPRequiresDecl(Loc, ClauseList); 2672 if (D) { 2673 CurContext->addDecl(D); 2674 DSAStack->addRequiresDecl(D); 2675 } 2676 } 2677 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2678 } 2679 2680 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2681 ArrayRef<OMPClause *> ClauseList) { 2682 /// For target specific clauses, the requires directive cannot be 2683 /// specified after the handling of any of the target regions in the 2684 /// current compilation unit. 2685 ArrayRef<SourceLocation> TargetLocations = 2686 DSAStack->getEncounteredTargetLocs(); 2687 if (!TargetLocations.empty()) { 2688 for (const OMPClause *CNew : ClauseList) { 2689 // Check if any of the requires clauses affect target regions. 2690 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2691 isa<OMPUnifiedAddressClause>(CNew) || 2692 isa<OMPReverseOffloadClause>(CNew) || 2693 isa<OMPDynamicAllocatorsClause>(CNew)) { 2694 Diag(Loc, diag::err_omp_target_before_requires) 2695 << getOpenMPClauseName(CNew->getClauseKind()); 2696 for (SourceLocation TargetLoc : TargetLocations) { 2697 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2698 } 2699 } 2700 } 2701 } 2702 2703 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2704 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2705 ClauseList); 2706 return nullptr; 2707 } 2708 2709 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2710 const ValueDecl *D, 2711 const DSAStackTy::DSAVarData &DVar, 2712 bool IsLoopIterVar = false) { 2713 if (DVar.RefExpr) { 2714 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2715 << getOpenMPClauseName(DVar.CKind); 2716 return; 2717 } 2718 enum { 2719 PDSA_StaticMemberShared, 2720 PDSA_StaticLocalVarShared, 2721 PDSA_LoopIterVarPrivate, 2722 PDSA_LoopIterVarLinear, 2723 PDSA_LoopIterVarLastprivate, 2724 PDSA_ConstVarShared, 2725 PDSA_GlobalVarShared, 2726 PDSA_TaskVarFirstprivate, 2727 PDSA_LocalVarPrivate, 2728 PDSA_Implicit 2729 } Reason = PDSA_Implicit; 2730 bool ReportHint = false; 2731 auto ReportLoc = D->getLocation(); 2732 auto *VD = dyn_cast<VarDecl>(D); 2733 if (IsLoopIterVar) { 2734 if (DVar.CKind == OMPC_private) 2735 Reason = PDSA_LoopIterVarPrivate; 2736 else if (DVar.CKind == OMPC_lastprivate) 2737 Reason = PDSA_LoopIterVarLastprivate; 2738 else 2739 Reason = PDSA_LoopIterVarLinear; 2740 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2741 DVar.CKind == OMPC_firstprivate) { 2742 Reason = PDSA_TaskVarFirstprivate; 2743 ReportLoc = DVar.ImplicitDSALoc; 2744 } else if (VD && VD->isStaticLocal()) 2745 Reason = PDSA_StaticLocalVarShared; 2746 else if (VD && VD->isStaticDataMember()) 2747 Reason = PDSA_StaticMemberShared; 2748 else if (VD && VD->isFileVarDecl()) 2749 Reason = PDSA_GlobalVarShared; 2750 else if (D->getType().isConstant(SemaRef.getASTContext())) 2751 Reason = PDSA_ConstVarShared; 2752 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2753 ReportHint = true; 2754 Reason = PDSA_LocalVarPrivate; 2755 } 2756 if (Reason != PDSA_Implicit) { 2757 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2758 << Reason << ReportHint 2759 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2760 } else if (DVar.ImplicitDSALoc.isValid()) { 2761 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2762 << getOpenMPClauseName(DVar.CKind); 2763 } 2764 } 2765 2766 namespace { 2767 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2768 DSAStackTy *Stack; 2769 Sema &SemaRef; 2770 bool ErrorFound = false; 2771 bool TryCaptureCXXThisMembers = false; 2772 CapturedStmt *CS = nullptr; 2773 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2774 llvm::SmallVector<Expr *, 4> ImplicitMap; 2775 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2776 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2777 2778 void VisitSubCaptures(OMPExecutableDirective *S) { 2779 // Check implicitly captured variables. 2780 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2781 return; 2782 visitSubCaptures(S->getInnermostCapturedStmt()); 2783 // Try to capture inner this->member references to generate correct mappings 2784 // and diagnostics. 2785 if (TryCaptureCXXThisMembers || 2786 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2787 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2788 [](const CapturedStmt::Capture &C) { 2789 return C.capturesThis(); 2790 }))) { 2791 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2792 TryCaptureCXXThisMembers = true; 2793 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2794 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2795 } 2796 } 2797 2798 public: 2799 void VisitDeclRefExpr(DeclRefExpr *E) { 2800 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 2801 E->isValueDependent() || E->containsUnexpandedParameterPack() || 2802 E->isInstantiationDependent()) 2803 return; 2804 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2805 // Check the datasharing rules for the expressions in the clauses. 2806 if (!CS) { 2807 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2808 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2809 Visit(CED->getInit()); 2810 return; 2811 } 2812 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2813 // Do not analyze internal variables and do not enclose them into 2814 // implicit clauses. 2815 return; 2816 VD = VD->getCanonicalDecl(); 2817 // Skip internally declared variables. 2818 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2819 return; 2820 2821 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2822 // Check if the variable has explicit DSA set and stop analysis if it so. 2823 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2824 return; 2825 2826 // Skip internally declared static variables. 2827 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2828 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2829 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2830 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2831 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2832 return; 2833 2834 SourceLocation ELoc = E->getExprLoc(); 2835 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2836 // The default(none) clause requires that each variable that is referenced 2837 // in the construct, and does not have a predetermined data-sharing 2838 // attribute, must have its data-sharing attribute explicitly determined 2839 // by being listed in a data-sharing attribute clause. 2840 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2841 isImplicitOrExplicitTaskingRegion(DKind) && 2842 VarsWithInheritedDSA.count(VD) == 0) { 2843 VarsWithInheritedDSA[VD] = E; 2844 return; 2845 } 2846 2847 if (isOpenMPTargetExecutionDirective(DKind) && 2848 !Stack->isLoopControlVariable(VD).first) { 2849 if (!Stack->checkMappableExprComponentListsForDecl( 2850 VD, /*CurrentRegionOnly=*/true, 2851 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2852 StackComponents, 2853 OpenMPClauseKind) { 2854 // Variable is used if it has been marked as an array, array 2855 // section or the variable iself. 2856 return StackComponents.size() == 1 || 2857 std::all_of( 2858 std::next(StackComponents.rbegin()), 2859 StackComponents.rend(), 2860 [](const OMPClauseMappableExprCommon:: 2861 MappableComponent &MC) { 2862 return MC.getAssociatedDeclaration() == 2863 nullptr && 2864 (isa<OMPArraySectionExpr>( 2865 MC.getAssociatedExpression()) || 2866 isa<ArraySubscriptExpr>( 2867 MC.getAssociatedExpression())); 2868 }); 2869 })) { 2870 bool IsFirstprivate = false; 2871 // By default lambdas are captured as firstprivates. 2872 if (const auto *RD = 2873 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2874 IsFirstprivate = RD->isLambda(); 2875 IsFirstprivate = 2876 IsFirstprivate || 2877 (VD->getType().getNonReferenceType()->isScalarType() && 2878 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2879 if (IsFirstprivate) 2880 ImplicitFirstprivate.emplace_back(E); 2881 else 2882 ImplicitMap.emplace_back(E); 2883 return; 2884 } 2885 } 2886 2887 // OpenMP [2.9.3.6, Restrictions, p.2] 2888 // A list item that appears in a reduction clause of the innermost 2889 // enclosing worksharing or parallel construct may not be accessed in an 2890 // explicit task. 2891 DVar = Stack->hasInnermostDSA( 2892 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2893 [](OpenMPDirectiveKind K) { 2894 return isOpenMPParallelDirective(K) || 2895 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2896 }, 2897 /*FromParent=*/true); 2898 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2899 ErrorFound = true; 2900 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2901 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2902 return; 2903 } 2904 2905 // Define implicit data-sharing attributes for task. 2906 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2907 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2908 !Stack->isLoopControlVariable(VD).first) { 2909 ImplicitFirstprivate.push_back(E); 2910 return; 2911 } 2912 2913 // Store implicitly used globals with declare target link for parent 2914 // target. 2915 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2916 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2917 Stack->addToParentTargetRegionLinkGlobals(E); 2918 return; 2919 } 2920 } 2921 } 2922 void VisitMemberExpr(MemberExpr *E) { 2923 if (E->isTypeDependent() || E->isValueDependent() || 2924 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2925 return; 2926 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2927 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2928 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2929 if (!FD) 2930 return; 2931 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2932 // Check if the variable has explicit DSA set and stop analysis if it 2933 // so. 2934 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2935 return; 2936 2937 if (isOpenMPTargetExecutionDirective(DKind) && 2938 !Stack->isLoopControlVariable(FD).first && 2939 !Stack->checkMappableExprComponentListsForDecl( 2940 FD, /*CurrentRegionOnly=*/true, 2941 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2942 StackComponents, 2943 OpenMPClauseKind) { 2944 return isa<CXXThisExpr>( 2945 cast<MemberExpr>( 2946 StackComponents.back().getAssociatedExpression()) 2947 ->getBase() 2948 ->IgnoreParens()); 2949 })) { 2950 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2951 // A bit-field cannot appear in a map clause. 2952 // 2953 if (FD->isBitField()) 2954 return; 2955 2956 // Check to see if the member expression is referencing a class that 2957 // has already been explicitly mapped 2958 if (Stack->isClassPreviouslyMapped(TE->getType())) 2959 return; 2960 2961 ImplicitMap.emplace_back(E); 2962 return; 2963 } 2964 2965 SourceLocation ELoc = E->getExprLoc(); 2966 // OpenMP [2.9.3.6, Restrictions, p.2] 2967 // A list item that appears in a reduction clause of the innermost 2968 // enclosing worksharing or parallel construct may not be accessed in 2969 // an explicit task. 2970 DVar = Stack->hasInnermostDSA( 2971 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2972 [](OpenMPDirectiveKind K) { 2973 return isOpenMPParallelDirective(K) || 2974 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2975 }, 2976 /*FromParent=*/true); 2977 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2978 ErrorFound = true; 2979 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2980 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2981 return; 2982 } 2983 2984 // Define implicit data-sharing attributes for task. 2985 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2986 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2987 !Stack->isLoopControlVariable(FD).first) { 2988 // Check if there is a captured expression for the current field in the 2989 // region. Do not mark it as firstprivate unless there is no captured 2990 // expression. 2991 // TODO: try to make it firstprivate. 2992 if (DVar.CKind != OMPC_unknown) 2993 ImplicitFirstprivate.push_back(E); 2994 } 2995 return; 2996 } 2997 if (isOpenMPTargetExecutionDirective(DKind)) { 2998 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2999 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3000 /*NoDiagnose=*/true)) 3001 return; 3002 const auto *VD = cast<ValueDecl>( 3003 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3004 if (!Stack->checkMappableExprComponentListsForDecl( 3005 VD, /*CurrentRegionOnly=*/true, 3006 [&CurComponents]( 3007 OMPClauseMappableExprCommon::MappableExprComponentListRef 3008 StackComponents, 3009 OpenMPClauseKind) { 3010 auto CCI = CurComponents.rbegin(); 3011 auto CCE = CurComponents.rend(); 3012 for (const auto &SC : llvm::reverse(StackComponents)) { 3013 // Do both expressions have the same kind? 3014 if (CCI->getAssociatedExpression()->getStmtClass() != 3015 SC.getAssociatedExpression()->getStmtClass()) 3016 if (!(isa<OMPArraySectionExpr>( 3017 SC.getAssociatedExpression()) && 3018 isa<ArraySubscriptExpr>( 3019 CCI->getAssociatedExpression()))) 3020 return false; 3021 3022 const Decl *CCD = CCI->getAssociatedDeclaration(); 3023 const Decl *SCD = SC.getAssociatedDeclaration(); 3024 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3025 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3026 if (SCD != CCD) 3027 return false; 3028 std::advance(CCI, 1); 3029 if (CCI == CCE) 3030 break; 3031 } 3032 return true; 3033 })) { 3034 Visit(E->getBase()); 3035 } 3036 } else if (!TryCaptureCXXThisMembers) { 3037 Visit(E->getBase()); 3038 } 3039 } 3040 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3041 for (OMPClause *C : S->clauses()) { 3042 // Skip analysis of arguments of implicitly defined firstprivate clause 3043 // for task|target directives. 3044 // Skip analysis of arguments of implicitly defined map clause for target 3045 // directives. 3046 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3047 C->isImplicit())) { 3048 for (Stmt *CC : C->children()) { 3049 if (CC) 3050 Visit(CC); 3051 } 3052 } 3053 } 3054 // Check implicitly captured variables. 3055 VisitSubCaptures(S); 3056 } 3057 void VisitStmt(Stmt *S) { 3058 for (Stmt *C : S->children()) { 3059 if (C) { 3060 // Check implicitly captured variables in the task-based directives to 3061 // check if they must be firstprivatized. 3062 Visit(C); 3063 } 3064 } 3065 } 3066 3067 void visitSubCaptures(CapturedStmt *S) { 3068 for (const CapturedStmt::Capture &Cap : S->captures()) { 3069 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3070 continue; 3071 VarDecl *VD = Cap.getCapturedVar(); 3072 // Do not try to map the variable if it or its sub-component was mapped 3073 // already. 3074 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3075 Stack->checkMappableExprComponentListsForDecl( 3076 VD, /*CurrentRegionOnly=*/true, 3077 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3078 OpenMPClauseKind) { return true; })) 3079 continue; 3080 DeclRefExpr *DRE = buildDeclRefExpr( 3081 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3082 Cap.getLocation(), /*RefersToCapture=*/true); 3083 Visit(DRE); 3084 } 3085 } 3086 bool isErrorFound() const { return ErrorFound; } 3087 ArrayRef<Expr *> getImplicitFirstprivate() const { 3088 return ImplicitFirstprivate; 3089 } 3090 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 3091 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3092 return VarsWithInheritedDSA; 3093 } 3094 3095 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3096 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3097 // Process declare target link variables for the target directives. 3098 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3099 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3100 Visit(E); 3101 } 3102 } 3103 }; 3104 } // namespace 3105 3106 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3107 switch (DKind) { 3108 case OMPD_parallel: 3109 case OMPD_parallel_for: 3110 case OMPD_parallel_for_simd: 3111 case OMPD_parallel_sections: 3112 case OMPD_teams: 3113 case OMPD_teams_distribute: 3114 case OMPD_teams_distribute_simd: { 3115 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3116 QualType KmpInt32PtrTy = 3117 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3118 Sema::CapturedParamNameType Params[] = { 3119 std::make_pair(".global_tid.", KmpInt32PtrTy), 3120 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3121 std::make_pair(StringRef(), QualType()) // __context with shared vars 3122 }; 3123 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3124 Params); 3125 break; 3126 } 3127 case OMPD_target_teams: 3128 case OMPD_target_parallel: 3129 case OMPD_target_parallel_for: 3130 case OMPD_target_parallel_for_simd: 3131 case OMPD_target_teams_distribute: 3132 case OMPD_target_teams_distribute_simd: { 3133 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3134 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3135 QualType KmpInt32PtrTy = 3136 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3137 QualType Args[] = {VoidPtrTy}; 3138 FunctionProtoType::ExtProtoInfo EPI; 3139 EPI.Variadic = true; 3140 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3141 Sema::CapturedParamNameType Params[] = { 3142 std::make_pair(".global_tid.", KmpInt32Ty), 3143 std::make_pair(".part_id.", KmpInt32PtrTy), 3144 std::make_pair(".privates.", VoidPtrTy), 3145 std::make_pair( 3146 ".copy_fn.", 3147 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3148 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3149 std::make_pair(StringRef(), QualType()) // __context with shared vars 3150 }; 3151 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3152 Params, /*OpenMPCaptureLevel=*/0); 3153 // Mark this captured region as inlined, because we don't use outlined 3154 // function directly. 3155 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3156 AlwaysInlineAttr::CreateImplicit( 3157 Context, {}, AttributeCommonInfo::AS_Keyword, 3158 AlwaysInlineAttr::Keyword_forceinline)); 3159 Sema::CapturedParamNameType ParamsTarget[] = { 3160 std::make_pair(StringRef(), QualType()) // __context with shared vars 3161 }; 3162 // Start a captured region for 'target' with no implicit parameters. 3163 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3164 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3165 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3166 std::make_pair(".global_tid.", KmpInt32PtrTy), 3167 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3168 std::make_pair(StringRef(), QualType()) // __context with shared vars 3169 }; 3170 // Start a captured region for 'teams' or 'parallel'. Both regions have 3171 // the same implicit parameters. 3172 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3173 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3174 break; 3175 } 3176 case OMPD_target: 3177 case OMPD_target_simd: { 3178 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3179 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3180 QualType KmpInt32PtrTy = 3181 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3182 QualType Args[] = {VoidPtrTy}; 3183 FunctionProtoType::ExtProtoInfo EPI; 3184 EPI.Variadic = true; 3185 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3186 Sema::CapturedParamNameType Params[] = { 3187 std::make_pair(".global_tid.", KmpInt32Ty), 3188 std::make_pair(".part_id.", KmpInt32PtrTy), 3189 std::make_pair(".privates.", VoidPtrTy), 3190 std::make_pair( 3191 ".copy_fn.", 3192 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3193 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3194 std::make_pair(StringRef(), QualType()) // __context with shared vars 3195 }; 3196 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3197 Params, /*OpenMPCaptureLevel=*/0); 3198 // Mark this captured region as inlined, because we don't use outlined 3199 // function directly. 3200 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3201 AlwaysInlineAttr::CreateImplicit( 3202 Context, {}, AttributeCommonInfo::AS_Keyword, 3203 AlwaysInlineAttr::Keyword_forceinline)); 3204 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3205 std::make_pair(StringRef(), QualType()), 3206 /*OpenMPCaptureLevel=*/1); 3207 break; 3208 } 3209 case OMPD_simd: 3210 case OMPD_for: 3211 case OMPD_for_simd: 3212 case OMPD_sections: 3213 case OMPD_section: 3214 case OMPD_single: 3215 case OMPD_master: 3216 case OMPD_critical: 3217 case OMPD_taskgroup: 3218 case OMPD_distribute: 3219 case OMPD_distribute_simd: 3220 case OMPD_ordered: 3221 case OMPD_atomic: 3222 case OMPD_target_data: { 3223 Sema::CapturedParamNameType Params[] = { 3224 std::make_pair(StringRef(), QualType()) // __context with shared vars 3225 }; 3226 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3227 Params); 3228 break; 3229 } 3230 case OMPD_task: { 3231 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3232 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3233 QualType KmpInt32PtrTy = 3234 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3235 QualType Args[] = {VoidPtrTy}; 3236 FunctionProtoType::ExtProtoInfo EPI; 3237 EPI.Variadic = true; 3238 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3239 Sema::CapturedParamNameType Params[] = { 3240 std::make_pair(".global_tid.", KmpInt32Ty), 3241 std::make_pair(".part_id.", KmpInt32PtrTy), 3242 std::make_pair(".privates.", VoidPtrTy), 3243 std::make_pair( 3244 ".copy_fn.", 3245 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3246 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3247 std::make_pair(StringRef(), QualType()) // __context with shared vars 3248 }; 3249 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3250 Params); 3251 // Mark this captured region as inlined, because we don't use outlined 3252 // function directly. 3253 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3254 AlwaysInlineAttr::CreateImplicit( 3255 Context, {}, AttributeCommonInfo::AS_Keyword, 3256 AlwaysInlineAttr::Keyword_forceinline)); 3257 break; 3258 } 3259 case OMPD_taskloop: 3260 case OMPD_taskloop_simd: 3261 case OMPD_master_taskloop: 3262 case OMPD_master_taskloop_simd: { 3263 QualType KmpInt32Ty = 3264 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3265 .withConst(); 3266 QualType KmpUInt64Ty = 3267 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3268 .withConst(); 3269 QualType KmpInt64Ty = 3270 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3271 .withConst(); 3272 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3273 QualType KmpInt32PtrTy = 3274 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3275 QualType Args[] = {VoidPtrTy}; 3276 FunctionProtoType::ExtProtoInfo EPI; 3277 EPI.Variadic = true; 3278 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3279 Sema::CapturedParamNameType Params[] = { 3280 std::make_pair(".global_tid.", KmpInt32Ty), 3281 std::make_pair(".part_id.", KmpInt32PtrTy), 3282 std::make_pair(".privates.", VoidPtrTy), 3283 std::make_pair( 3284 ".copy_fn.", 3285 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3286 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3287 std::make_pair(".lb.", KmpUInt64Ty), 3288 std::make_pair(".ub.", KmpUInt64Ty), 3289 std::make_pair(".st.", KmpInt64Ty), 3290 std::make_pair(".liter.", KmpInt32Ty), 3291 std::make_pair(".reductions.", VoidPtrTy), 3292 std::make_pair(StringRef(), QualType()) // __context with shared vars 3293 }; 3294 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3295 Params); 3296 // Mark this captured region as inlined, because we don't use outlined 3297 // function directly. 3298 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3299 AlwaysInlineAttr::CreateImplicit( 3300 Context, {}, AttributeCommonInfo::AS_Keyword, 3301 AlwaysInlineAttr::Keyword_forceinline)); 3302 break; 3303 } 3304 case OMPD_parallel_master_taskloop: 3305 case OMPD_parallel_master_taskloop_simd: { 3306 QualType KmpInt32Ty = 3307 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3308 .withConst(); 3309 QualType KmpUInt64Ty = 3310 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3311 .withConst(); 3312 QualType KmpInt64Ty = 3313 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3314 .withConst(); 3315 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3316 QualType KmpInt32PtrTy = 3317 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3318 Sema::CapturedParamNameType ParamsParallel[] = { 3319 std::make_pair(".global_tid.", KmpInt32PtrTy), 3320 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3321 std::make_pair(StringRef(), QualType()) // __context with shared vars 3322 }; 3323 // Start a captured region for 'parallel'. 3324 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3325 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3326 QualType Args[] = {VoidPtrTy}; 3327 FunctionProtoType::ExtProtoInfo EPI; 3328 EPI.Variadic = true; 3329 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3330 Sema::CapturedParamNameType Params[] = { 3331 std::make_pair(".global_tid.", KmpInt32Ty), 3332 std::make_pair(".part_id.", KmpInt32PtrTy), 3333 std::make_pair(".privates.", VoidPtrTy), 3334 std::make_pair( 3335 ".copy_fn.", 3336 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3337 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3338 std::make_pair(".lb.", KmpUInt64Ty), 3339 std::make_pair(".ub.", KmpUInt64Ty), 3340 std::make_pair(".st.", KmpInt64Ty), 3341 std::make_pair(".liter.", KmpInt32Ty), 3342 std::make_pair(".reductions.", VoidPtrTy), 3343 std::make_pair(StringRef(), QualType()) // __context with shared vars 3344 }; 3345 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3346 Params, /*OpenMPCaptureLevel=*/2); 3347 // Mark this captured region as inlined, because we don't use outlined 3348 // function directly. 3349 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3350 AlwaysInlineAttr::CreateImplicit( 3351 Context, {}, AttributeCommonInfo::AS_Keyword, 3352 AlwaysInlineAttr::Keyword_forceinline)); 3353 break; 3354 } 3355 case OMPD_distribute_parallel_for_simd: 3356 case OMPD_distribute_parallel_for: { 3357 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3358 QualType KmpInt32PtrTy = 3359 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3360 Sema::CapturedParamNameType Params[] = { 3361 std::make_pair(".global_tid.", KmpInt32PtrTy), 3362 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3363 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3364 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3365 std::make_pair(StringRef(), QualType()) // __context with shared vars 3366 }; 3367 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3368 Params); 3369 break; 3370 } 3371 case OMPD_target_teams_distribute_parallel_for: 3372 case OMPD_target_teams_distribute_parallel_for_simd: { 3373 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3374 QualType KmpInt32PtrTy = 3375 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3376 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3377 3378 QualType Args[] = {VoidPtrTy}; 3379 FunctionProtoType::ExtProtoInfo EPI; 3380 EPI.Variadic = true; 3381 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3382 Sema::CapturedParamNameType Params[] = { 3383 std::make_pair(".global_tid.", KmpInt32Ty), 3384 std::make_pair(".part_id.", KmpInt32PtrTy), 3385 std::make_pair(".privates.", VoidPtrTy), 3386 std::make_pair( 3387 ".copy_fn.", 3388 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3389 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3390 std::make_pair(StringRef(), QualType()) // __context with shared vars 3391 }; 3392 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3393 Params, /*OpenMPCaptureLevel=*/0); 3394 // Mark this captured region as inlined, because we don't use outlined 3395 // function directly. 3396 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3397 AlwaysInlineAttr::CreateImplicit( 3398 Context, {}, AttributeCommonInfo::AS_Keyword, 3399 AlwaysInlineAttr::Keyword_forceinline)); 3400 Sema::CapturedParamNameType ParamsTarget[] = { 3401 std::make_pair(StringRef(), QualType()) // __context with shared vars 3402 }; 3403 // Start a captured region for 'target' with no implicit parameters. 3404 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3405 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3406 3407 Sema::CapturedParamNameType ParamsTeams[] = { 3408 std::make_pair(".global_tid.", KmpInt32PtrTy), 3409 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3410 std::make_pair(StringRef(), QualType()) // __context with shared vars 3411 }; 3412 // Start a captured region for 'target' with no implicit parameters. 3413 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3414 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3415 3416 Sema::CapturedParamNameType ParamsParallel[] = { 3417 std::make_pair(".global_tid.", KmpInt32PtrTy), 3418 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3419 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3420 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3421 std::make_pair(StringRef(), QualType()) // __context with shared vars 3422 }; 3423 // Start a captured region for 'teams' or 'parallel'. Both regions have 3424 // the same implicit parameters. 3425 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3426 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3427 break; 3428 } 3429 3430 case OMPD_teams_distribute_parallel_for: 3431 case OMPD_teams_distribute_parallel_for_simd: { 3432 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3433 QualType KmpInt32PtrTy = 3434 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3435 3436 Sema::CapturedParamNameType ParamsTeams[] = { 3437 std::make_pair(".global_tid.", KmpInt32PtrTy), 3438 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3439 std::make_pair(StringRef(), QualType()) // __context with shared vars 3440 }; 3441 // Start a captured region for 'target' with no implicit parameters. 3442 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3443 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3444 3445 Sema::CapturedParamNameType ParamsParallel[] = { 3446 std::make_pair(".global_tid.", KmpInt32PtrTy), 3447 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3448 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3449 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3450 std::make_pair(StringRef(), QualType()) // __context with shared vars 3451 }; 3452 // Start a captured region for 'teams' or 'parallel'. Both regions have 3453 // the same implicit parameters. 3454 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3455 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3456 break; 3457 } 3458 case OMPD_target_update: 3459 case OMPD_target_enter_data: 3460 case OMPD_target_exit_data: { 3461 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3462 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3463 QualType KmpInt32PtrTy = 3464 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3465 QualType Args[] = {VoidPtrTy}; 3466 FunctionProtoType::ExtProtoInfo EPI; 3467 EPI.Variadic = true; 3468 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3469 Sema::CapturedParamNameType Params[] = { 3470 std::make_pair(".global_tid.", KmpInt32Ty), 3471 std::make_pair(".part_id.", KmpInt32PtrTy), 3472 std::make_pair(".privates.", VoidPtrTy), 3473 std::make_pair( 3474 ".copy_fn.", 3475 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3476 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3477 std::make_pair(StringRef(), QualType()) // __context with shared vars 3478 }; 3479 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3480 Params); 3481 // Mark this captured region as inlined, because we don't use outlined 3482 // function directly. 3483 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3484 AlwaysInlineAttr::CreateImplicit( 3485 Context, {}, AttributeCommonInfo::AS_Keyword, 3486 AlwaysInlineAttr::Keyword_forceinline)); 3487 break; 3488 } 3489 case OMPD_threadprivate: 3490 case OMPD_allocate: 3491 case OMPD_taskyield: 3492 case OMPD_barrier: 3493 case OMPD_taskwait: 3494 case OMPD_cancellation_point: 3495 case OMPD_cancel: 3496 case OMPD_flush: 3497 case OMPD_declare_reduction: 3498 case OMPD_declare_mapper: 3499 case OMPD_declare_simd: 3500 case OMPD_declare_target: 3501 case OMPD_end_declare_target: 3502 case OMPD_requires: 3503 case OMPD_declare_variant: 3504 llvm_unreachable("OpenMP Directive is not allowed"); 3505 case OMPD_unknown: 3506 llvm_unreachable("Unknown OpenMP directive"); 3507 } 3508 } 3509 3510 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3511 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3512 } 3513 3514 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3515 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3516 getOpenMPCaptureRegions(CaptureRegions, DKind); 3517 return CaptureRegions.size(); 3518 } 3519 3520 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3521 Expr *CaptureExpr, bool WithInit, 3522 bool AsExpression) { 3523 assert(CaptureExpr); 3524 ASTContext &C = S.getASTContext(); 3525 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3526 QualType Ty = Init->getType(); 3527 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3528 if (S.getLangOpts().CPlusPlus) { 3529 Ty = C.getLValueReferenceType(Ty); 3530 } else { 3531 Ty = C.getPointerType(Ty); 3532 ExprResult Res = 3533 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3534 if (!Res.isUsable()) 3535 return nullptr; 3536 Init = Res.get(); 3537 } 3538 WithInit = true; 3539 } 3540 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3541 CaptureExpr->getBeginLoc()); 3542 if (!WithInit) 3543 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3544 S.CurContext->addHiddenDecl(CED); 3545 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3546 return CED; 3547 } 3548 3549 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3550 bool WithInit) { 3551 OMPCapturedExprDecl *CD; 3552 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3553 CD = cast<OMPCapturedExprDecl>(VD); 3554 else 3555 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3556 /*AsExpression=*/false); 3557 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3558 CaptureExpr->getExprLoc()); 3559 } 3560 3561 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3562 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3563 if (!Ref) { 3564 OMPCapturedExprDecl *CD = buildCaptureDecl( 3565 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3566 /*WithInit=*/true, /*AsExpression=*/true); 3567 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3568 CaptureExpr->getExprLoc()); 3569 } 3570 ExprResult Res = Ref; 3571 if (!S.getLangOpts().CPlusPlus && 3572 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3573 Ref->getType()->isPointerType()) { 3574 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3575 if (!Res.isUsable()) 3576 return ExprError(); 3577 } 3578 return S.DefaultLvalueConversion(Res.get()); 3579 } 3580 3581 namespace { 3582 // OpenMP directives parsed in this section are represented as a 3583 // CapturedStatement with an associated statement. If a syntax error 3584 // is detected during the parsing of the associated statement, the 3585 // compiler must abort processing and close the CapturedStatement. 3586 // 3587 // Combined directives such as 'target parallel' have more than one 3588 // nested CapturedStatements. This RAII ensures that we unwind out 3589 // of all the nested CapturedStatements when an error is found. 3590 class CaptureRegionUnwinderRAII { 3591 private: 3592 Sema &S; 3593 bool &ErrorFound; 3594 OpenMPDirectiveKind DKind = OMPD_unknown; 3595 3596 public: 3597 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3598 OpenMPDirectiveKind DKind) 3599 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3600 ~CaptureRegionUnwinderRAII() { 3601 if (ErrorFound) { 3602 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3603 while (--ThisCaptureLevel >= 0) 3604 S.ActOnCapturedRegionError(); 3605 } 3606 } 3607 }; 3608 } // namespace 3609 3610 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3611 // Capture variables captured by reference in lambdas for target-based 3612 // directives. 3613 if (!CurContext->isDependentContext() && 3614 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3615 isOpenMPTargetDataManagementDirective( 3616 DSAStack->getCurrentDirective()))) { 3617 QualType Type = V->getType(); 3618 if (const auto *RD = Type.getCanonicalType() 3619 .getNonReferenceType() 3620 ->getAsCXXRecordDecl()) { 3621 bool SavedForceCaptureByReferenceInTargetExecutable = 3622 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3623 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3624 /*V=*/true); 3625 if (RD->isLambda()) { 3626 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3627 FieldDecl *ThisCapture; 3628 RD->getCaptureFields(Captures, ThisCapture); 3629 for (const LambdaCapture &LC : RD->captures()) { 3630 if (LC.getCaptureKind() == LCK_ByRef) { 3631 VarDecl *VD = LC.getCapturedVar(); 3632 DeclContext *VDC = VD->getDeclContext(); 3633 if (!VDC->Encloses(CurContext)) 3634 continue; 3635 MarkVariableReferenced(LC.getLocation(), VD); 3636 } else if (LC.getCaptureKind() == LCK_This) { 3637 QualType ThisTy = getCurrentThisType(); 3638 if (!ThisTy.isNull() && 3639 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3640 CheckCXXThisCapture(LC.getLocation()); 3641 } 3642 } 3643 } 3644 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3645 SavedForceCaptureByReferenceInTargetExecutable); 3646 } 3647 } 3648 } 3649 3650 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3651 ArrayRef<OMPClause *> Clauses) { 3652 bool ErrorFound = false; 3653 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3654 *this, ErrorFound, DSAStack->getCurrentDirective()); 3655 if (!S.isUsable()) { 3656 ErrorFound = true; 3657 return StmtError(); 3658 } 3659 3660 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3661 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3662 OMPOrderedClause *OC = nullptr; 3663 OMPScheduleClause *SC = nullptr; 3664 SmallVector<const OMPLinearClause *, 4> LCs; 3665 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3666 // This is required for proper codegen. 3667 for (OMPClause *Clause : Clauses) { 3668 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3669 Clause->getClauseKind() == OMPC_in_reduction) { 3670 // Capture taskgroup task_reduction descriptors inside the tasking regions 3671 // with the corresponding in_reduction items. 3672 auto *IRC = cast<OMPInReductionClause>(Clause); 3673 for (Expr *E : IRC->taskgroup_descriptors()) 3674 if (E) 3675 MarkDeclarationsReferencedInExpr(E); 3676 } 3677 if (isOpenMPPrivate(Clause->getClauseKind()) || 3678 Clause->getClauseKind() == OMPC_copyprivate || 3679 (getLangOpts().OpenMPUseTLS && 3680 getASTContext().getTargetInfo().isTLSSupported() && 3681 Clause->getClauseKind() == OMPC_copyin)) { 3682 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3683 // Mark all variables in private list clauses as used in inner region. 3684 for (Stmt *VarRef : Clause->children()) { 3685 if (auto *E = cast_or_null<Expr>(VarRef)) { 3686 MarkDeclarationsReferencedInExpr(E); 3687 } 3688 } 3689 DSAStack->setForceVarCapturing(/*V=*/false); 3690 } else if (CaptureRegions.size() > 1 || 3691 CaptureRegions.back() != OMPD_unknown) { 3692 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3693 PICs.push_back(C); 3694 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3695 if (Expr *E = C->getPostUpdateExpr()) 3696 MarkDeclarationsReferencedInExpr(E); 3697 } 3698 } 3699 if (Clause->getClauseKind() == OMPC_schedule) 3700 SC = cast<OMPScheduleClause>(Clause); 3701 else if (Clause->getClauseKind() == OMPC_ordered) 3702 OC = cast<OMPOrderedClause>(Clause); 3703 else if (Clause->getClauseKind() == OMPC_linear) 3704 LCs.push_back(cast<OMPLinearClause>(Clause)); 3705 } 3706 // OpenMP, 2.7.1 Loop Construct, Restrictions 3707 // The nonmonotonic modifier cannot be specified if an ordered clause is 3708 // specified. 3709 if (SC && 3710 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3711 SC->getSecondScheduleModifier() == 3712 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3713 OC) { 3714 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3715 ? SC->getFirstScheduleModifierLoc() 3716 : SC->getSecondScheduleModifierLoc(), 3717 diag::err_omp_schedule_nonmonotonic_ordered) 3718 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3719 ErrorFound = true; 3720 } 3721 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3722 for (const OMPLinearClause *C : LCs) { 3723 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3724 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3725 } 3726 ErrorFound = true; 3727 } 3728 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3729 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3730 OC->getNumForLoops()) { 3731 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3732 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3733 ErrorFound = true; 3734 } 3735 if (ErrorFound) { 3736 return StmtError(); 3737 } 3738 StmtResult SR = S; 3739 unsigned CompletedRegions = 0; 3740 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3741 // Mark all variables in private list clauses as used in inner region. 3742 // Required for proper codegen of combined directives. 3743 // TODO: add processing for other clauses. 3744 if (ThisCaptureRegion != OMPD_unknown) { 3745 for (const clang::OMPClauseWithPreInit *C : PICs) { 3746 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3747 // Find the particular capture region for the clause if the 3748 // directive is a combined one with multiple capture regions. 3749 // If the directive is not a combined one, the capture region 3750 // associated with the clause is OMPD_unknown and is generated 3751 // only once. 3752 if (CaptureRegion == ThisCaptureRegion || 3753 CaptureRegion == OMPD_unknown) { 3754 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3755 for (Decl *D : DS->decls()) 3756 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3757 } 3758 } 3759 } 3760 } 3761 if (++CompletedRegions == CaptureRegions.size()) 3762 DSAStack->setBodyComplete(); 3763 SR = ActOnCapturedRegionEnd(SR.get()); 3764 } 3765 return SR; 3766 } 3767 3768 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3769 OpenMPDirectiveKind CancelRegion, 3770 SourceLocation StartLoc) { 3771 // CancelRegion is only needed for cancel and cancellation_point. 3772 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3773 return false; 3774 3775 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3776 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3777 return false; 3778 3779 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3780 << getOpenMPDirectiveName(CancelRegion); 3781 return true; 3782 } 3783 3784 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3785 OpenMPDirectiveKind CurrentRegion, 3786 const DeclarationNameInfo &CurrentName, 3787 OpenMPDirectiveKind CancelRegion, 3788 SourceLocation StartLoc) { 3789 if (Stack->getCurScope()) { 3790 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3791 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3792 bool NestingProhibited = false; 3793 bool CloseNesting = true; 3794 bool OrphanSeen = false; 3795 enum { 3796 NoRecommend, 3797 ShouldBeInParallelRegion, 3798 ShouldBeInOrderedRegion, 3799 ShouldBeInTargetRegion, 3800 ShouldBeInTeamsRegion 3801 } Recommend = NoRecommend; 3802 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3803 // OpenMP [2.16, Nesting of Regions] 3804 // OpenMP constructs may not be nested inside a simd region. 3805 // OpenMP [2.8.1,simd Construct, Restrictions] 3806 // An ordered construct with the simd clause is the only OpenMP 3807 // construct that can appear in the simd region. 3808 // Allowing a SIMD construct nested in another SIMD construct is an 3809 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3810 // message. 3811 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3812 ? diag::err_omp_prohibited_region_simd 3813 : diag::warn_omp_nesting_simd); 3814 return CurrentRegion != OMPD_simd; 3815 } 3816 if (ParentRegion == OMPD_atomic) { 3817 // OpenMP [2.16, Nesting of Regions] 3818 // OpenMP constructs may not be nested inside an atomic region. 3819 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3820 return true; 3821 } 3822 if (CurrentRegion == OMPD_section) { 3823 // OpenMP [2.7.2, sections Construct, Restrictions] 3824 // Orphaned section directives are prohibited. That is, the section 3825 // directives must appear within the sections construct and must not be 3826 // encountered elsewhere in the sections region. 3827 if (ParentRegion != OMPD_sections && 3828 ParentRegion != OMPD_parallel_sections) { 3829 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3830 << (ParentRegion != OMPD_unknown) 3831 << getOpenMPDirectiveName(ParentRegion); 3832 return true; 3833 } 3834 return false; 3835 } 3836 // Allow some constructs (except teams and cancellation constructs) to be 3837 // orphaned (they could be used in functions, called from OpenMP regions 3838 // with the required preconditions). 3839 if (ParentRegion == OMPD_unknown && 3840 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3841 CurrentRegion != OMPD_cancellation_point && 3842 CurrentRegion != OMPD_cancel) 3843 return false; 3844 if (CurrentRegion == OMPD_cancellation_point || 3845 CurrentRegion == OMPD_cancel) { 3846 // OpenMP [2.16, Nesting of Regions] 3847 // A cancellation point construct for which construct-type-clause is 3848 // taskgroup must be nested inside a task construct. A cancellation 3849 // point construct for which construct-type-clause is not taskgroup must 3850 // be closely nested inside an OpenMP construct that matches the type 3851 // specified in construct-type-clause. 3852 // A cancel construct for which construct-type-clause is taskgroup must be 3853 // nested inside a task construct. A cancel construct for which 3854 // construct-type-clause is not taskgroup must be closely nested inside an 3855 // OpenMP construct that matches the type specified in 3856 // construct-type-clause. 3857 NestingProhibited = 3858 !((CancelRegion == OMPD_parallel && 3859 (ParentRegion == OMPD_parallel || 3860 ParentRegion == OMPD_target_parallel)) || 3861 (CancelRegion == OMPD_for && 3862 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3863 ParentRegion == OMPD_target_parallel_for || 3864 ParentRegion == OMPD_distribute_parallel_for || 3865 ParentRegion == OMPD_teams_distribute_parallel_for || 3866 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3867 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3868 (CancelRegion == OMPD_sections && 3869 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3870 ParentRegion == OMPD_parallel_sections))); 3871 OrphanSeen = ParentRegion == OMPD_unknown; 3872 } else if (CurrentRegion == OMPD_master) { 3873 // OpenMP [2.16, Nesting of Regions] 3874 // A master region may not be closely nested inside a worksharing, 3875 // atomic, or explicit task region. 3876 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3877 isOpenMPTaskingDirective(ParentRegion); 3878 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3879 // OpenMP [2.16, Nesting of Regions] 3880 // A critical region may not be nested (closely or otherwise) inside a 3881 // critical region with the same name. Note that this restriction is not 3882 // sufficient to prevent deadlock. 3883 SourceLocation PreviousCriticalLoc; 3884 bool DeadLock = Stack->hasDirective( 3885 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3886 const DeclarationNameInfo &DNI, 3887 SourceLocation Loc) { 3888 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3889 PreviousCriticalLoc = Loc; 3890 return true; 3891 } 3892 return false; 3893 }, 3894 false /* skip top directive */); 3895 if (DeadLock) { 3896 SemaRef.Diag(StartLoc, 3897 diag::err_omp_prohibited_region_critical_same_name) 3898 << CurrentName.getName(); 3899 if (PreviousCriticalLoc.isValid()) 3900 SemaRef.Diag(PreviousCriticalLoc, 3901 diag::note_omp_previous_critical_region); 3902 return true; 3903 } 3904 } else if (CurrentRegion == OMPD_barrier) { 3905 // OpenMP [2.16, Nesting of Regions] 3906 // A barrier region may not be closely nested inside a worksharing, 3907 // explicit task, critical, ordered, atomic, or master region. 3908 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3909 isOpenMPTaskingDirective(ParentRegion) || 3910 ParentRegion == OMPD_master || 3911 ParentRegion == OMPD_critical || 3912 ParentRegion == OMPD_ordered; 3913 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3914 !isOpenMPParallelDirective(CurrentRegion) && 3915 !isOpenMPTeamsDirective(CurrentRegion)) { 3916 // OpenMP [2.16, Nesting of Regions] 3917 // A worksharing region may not be closely nested inside a worksharing, 3918 // explicit task, critical, ordered, atomic, or master region. 3919 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3920 isOpenMPTaskingDirective(ParentRegion) || 3921 ParentRegion == OMPD_master || 3922 ParentRegion == OMPD_critical || 3923 ParentRegion == OMPD_ordered; 3924 Recommend = ShouldBeInParallelRegion; 3925 } else if (CurrentRegion == OMPD_ordered) { 3926 // OpenMP [2.16, Nesting of Regions] 3927 // An ordered region may not be closely nested inside a critical, 3928 // atomic, or explicit task region. 3929 // An ordered region must be closely nested inside a loop region (or 3930 // parallel loop region) with an ordered clause. 3931 // OpenMP [2.8.1,simd Construct, Restrictions] 3932 // An ordered construct with the simd clause is the only OpenMP construct 3933 // that can appear in the simd region. 3934 NestingProhibited = ParentRegion == OMPD_critical || 3935 isOpenMPTaskingDirective(ParentRegion) || 3936 !(isOpenMPSimdDirective(ParentRegion) || 3937 Stack->isParentOrderedRegion()); 3938 Recommend = ShouldBeInOrderedRegion; 3939 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3940 // OpenMP [2.16, Nesting of Regions] 3941 // If specified, a teams construct must be contained within a target 3942 // construct. 3943 NestingProhibited = 3944 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 3945 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 3946 ParentRegion != OMPD_target); 3947 OrphanSeen = ParentRegion == OMPD_unknown; 3948 Recommend = ShouldBeInTargetRegion; 3949 } 3950 if (!NestingProhibited && 3951 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3952 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3953 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3954 // OpenMP [2.16, Nesting of Regions] 3955 // distribute, parallel, parallel sections, parallel workshare, and the 3956 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3957 // constructs that can be closely nested in the teams region. 3958 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3959 !isOpenMPDistributeDirective(CurrentRegion); 3960 Recommend = ShouldBeInParallelRegion; 3961 } 3962 if (!NestingProhibited && 3963 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3964 // OpenMP 4.5 [2.17 Nesting of Regions] 3965 // The region associated with the distribute construct must be strictly 3966 // nested inside a teams region 3967 NestingProhibited = 3968 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3969 Recommend = ShouldBeInTeamsRegion; 3970 } 3971 if (!NestingProhibited && 3972 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3973 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3974 // OpenMP 4.5 [2.17 Nesting of Regions] 3975 // If a target, target update, target data, target enter data, or 3976 // target exit data construct is encountered during execution of a 3977 // target region, the behavior is unspecified. 3978 NestingProhibited = Stack->hasDirective( 3979 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3980 SourceLocation) { 3981 if (isOpenMPTargetExecutionDirective(K)) { 3982 OffendingRegion = K; 3983 return true; 3984 } 3985 return false; 3986 }, 3987 false /* don't skip top directive */); 3988 CloseNesting = false; 3989 } 3990 if (NestingProhibited) { 3991 if (OrphanSeen) { 3992 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3993 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3994 } else { 3995 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3996 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3997 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3998 } 3999 return true; 4000 } 4001 } 4002 return false; 4003 } 4004 4005 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4006 ArrayRef<OMPClause *> Clauses, 4007 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4008 bool ErrorFound = false; 4009 unsigned NamedModifiersNumber = 0; 4010 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 4011 OMPD_unknown + 1); 4012 SmallVector<SourceLocation, 4> NameModifierLoc; 4013 for (const OMPClause *C : Clauses) { 4014 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4015 // At most one if clause without a directive-name-modifier can appear on 4016 // the directive. 4017 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4018 if (FoundNameModifiers[CurNM]) { 4019 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4020 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4021 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4022 ErrorFound = true; 4023 } else if (CurNM != OMPD_unknown) { 4024 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4025 ++NamedModifiersNumber; 4026 } 4027 FoundNameModifiers[CurNM] = IC; 4028 if (CurNM == OMPD_unknown) 4029 continue; 4030 // Check if the specified name modifier is allowed for the current 4031 // directive. 4032 // At most one if clause with the particular directive-name-modifier can 4033 // appear on the directive. 4034 bool MatchFound = false; 4035 for (auto NM : AllowedNameModifiers) { 4036 if (CurNM == NM) { 4037 MatchFound = true; 4038 break; 4039 } 4040 } 4041 if (!MatchFound) { 4042 S.Diag(IC->getNameModifierLoc(), 4043 diag::err_omp_wrong_if_directive_name_modifier) 4044 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4045 ErrorFound = true; 4046 } 4047 } 4048 } 4049 // If any if clause on the directive includes a directive-name-modifier then 4050 // all if clauses on the directive must include a directive-name-modifier. 4051 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4052 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4053 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4054 diag::err_omp_no_more_if_clause); 4055 } else { 4056 std::string Values; 4057 std::string Sep(", "); 4058 unsigned AllowedCnt = 0; 4059 unsigned TotalAllowedNum = 4060 AllowedNameModifiers.size() - NamedModifiersNumber; 4061 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4062 ++Cnt) { 4063 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4064 if (!FoundNameModifiers[NM]) { 4065 Values += "'"; 4066 Values += getOpenMPDirectiveName(NM); 4067 Values += "'"; 4068 if (AllowedCnt + 2 == TotalAllowedNum) 4069 Values += " or "; 4070 else if (AllowedCnt + 1 != TotalAllowedNum) 4071 Values += Sep; 4072 ++AllowedCnt; 4073 } 4074 } 4075 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4076 diag::err_omp_unnamed_if_clause) 4077 << (TotalAllowedNum > 1) << Values; 4078 } 4079 for (SourceLocation Loc : NameModifierLoc) { 4080 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4081 } 4082 ErrorFound = true; 4083 } 4084 return ErrorFound; 4085 } 4086 4087 static std::pair<ValueDecl *, bool> 4088 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4089 SourceRange &ERange, bool AllowArraySection = false) { 4090 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4091 RefExpr->containsUnexpandedParameterPack()) 4092 return std::make_pair(nullptr, true); 4093 4094 // OpenMP [3.1, C/C++] 4095 // A list item is a variable name. 4096 // OpenMP [2.9.3.3, Restrictions, p.1] 4097 // A variable that is part of another variable (as an array or 4098 // structure element) cannot appear in a private clause. 4099 RefExpr = RefExpr->IgnoreParens(); 4100 enum { 4101 NoArrayExpr = -1, 4102 ArraySubscript = 0, 4103 OMPArraySection = 1 4104 } IsArrayExpr = NoArrayExpr; 4105 if (AllowArraySection) { 4106 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4107 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4108 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4109 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4110 RefExpr = Base; 4111 IsArrayExpr = ArraySubscript; 4112 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4113 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4114 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4115 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4116 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4117 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4118 RefExpr = Base; 4119 IsArrayExpr = OMPArraySection; 4120 } 4121 } 4122 ELoc = RefExpr->getExprLoc(); 4123 ERange = RefExpr->getSourceRange(); 4124 RefExpr = RefExpr->IgnoreParenImpCasts(); 4125 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4126 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4127 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4128 (S.getCurrentThisType().isNull() || !ME || 4129 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4130 !isa<FieldDecl>(ME->getMemberDecl()))) { 4131 if (IsArrayExpr != NoArrayExpr) { 4132 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4133 << ERange; 4134 } else { 4135 S.Diag(ELoc, 4136 AllowArraySection 4137 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4138 : diag::err_omp_expected_var_name_member_expr) 4139 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4140 } 4141 return std::make_pair(nullptr, false); 4142 } 4143 return std::make_pair( 4144 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4145 } 4146 4147 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4148 ArrayRef<OMPClause *> Clauses) { 4149 assert(!S.CurContext->isDependentContext() && 4150 "Expected non-dependent context."); 4151 auto AllocateRange = 4152 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4153 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4154 DeclToCopy; 4155 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4156 return isOpenMPPrivate(C->getClauseKind()); 4157 }); 4158 for (OMPClause *Cl : PrivateRange) { 4159 MutableArrayRef<Expr *>::iterator I, It, Et; 4160 if (Cl->getClauseKind() == OMPC_private) { 4161 auto *PC = cast<OMPPrivateClause>(Cl); 4162 I = PC->private_copies().begin(); 4163 It = PC->varlist_begin(); 4164 Et = PC->varlist_end(); 4165 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4166 auto *PC = cast<OMPFirstprivateClause>(Cl); 4167 I = PC->private_copies().begin(); 4168 It = PC->varlist_begin(); 4169 Et = PC->varlist_end(); 4170 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4171 auto *PC = cast<OMPLastprivateClause>(Cl); 4172 I = PC->private_copies().begin(); 4173 It = PC->varlist_begin(); 4174 Et = PC->varlist_end(); 4175 } else if (Cl->getClauseKind() == OMPC_linear) { 4176 auto *PC = cast<OMPLinearClause>(Cl); 4177 I = PC->privates().begin(); 4178 It = PC->varlist_begin(); 4179 Et = PC->varlist_end(); 4180 } else if (Cl->getClauseKind() == OMPC_reduction) { 4181 auto *PC = cast<OMPReductionClause>(Cl); 4182 I = PC->privates().begin(); 4183 It = PC->varlist_begin(); 4184 Et = PC->varlist_end(); 4185 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4186 auto *PC = cast<OMPTaskReductionClause>(Cl); 4187 I = PC->privates().begin(); 4188 It = PC->varlist_begin(); 4189 Et = PC->varlist_end(); 4190 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4191 auto *PC = cast<OMPInReductionClause>(Cl); 4192 I = PC->privates().begin(); 4193 It = PC->varlist_begin(); 4194 Et = PC->varlist_end(); 4195 } else { 4196 llvm_unreachable("Expected private clause."); 4197 } 4198 for (Expr *E : llvm::make_range(It, Et)) { 4199 if (!*I) { 4200 ++I; 4201 continue; 4202 } 4203 SourceLocation ELoc; 4204 SourceRange ERange; 4205 Expr *SimpleRefExpr = E; 4206 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4207 /*AllowArraySection=*/true); 4208 DeclToCopy.try_emplace(Res.first, 4209 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4210 ++I; 4211 } 4212 } 4213 for (OMPClause *C : AllocateRange) { 4214 auto *AC = cast<OMPAllocateClause>(C); 4215 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4216 getAllocatorKind(S, Stack, AC->getAllocator()); 4217 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4218 // For task, taskloop or target directives, allocation requests to memory 4219 // allocators with the trait access set to thread result in unspecified 4220 // behavior. 4221 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4222 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4223 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4224 S.Diag(AC->getAllocator()->getExprLoc(), 4225 diag::warn_omp_allocate_thread_on_task_target_directive) 4226 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4227 } 4228 for (Expr *E : AC->varlists()) { 4229 SourceLocation ELoc; 4230 SourceRange ERange; 4231 Expr *SimpleRefExpr = E; 4232 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4233 ValueDecl *VD = Res.first; 4234 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4235 if (!isOpenMPPrivate(Data.CKind)) { 4236 S.Diag(E->getExprLoc(), 4237 diag::err_omp_expected_private_copy_for_allocate); 4238 continue; 4239 } 4240 VarDecl *PrivateVD = DeclToCopy[VD]; 4241 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4242 AllocatorKind, AC->getAllocator())) 4243 continue; 4244 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4245 E->getSourceRange()); 4246 } 4247 } 4248 } 4249 4250 StmtResult Sema::ActOnOpenMPExecutableDirective( 4251 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4252 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4253 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4254 StmtResult Res = StmtError(); 4255 // First check CancelRegion which is then used in checkNestingOfRegions. 4256 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4257 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4258 StartLoc)) 4259 return StmtError(); 4260 4261 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4262 VarsWithInheritedDSAType VarsWithInheritedDSA; 4263 bool ErrorFound = false; 4264 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4265 if (AStmt && !CurContext->isDependentContext()) { 4266 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4267 4268 // Check default data sharing attributes for referenced variables. 4269 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4270 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4271 Stmt *S = AStmt; 4272 while (--ThisCaptureLevel >= 0) 4273 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4274 DSAChecker.Visit(S); 4275 if (!isOpenMPTargetDataManagementDirective(Kind) && 4276 !isOpenMPTaskingDirective(Kind)) { 4277 // Visit subcaptures to generate implicit clauses for captured vars. 4278 auto *CS = cast<CapturedStmt>(AStmt); 4279 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4280 getOpenMPCaptureRegions(CaptureRegions, Kind); 4281 // Ignore outer tasking regions for target directives. 4282 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4283 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4284 DSAChecker.visitSubCaptures(CS); 4285 } 4286 if (DSAChecker.isErrorFound()) 4287 return StmtError(); 4288 // Generate list of implicitly defined firstprivate variables. 4289 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4290 4291 SmallVector<Expr *, 4> ImplicitFirstprivates( 4292 DSAChecker.getImplicitFirstprivate().begin(), 4293 DSAChecker.getImplicitFirstprivate().end()); 4294 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4295 DSAChecker.getImplicitMap().end()); 4296 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4297 for (OMPClause *C : Clauses) { 4298 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4299 for (Expr *E : IRC->taskgroup_descriptors()) 4300 if (E) 4301 ImplicitFirstprivates.emplace_back(E); 4302 } 4303 } 4304 if (!ImplicitFirstprivates.empty()) { 4305 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4306 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4307 SourceLocation())) { 4308 ClausesWithImplicit.push_back(Implicit); 4309 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4310 ImplicitFirstprivates.size(); 4311 } else { 4312 ErrorFound = true; 4313 } 4314 } 4315 if (!ImplicitMaps.empty()) { 4316 CXXScopeSpec MapperIdScopeSpec; 4317 DeclarationNameInfo MapperId; 4318 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4319 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4320 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4321 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4322 ClausesWithImplicit.emplace_back(Implicit); 4323 ErrorFound |= 4324 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4325 } else { 4326 ErrorFound = true; 4327 } 4328 } 4329 } 4330 4331 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4332 switch (Kind) { 4333 case OMPD_parallel: 4334 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4335 EndLoc); 4336 AllowedNameModifiers.push_back(OMPD_parallel); 4337 break; 4338 case OMPD_simd: 4339 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4340 VarsWithInheritedDSA); 4341 break; 4342 case OMPD_for: 4343 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4344 VarsWithInheritedDSA); 4345 break; 4346 case OMPD_for_simd: 4347 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4348 EndLoc, VarsWithInheritedDSA); 4349 break; 4350 case OMPD_sections: 4351 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4352 EndLoc); 4353 break; 4354 case OMPD_section: 4355 assert(ClausesWithImplicit.empty() && 4356 "No clauses are allowed for 'omp section' directive"); 4357 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4358 break; 4359 case OMPD_single: 4360 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4361 EndLoc); 4362 break; 4363 case OMPD_master: 4364 assert(ClausesWithImplicit.empty() && 4365 "No clauses are allowed for 'omp master' directive"); 4366 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4367 break; 4368 case OMPD_critical: 4369 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4370 StartLoc, EndLoc); 4371 break; 4372 case OMPD_parallel_for: 4373 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4374 EndLoc, VarsWithInheritedDSA); 4375 AllowedNameModifiers.push_back(OMPD_parallel); 4376 break; 4377 case OMPD_parallel_for_simd: 4378 Res = ActOnOpenMPParallelForSimdDirective( 4379 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4380 AllowedNameModifiers.push_back(OMPD_parallel); 4381 break; 4382 case OMPD_parallel_sections: 4383 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4384 StartLoc, EndLoc); 4385 AllowedNameModifiers.push_back(OMPD_parallel); 4386 break; 4387 case OMPD_task: 4388 Res = 4389 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4390 AllowedNameModifiers.push_back(OMPD_task); 4391 break; 4392 case OMPD_taskyield: 4393 assert(ClausesWithImplicit.empty() && 4394 "No clauses are allowed for 'omp taskyield' directive"); 4395 assert(AStmt == nullptr && 4396 "No associated statement allowed for 'omp taskyield' directive"); 4397 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4398 break; 4399 case OMPD_barrier: 4400 assert(ClausesWithImplicit.empty() && 4401 "No clauses are allowed for 'omp barrier' directive"); 4402 assert(AStmt == nullptr && 4403 "No associated statement allowed for 'omp barrier' directive"); 4404 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4405 break; 4406 case OMPD_taskwait: 4407 assert(ClausesWithImplicit.empty() && 4408 "No clauses are allowed for 'omp taskwait' directive"); 4409 assert(AStmt == nullptr && 4410 "No associated statement allowed for 'omp taskwait' directive"); 4411 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4412 break; 4413 case OMPD_taskgroup: 4414 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4415 EndLoc); 4416 break; 4417 case OMPD_flush: 4418 assert(AStmt == nullptr && 4419 "No associated statement allowed for 'omp flush' directive"); 4420 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4421 break; 4422 case OMPD_ordered: 4423 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4424 EndLoc); 4425 break; 4426 case OMPD_atomic: 4427 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4428 EndLoc); 4429 break; 4430 case OMPD_teams: 4431 Res = 4432 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4433 break; 4434 case OMPD_target: 4435 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4436 EndLoc); 4437 AllowedNameModifiers.push_back(OMPD_target); 4438 break; 4439 case OMPD_target_parallel: 4440 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4441 StartLoc, EndLoc); 4442 AllowedNameModifiers.push_back(OMPD_target); 4443 AllowedNameModifiers.push_back(OMPD_parallel); 4444 break; 4445 case OMPD_target_parallel_for: 4446 Res = ActOnOpenMPTargetParallelForDirective( 4447 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4448 AllowedNameModifiers.push_back(OMPD_target); 4449 AllowedNameModifiers.push_back(OMPD_parallel); 4450 break; 4451 case OMPD_cancellation_point: 4452 assert(ClausesWithImplicit.empty() && 4453 "No clauses are allowed for 'omp cancellation point' directive"); 4454 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4455 "cancellation point' directive"); 4456 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4457 break; 4458 case OMPD_cancel: 4459 assert(AStmt == nullptr && 4460 "No associated statement allowed for 'omp cancel' directive"); 4461 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4462 CancelRegion); 4463 AllowedNameModifiers.push_back(OMPD_cancel); 4464 break; 4465 case OMPD_target_data: 4466 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4467 EndLoc); 4468 AllowedNameModifiers.push_back(OMPD_target_data); 4469 break; 4470 case OMPD_target_enter_data: 4471 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4472 EndLoc, AStmt); 4473 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4474 break; 4475 case OMPD_target_exit_data: 4476 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4477 EndLoc, AStmt); 4478 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4479 break; 4480 case OMPD_taskloop: 4481 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4482 EndLoc, VarsWithInheritedDSA); 4483 AllowedNameModifiers.push_back(OMPD_taskloop); 4484 break; 4485 case OMPD_taskloop_simd: 4486 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4487 EndLoc, VarsWithInheritedDSA); 4488 AllowedNameModifiers.push_back(OMPD_taskloop); 4489 break; 4490 case OMPD_master_taskloop: 4491 Res = ActOnOpenMPMasterTaskLoopDirective( 4492 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4493 AllowedNameModifiers.push_back(OMPD_taskloop); 4494 break; 4495 case OMPD_master_taskloop_simd: 4496 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4497 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4498 AllowedNameModifiers.push_back(OMPD_taskloop); 4499 break; 4500 case OMPD_parallel_master_taskloop: 4501 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4502 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4503 AllowedNameModifiers.push_back(OMPD_taskloop); 4504 AllowedNameModifiers.push_back(OMPD_parallel); 4505 break; 4506 case OMPD_parallel_master_taskloop_simd: 4507 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4508 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4509 AllowedNameModifiers.push_back(OMPD_taskloop); 4510 AllowedNameModifiers.push_back(OMPD_parallel); 4511 break; 4512 case OMPD_distribute: 4513 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4514 EndLoc, VarsWithInheritedDSA); 4515 break; 4516 case OMPD_target_update: 4517 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4518 EndLoc, AStmt); 4519 AllowedNameModifiers.push_back(OMPD_target_update); 4520 break; 4521 case OMPD_distribute_parallel_for: 4522 Res = ActOnOpenMPDistributeParallelForDirective( 4523 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4524 AllowedNameModifiers.push_back(OMPD_parallel); 4525 break; 4526 case OMPD_distribute_parallel_for_simd: 4527 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4528 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4529 AllowedNameModifiers.push_back(OMPD_parallel); 4530 break; 4531 case OMPD_distribute_simd: 4532 Res = ActOnOpenMPDistributeSimdDirective( 4533 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4534 break; 4535 case OMPD_target_parallel_for_simd: 4536 Res = ActOnOpenMPTargetParallelForSimdDirective( 4537 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4538 AllowedNameModifiers.push_back(OMPD_target); 4539 AllowedNameModifiers.push_back(OMPD_parallel); 4540 break; 4541 case OMPD_target_simd: 4542 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4543 EndLoc, VarsWithInheritedDSA); 4544 AllowedNameModifiers.push_back(OMPD_target); 4545 break; 4546 case OMPD_teams_distribute: 4547 Res = ActOnOpenMPTeamsDistributeDirective( 4548 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4549 break; 4550 case OMPD_teams_distribute_simd: 4551 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4552 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4553 break; 4554 case OMPD_teams_distribute_parallel_for_simd: 4555 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4556 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4557 AllowedNameModifiers.push_back(OMPD_parallel); 4558 break; 4559 case OMPD_teams_distribute_parallel_for: 4560 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4561 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4562 AllowedNameModifiers.push_back(OMPD_parallel); 4563 break; 4564 case OMPD_target_teams: 4565 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4566 EndLoc); 4567 AllowedNameModifiers.push_back(OMPD_target); 4568 break; 4569 case OMPD_target_teams_distribute: 4570 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4571 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4572 AllowedNameModifiers.push_back(OMPD_target); 4573 break; 4574 case OMPD_target_teams_distribute_parallel_for: 4575 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4576 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4577 AllowedNameModifiers.push_back(OMPD_target); 4578 AllowedNameModifiers.push_back(OMPD_parallel); 4579 break; 4580 case OMPD_target_teams_distribute_parallel_for_simd: 4581 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4582 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4583 AllowedNameModifiers.push_back(OMPD_target); 4584 AllowedNameModifiers.push_back(OMPD_parallel); 4585 break; 4586 case OMPD_target_teams_distribute_simd: 4587 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4588 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4589 AllowedNameModifiers.push_back(OMPD_target); 4590 break; 4591 case OMPD_declare_target: 4592 case OMPD_end_declare_target: 4593 case OMPD_threadprivate: 4594 case OMPD_allocate: 4595 case OMPD_declare_reduction: 4596 case OMPD_declare_mapper: 4597 case OMPD_declare_simd: 4598 case OMPD_requires: 4599 case OMPD_declare_variant: 4600 llvm_unreachable("OpenMP Directive is not allowed"); 4601 case OMPD_unknown: 4602 llvm_unreachable("Unknown OpenMP directive"); 4603 } 4604 4605 ErrorFound = Res.isInvalid() || ErrorFound; 4606 4607 // Check variables in the clauses if default(none) was specified. 4608 if (DSAStack->getDefaultDSA() == DSA_none) { 4609 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4610 for (OMPClause *C : Clauses) { 4611 switch (C->getClauseKind()) { 4612 case OMPC_num_threads: 4613 case OMPC_dist_schedule: 4614 // Do not analyse if no parent teams directive. 4615 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4616 break; 4617 continue; 4618 case OMPC_if: 4619 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4620 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4621 break; 4622 continue; 4623 case OMPC_schedule: 4624 break; 4625 case OMPC_grainsize: 4626 case OMPC_num_tasks: 4627 case OMPC_final: 4628 case OMPC_priority: 4629 // Do not analyze if no parent parallel directive. 4630 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective())) 4631 break; 4632 continue; 4633 case OMPC_ordered: 4634 case OMPC_device: 4635 case OMPC_num_teams: 4636 case OMPC_thread_limit: 4637 case OMPC_hint: 4638 case OMPC_collapse: 4639 case OMPC_safelen: 4640 case OMPC_simdlen: 4641 case OMPC_default: 4642 case OMPC_proc_bind: 4643 case OMPC_private: 4644 case OMPC_firstprivate: 4645 case OMPC_lastprivate: 4646 case OMPC_shared: 4647 case OMPC_reduction: 4648 case OMPC_task_reduction: 4649 case OMPC_in_reduction: 4650 case OMPC_linear: 4651 case OMPC_aligned: 4652 case OMPC_copyin: 4653 case OMPC_copyprivate: 4654 case OMPC_nowait: 4655 case OMPC_untied: 4656 case OMPC_mergeable: 4657 case OMPC_allocate: 4658 case OMPC_read: 4659 case OMPC_write: 4660 case OMPC_update: 4661 case OMPC_capture: 4662 case OMPC_seq_cst: 4663 case OMPC_depend: 4664 case OMPC_threads: 4665 case OMPC_simd: 4666 case OMPC_map: 4667 case OMPC_nogroup: 4668 case OMPC_defaultmap: 4669 case OMPC_to: 4670 case OMPC_from: 4671 case OMPC_use_device_ptr: 4672 case OMPC_is_device_ptr: 4673 continue; 4674 case OMPC_allocator: 4675 case OMPC_flush: 4676 case OMPC_threadprivate: 4677 case OMPC_uniform: 4678 case OMPC_unknown: 4679 case OMPC_unified_address: 4680 case OMPC_unified_shared_memory: 4681 case OMPC_reverse_offload: 4682 case OMPC_dynamic_allocators: 4683 case OMPC_atomic_default_mem_order: 4684 case OMPC_device_type: 4685 case OMPC_match: 4686 llvm_unreachable("Unexpected clause"); 4687 } 4688 for (Stmt *CC : C->children()) { 4689 if (CC) 4690 DSAChecker.Visit(CC); 4691 } 4692 } 4693 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4694 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4695 } 4696 for (const auto &P : VarsWithInheritedDSA) { 4697 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4698 continue; 4699 ErrorFound = true; 4700 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4701 << P.first << P.second->getSourceRange(); 4702 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4703 } 4704 4705 if (!AllowedNameModifiers.empty()) 4706 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4707 ErrorFound; 4708 4709 if (ErrorFound) 4710 return StmtError(); 4711 4712 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4713 Res.getAs<OMPExecutableDirective>() 4714 ->getStructuredBlock() 4715 ->setIsOMPStructuredBlock(true); 4716 } 4717 4718 if (!CurContext->isDependentContext() && 4719 isOpenMPTargetExecutionDirective(Kind) && 4720 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4721 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4722 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4723 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4724 // Register target to DSA Stack. 4725 DSAStack->addTargetDirLocation(StartLoc); 4726 } 4727 4728 return Res; 4729 } 4730 4731 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4732 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4733 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4734 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4735 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4736 assert(Aligneds.size() == Alignments.size()); 4737 assert(Linears.size() == LinModifiers.size()); 4738 assert(Linears.size() == Steps.size()); 4739 if (!DG || DG.get().isNull()) 4740 return DeclGroupPtrTy(); 4741 4742 const int SimdId = 0; 4743 if (!DG.get().isSingleDecl()) { 4744 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4745 << SimdId; 4746 return DG; 4747 } 4748 Decl *ADecl = DG.get().getSingleDecl(); 4749 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4750 ADecl = FTD->getTemplatedDecl(); 4751 4752 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4753 if (!FD) { 4754 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4755 return DeclGroupPtrTy(); 4756 } 4757 4758 // OpenMP [2.8.2, declare simd construct, Description] 4759 // The parameter of the simdlen clause must be a constant positive integer 4760 // expression. 4761 ExprResult SL; 4762 if (Simdlen) 4763 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4764 // OpenMP [2.8.2, declare simd construct, Description] 4765 // The special this pointer can be used as if was one of the arguments to the 4766 // function in any of the linear, aligned, or uniform clauses. 4767 // The uniform clause declares one or more arguments to have an invariant 4768 // value for all concurrent invocations of the function in the execution of a 4769 // single SIMD loop. 4770 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4771 const Expr *UniformedLinearThis = nullptr; 4772 for (const Expr *E : Uniforms) { 4773 E = E->IgnoreParenImpCasts(); 4774 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4775 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4776 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4777 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4778 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4779 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4780 continue; 4781 } 4782 if (isa<CXXThisExpr>(E)) { 4783 UniformedLinearThis = E; 4784 continue; 4785 } 4786 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4787 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4788 } 4789 // OpenMP [2.8.2, declare simd construct, Description] 4790 // The aligned clause declares that the object to which each list item points 4791 // is aligned to the number of bytes expressed in the optional parameter of 4792 // the aligned clause. 4793 // The special this pointer can be used as if was one of the arguments to the 4794 // function in any of the linear, aligned, or uniform clauses. 4795 // The type of list items appearing in the aligned clause must be array, 4796 // pointer, reference to array, or reference to pointer. 4797 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4798 const Expr *AlignedThis = nullptr; 4799 for (const Expr *E : Aligneds) { 4800 E = E->IgnoreParenImpCasts(); 4801 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4802 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4803 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4804 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4805 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4806 ->getCanonicalDecl() == CanonPVD) { 4807 // OpenMP [2.8.1, simd construct, Restrictions] 4808 // A list-item cannot appear in more than one aligned clause. 4809 if (AlignedArgs.count(CanonPVD) > 0) { 4810 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4811 << 1 << E->getSourceRange(); 4812 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4813 diag::note_omp_explicit_dsa) 4814 << getOpenMPClauseName(OMPC_aligned); 4815 continue; 4816 } 4817 AlignedArgs[CanonPVD] = E; 4818 QualType QTy = PVD->getType() 4819 .getNonReferenceType() 4820 .getUnqualifiedType() 4821 .getCanonicalType(); 4822 const Type *Ty = QTy.getTypePtrOrNull(); 4823 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4824 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4825 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4826 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4827 } 4828 continue; 4829 } 4830 } 4831 if (isa<CXXThisExpr>(E)) { 4832 if (AlignedThis) { 4833 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4834 << 2 << E->getSourceRange(); 4835 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4836 << getOpenMPClauseName(OMPC_aligned); 4837 } 4838 AlignedThis = E; 4839 continue; 4840 } 4841 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4842 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4843 } 4844 // The optional parameter of the aligned clause, alignment, must be a constant 4845 // positive integer expression. If no optional parameter is specified, 4846 // implementation-defined default alignments for SIMD instructions on the 4847 // target platforms are assumed. 4848 SmallVector<const Expr *, 4> NewAligns; 4849 for (Expr *E : Alignments) { 4850 ExprResult Align; 4851 if (E) 4852 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4853 NewAligns.push_back(Align.get()); 4854 } 4855 // OpenMP [2.8.2, declare simd construct, Description] 4856 // The linear clause declares one or more list items to be private to a SIMD 4857 // lane and to have a linear relationship with respect to the iteration space 4858 // of a loop. 4859 // The special this pointer can be used as if was one of the arguments to the 4860 // function in any of the linear, aligned, or uniform clauses. 4861 // When a linear-step expression is specified in a linear clause it must be 4862 // either a constant integer expression or an integer-typed parameter that is 4863 // specified in a uniform clause on the directive. 4864 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4865 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4866 auto MI = LinModifiers.begin(); 4867 for (const Expr *E : Linears) { 4868 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4869 ++MI; 4870 E = E->IgnoreParenImpCasts(); 4871 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4872 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4873 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4874 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4875 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4876 ->getCanonicalDecl() == CanonPVD) { 4877 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4878 // A list-item cannot appear in more than one linear clause. 4879 if (LinearArgs.count(CanonPVD) > 0) { 4880 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4881 << getOpenMPClauseName(OMPC_linear) 4882 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4883 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4884 diag::note_omp_explicit_dsa) 4885 << getOpenMPClauseName(OMPC_linear); 4886 continue; 4887 } 4888 // Each argument can appear in at most one uniform or linear clause. 4889 if (UniformedArgs.count(CanonPVD) > 0) { 4890 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4891 << getOpenMPClauseName(OMPC_linear) 4892 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4893 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4894 diag::note_omp_explicit_dsa) 4895 << getOpenMPClauseName(OMPC_uniform); 4896 continue; 4897 } 4898 LinearArgs[CanonPVD] = E; 4899 if (E->isValueDependent() || E->isTypeDependent() || 4900 E->isInstantiationDependent() || 4901 E->containsUnexpandedParameterPack()) 4902 continue; 4903 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4904 PVD->getOriginalType()); 4905 continue; 4906 } 4907 } 4908 if (isa<CXXThisExpr>(E)) { 4909 if (UniformedLinearThis) { 4910 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4911 << getOpenMPClauseName(OMPC_linear) 4912 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4913 << E->getSourceRange(); 4914 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4915 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4916 : OMPC_linear); 4917 continue; 4918 } 4919 UniformedLinearThis = E; 4920 if (E->isValueDependent() || E->isTypeDependent() || 4921 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4922 continue; 4923 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4924 E->getType()); 4925 continue; 4926 } 4927 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4928 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4929 } 4930 Expr *Step = nullptr; 4931 Expr *NewStep = nullptr; 4932 SmallVector<Expr *, 4> NewSteps; 4933 for (Expr *E : Steps) { 4934 // Skip the same step expression, it was checked already. 4935 if (Step == E || !E) { 4936 NewSteps.push_back(E ? NewStep : nullptr); 4937 continue; 4938 } 4939 Step = E; 4940 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4941 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4942 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4943 if (UniformedArgs.count(CanonPVD) == 0) { 4944 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4945 << Step->getSourceRange(); 4946 } else if (E->isValueDependent() || E->isTypeDependent() || 4947 E->isInstantiationDependent() || 4948 E->containsUnexpandedParameterPack() || 4949 CanonPVD->getType()->hasIntegerRepresentation()) { 4950 NewSteps.push_back(Step); 4951 } else { 4952 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4953 << Step->getSourceRange(); 4954 } 4955 continue; 4956 } 4957 NewStep = Step; 4958 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4959 !Step->isInstantiationDependent() && 4960 !Step->containsUnexpandedParameterPack()) { 4961 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4962 .get(); 4963 if (NewStep) 4964 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4965 } 4966 NewSteps.push_back(NewStep); 4967 } 4968 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4969 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4970 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4971 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4972 const_cast<Expr **>(Linears.data()), Linears.size(), 4973 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4974 NewSteps.data(), NewSteps.size(), SR); 4975 ADecl->addAttr(NewAttr); 4976 return DG; 4977 } 4978 4979 Optional<std::pair<FunctionDecl *, Expr *>> 4980 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 4981 Expr *VariantRef, SourceRange SR) { 4982 if (!DG || DG.get().isNull()) 4983 return None; 4984 4985 const int VariantId = 1; 4986 // Must be applied only to single decl. 4987 if (!DG.get().isSingleDecl()) { 4988 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4989 << VariantId << SR; 4990 return None; 4991 } 4992 Decl *ADecl = DG.get().getSingleDecl(); 4993 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4994 ADecl = FTD->getTemplatedDecl(); 4995 4996 // Decl must be a function. 4997 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4998 if (!FD) { 4999 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5000 << VariantId << SR; 5001 return None; 5002 } 5003 5004 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5005 return FD->hasAttrs() && 5006 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5007 FD->hasAttr<TargetAttr>()); 5008 }; 5009 // OpenMP is not compatible with CPU-specific attributes. 5010 if (HasMultiVersionAttributes(FD)) { 5011 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5012 << SR; 5013 return None; 5014 } 5015 5016 // Allow #pragma omp declare variant only if the function is not used. 5017 if (FD->isUsed(false)) 5018 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5019 << FD->getLocation(); 5020 5021 // Check if the function was emitted already. 5022 const FunctionDecl *Definition; 5023 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5024 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5025 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5026 << FD->getLocation(); 5027 5028 // The VariantRef must point to function. 5029 if (!VariantRef) { 5030 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5031 return None; 5032 } 5033 5034 // Do not check templates, wait until instantiation. 5035 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5036 VariantRef->containsUnexpandedParameterPack() || 5037 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5038 return std::make_pair(FD, VariantRef); 5039 5040 // Convert VariantRef expression to the type of the original function to 5041 // resolve possible conflicts. 5042 ExprResult VariantRefCast; 5043 if (LangOpts.CPlusPlus) { 5044 QualType FnPtrType; 5045 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5046 if (Method && !Method->isStatic()) { 5047 const Type *ClassType = 5048 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5049 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5050 ExprResult ER; 5051 { 5052 // Build adrr_of unary op to correctly handle type checks for member 5053 // functions. 5054 Sema::TentativeAnalysisScope Trap(*this); 5055 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5056 VariantRef); 5057 } 5058 if (!ER.isUsable()) { 5059 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5060 << VariantId << VariantRef->getSourceRange(); 5061 return None; 5062 } 5063 VariantRef = ER.get(); 5064 } else { 5065 FnPtrType = Context.getPointerType(FD->getType()); 5066 } 5067 ImplicitConversionSequence ICS = 5068 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5069 /*SuppressUserConversions=*/false, 5070 /*AllowExplicit=*/false, 5071 /*InOverloadResolution=*/false, 5072 /*CStyle=*/false, 5073 /*AllowObjCWritebackConversion=*/false); 5074 if (ICS.isFailure()) { 5075 Diag(VariantRef->getExprLoc(), 5076 diag::err_omp_declare_variant_incompat_types) 5077 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 5078 return None; 5079 } 5080 VariantRefCast = PerformImplicitConversion( 5081 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5082 if (!VariantRefCast.isUsable()) 5083 return None; 5084 // Drop previously built artificial addr_of unary op for member functions. 5085 if (Method && !Method->isStatic()) { 5086 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5087 if (auto *UO = dyn_cast<UnaryOperator>( 5088 PossibleAddrOfVariantRef->IgnoreImplicit())) 5089 VariantRefCast = UO->getSubExpr(); 5090 } 5091 } else { 5092 VariantRefCast = VariantRef; 5093 } 5094 5095 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5096 if (!ER.isUsable() || 5097 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5098 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5099 << VariantId << VariantRef->getSourceRange(); 5100 return None; 5101 } 5102 5103 // The VariantRef must point to function. 5104 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5105 if (!DRE) { 5106 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5107 << VariantId << VariantRef->getSourceRange(); 5108 return None; 5109 } 5110 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5111 if (!NewFD) { 5112 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5113 << VariantId << VariantRef->getSourceRange(); 5114 return None; 5115 } 5116 5117 // Check if variant function is not marked with declare variant directive. 5118 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5119 Diag(VariantRef->getExprLoc(), 5120 diag::warn_omp_declare_variant_marked_as_declare_variant) 5121 << VariantRef->getSourceRange(); 5122 SourceRange SR = 5123 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5124 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5125 return None; 5126 } 5127 5128 enum DoesntSupport { 5129 VirtFuncs = 1, 5130 Constructors = 3, 5131 Destructors = 4, 5132 DeletedFuncs = 5, 5133 DefaultedFuncs = 6, 5134 ConstexprFuncs = 7, 5135 ConstevalFuncs = 8, 5136 }; 5137 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5138 if (CXXFD->isVirtual()) { 5139 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5140 << VirtFuncs; 5141 return None; 5142 } 5143 5144 if (isa<CXXConstructorDecl>(FD)) { 5145 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5146 << Constructors; 5147 return None; 5148 } 5149 5150 if (isa<CXXDestructorDecl>(FD)) { 5151 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5152 << Destructors; 5153 return None; 5154 } 5155 } 5156 5157 if (FD->isDeleted()) { 5158 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5159 << DeletedFuncs; 5160 return None; 5161 } 5162 5163 if (FD->isDefaulted()) { 5164 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5165 << DefaultedFuncs; 5166 return None; 5167 } 5168 5169 if (FD->isConstexpr()) { 5170 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5171 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5172 return None; 5173 } 5174 5175 // Check general compatibility. 5176 if (areMultiversionVariantFunctionsCompatible( 5177 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5178 PartialDiagnosticAt( 5179 SR.getBegin(), 5180 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5181 PartialDiagnosticAt( 5182 VariantRef->getExprLoc(), 5183 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5184 PartialDiagnosticAt(VariantRef->getExprLoc(), 5185 PDiag(diag::err_omp_declare_variant_diff) 5186 << FD->getLocation()), 5187 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5188 /*CLinkageMayDiffer=*/true)) 5189 return None; 5190 return std::make_pair(FD, cast<Expr>(DRE)); 5191 } 5192 5193 void Sema::ActOnOpenMPDeclareVariantDirective( 5194 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5195 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { 5196 if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || 5197 Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) 5198 return; 5199 Expr *Score = nullptr; 5200 OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown; 5201 if (Data.CtxScore.isUsable()) { 5202 ST = OMPDeclareVariantAttr::ScoreSpecified; 5203 Score = Data.CtxScore.get(); 5204 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5205 !Score->isInstantiationDependent() && 5206 !Score->containsUnexpandedParameterPack()) { 5207 llvm::APSInt Result; 5208 ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result); 5209 if (ICE.isInvalid()) 5210 return; 5211 } 5212 } 5213 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5214 Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, 5215 Data.ImplVendors.begin(), Data.ImplVendors.size(), SR); 5216 FD->addAttr(NewAttr); 5217 } 5218 5219 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5220 FunctionDecl *Func, 5221 bool MightBeOdrUse) { 5222 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5223 5224 if (!Func->isDependentContext() && Func->hasAttrs()) { 5225 for (OMPDeclareVariantAttr *A : 5226 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5227 // TODO: add checks for active OpenMP context where possible. 5228 Expr *VariantRef = A->getVariantFuncRef(); 5229 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5230 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5231 if (!F->isDefined() && F->isTemplateInstantiation()) 5232 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5233 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5234 } 5235 } 5236 } 5237 5238 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5239 Stmt *AStmt, 5240 SourceLocation StartLoc, 5241 SourceLocation EndLoc) { 5242 if (!AStmt) 5243 return StmtError(); 5244 5245 auto *CS = cast<CapturedStmt>(AStmt); 5246 // 1.2.2 OpenMP Language Terminology 5247 // Structured block - An executable statement with a single entry at the 5248 // top and a single exit at the bottom. 5249 // The point of exit cannot be a branch out of the structured block. 5250 // longjmp() and throw() must not violate the entry/exit criteria. 5251 CS->getCapturedDecl()->setNothrow(); 5252 5253 setFunctionHasBranchProtectedScope(); 5254 5255 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5256 DSAStack->isCancelRegion()); 5257 } 5258 5259 namespace { 5260 /// Iteration space of a single for loop. 5261 struct LoopIterationSpace final { 5262 /// True if the condition operator is the strict compare operator (<, > or 5263 /// !=). 5264 bool IsStrictCompare = false; 5265 /// Condition of the loop. 5266 Expr *PreCond = nullptr; 5267 /// This expression calculates the number of iterations in the loop. 5268 /// It is always possible to calculate it before starting the loop. 5269 Expr *NumIterations = nullptr; 5270 /// The loop counter variable. 5271 Expr *CounterVar = nullptr; 5272 /// Private loop counter variable. 5273 Expr *PrivateCounterVar = nullptr; 5274 /// This is initializer for the initial value of #CounterVar. 5275 Expr *CounterInit = nullptr; 5276 /// This is step for the #CounterVar used to generate its update: 5277 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5278 Expr *CounterStep = nullptr; 5279 /// Should step be subtracted? 5280 bool Subtract = false; 5281 /// Source range of the loop init. 5282 SourceRange InitSrcRange; 5283 /// Source range of the loop condition. 5284 SourceRange CondSrcRange; 5285 /// Source range of the loop increment. 5286 SourceRange IncSrcRange; 5287 /// Minimum value that can have the loop control variable. Used to support 5288 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5289 /// since only such variables can be used in non-loop invariant expressions. 5290 Expr *MinValue = nullptr; 5291 /// Maximum value that can have the loop control variable. Used to support 5292 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5293 /// since only such variables can be used in non-loop invariant expressions. 5294 Expr *MaxValue = nullptr; 5295 /// true, if the lower bound depends on the outer loop control var. 5296 bool IsNonRectangularLB = false; 5297 /// true, if the upper bound depends on the outer loop control var. 5298 bool IsNonRectangularUB = false; 5299 /// Index of the loop this loop depends on and forms non-rectangular loop 5300 /// nest. 5301 unsigned LoopDependentIdx = 0; 5302 /// Final condition for the non-rectangular loop nest support. It is used to 5303 /// check that the number of iterations for this particular counter must be 5304 /// finished. 5305 Expr *FinalCondition = nullptr; 5306 }; 5307 5308 /// Helper class for checking canonical form of the OpenMP loops and 5309 /// extracting iteration space of each loop in the loop nest, that will be used 5310 /// for IR generation. 5311 class OpenMPIterationSpaceChecker { 5312 /// Reference to Sema. 5313 Sema &SemaRef; 5314 /// Data-sharing stack. 5315 DSAStackTy &Stack; 5316 /// A location for diagnostics (when there is no some better location). 5317 SourceLocation DefaultLoc; 5318 /// A location for diagnostics (when increment is not compatible). 5319 SourceLocation ConditionLoc; 5320 /// A source location for referring to loop init later. 5321 SourceRange InitSrcRange; 5322 /// A source location for referring to condition later. 5323 SourceRange ConditionSrcRange; 5324 /// A source location for referring to increment later. 5325 SourceRange IncrementSrcRange; 5326 /// Loop variable. 5327 ValueDecl *LCDecl = nullptr; 5328 /// Reference to loop variable. 5329 Expr *LCRef = nullptr; 5330 /// Lower bound (initializer for the var). 5331 Expr *LB = nullptr; 5332 /// Upper bound. 5333 Expr *UB = nullptr; 5334 /// Loop step (increment). 5335 Expr *Step = nullptr; 5336 /// This flag is true when condition is one of: 5337 /// Var < UB 5338 /// Var <= UB 5339 /// UB > Var 5340 /// UB >= Var 5341 /// This will have no value when the condition is != 5342 llvm::Optional<bool> TestIsLessOp; 5343 /// This flag is true when condition is strict ( < or > ). 5344 bool TestIsStrictOp = false; 5345 /// This flag is true when step is subtracted on each iteration. 5346 bool SubtractStep = false; 5347 /// The outer loop counter this loop depends on (if any). 5348 const ValueDecl *DepDecl = nullptr; 5349 /// Contains number of loop (starts from 1) on which loop counter init 5350 /// expression of this loop depends on. 5351 Optional<unsigned> InitDependOnLC; 5352 /// Contains number of loop (starts from 1) on which loop counter condition 5353 /// expression of this loop depends on. 5354 Optional<unsigned> CondDependOnLC; 5355 /// Checks if the provide statement depends on the loop counter. 5356 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5357 /// Original condition required for checking of the exit condition for 5358 /// non-rectangular loop. 5359 Expr *Condition = nullptr; 5360 5361 public: 5362 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5363 SourceLocation DefaultLoc) 5364 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5365 ConditionLoc(DefaultLoc) {} 5366 /// Check init-expr for canonical loop form and save loop counter 5367 /// variable - #Var and its initialization value - #LB. 5368 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5369 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5370 /// for less/greater and for strict/non-strict comparison. 5371 bool checkAndSetCond(Expr *S); 5372 /// Check incr-expr for canonical loop form and return true if it 5373 /// does not conform, otherwise save loop step (#Step). 5374 bool checkAndSetInc(Expr *S); 5375 /// Return the loop counter variable. 5376 ValueDecl *getLoopDecl() const { return LCDecl; } 5377 /// Return the reference expression to loop counter variable. 5378 Expr *getLoopDeclRefExpr() const { return LCRef; } 5379 /// Source range of the loop init. 5380 SourceRange getInitSrcRange() const { return InitSrcRange; } 5381 /// Source range of the loop condition. 5382 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5383 /// Source range of the loop increment. 5384 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5385 /// True if the step should be subtracted. 5386 bool shouldSubtractStep() const { return SubtractStep; } 5387 /// True, if the compare operator is strict (<, > or !=). 5388 bool isStrictTestOp() const { return TestIsStrictOp; } 5389 /// Build the expression to calculate the number of iterations. 5390 Expr *buildNumIterations( 5391 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5392 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5393 /// Build the precondition expression for the loops. 5394 Expr * 5395 buildPreCond(Scope *S, Expr *Cond, 5396 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5397 /// Build reference expression to the counter be used for codegen. 5398 DeclRefExpr * 5399 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5400 DSAStackTy &DSA) const; 5401 /// Build reference expression to the private counter be used for 5402 /// codegen. 5403 Expr *buildPrivateCounterVar() const; 5404 /// Build initialization of the counter be used for codegen. 5405 Expr *buildCounterInit() const; 5406 /// Build step of the counter be used for codegen. 5407 Expr *buildCounterStep() const; 5408 /// Build loop data with counter value for depend clauses in ordered 5409 /// directives. 5410 Expr * 5411 buildOrderedLoopData(Scope *S, Expr *Counter, 5412 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5413 SourceLocation Loc, Expr *Inc = nullptr, 5414 OverloadedOperatorKind OOK = OO_Amp); 5415 /// Builds the minimum value for the loop counter. 5416 std::pair<Expr *, Expr *> buildMinMaxValues( 5417 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5418 /// Builds final condition for the non-rectangular loops. 5419 Expr *buildFinalCondition(Scope *S) const; 5420 /// Return true if any expression is dependent. 5421 bool dependent() const; 5422 /// Returns true if the initializer forms non-rectangular loop. 5423 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5424 /// Returns true if the condition forms non-rectangular loop. 5425 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5426 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5427 unsigned getLoopDependentIdx() const { 5428 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5429 } 5430 5431 private: 5432 /// Check the right-hand side of an assignment in the increment 5433 /// expression. 5434 bool checkAndSetIncRHS(Expr *RHS); 5435 /// Helper to set loop counter variable and its initializer. 5436 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5437 bool EmitDiags); 5438 /// Helper to set upper bound. 5439 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5440 SourceRange SR, SourceLocation SL); 5441 /// Helper to set loop increment. 5442 bool setStep(Expr *NewStep, bool Subtract); 5443 }; 5444 5445 bool OpenMPIterationSpaceChecker::dependent() const { 5446 if (!LCDecl) { 5447 assert(!LB && !UB && !Step); 5448 return false; 5449 } 5450 return LCDecl->getType()->isDependentType() || 5451 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5452 (Step && Step->isValueDependent()); 5453 } 5454 5455 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5456 Expr *NewLCRefExpr, 5457 Expr *NewLB, bool EmitDiags) { 5458 // State consistency checking to ensure correct usage. 5459 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5460 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5461 if (!NewLCDecl || !NewLB) 5462 return true; 5463 LCDecl = getCanonicalDecl(NewLCDecl); 5464 LCRef = NewLCRefExpr; 5465 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5466 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5467 if ((Ctor->isCopyOrMoveConstructor() || 5468 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5469 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5470 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5471 LB = NewLB; 5472 if (EmitDiags) 5473 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5474 return false; 5475 } 5476 5477 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5478 llvm::Optional<bool> LessOp, 5479 bool StrictOp, SourceRange SR, 5480 SourceLocation SL) { 5481 // State consistency checking to ensure correct usage. 5482 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5483 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5484 if (!NewUB) 5485 return true; 5486 UB = NewUB; 5487 if (LessOp) 5488 TestIsLessOp = LessOp; 5489 TestIsStrictOp = StrictOp; 5490 ConditionSrcRange = SR; 5491 ConditionLoc = SL; 5492 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5493 return false; 5494 } 5495 5496 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5497 // State consistency checking to ensure correct usage. 5498 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5499 if (!NewStep) 5500 return true; 5501 if (!NewStep->isValueDependent()) { 5502 // Check that the step is integer expression. 5503 SourceLocation StepLoc = NewStep->getBeginLoc(); 5504 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5505 StepLoc, getExprAsWritten(NewStep)); 5506 if (Val.isInvalid()) 5507 return true; 5508 NewStep = Val.get(); 5509 5510 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5511 // If test-expr is of form var relational-op b and relational-op is < or 5512 // <= then incr-expr must cause var to increase on each iteration of the 5513 // loop. If test-expr is of form var relational-op b and relational-op is 5514 // > or >= then incr-expr must cause var to decrease on each iteration of 5515 // the loop. 5516 // If test-expr is of form b relational-op var and relational-op is < or 5517 // <= then incr-expr must cause var to decrease on each iteration of the 5518 // loop. If test-expr is of form b relational-op var and relational-op is 5519 // > or >= then incr-expr must cause var to increase on each iteration of 5520 // the loop. 5521 llvm::APSInt Result; 5522 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5523 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5524 bool IsConstNeg = 5525 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5526 bool IsConstPos = 5527 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5528 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5529 5530 // != with increment is treated as <; != with decrement is treated as > 5531 if (!TestIsLessOp.hasValue()) 5532 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5533 if (UB && (IsConstZero || 5534 (TestIsLessOp.getValue() ? 5535 (IsConstNeg || (IsUnsigned && Subtract)) : 5536 (IsConstPos || (IsUnsigned && !Subtract))))) { 5537 SemaRef.Diag(NewStep->getExprLoc(), 5538 diag::err_omp_loop_incr_not_compatible) 5539 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5540 SemaRef.Diag(ConditionLoc, 5541 diag::note_omp_loop_cond_requres_compatible_incr) 5542 << TestIsLessOp.getValue() << ConditionSrcRange; 5543 return true; 5544 } 5545 if (TestIsLessOp.getValue() == Subtract) { 5546 NewStep = 5547 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5548 .get(); 5549 Subtract = !Subtract; 5550 } 5551 } 5552 5553 Step = NewStep; 5554 SubtractStep = Subtract; 5555 return false; 5556 } 5557 5558 namespace { 5559 /// Checker for the non-rectangular loops. Checks if the initializer or 5560 /// condition expression references loop counter variable. 5561 class LoopCounterRefChecker final 5562 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5563 Sema &SemaRef; 5564 DSAStackTy &Stack; 5565 const ValueDecl *CurLCDecl = nullptr; 5566 const ValueDecl *DepDecl = nullptr; 5567 const ValueDecl *PrevDepDecl = nullptr; 5568 bool IsInitializer = true; 5569 unsigned BaseLoopId = 0; 5570 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5571 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5572 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5573 << (IsInitializer ? 0 : 1); 5574 return false; 5575 } 5576 const auto &&Data = Stack.isLoopControlVariable(VD); 5577 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5578 // The type of the loop iterator on which we depend may not have a random 5579 // access iterator type. 5580 if (Data.first && VD->getType()->isRecordType()) { 5581 SmallString<128> Name; 5582 llvm::raw_svector_ostream OS(Name); 5583 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5584 /*Qualified=*/true); 5585 SemaRef.Diag(E->getExprLoc(), 5586 diag::err_omp_wrong_dependency_iterator_type) 5587 << OS.str(); 5588 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5589 return false; 5590 } 5591 if (Data.first && 5592 (DepDecl || (PrevDepDecl && 5593 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5594 if (!DepDecl && PrevDepDecl) 5595 DepDecl = PrevDepDecl; 5596 SmallString<128> Name; 5597 llvm::raw_svector_ostream OS(Name); 5598 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5599 /*Qualified=*/true); 5600 SemaRef.Diag(E->getExprLoc(), 5601 diag::err_omp_invariant_or_linear_dependency) 5602 << OS.str(); 5603 return false; 5604 } 5605 if (Data.first) { 5606 DepDecl = VD; 5607 BaseLoopId = Data.first; 5608 } 5609 return Data.first; 5610 } 5611 5612 public: 5613 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5614 const ValueDecl *VD = E->getDecl(); 5615 if (isa<VarDecl>(VD)) 5616 return checkDecl(E, VD); 5617 return false; 5618 } 5619 bool VisitMemberExpr(const MemberExpr *E) { 5620 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5621 const ValueDecl *VD = E->getMemberDecl(); 5622 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5623 return checkDecl(E, VD); 5624 } 5625 return false; 5626 } 5627 bool VisitStmt(const Stmt *S) { 5628 bool Res = false; 5629 for (const Stmt *Child : S->children()) 5630 Res = (Child && Visit(Child)) || Res; 5631 return Res; 5632 } 5633 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5634 const ValueDecl *CurLCDecl, bool IsInitializer, 5635 const ValueDecl *PrevDepDecl = nullptr) 5636 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5637 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5638 unsigned getBaseLoopId() const { 5639 assert(CurLCDecl && "Expected loop dependency."); 5640 return BaseLoopId; 5641 } 5642 const ValueDecl *getDepDecl() const { 5643 assert(CurLCDecl && "Expected loop dependency."); 5644 return DepDecl; 5645 } 5646 }; 5647 } // namespace 5648 5649 Optional<unsigned> 5650 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5651 bool IsInitializer) { 5652 // Check for the non-rectangular loops. 5653 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5654 DepDecl); 5655 if (LoopStmtChecker.Visit(S)) { 5656 DepDecl = LoopStmtChecker.getDepDecl(); 5657 return LoopStmtChecker.getBaseLoopId(); 5658 } 5659 return llvm::None; 5660 } 5661 5662 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5663 // Check init-expr for canonical loop form and save loop counter 5664 // variable - #Var and its initialization value - #LB. 5665 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5666 // var = lb 5667 // integer-type var = lb 5668 // random-access-iterator-type var = lb 5669 // pointer-type var = lb 5670 // 5671 if (!S) { 5672 if (EmitDiags) { 5673 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5674 } 5675 return true; 5676 } 5677 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5678 if (!ExprTemp->cleanupsHaveSideEffects()) 5679 S = ExprTemp->getSubExpr(); 5680 5681 InitSrcRange = S->getSourceRange(); 5682 if (Expr *E = dyn_cast<Expr>(S)) 5683 S = E->IgnoreParens(); 5684 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5685 if (BO->getOpcode() == BO_Assign) { 5686 Expr *LHS = BO->getLHS()->IgnoreParens(); 5687 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5688 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5689 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5690 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5691 EmitDiags); 5692 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5693 } 5694 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5695 if (ME->isArrow() && 5696 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5697 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5698 EmitDiags); 5699 } 5700 } 5701 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5702 if (DS->isSingleDecl()) { 5703 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5704 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5705 // Accept non-canonical init form here but emit ext. warning. 5706 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5707 SemaRef.Diag(S->getBeginLoc(), 5708 diag::ext_omp_loop_not_canonical_init) 5709 << S->getSourceRange(); 5710 return setLCDeclAndLB( 5711 Var, 5712 buildDeclRefExpr(SemaRef, Var, 5713 Var->getType().getNonReferenceType(), 5714 DS->getBeginLoc()), 5715 Var->getInit(), EmitDiags); 5716 } 5717 } 5718 } 5719 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5720 if (CE->getOperator() == OO_Equal) { 5721 Expr *LHS = CE->getArg(0); 5722 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5723 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5724 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5725 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5726 EmitDiags); 5727 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5728 } 5729 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5730 if (ME->isArrow() && 5731 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5732 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5733 EmitDiags); 5734 } 5735 } 5736 } 5737 5738 if (dependent() || SemaRef.CurContext->isDependentContext()) 5739 return false; 5740 if (EmitDiags) { 5741 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5742 << S->getSourceRange(); 5743 } 5744 return true; 5745 } 5746 5747 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5748 /// variable (which may be the loop variable) if possible. 5749 static const ValueDecl *getInitLCDecl(const Expr *E) { 5750 if (!E) 5751 return nullptr; 5752 E = getExprAsWritten(E); 5753 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5754 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5755 if ((Ctor->isCopyOrMoveConstructor() || 5756 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5757 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5758 E = CE->getArg(0)->IgnoreParenImpCasts(); 5759 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5760 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5761 return getCanonicalDecl(VD); 5762 } 5763 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5764 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5765 return getCanonicalDecl(ME->getMemberDecl()); 5766 return nullptr; 5767 } 5768 5769 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5770 // Check test-expr for canonical form, save upper-bound UB, flags for 5771 // less/greater and for strict/non-strict comparison. 5772 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5773 // var relational-op b 5774 // b relational-op var 5775 // 5776 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5777 if (!S) { 5778 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5779 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5780 return true; 5781 } 5782 Condition = S; 5783 S = getExprAsWritten(S); 5784 SourceLocation CondLoc = S->getBeginLoc(); 5785 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5786 if (BO->isRelationalOp()) { 5787 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5788 return setUB(BO->getRHS(), 5789 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5790 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5791 BO->getSourceRange(), BO->getOperatorLoc()); 5792 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5793 return setUB(BO->getLHS(), 5794 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5795 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5796 BO->getSourceRange(), BO->getOperatorLoc()); 5797 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5798 return setUB( 5799 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5800 /*LessOp=*/llvm::None, 5801 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5802 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5803 if (CE->getNumArgs() == 2) { 5804 auto Op = CE->getOperator(); 5805 switch (Op) { 5806 case OO_Greater: 5807 case OO_GreaterEqual: 5808 case OO_Less: 5809 case OO_LessEqual: 5810 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5811 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5812 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5813 CE->getOperatorLoc()); 5814 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5815 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5816 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5817 CE->getOperatorLoc()); 5818 break; 5819 case OO_ExclaimEqual: 5820 if (IneqCondIsCanonical) 5821 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5822 : CE->getArg(0), 5823 /*LessOp=*/llvm::None, 5824 /*StrictOp=*/true, CE->getSourceRange(), 5825 CE->getOperatorLoc()); 5826 break; 5827 default: 5828 break; 5829 } 5830 } 5831 } 5832 if (dependent() || SemaRef.CurContext->isDependentContext()) 5833 return false; 5834 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5835 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5836 return true; 5837 } 5838 5839 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5840 // RHS of canonical loop form increment can be: 5841 // var + incr 5842 // incr + var 5843 // var - incr 5844 // 5845 RHS = RHS->IgnoreParenImpCasts(); 5846 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5847 if (BO->isAdditiveOp()) { 5848 bool IsAdd = BO->getOpcode() == BO_Add; 5849 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5850 return setStep(BO->getRHS(), !IsAdd); 5851 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5852 return setStep(BO->getLHS(), /*Subtract=*/false); 5853 } 5854 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5855 bool IsAdd = CE->getOperator() == OO_Plus; 5856 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5857 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5858 return setStep(CE->getArg(1), !IsAdd); 5859 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5860 return setStep(CE->getArg(0), /*Subtract=*/false); 5861 } 5862 } 5863 if (dependent() || SemaRef.CurContext->isDependentContext()) 5864 return false; 5865 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5866 << RHS->getSourceRange() << LCDecl; 5867 return true; 5868 } 5869 5870 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5871 // Check incr-expr for canonical loop form and return true if it 5872 // does not conform. 5873 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5874 // ++var 5875 // var++ 5876 // --var 5877 // var-- 5878 // var += incr 5879 // var -= incr 5880 // var = var + incr 5881 // var = incr + var 5882 // var = var - incr 5883 // 5884 if (!S) { 5885 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5886 return true; 5887 } 5888 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5889 if (!ExprTemp->cleanupsHaveSideEffects()) 5890 S = ExprTemp->getSubExpr(); 5891 5892 IncrementSrcRange = S->getSourceRange(); 5893 S = S->IgnoreParens(); 5894 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5895 if (UO->isIncrementDecrementOp() && 5896 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5897 return setStep(SemaRef 5898 .ActOnIntegerConstant(UO->getBeginLoc(), 5899 (UO->isDecrementOp() ? -1 : 1)) 5900 .get(), 5901 /*Subtract=*/false); 5902 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5903 switch (BO->getOpcode()) { 5904 case BO_AddAssign: 5905 case BO_SubAssign: 5906 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5907 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5908 break; 5909 case BO_Assign: 5910 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5911 return checkAndSetIncRHS(BO->getRHS()); 5912 break; 5913 default: 5914 break; 5915 } 5916 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5917 switch (CE->getOperator()) { 5918 case OO_PlusPlus: 5919 case OO_MinusMinus: 5920 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5921 return setStep(SemaRef 5922 .ActOnIntegerConstant( 5923 CE->getBeginLoc(), 5924 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5925 .get(), 5926 /*Subtract=*/false); 5927 break; 5928 case OO_PlusEqual: 5929 case OO_MinusEqual: 5930 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5931 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5932 break; 5933 case OO_Equal: 5934 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5935 return checkAndSetIncRHS(CE->getArg(1)); 5936 break; 5937 default: 5938 break; 5939 } 5940 } 5941 if (dependent() || SemaRef.CurContext->isDependentContext()) 5942 return false; 5943 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5944 << S->getSourceRange() << LCDecl; 5945 return true; 5946 } 5947 5948 static ExprResult 5949 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5950 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5951 if (SemaRef.CurContext->isDependentContext()) 5952 return ExprResult(Capture); 5953 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5954 return SemaRef.PerformImplicitConversion( 5955 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5956 /*AllowExplicit=*/true); 5957 auto I = Captures.find(Capture); 5958 if (I != Captures.end()) 5959 return buildCapture(SemaRef, Capture, I->second); 5960 DeclRefExpr *Ref = nullptr; 5961 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5962 Captures[Capture] = Ref; 5963 return Res; 5964 } 5965 5966 /// Build the expression to calculate the number of iterations. 5967 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5968 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5969 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5970 ExprResult Diff; 5971 QualType VarType = LCDecl->getType().getNonReferenceType(); 5972 if (VarType->isIntegerType() || VarType->isPointerType() || 5973 SemaRef.getLangOpts().CPlusPlus) { 5974 Expr *LBVal = LB; 5975 Expr *UBVal = UB; 5976 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5977 // max(LB(MinVal), LB(MaxVal)) 5978 if (InitDependOnLC) { 5979 const LoopIterationSpace &IS = 5980 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5981 InitDependOnLC.getValueOr( 5982 CondDependOnLC.getValueOr(0))]; 5983 if (!IS.MinValue || !IS.MaxValue) 5984 return nullptr; 5985 // OuterVar = Min 5986 ExprResult MinValue = 5987 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5988 if (!MinValue.isUsable()) 5989 return nullptr; 5990 5991 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5992 IS.CounterVar, MinValue.get()); 5993 if (!LBMinVal.isUsable()) 5994 return nullptr; 5995 // OuterVar = Min, LBVal 5996 LBMinVal = 5997 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5998 if (!LBMinVal.isUsable()) 5999 return nullptr; 6000 // (OuterVar = Min, LBVal) 6001 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6002 if (!LBMinVal.isUsable()) 6003 return nullptr; 6004 6005 // OuterVar = Max 6006 ExprResult MaxValue = 6007 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6008 if (!MaxValue.isUsable()) 6009 return nullptr; 6010 6011 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6012 IS.CounterVar, MaxValue.get()); 6013 if (!LBMaxVal.isUsable()) 6014 return nullptr; 6015 // OuterVar = Max, LBVal 6016 LBMaxVal = 6017 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6018 if (!LBMaxVal.isUsable()) 6019 return nullptr; 6020 // (OuterVar = Max, LBVal) 6021 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6022 if (!LBMaxVal.isUsable()) 6023 return nullptr; 6024 6025 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6026 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6027 if (!LBMin || !LBMax) 6028 return nullptr; 6029 // LB(MinVal) < LB(MaxVal) 6030 ExprResult MinLessMaxRes = 6031 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6032 if (!MinLessMaxRes.isUsable()) 6033 return nullptr; 6034 Expr *MinLessMax = 6035 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6036 if (!MinLessMax) 6037 return nullptr; 6038 if (TestIsLessOp.getValue()) { 6039 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6040 // LB(MaxVal)) 6041 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6042 MinLessMax, LBMin, LBMax); 6043 if (!MinLB.isUsable()) 6044 return nullptr; 6045 LBVal = MinLB.get(); 6046 } else { 6047 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6048 // LB(MaxVal)) 6049 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6050 MinLessMax, LBMax, LBMin); 6051 if (!MaxLB.isUsable()) 6052 return nullptr; 6053 LBVal = MaxLB.get(); 6054 } 6055 } 6056 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6057 // min(UB(MinVal), UB(MaxVal)) 6058 if (CondDependOnLC) { 6059 const LoopIterationSpace &IS = 6060 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6061 InitDependOnLC.getValueOr( 6062 CondDependOnLC.getValueOr(0))]; 6063 if (!IS.MinValue || !IS.MaxValue) 6064 return nullptr; 6065 // OuterVar = Min 6066 ExprResult MinValue = 6067 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6068 if (!MinValue.isUsable()) 6069 return nullptr; 6070 6071 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6072 IS.CounterVar, MinValue.get()); 6073 if (!UBMinVal.isUsable()) 6074 return nullptr; 6075 // OuterVar = Min, UBVal 6076 UBMinVal = 6077 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6078 if (!UBMinVal.isUsable()) 6079 return nullptr; 6080 // (OuterVar = Min, UBVal) 6081 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6082 if (!UBMinVal.isUsable()) 6083 return nullptr; 6084 6085 // OuterVar = Max 6086 ExprResult MaxValue = 6087 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6088 if (!MaxValue.isUsable()) 6089 return nullptr; 6090 6091 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6092 IS.CounterVar, MaxValue.get()); 6093 if (!UBMaxVal.isUsable()) 6094 return nullptr; 6095 // OuterVar = Max, UBVal 6096 UBMaxVal = 6097 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6098 if (!UBMaxVal.isUsable()) 6099 return nullptr; 6100 // (OuterVar = Max, UBVal) 6101 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6102 if (!UBMaxVal.isUsable()) 6103 return nullptr; 6104 6105 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6106 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6107 if (!UBMin || !UBMax) 6108 return nullptr; 6109 // UB(MinVal) > UB(MaxVal) 6110 ExprResult MinGreaterMaxRes = 6111 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6112 if (!MinGreaterMaxRes.isUsable()) 6113 return nullptr; 6114 Expr *MinGreaterMax = 6115 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6116 if (!MinGreaterMax) 6117 return nullptr; 6118 if (TestIsLessOp.getValue()) { 6119 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6120 // UB(MaxVal)) 6121 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6122 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6123 if (!MaxUB.isUsable()) 6124 return nullptr; 6125 UBVal = MaxUB.get(); 6126 } else { 6127 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6128 // UB(MaxVal)) 6129 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6130 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6131 if (!MinUB.isUsable()) 6132 return nullptr; 6133 UBVal = MinUB.get(); 6134 } 6135 } 6136 // Upper - Lower 6137 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6138 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6139 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6140 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6141 if (!Upper || !Lower) 6142 return nullptr; 6143 6144 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6145 6146 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6147 // BuildBinOp already emitted error, this one is to point user to upper 6148 // and lower bound, and to tell what is passed to 'operator-'. 6149 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6150 << Upper->getSourceRange() << Lower->getSourceRange(); 6151 return nullptr; 6152 } 6153 } 6154 6155 if (!Diff.isUsable()) 6156 return nullptr; 6157 6158 // Upper - Lower [- 1] 6159 if (TestIsStrictOp) 6160 Diff = SemaRef.BuildBinOp( 6161 S, DefaultLoc, BO_Sub, Diff.get(), 6162 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6163 if (!Diff.isUsable()) 6164 return nullptr; 6165 6166 // Upper - Lower [- 1] + Step 6167 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6168 if (!NewStep.isUsable()) 6169 return nullptr; 6170 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6171 if (!Diff.isUsable()) 6172 return nullptr; 6173 6174 // Parentheses (for dumping/debugging purposes only). 6175 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6176 if (!Diff.isUsable()) 6177 return nullptr; 6178 6179 // (Upper - Lower [- 1] + Step) / Step 6180 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6181 if (!Diff.isUsable()) 6182 return nullptr; 6183 6184 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6185 QualType Type = Diff.get()->getType(); 6186 ASTContext &C = SemaRef.Context; 6187 bool UseVarType = VarType->hasIntegerRepresentation() && 6188 C.getTypeSize(Type) > C.getTypeSize(VarType); 6189 if (!Type->isIntegerType() || UseVarType) { 6190 unsigned NewSize = 6191 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6192 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6193 : Type->hasSignedIntegerRepresentation(); 6194 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6195 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6196 Diff = SemaRef.PerformImplicitConversion( 6197 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6198 if (!Diff.isUsable()) 6199 return nullptr; 6200 } 6201 } 6202 if (LimitedType) { 6203 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6204 if (NewSize != C.getTypeSize(Type)) { 6205 if (NewSize < C.getTypeSize(Type)) { 6206 assert(NewSize == 64 && "incorrect loop var size"); 6207 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6208 << InitSrcRange << ConditionSrcRange; 6209 } 6210 QualType NewType = C.getIntTypeForBitwidth( 6211 NewSize, Type->hasSignedIntegerRepresentation() || 6212 C.getTypeSize(Type) < NewSize); 6213 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6214 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6215 Sema::AA_Converting, true); 6216 if (!Diff.isUsable()) 6217 return nullptr; 6218 } 6219 } 6220 } 6221 6222 return Diff.get(); 6223 } 6224 6225 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6226 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6227 // Do not build for iterators, they cannot be used in non-rectangular loop 6228 // nests. 6229 if (LCDecl->getType()->isRecordType()) 6230 return std::make_pair(nullptr, nullptr); 6231 // If we subtract, the min is in the condition, otherwise the min is in the 6232 // init value. 6233 Expr *MinExpr = nullptr; 6234 Expr *MaxExpr = nullptr; 6235 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6236 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6237 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6238 : CondDependOnLC.hasValue(); 6239 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6240 : InitDependOnLC.hasValue(); 6241 Expr *Lower = 6242 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6243 Expr *Upper = 6244 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6245 if (!Upper || !Lower) 6246 return std::make_pair(nullptr, nullptr); 6247 6248 if (TestIsLessOp.getValue()) 6249 MinExpr = Lower; 6250 else 6251 MaxExpr = Upper; 6252 6253 // Build minimum/maximum value based on number of iterations. 6254 ExprResult Diff; 6255 QualType VarType = LCDecl->getType().getNonReferenceType(); 6256 6257 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6258 if (!Diff.isUsable()) 6259 return std::make_pair(nullptr, nullptr); 6260 6261 // Upper - Lower [- 1] 6262 if (TestIsStrictOp) 6263 Diff = SemaRef.BuildBinOp( 6264 S, DefaultLoc, BO_Sub, Diff.get(), 6265 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6266 if (!Diff.isUsable()) 6267 return std::make_pair(nullptr, nullptr); 6268 6269 // Upper - Lower [- 1] + Step 6270 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6271 if (!NewStep.isUsable()) 6272 return std::make_pair(nullptr, nullptr); 6273 6274 // Parentheses (for dumping/debugging purposes only). 6275 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6276 if (!Diff.isUsable()) 6277 return std::make_pair(nullptr, nullptr); 6278 6279 // (Upper - Lower [- 1]) / Step 6280 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6281 if (!Diff.isUsable()) 6282 return std::make_pair(nullptr, nullptr); 6283 6284 // ((Upper - Lower [- 1]) / Step) * Step 6285 // Parentheses (for dumping/debugging purposes only). 6286 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6287 if (!Diff.isUsable()) 6288 return std::make_pair(nullptr, nullptr); 6289 6290 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6291 if (!Diff.isUsable()) 6292 return std::make_pair(nullptr, nullptr); 6293 6294 // Convert to the original type or ptrdiff_t, if original type is pointer. 6295 if (!VarType->isAnyPointerType() && 6296 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6297 Diff = SemaRef.PerformImplicitConversion( 6298 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6299 } else if (VarType->isAnyPointerType() && 6300 !SemaRef.Context.hasSameType( 6301 Diff.get()->getType(), 6302 SemaRef.Context.getUnsignedPointerDiffType())) { 6303 Diff = SemaRef.PerformImplicitConversion( 6304 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6305 Sema::AA_Converting, /*AllowExplicit=*/true); 6306 } 6307 if (!Diff.isUsable()) 6308 return std::make_pair(nullptr, nullptr); 6309 6310 // Parentheses (for dumping/debugging purposes only). 6311 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6312 if (!Diff.isUsable()) 6313 return std::make_pair(nullptr, nullptr); 6314 6315 if (TestIsLessOp.getValue()) { 6316 // MinExpr = Lower; 6317 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6318 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6319 if (!Diff.isUsable()) 6320 return std::make_pair(nullptr, nullptr); 6321 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6322 if (!Diff.isUsable()) 6323 return std::make_pair(nullptr, nullptr); 6324 MaxExpr = Diff.get(); 6325 } else { 6326 // MaxExpr = Upper; 6327 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6328 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6329 if (!Diff.isUsable()) 6330 return std::make_pair(nullptr, nullptr); 6331 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6332 if (!Diff.isUsable()) 6333 return std::make_pair(nullptr, nullptr); 6334 MinExpr = Diff.get(); 6335 } 6336 6337 return std::make_pair(MinExpr, MaxExpr); 6338 } 6339 6340 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6341 if (InitDependOnLC || CondDependOnLC) 6342 return Condition; 6343 return nullptr; 6344 } 6345 6346 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6347 Scope *S, Expr *Cond, 6348 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6349 // Do not build a precondition when the condition/initialization is dependent 6350 // to prevent pessimistic early loop exit. 6351 // TODO: this can be improved by calculating min/max values but not sure that 6352 // it will be very effective. 6353 if (CondDependOnLC || InitDependOnLC) 6354 return SemaRef.PerformImplicitConversion( 6355 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6356 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6357 /*AllowExplicit=*/true).get(); 6358 6359 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6360 Sema::TentativeAnalysisScope Trap(SemaRef); 6361 6362 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6363 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6364 if (!NewLB.isUsable() || !NewUB.isUsable()) 6365 return nullptr; 6366 6367 ExprResult CondExpr = 6368 SemaRef.BuildBinOp(S, DefaultLoc, 6369 TestIsLessOp.getValue() ? 6370 (TestIsStrictOp ? BO_LT : BO_LE) : 6371 (TestIsStrictOp ? BO_GT : BO_GE), 6372 NewLB.get(), NewUB.get()); 6373 if (CondExpr.isUsable()) { 6374 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6375 SemaRef.Context.BoolTy)) 6376 CondExpr = SemaRef.PerformImplicitConversion( 6377 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6378 /*AllowExplicit=*/true); 6379 } 6380 6381 // Otherwise use original loop condition and evaluate it in runtime. 6382 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6383 } 6384 6385 /// Build reference expression to the counter be used for codegen. 6386 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6387 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6388 DSAStackTy &DSA) const { 6389 auto *VD = dyn_cast<VarDecl>(LCDecl); 6390 if (!VD) { 6391 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6392 DeclRefExpr *Ref = buildDeclRefExpr( 6393 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6394 const DSAStackTy::DSAVarData Data = 6395 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6396 // If the loop control decl is explicitly marked as private, do not mark it 6397 // as captured again. 6398 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6399 Captures.insert(std::make_pair(LCRef, Ref)); 6400 return Ref; 6401 } 6402 return cast<DeclRefExpr>(LCRef); 6403 } 6404 6405 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6406 if (LCDecl && !LCDecl->isInvalidDecl()) { 6407 QualType Type = LCDecl->getType().getNonReferenceType(); 6408 VarDecl *PrivateVar = buildVarDecl( 6409 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6410 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6411 isa<VarDecl>(LCDecl) 6412 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6413 : nullptr); 6414 if (PrivateVar->isInvalidDecl()) 6415 return nullptr; 6416 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6417 } 6418 return nullptr; 6419 } 6420 6421 /// Build initialization of the counter to be used for codegen. 6422 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6423 6424 /// Build step of the counter be used for codegen. 6425 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6426 6427 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6428 Scope *S, Expr *Counter, 6429 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6430 Expr *Inc, OverloadedOperatorKind OOK) { 6431 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6432 if (!Cnt) 6433 return nullptr; 6434 if (Inc) { 6435 assert((OOK == OO_Plus || OOK == OO_Minus) && 6436 "Expected only + or - operations for depend clauses."); 6437 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6438 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6439 if (!Cnt) 6440 return nullptr; 6441 } 6442 ExprResult Diff; 6443 QualType VarType = LCDecl->getType().getNonReferenceType(); 6444 if (VarType->isIntegerType() || VarType->isPointerType() || 6445 SemaRef.getLangOpts().CPlusPlus) { 6446 // Upper - Lower 6447 Expr *Upper = TestIsLessOp.getValue() 6448 ? Cnt 6449 : tryBuildCapture(SemaRef, UB, Captures).get(); 6450 Expr *Lower = TestIsLessOp.getValue() 6451 ? tryBuildCapture(SemaRef, LB, Captures).get() 6452 : Cnt; 6453 if (!Upper || !Lower) 6454 return nullptr; 6455 6456 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6457 6458 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6459 // BuildBinOp already emitted error, this one is to point user to upper 6460 // and lower bound, and to tell what is passed to 'operator-'. 6461 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6462 << Upper->getSourceRange() << Lower->getSourceRange(); 6463 return nullptr; 6464 } 6465 } 6466 6467 if (!Diff.isUsable()) 6468 return nullptr; 6469 6470 // Parentheses (for dumping/debugging purposes only). 6471 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6472 if (!Diff.isUsable()) 6473 return nullptr; 6474 6475 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6476 if (!NewStep.isUsable()) 6477 return nullptr; 6478 // (Upper - Lower) / Step 6479 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6480 if (!Diff.isUsable()) 6481 return nullptr; 6482 6483 return Diff.get(); 6484 } 6485 } // namespace 6486 6487 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6488 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6489 assert(Init && "Expected loop in canonical form."); 6490 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6491 if (AssociatedLoops > 0 && 6492 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6493 DSAStack->loopStart(); 6494 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6495 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6496 if (ValueDecl *D = ISC.getLoopDecl()) { 6497 auto *VD = dyn_cast<VarDecl>(D); 6498 DeclRefExpr *PrivateRef = nullptr; 6499 if (!VD) { 6500 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6501 VD = Private; 6502 } else { 6503 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6504 /*WithInit=*/false); 6505 VD = cast<VarDecl>(PrivateRef->getDecl()); 6506 } 6507 } 6508 DSAStack->addLoopControlVariable(D, VD); 6509 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6510 if (LD != D->getCanonicalDecl()) { 6511 DSAStack->resetPossibleLoopCounter(); 6512 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6513 MarkDeclarationsReferencedInExpr( 6514 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6515 Var->getType().getNonLValueExprType(Context), 6516 ForLoc, /*RefersToCapture=*/true)); 6517 } 6518 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6519 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6520 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6521 // associated for-loop of a simd construct with just one associated 6522 // for-loop may be listed in a linear clause with a constant-linear-step 6523 // that is the increment of the associated for-loop. The loop iteration 6524 // variable(s) in the associated for-loop(s) of a for or parallel for 6525 // construct may be listed in a private or lastprivate clause. 6526 DSAStackTy::DSAVarData DVar = 6527 DSAStack->getTopDSA(D, /*FromParent=*/false); 6528 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6529 // is declared in the loop and it is predetermined as a private. 6530 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6531 OpenMPClauseKind PredeterminedCKind = 6532 isOpenMPSimdDirective(DKind) 6533 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6534 : OMPC_private; 6535 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6536 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6537 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6538 DVar.CKind != OMPC_private))) || 6539 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6540 DKind == OMPD_master_taskloop || 6541 DKind == OMPD_parallel_master_taskloop || 6542 isOpenMPDistributeDirective(DKind)) && 6543 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6544 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6545 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6546 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6547 << getOpenMPClauseName(DVar.CKind) 6548 << getOpenMPDirectiveName(DKind) 6549 << getOpenMPClauseName(PredeterminedCKind); 6550 if (DVar.RefExpr == nullptr) 6551 DVar.CKind = PredeterminedCKind; 6552 reportOriginalDsa(*this, DSAStack, D, DVar, 6553 /*IsLoopIterVar=*/true); 6554 } else if (LoopDeclRefExpr) { 6555 // Make the loop iteration variable private (for worksharing 6556 // constructs), linear (for simd directives with the only one 6557 // associated loop) or lastprivate (for simd directives with several 6558 // collapsed or ordered loops). 6559 if (DVar.CKind == OMPC_unknown) 6560 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6561 PrivateRef); 6562 } 6563 } 6564 } 6565 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6566 } 6567 } 6568 6569 /// Called on a for stmt to check and extract its iteration space 6570 /// for further processing (such as collapsing). 6571 static bool checkOpenMPIterationSpace( 6572 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6573 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6574 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6575 Expr *OrderedLoopCountExpr, 6576 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6577 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6578 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6579 // OpenMP [2.9.1, Canonical Loop Form] 6580 // for (init-expr; test-expr; incr-expr) structured-block 6581 // for (range-decl: range-expr) structured-block 6582 auto *For = dyn_cast_or_null<ForStmt>(S); 6583 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6584 // Ranged for is supported only in OpenMP 5.0. 6585 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6586 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6587 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6588 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6589 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6590 if (TotalNestedLoopCount > 1) { 6591 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6592 SemaRef.Diag(DSA.getConstructLoc(), 6593 diag::note_omp_collapse_ordered_expr) 6594 << 2 << CollapseLoopCountExpr->getSourceRange() 6595 << OrderedLoopCountExpr->getSourceRange(); 6596 else if (CollapseLoopCountExpr) 6597 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6598 diag::note_omp_collapse_ordered_expr) 6599 << 0 << CollapseLoopCountExpr->getSourceRange(); 6600 else 6601 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6602 diag::note_omp_collapse_ordered_expr) 6603 << 1 << OrderedLoopCountExpr->getSourceRange(); 6604 } 6605 return true; 6606 } 6607 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6608 "No loop body."); 6609 6610 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6611 For ? For->getForLoc() : CXXFor->getForLoc()); 6612 6613 // Check init. 6614 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6615 if (ISC.checkAndSetInit(Init)) 6616 return true; 6617 6618 bool HasErrors = false; 6619 6620 // Check loop variable's type. 6621 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6622 // OpenMP [2.6, Canonical Loop Form] 6623 // Var is one of the following: 6624 // A variable of signed or unsigned integer type. 6625 // For C++, a variable of a random access iterator type. 6626 // For C, a variable of a pointer type. 6627 QualType VarType = LCDecl->getType().getNonReferenceType(); 6628 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6629 !VarType->isPointerType() && 6630 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6631 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6632 << SemaRef.getLangOpts().CPlusPlus; 6633 HasErrors = true; 6634 } 6635 6636 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6637 // a Construct 6638 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6639 // parallel for construct is (are) private. 6640 // The loop iteration variable in the associated for-loop of a simd 6641 // construct with just one associated for-loop is linear with a 6642 // constant-linear-step that is the increment of the associated for-loop. 6643 // Exclude loop var from the list of variables with implicitly defined data 6644 // sharing attributes. 6645 VarsWithImplicitDSA.erase(LCDecl); 6646 6647 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6648 6649 // Check test-expr. 6650 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6651 6652 // Check incr-expr. 6653 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6654 } 6655 6656 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6657 return HasErrors; 6658 6659 // Build the loop's iteration space representation. 6660 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6661 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6662 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6663 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6664 (isOpenMPWorksharingDirective(DKind) || 6665 isOpenMPTaskLoopDirective(DKind) || 6666 isOpenMPDistributeDirective(DKind)), 6667 Captures); 6668 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6669 ISC.buildCounterVar(Captures, DSA); 6670 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6671 ISC.buildPrivateCounterVar(); 6672 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6673 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6674 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6675 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6676 ISC.getConditionSrcRange(); 6677 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6678 ISC.getIncrementSrcRange(); 6679 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6680 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6681 ISC.isStrictTestOp(); 6682 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6683 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6684 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6685 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6686 ISC.buildFinalCondition(DSA.getCurScope()); 6687 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6688 ISC.doesInitDependOnLC(); 6689 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6690 ISC.doesCondDependOnLC(); 6691 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6692 ISC.getLoopDependentIdx(); 6693 6694 HasErrors |= 6695 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6696 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6697 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6698 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6699 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6700 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6701 if (!HasErrors && DSA.isOrderedRegion()) { 6702 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6703 if (CurrentNestedLoopCount < 6704 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6705 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6706 CurrentNestedLoopCount, 6707 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6708 DSA.getOrderedRegionParam().second->setLoopCounter( 6709 CurrentNestedLoopCount, 6710 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6711 } 6712 } 6713 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6714 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6715 // Erroneous case - clause has some problems. 6716 continue; 6717 } 6718 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6719 Pair.second.size() <= CurrentNestedLoopCount) { 6720 // Erroneous case - clause has some problems. 6721 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6722 continue; 6723 } 6724 Expr *CntValue; 6725 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6726 CntValue = ISC.buildOrderedLoopData( 6727 DSA.getCurScope(), 6728 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6729 Pair.first->getDependencyLoc()); 6730 else 6731 CntValue = ISC.buildOrderedLoopData( 6732 DSA.getCurScope(), 6733 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6734 Pair.first->getDependencyLoc(), 6735 Pair.second[CurrentNestedLoopCount].first, 6736 Pair.second[CurrentNestedLoopCount].second); 6737 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6738 } 6739 } 6740 6741 return HasErrors; 6742 } 6743 6744 /// Build 'VarRef = Start. 6745 static ExprResult 6746 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6747 ExprResult Start, bool IsNonRectangularLB, 6748 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6749 // Build 'VarRef = Start. 6750 ExprResult NewStart = IsNonRectangularLB 6751 ? Start.get() 6752 : tryBuildCapture(SemaRef, Start.get(), Captures); 6753 if (!NewStart.isUsable()) 6754 return ExprError(); 6755 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6756 VarRef.get()->getType())) { 6757 NewStart = SemaRef.PerformImplicitConversion( 6758 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6759 /*AllowExplicit=*/true); 6760 if (!NewStart.isUsable()) 6761 return ExprError(); 6762 } 6763 6764 ExprResult Init = 6765 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6766 return Init; 6767 } 6768 6769 /// Build 'VarRef = Start + Iter * Step'. 6770 static ExprResult buildCounterUpdate( 6771 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6772 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6773 bool IsNonRectangularLB, 6774 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6775 // Add parentheses (for debugging purposes only). 6776 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6777 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6778 !Step.isUsable()) 6779 return ExprError(); 6780 6781 ExprResult NewStep = Step; 6782 if (Captures) 6783 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6784 if (NewStep.isInvalid()) 6785 return ExprError(); 6786 ExprResult Update = 6787 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6788 if (!Update.isUsable()) 6789 return ExprError(); 6790 6791 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6792 // 'VarRef = Start (+|-) Iter * Step'. 6793 if (!Start.isUsable()) 6794 return ExprError(); 6795 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6796 if (!NewStart.isUsable()) 6797 return ExprError(); 6798 if (Captures && !IsNonRectangularLB) 6799 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6800 if (NewStart.isInvalid()) 6801 return ExprError(); 6802 6803 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6804 ExprResult SavedUpdate = Update; 6805 ExprResult UpdateVal; 6806 if (VarRef.get()->getType()->isOverloadableType() || 6807 NewStart.get()->getType()->isOverloadableType() || 6808 Update.get()->getType()->isOverloadableType()) { 6809 Sema::TentativeAnalysisScope Trap(SemaRef); 6810 6811 Update = 6812 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6813 if (Update.isUsable()) { 6814 UpdateVal = 6815 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6816 VarRef.get(), SavedUpdate.get()); 6817 if (UpdateVal.isUsable()) { 6818 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6819 UpdateVal.get()); 6820 } 6821 } 6822 } 6823 6824 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6825 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6826 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6827 NewStart.get(), SavedUpdate.get()); 6828 if (!Update.isUsable()) 6829 return ExprError(); 6830 6831 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6832 VarRef.get()->getType())) { 6833 Update = SemaRef.PerformImplicitConversion( 6834 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6835 if (!Update.isUsable()) 6836 return ExprError(); 6837 } 6838 6839 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6840 } 6841 return Update; 6842 } 6843 6844 /// Convert integer expression \a E to make it have at least \a Bits 6845 /// bits. 6846 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6847 if (E == nullptr) 6848 return ExprError(); 6849 ASTContext &C = SemaRef.Context; 6850 QualType OldType = E->getType(); 6851 unsigned HasBits = C.getTypeSize(OldType); 6852 if (HasBits >= Bits) 6853 return ExprResult(E); 6854 // OK to convert to signed, because new type has more bits than old. 6855 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6856 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6857 true); 6858 } 6859 6860 /// Check if the given expression \a E is a constant integer that fits 6861 /// into \a Bits bits. 6862 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6863 if (E == nullptr) 6864 return false; 6865 llvm::APSInt Result; 6866 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6867 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6868 return false; 6869 } 6870 6871 /// Build preinits statement for the given declarations. 6872 static Stmt *buildPreInits(ASTContext &Context, 6873 MutableArrayRef<Decl *> PreInits) { 6874 if (!PreInits.empty()) { 6875 return new (Context) DeclStmt( 6876 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6877 SourceLocation(), SourceLocation()); 6878 } 6879 return nullptr; 6880 } 6881 6882 /// Build preinits statement for the given declarations. 6883 static Stmt * 6884 buildPreInits(ASTContext &Context, 6885 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6886 if (!Captures.empty()) { 6887 SmallVector<Decl *, 16> PreInits; 6888 for (const auto &Pair : Captures) 6889 PreInits.push_back(Pair.second->getDecl()); 6890 return buildPreInits(Context, PreInits); 6891 } 6892 return nullptr; 6893 } 6894 6895 /// Build postupdate expression for the given list of postupdates expressions. 6896 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6897 Expr *PostUpdate = nullptr; 6898 if (!PostUpdates.empty()) { 6899 for (Expr *E : PostUpdates) { 6900 Expr *ConvE = S.BuildCStyleCastExpr( 6901 E->getExprLoc(), 6902 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6903 E->getExprLoc(), E) 6904 .get(); 6905 PostUpdate = PostUpdate 6906 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6907 PostUpdate, ConvE) 6908 .get() 6909 : ConvE; 6910 } 6911 } 6912 return PostUpdate; 6913 } 6914 6915 /// Called on a for stmt to check itself and nested loops (if any). 6916 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6917 /// number of collapsed loops otherwise. 6918 static unsigned 6919 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6920 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6921 DSAStackTy &DSA, 6922 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6923 OMPLoopDirective::HelperExprs &Built) { 6924 unsigned NestedLoopCount = 1; 6925 if (CollapseLoopCountExpr) { 6926 // Found 'collapse' clause - calculate collapse number. 6927 Expr::EvalResult Result; 6928 if (!CollapseLoopCountExpr->isValueDependent() && 6929 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6930 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6931 } else { 6932 Built.clear(/*Size=*/1); 6933 return 1; 6934 } 6935 } 6936 unsigned OrderedLoopCount = 1; 6937 if (OrderedLoopCountExpr) { 6938 // Found 'ordered' clause - calculate collapse number. 6939 Expr::EvalResult EVResult; 6940 if (!OrderedLoopCountExpr->isValueDependent() && 6941 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6942 SemaRef.getASTContext())) { 6943 llvm::APSInt Result = EVResult.Val.getInt(); 6944 if (Result.getLimitedValue() < NestedLoopCount) { 6945 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6946 diag::err_omp_wrong_ordered_loop_count) 6947 << OrderedLoopCountExpr->getSourceRange(); 6948 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6949 diag::note_collapse_loop_count) 6950 << CollapseLoopCountExpr->getSourceRange(); 6951 } 6952 OrderedLoopCount = Result.getLimitedValue(); 6953 } else { 6954 Built.clear(/*Size=*/1); 6955 return 1; 6956 } 6957 } 6958 // This is helper routine for loop directives (e.g., 'for', 'simd', 6959 // 'for simd', etc.). 6960 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6961 SmallVector<LoopIterationSpace, 4> IterSpaces( 6962 std::max(OrderedLoopCount, NestedLoopCount)); 6963 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6964 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6965 if (checkOpenMPIterationSpace( 6966 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6967 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6968 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6969 return 0; 6970 // Move on to the next nested for loop, or to the loop body. 6971 // OpenMP [2.8.1, simd construct, Restrictions] 6972 // All loops associated with the construct must be perfectly nested; that 6973 // is, there must be no intervening code nor any OpenMP directive between 6974 // any two loops. 6975 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6976 CurStmt = For->getBody(); 6977 } else { 6978 assert(isa<CXXForRangeStmt>(CurStmt) && 6979 "Expected canonical for or range-based for loops."); 6980 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6981 } 6982 CurStmt = CurStmt->IgnoreContainers(); 6983 } 6984 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6985 if (checkOpenMPIterationSpace( 6986 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6987 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6988 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6989 return 0; 6990 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6991 // Handle initialization of captured loop iterator variables. 6992 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6993 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6994 Captures[DRE] = DRE; 6995 } 6996 } 6997 // Move on to the next nested for loop, or to the loop body. 6998 // OpenMP [2.8.1, simd construct, Restrictions] 6999 // All loops associated with the construct must be perfectly nested; that 7000 // is, there must be no intervening code nor any OpenMP directive between 7001 // any two loops. 7002 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7003 CurStmt = For->getBody(); 7004 } else { 7005 assert(isa<CXXForRangeStmt>(CurStmt) && 7006 "Expected canonical for or range-based for loops."); 7007 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7008 } 7009 CurStmt = CurStmt->IgnoreContainers(); 7010 } 7011 7012 Built.clear(/* size */ NestedLoopCount); 7013 7014 if (SemaRef.CurContext->isDependentContext()) 7015 return NestedLoopCount; 7016 7017 // An example of what is generated for the following code: 7018 // 7019 // #pragma omp simd collapse(2) ordered(2) 7020 // for (i = 0; i < NI; ++i) 7021 // for (k = 0; k < NK; ++k) 7022 // for (j = J0; j < NJ; j+=2) { 7023 // <loop body> 7024 // } 7025 // 7026 // We generate the code below. 7027 // Note: the loop body may be outlined in CodeGen. 7028 // Note: some counters may be C++ classes, operator- is used to find number of 7029 // iterations and operator+= to calculate counter value. 7030 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7031 // or i64 is currently supported). 7032 // 7033 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7034 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7035 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7036 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7037 // // similar updates for vars in clauses (e.g. 'linear') 7038 // <loop body (using local i and j)> 7039 // } 7040 // i = NI; // assign final values of counters 7041 // j = NJ; 7042 // 7043 7044 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7045 // the iteration counts of the collapsed for loops. 7046 // Precondition tests if there is at least one iteration (all conditions are 7047 // true). 7048 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7049 Expr *N0 = IterSpaces[0].NumIterations; 7050 ExprResult LastIteration32 = 7051 widenIterationCount(/*Bits=*/32, 7052 SemaRef 7053 .PerformImplicitConversion( 7054 N0->IgnoreImpCasts(), N0->getType(), 7055 Sema::AA_Converting, /*AllowExplicit=*/true) 7056 .get(), 7057 SemaRef); 7058 ExprResult LastIteration64 = widenIterationCount( 7059 /*Bits=*/64, 7060 SemaRef 7061 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7062 Sema::AA_Converting, 7063 /*AllowExplicit=*/true) 7064 .get(), 7065 SemaRef); 7066 7067 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7068 return NestedLoopCount; 7069 7070 ASTContext &C = SemaRef.Context; 7071 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7072 7073 Scope *CurScope = DSA.getCurScope(); 7074 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7075 if (PreCond.isUsable()) { 7076 PreCond = 7077 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7078 PreCond.get(), IterSpaces[Cnt].PreCond); 7079 } 7080 Expr *N = IterSpaces[Cnt].NumIterations; 7081 SourceLocation Loc = N->getExprLoc(); 7082 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7083 if (LastIteration32.isUsable()) 7084 LastIteration32 = SemaRef.BuildBinOp( 7085 CurScope, Loc, BO_Mul, LastIteration32.get(), 7086 SemaRef 7087 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7088 Sema::AA_Converting, 7089 /*AllowExplicit=*/true) 7090 .get()); 7091 if (LastIteration64.isUsable()) 7092 LastIteration64 = SemaRef.BuildBinOp( 7093 CurScope, Loc, BO_Mul, LastIteration64.get(), 7094 SemaRef 7095 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7096 Sema::AA_Converting, 7097 /*AllowExplicit=*/true) 7098 .get()); 7099 } 7100 7101 // Choose either the 32-bit or 64-bit version. 7102 ExprResult LastIteration = LastIteration64; 7103 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7104 (LastIteration32.isUsable() && 7105 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7106 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7107 fitsInto( 7108 /*Bits=*/32, 7109 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7110 LastIteration64.get(), SemaRef)))) 7111 LastIteration = LastIteration32; 7112 QualType VType = LastIteration.get()->getType(); 7113 QualType RealVType = VType; 7114 QualType StrideVType = VType; 7115 if (isOpenMPTaskLoopDirective(DKind)) { 7116 VType = 7117 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7118 StrideVType = 7119 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7120 } 7121 7122 if (!LastIteration.isUsable()) 7123 return 0; 7124 7125 // Save the number of iterations. 7126 ExprResult NumIterations = LastIteration; 7127 { 7128 LastIteration = SemaRef.BuildBinOp( 7129 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7130 LastIteration.get(), 7131 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7132 if (!LastIteration.isUsable()) 7133 return 0; 7134 } 7135 7136 // Calculate the last iteration number beforehand instead of doing this on 7137 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7138 llvm::APSInt Result; 7139 bool IsConstant = 7140 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7141 ExprResult CalcLastIteration; 7142 if (!IsConstant) { 7143 ExprResult SaveRef = 7144 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7145 LastIteration = SaveRef; 7146 7147 // Prepare SaveRef + 1. 7148 NumIterations = SemaRef.BuildBinOp( 7149 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7150 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7151 if (!NumIterations.isUsable()) 7152 return 0; 7153 } 7154 7155 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7156 7157 // Build variables passed into runtime, necessary for worksharing directives. 7158 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7159 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7160 isOpenMPDistributeDirective(DKind)) { 7161 // Lower bound variable, initialized with zero. 7162 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7163 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7164 SemaRef.AddInitializerToDecl(LBDecl, 7165 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7166 /*DirectInit*/ false); 7167 7168 // Upper bound variable, initialized with last iteration number. 7169 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7170 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7171 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7172 /*DirectInit*/ false); 7173 7174 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7175 // This will be used to implement clause 'lastprivate'. 7176 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7177 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7178 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7179 SemaRef.AddInitializerToDecl(ILDecl, 7180 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7181 /*DirectInit*/ false); 7182 7183 // Stride variable returned by runtime (we initialize it to 1 by default). 7184 VarDecl *STDecl = 7185 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7186 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7187 SemaRef.AddInitializerToDecl(STDecl, 7188 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7189 /*DirectInit*/ false); 7190 7191 // Build expression: UB = min(UB, LastIteration) 7192 // It is necessary for CodeGen of directives with static scheduling. 7193 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7194 UB.get(), LastIteration.get()); 7195 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7196 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7197 LastIteration.get(), UB.get()); 7198 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7199 CondOp.get()); 7200 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7201 7202 // If we have a combined directive that combines 'distribute', 'for' or 7203 // 'simd' we need to be able to access the bounds of the schedule of the 7204 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7205 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7206 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7207 // Lower bound variable, initialized with zero. 7208 VarDecl *CombLBDecl = 7209 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7210 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7211 SemaRef.AddInitializerToDecl( 7212 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7213 /*DirectInit*/ false); 7214 7215 // Upper bound variable, initialized with last iteration number. 7216 VarDecl *CombUBDecl = 7217 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7218 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7219 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7220 /*DirectInit*/ false); 7221 7222 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7223 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7224 ExprResult CombCondOp = 7225 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7226 LastIteration.get(), CombUB.get()); 7227 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7228 CombCondOp.get()); 7229 CombEUB = 7230 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7231 7232 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7233 // We expect to have at least 2 more parameters than the 'parallel' 7234 // directive does - the lower and upper bounds of the previous schedule. 7235 assert(CD->getNumParams() >= 4 && 7236 "Unexpected number of parameters in loop combined directive"); 7237 7238 // Set the proper type for the bounds given what we learned from the 7239 // enclosed loops. 7240 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7241 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7242 7243 // Previous lower and upper bounds are obtained from the region 7244 // parameters. 7245 PrevLB = 7246 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7247 PrevUB = 7248 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7249 } 7250 } 7251 7252 // Build the iteration variable and its initialization before loop. 7253 ExprResult IV; 7254 ExprResult Init, CombInit; 7255 { 7256 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7257 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7258 Expr *RHS = 7259 (isOpenMPWorksharingDirective(DKind) || 7260 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7261 ? LB.get() 7262 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7263 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7264 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7265 7266 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7267 Expr *CombRHS = 7268 (isOpenMPWorksharingDirective(DKind) || 7269 isOpenMPTaskLoopDirective(DKind) || 7270 isOpenMPDistributeDirective(DKind)) 7271 ? CombLB.get() 7272 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7273 CombInit = 7274 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7275 CombInit = 7276 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7277 } 7278 } 7279 7280 bool UseStrictCompare = 7281 RealVType->hasUnsignedIntegerRepresentation() && 7282 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7283 return LIS.IsStrictCompare; 7284 }); 7285 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7286 // unsigned IV)) for worksharing loops. 7287 SourceLocation CondLoc = AStmt->getBeginLoc(); 7288 Expr *BoundUB = UB.get(); 7289 if (UseStrictCompare) { 7290 BoundUB = 7291 SemaRef 7292 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7293 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7294 .get(); 7295 BoundUB = 7296 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7297 } 7298 ExprResult Cond = 7299 (isOpenMPWorksharingDirective(DKind) || 7300 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7301 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7302 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7303 BoundUB) 7304 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7305 NumIterations.get()); 7306 ExprResult CombDistCond; 7307 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7308 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7309 NumIterations.get()); 7310 } 7311 7312 ExprResult CombCond; 7313 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7314 Expr *BoundCombUB = CombUB.get(); 7315 if (UseStrictCompare) { 7316 BoundCombUB = 7317 SemaRef 7318 .BuildBinOp( 7319 CurScope, CondLoc, BO_Add, BoundCombUB, 7320 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7321 .get(); 7322 BoundCombUB = 7323 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7324 .get(); 7325 } 7326 CombCond = 7327 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7328 IV.get(), BoundCombUB); 7329 } 7330 // Loop increment (IV = IV + 1) 7331 SourceLocation IncLoc = AStmt->getBeginLoc(); 7332 ExprResult Inc = 7333 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7334 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7335 if (!Inc.isUsable()) 7336 return 0; 7337 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7338 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7339 if (!Inc.isUsable()) 7340 return 0; 7341 7342 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7343 // Used for directives with static scheduling. 7344 // In combined construct, add combined version that use CombLB and CombUB 7345 // base variables for the update 7346 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7347 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7348 isOpenMPDistributeDirective(DKind)) { 7349 // LB + ST 7350 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7351 if (!NextLB.isUsable()) 7352 return 0; 7353 // LB = LB + ST 7354 NextLB = 7355 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7356 NextLB = 7357 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7358 if (!NextLB.isUsable()) 7359 return 0; 7360 // UB + ST 7361 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7362 if (!NextUB.isUsable()) 7363 return 0; 7364 // UB = UB + ST 7365 NextUB = 7366 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7367 NextUB = 7368 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7369 if (!NextUB.isUsable()) 7370 return 0; 7371 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7372 CombNextLB = 7373 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7374 if (!NextLB.isUsable()) 7375 return 0; 7376 // LB = LB + ST 7377 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7378 CombNextLB.get()); 7379 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7380 /*DiscardedValue*/ false); 7381 if (!CombNextLB.isUsable()) 7382 return 0; 7383 // UB + ST 7384 CombNextUB = 7385 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7386 if (!CombNextUB.isUsable()) 7387 return 0; 7388 // UB = UB + ST 7389 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7390 CombNextUB.get()); 7391 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7392 /*DiscardedValue*/ false); 7393 if (!CombNextUB.isUsable()) 7394 return 0; 7395 } 7396 } 7397 7398 // Create increment expression for distribute loop when combined in a same 7399 // directive with for as IV = IV + ST; ensure upper bound expression based 7400 // on PrevUB instead of NumIterations - used to implement 'for' when found 7401 // in combination with 'distribute', like in 'distribute parallel for' 7402 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7403 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7404 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7405 DistCond = SemaRef.BuildBinOp( 7406 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7407 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7408 7409 DistInc = 7410 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7411 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7412 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7413 DistInc.get()); 7414 DistInc = 7415 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7416 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7417 7418 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7419 // construct 7420 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7421 ExprResult IsUBGreater = 7422 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7423 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7424 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7425 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7426 CondOp.get()); 7427 PrevEUB = 7428 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7429 7430 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7431 // parallel for is in combination with a distribute directive with 7432 // schedule(static, 1) 7433 Expr *BoundPrevUB = PrevUB.get(); 7434 if (UseStrictCompare) { 7435 BoundPrevUB = 7436 SemaRef 7437 .BuildBinOp( 7438 CurScope, CondLoc, BO_Add, BoundPrevUB, 7439 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7440 .get(); 7441 BoundPrevUB = 7442 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7443 .get(); 7444 } 7445 ParForInDistCond = 7446 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7447 IV.get(), BoundPrevUB); 7448 } 7449 7450 // Build updates and final values of the loop counters. 7451 bool HasErrors = false; 7452 Built.Counters.resize(NestedLoopCount); 7453 Built.Inits.resize(NestedLoopCount); 7454 Built.Updates.resize(NestedLoopCount); 7455 Built.Finals.resize(NestedLoopCount); 7456 Built.DependentCounters.resize(NestedLoopCount); 7457 Built.DependentInits.resize(NestedLoopCount); 7458 Built.FinalsConditions.resize(NestedLoopCount); 7459 { 7460 // We implement the following algorithm for obtaining the 7461 // original loop iteration variable values based on the 7462 // value of the collapsed loop iteration variable IV. 7463 // 7464 // Let n+1 be the number of collapsed loops in the nest. 7465 // Iteration variables (I0, I1, .... In) 7466 // Iteration counts (N0, N1, ... Nn) 7467 // 7468 // Acc = IV; 7469 // 7470 // To compute Ik for loop k, 0 <= k <= n, generate: 7471 // Prod = N(k+1) * N(k+2) * ... * Nn; 7472 // Ik = Acc / Prod; 7473 // Acc -= Ik * Prod; 7474 // 7475 ExprResult Acc = IV; 7476 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7477 LoopIterationSpace &IS = IterSpaces[Cnt]; 7478 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7479 ExprResult Iter; 7480 7481 // Compute prod 7482 ExprResult Prod = 7483 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7484 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7485 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7486 IterSpaces[K].NumIterations); 7487 7488 // Iter = Acc / Prod 7489 // If there is at least one more inner loop to avoid 7490 // multiplication by 1. 7491 if (Cnt + 1 < NestedLoopCount) 7492 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7493 Acc.get(), Prod.get()); 7494 else 7495 Iter = Acc; 7496 if (!Iter.isUsable()) { 7497 HasErrors = true; 7498 break; 7499 } 7500 7501 // Update Acc: 7502 // Acc -= Iter * Prod 7503 // Check if there is at least one more inner loop to avoid 7504 // multiplication by 1. 7505 if (Cnt + 1 < NestedLoopCount) 7506 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7507 Iter.get(), Prod.get()); 7508 else 7509 Prod = Iter; 7510 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7511 Acc.get(), Prod.get()); 7512 7513 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7514 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7515 DeclRefExpr *CounterVar = buildDeclRefExpr( 7516 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7517 /*RefersToCapture=*/true); 7518 ExprResult Init = 7519 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7520 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7521 if (!Init.isUsable()) { 7522 HasErrors = true; 7523 break; 7524 } 7525 ExprResult Update = buildCounterUpdate( 7526 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7527 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7528 if (!Update.isUsable()) { 7529 HasErrors = true; 7530 break; 7531 } 7532 7533 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7534 ExprResult Final = 7535 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7536 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7537 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7538 if (!Final.isUsable()) { 7539 HasErrors = true; 7540 break; 7541 } 7542 7543 if (!Update.isUsable() || !Final.isUsable()) { 7544 HasErrors = true; 7545 break; 7546 } 7547 // Save results 7548 Built.Counters[Cnt] = IS.CounterVar; 7549 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7550 Built.Inits[Cnt] = Init.get(); 7551 Built.Updates[Cnt] = Update.get(); 7552 Built.Finals[Cnt] = Final.get(); 7553 Built.DependentCounters[Cnt] = nullptr; 7554 Built.DependentInits[Cnt] = nullptr; 7555 Built.FinalsConditions[Cnt] = nullptr; 7556 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7557 Built.DependentCounters[Cnt] = 7558 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7559 Built.DependentInits[Cnt] = 7560 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7561 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7562 } 7563 } 7564 } 7565 7566 if (HasErrors) 7567 return 0; 7568 7569 // Save results 7570 Built.IterationVarRef = IV.get(); 7571 Built.LastIteration = LastIteration.get(); 7572 Built.NumIterations = NumIterations.get(); 7573 Built.CalcLastIteration = SemaRef 7574 .ActOnFinishFullExpr(CalcLastIteration.get(), 7575 /*DiscardedValue=*/false) 7576 .get(); 7577 Built.PreCond = PreCond.get(); 7578 Built.PreInits = buildPreInits(C, Captures); 7579 Built.Cond = Cond.get(); 7580 Built.Init = Init.get(); 7581 Built.Inc = Inc.get(); 7582 Built.LB = LB.get(); 7583 Built.UB = UB.get(); 7584 Built.IL = IL.get(); 7585 Built.ST = ST.get(); 7586 Built.EUB = EUB.get(); 7587 Built.NLB = NextLB.get(); 7588 Built.NUB = NextUB.get(); 7589 Built.PrevLB = PrevLB.get(); 7590 Built.PrevUB = PrevUB.get(); 7591 Built.DistInc = DistInc.get(); 7592 Built.PrevEUB = PrevEUB.get(); 7593 Built.DistCombinedFields.LB = CombLB.get(); 7594 Built.DistCombinedFields.UB = CombUB.get(); 7595 Built.DistCombinedFields.EUB = CombEUB.get(); 7596 Built.DistCombinedFields.Init = CombInit.get(); 7597 Built.DistCombinedFields.Cond = CombCond.get(); 7598 Built.DistCombinedFields.NLB = CombNextLB.get(); 7599 Built.DistCombinedFields.NUB = CombNextUB.get(); 7600 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7601 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7602 7603 return NestedLoopCount; 7604 } 7605 7606 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7607 auto CollapseClauses = 7608 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7609 if (CollapseClauses.begin() != CollapseClauses.end()) 7610 return (*CollapseClauses.begin())->getNumForLoops(); 7611 return nullptr; 7612 } 7613 7614 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7615 auto OrderedClauses = 7616 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7617 if (OrderedClauses.begin() != OrderedClauses.end()) 7618 return (*OrderedClauses.begin())->getNumForLoops(); 7619 return nullptr; 7620 } 7621 7622 static bool checkSimdlenSafelenSpecified(Sema &S, 7623 const ArrayRef<OMPClause *> Clauses) { 7624 const OMPSafelenClause *Safelen = nullptr; 7625 const OMPSimdlenClause *Simdlen = nullptr; 7626 7627 for (const OMPClause *Clause : Clauses) { 7628 if (Clause->getClauseKind() == OMPC_safelen) 7629 Safelen = cast<OMPSafelenClause>(Clause); 7630 else if (Clause->getClauseKind() == OMPC_simdlen) 7631 Simdlen = cast<OMPSimdlenClause>(Clause); 7632 if (Safelen && Simdlen) 7633 break; 7634 } 7635 7636 if (Simdlen && Safelen) { 7637 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7638 const Expr *SafelenLength = Safelen->getSafelen(); 7639 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7640 SimdlenLength->isInstantiationDependent() || 7641 SimdlenLength->containsUnexpandedParameterPack()) 7642 return false; 7643 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7644 SafelenLength->isInstantiationDependent() || 7645 SafelenLength->containsUnexpandedParameterPack()) 7646 return false; 7647 Expr::EvalResult SimdlenResult, SafelenResult; 7648 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7649 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7650 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7651 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7652 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7653 // If both simdlen and safelen clauses are specified, the value of the 7654 // simdlen parameter must be less than or equal to the value of the safelen 7655 // parameter. 7656 if (SimdlenRes > SafelenRes) { 7657 S.Diag(SimdlenLength->getExprLoc(), 7658 diag::err_omp_wrong_simdlen_safelen_values) 7659 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7660 return true; 7661 } 7662 } 7663 return false; 7664 } 7665 7666 StmtResult 7667 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7668 SourceLocation StartLoc, SourceLocation EndLoc, 7669 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7670 if (!AStmt) 7671 return StmtError(); 7672 7673 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7674 OMPLoopDirective::HelperExprs B; 7675 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7676 // define the nested loops number. 7677 unsigned NestedLoopCount = checkOpenMPLoop( 7678 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7679 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7680 if (NestedLoopCount == 0) 7681 return StmtError(); 7682 7683 assert((CurContext->isDependentContext() || B.builtAll()) && 7684 "omp simd loop exprs were not built"); 7685 7686 if (!CurContext->isDependentContext()) { 7687 // Finalize the clauses that need pre-built expressions for CodeGen. 7688 for (OMPClause *C : Clauses) { 7689 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7690 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7691 B.NumIterations, *this, CurScope, 7692 DSAStack)) 7693 return StmtError(); 7694 } 7695 } 7696 7697 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7698 return StmtError(); 7699 7700 setFunctionHasBranchProtectedScope(); 7701 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7702 Clauses, AStmt, B); 7703 } 7704 7705 StmtResult 7706 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7707 SourceLocation StartLoc, SourceLocation EndLoc, 7708 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7709 if (!AStmt) 7710 return StmtError(); 7711 7712 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7713 OMPLoopDirective::HelperExprs B; 7714 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7715 // define the nested loops number. 7716 unsigned NestedLoopCount = checkOpenMPLoop( 7717 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7718 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7719 if (NestedLoopCount == 0) 7720 return StmtError(); 7721 7722 assert((CurContext->isDependentContext() || B.builtAll()) && 7723 "omp for loop exprs were not built"); 7724 7725 if (!CurContext->isDependentContext()) { 7726 // Finalize the clauses that need pre-built expressions for CodeGen. 7727 for (OMPClause *C : Clauses) { 7728 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7729 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7730 B.NumIterations, *this, CurScope, 7731 DSAStack)) 7732 return StmtError(); 7733 } 7734 } 7735 7736 setFunctionHasBranchProtectedScope(); 7737 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7738 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7739 } 7740 7741 StmtResult Sema::ActOnOpenMPForSimdDirective( 7742 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7743 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7744 if (!AStmt) 7745 return StmtError(); 7746 7747 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7748 OMPLoopDirective::HelperExprs B; 7749 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7750 // define the nested loops number. 7751 unsigned NestedLoopCount = 7752 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7753 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7754 VarsWithImplicitDSA, B); 7755 if (NestedLoopCount == 0) 7756 return StmtError(); 7757 7758 assert((CurContext->isDependentContext() || B.builtAll()) && 7759 "omp for simd loop exprs were not built"); 7760 7761 if (!CurContext->isDependentContext()) { 7762 // Finalize the clauses that need pre-built expressions for CodeGen. 7763 for (OMPClause *C : Clauses) { 7764 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7765 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7766 B.NumIterations, *this, CurScope, 7767 DSAStack)) 7768 return StmtError(); 7769 } 7770 } 7771 7772 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7773 return StmtError(); 7774 7775 setFunctionHasBranchProtectedScope(); 7776 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7777 Clauses, AStmt, B); 7778 } 7779 7780 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7781 Stmt *AStmt, 7782 SourceLocation StartLoc, 7783 SourceLocation EndLoc) { 7784 if (!AStmt) 7785 return StmtError(); 7786 7787 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7788 auto BaseStmt = AStmt; 7789 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7790 BaseStmt = CS->getCapturedStmt(); 7791 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7792 auto S = C->children(); 7793 if (S.begin() == S.end()) 7794 return StmtError(); 7795 // All associated statements must be '#pragma omp section' except for 7796 // the first one. 7797 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7798 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7799 if (SectionStmt) 7800 Diag(SectionStmt->getBeginLoc(), 7801 diag::err_omp_sections_substmt_not_section); 7802 return StmtError(); 7803 } 7804 cast<OMPSectionDirective>(SectionStmt) 7805 ->setHasCancel(DSAStack->isCancelRegion()); 7806 } 7807 } else { 7808 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7809 return StmtError(); 7810 } 7811 7812 setFunctionHasBranchProtectedScope(); 7813 7814 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7815 DSAStack->isCancelRegion()); 7816 } 7817 7818 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7819 SourceLocation StartLoc, 7820 SourceLocation EndLoc) { 7821 if (!AStmt) 7822 return StmtError(); 7823 7824 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7825 7826 setFunctionHasBranchProtectedScope(); 7827 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7828 7829 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7830 DSAStack->isCancelRegion()); 7831 } 7832 7833 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7834 Stmt *AStmt, 7835 SourceLocation StartLoc, 7836 SourceLocation EndLoc) { 7837 if (!AStmt) 7838 return StmtError(); 7839 7840 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7841 7842 setFunctionHasBranchProtectedScope(); 7843 7844 // OpenMP [2.7.3, single Construct, Restrictions] 7845 // The copyprivate clause must not be used with the nowait clause. 7846 const OMPClause *Nowait = nullptr; 7847 const OMPClause *Copyprivate = nullptr; 7848 for (const OMPClause *Clause : Clauses) { 7849 if (Clause->getClauseKind() == OMPC_nowait) 7850 Nowait = Clause; 7851 else if (Clause->getClauseKind() == OMPC_copyprivate) 7852 Copyprivate = Clause; 7853 if (Copyprivate && Nowait) { 7854 Diag(Copyprivate->getBeginLoc(), 7855 diag::err_omp_single_copyprivate_with_nowait); 7856 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7857 return StmtError(); 7858 } 7859 } 7860 7861 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7862 } 7863 7864 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7865 SourceLocation StartLoc, 7866 SourceLocation EndLoc) { 7867 if (!AStmt) 7868 return StmtError(); 7869 7870 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7871 7872 setFunctionHasBranchProtectedScope(); 7873 7874 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7875 } 7876 7877 StmtResult Sema::ActOnOpenMPCriticalDirective( 7878 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7879 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7880 if (!AStmt) 7881 return StmtError(); 7882 7883 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7884 7885 bool ErrorFound = false; 7886 llvm::APSInt Hint; 7887 SourceLocation HintLoc; 7888 bool DependentHint = false; 7889 for (const OMPClause *C : Clauses) { 7890 if (C->getClauseKind() == OMPC_hint) { 7891 if (!DirName.getName()) { 7892 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7893 ErrorFound = true; 7894 } 7895 Expr *E = cast<OMPHintClause>(C)->getHint(); 7896 if (E->isTypeDependent() || E->isValueDependent() || 7897 E->isInstantiationDependent()) { 7898 DependentHint = true; 7899 } else { 7900 Hint = E->EvaluateKnownConstInt(Context); 7901 HintLoc = C->getBeginLoc(); 7902 } 7903 } 7904 } 7905 if (ErrorFound) 7906 return StmtError(); 7907 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7908 if (Pair.first && DirName.getName() && !DependentHint) { 7909 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7910 Diag(StartLoc, diag::err_omp_critical_with_hint); 7911 if (HintLoc.isValid()) 7912 Diag(HintLoc, diag::note_omp_critical_hint_here) 7913 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7914 else 7915 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7916 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7917 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7918 << 1 7919 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7920 /*Radix=*/10, /*Signed=*/false); 7921 } else { 7922 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7923 } 7924 } 7925 } 7926 7927 setFunctionHasBranchProtectedScope(); 7928 7929 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7930 Clauses, AStmt); 7931 if (!Pair.first && DirName.getName() && !DependentHint) 7932 DSAStack->addCriticalWithHint(Dir, Hint); 7933 return Dir; 7934 } 7935 7936 StmtResult Sema::ActOnOpenMPParallelForDirective( 7937 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7938 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7939 if (!AStmt) 7940 return StmtError(); 7941 7942 auto *CS = cast<CapturedStmt>(AStmt); 7943 // 1.2.2 OpenMP Language Terminology 7944 // Structured block - An executable statement with a single entry at the 7945 // top and a single exit at the bottom. 7946 // The point of exit cannot be a branch out of the structured block. 7947 // longjmp() and throw() must not violate the entry/exit criteria. 7948 CS->getCapturedDecl()->setNothrow(); 7949 7950 OMPLoopDirective::HelperExprs B; 7951 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7952 // define the nested loops number. 7953 unsigned NestedLoopCount = 7954 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7955 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7956 VarsWithImplicitDSA, B); 7957 if (NestedLoopCount == 0) 7958 return StmtError(); 7959 7960 assert((CurContext->isDependentContext() || B.builtAll()) && 7961 "omp parallel for loop exprs were not built"); 7962 7963 if (!CurContext->isDependentContext()) { 7964 // Finalize the clauses that need pre-built expressions for CodeGen. 7965 for (OMPClause *C : Clauses) { 7966 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7967 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7968 B.NumIterations, *this, CurScope, 7969 DSAStack)) 7970 return StmtError(); 7971 } 7972 } 7973 7974 setFunctionHasBranchProtectedScope(); 7975 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7976 NestedLoopCount, Clauses, AStmt, B, 7977 DSAStack->isCancelRegion()); 7978 } 7979 7980 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7981 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7982 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7983 if (!AStmt) 7984 return StmtError(); 7985 7986 auto *CS = cast<CapturedStmt>(AStmt); 7987 // 1.2.2 OpenMP Language Terminology 7988 // Structured block - An executable statement with a single entry at the 7989 // top and a single exit at the bottom. 7990 // The point of exit cannot be a branch out of the structured block. 7991 // longjmp() and throw() must not violate the entry/exit criteria. 7992 CS->getCapturedDecl()->setNothrow(); 7993 7994 OMPLoopDirective::HelperExprs B; 7995 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7996 // define the nested loops number. 7997 unsigned NestedLoopCount = 7998 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7999 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8000 VarsWithImplicitDSA, B); 8001 if (NestedLoopCount == 0) 8002 return StmtError(); 8003 8004 if (!CurContext->isDependentContext()) { 8005 // Finalize the clauses that need pre-built expressions for CodeGen. 8006 for (OMPClause *C : Clauses) { 8007 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8008 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8009 B.NumIterations, *this, CurScope, 8010 DSAStack)) 8011 return StmtError(); 8012 } 8013 } 8014 8015 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8016 return StmtError(); 8017 8018 setFunctionHasBranchProtectedScope(); 8019 return OMPParallelForSimdDirective::Create( 8020 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8021 } 8022 8023 StmtResult 8024 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8025 Stmt *AStmt, SourceLocation StartLoc, 8026 SourceLocation EndLoc) { 8027 if (!AStmt) 8028 return StmtError(); 8029 8030 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8031 auto BaseStmt = AStmt; 8032 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8033 BaseStmt = CS->getCapturedStmt(); 8034 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8035 auto S = C->children(); 8036 if (S.begin() == S.end()) 8037 return StmtError(); 8038 // All associated statements must be '#pragma omp section' except for 8039 // the first one. 8040 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8041 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8042 if (SectionStmt) 8043 Diag(SectionStmt->getBeginLoc(), 8044 diag::err_omp_parallel_sections_substmt_not_section); 8045 return StmtError(); 8046 } 8047 cast<OMPSectionDirective>(SectionStmt) 8048 ->setHasCancel(DSAStack->isCancelRegion()); 8049 } 8050 } else { 8051 Diag(AStmt->getBeginLoc(), 8052 diag::err_omp_parallel_sections_not_compound_stmt); 8053 return StmtError(); 8054 } 8055 8056 setFunctionHasBranchProtectedScope(); 8057 8058 return OMPParallelSectionsDirective::Create( 8059 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8060 } 8061 8062 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8063 Stmt *AStmt, SourceLocation StartLoc, 8064 SourceLocation EndLoc) { 8065 if (!AStmt) 8066 return StmtError(); 8067 8068 auto *CS = cast<CapturedStmt>(AStmt); 8069 // 1.2.2 OpenMP Language Terminology 8070 // Structured block - An executable statement with a single entry at the 8071 // top and a single exit at the bottom. 8072 // The point of exit cannot be a branch out of the structured block. 8073 // longjmp() and throw() must not violate the entry/exit criteria. 8074 CS->getCapturedDecl()->setNothrow(); 8075 8076 setFunctionHasBranchProtectedScope(); 8077 8078 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8079 DSAStack->isCancelRegion()); 8080 } 8081 8082 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8083 SourceLocation EndLoc) { 8084 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8085 } 8086 8087 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8088 SourceLocation EndLoc) { 8089 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8090 } 8091 8092 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8093 SourceLocation EndLoc) { 8094 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8095 } 8096 8097 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8098 Stmt *AStmt, 8099 SourceLocation StartLoc, 8100 SourceLocation EndLoc) { 8101 if (!AStmt) 8102 return StmtError(); 8103 8104 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8105 8106 setFunctionHasBranchProtectedScope(); 8107 8108 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8109 AStmt, 8110 DSAStack->getTaskgroupReductionRef()); 8111 } 8112 8113 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8114 SourceLocation StartLoc, 8115 SourceLocation EndLoc) { 8116 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8117 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8118 } 8119 8120 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8121 Stmt *AStmt, 8122 SourceLocation StartLoc, 8123 SourceLocation EndLoc) { 8124 const OMPClause *DependFound = nullptr; 8125 const OMPClause *DependSourceClause = nullptr; 8126 const OMPClause *DependSinkClause = nullptr; 8127 bool ErrorFound = false; 8128 const OMPThreadsClause *TC = nullptr; 8129 const OMPSIMDClause *SC = nullptr; 8130 for (const OMPClause *C : Clauses) { 8131 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8132 DependFound = C; 8133 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8134 if (DependSourceClause) { 8135 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8136 << getOpenMPDirectiveName(OMPD_ordered) 8137 << getOpenMPClauseName(OMPC_depend) << 2; 8138 ErrorFound = true; 8139 } else { 8140 DependSourceClause = C; 8141 } 8142 if (DependSinkClause) { 8143 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8144 << 0; 8145 ErrorFound = true; 8146 } 8147 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8148 if (DependSourceClause) { 8149 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8150 << 1; 8151 ErrorFound = true; 8152 } 8153 DependSinkClause = C; 8154 } 8155 } else if (C->getClauseKind() == OMPC_threads) { 8156 TC = cast<OMPThreadsClause>(C); 8157 } else if (C->getClauseKind() == OMPC_simd) { 8158 SC = cast<OMPSIMDClause>(C); 8159 } 8160 } 8161 if (!ErrorFound && !SC && 8162 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8163 // OpenMP [2.8.1,simd Construct, Restrictions] 8164 // An ordered construct with the simd clause is the only OpenMP construct 8165 // that can appear in the simd region. 8166 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 8167 ErrorFound = true; 8168 } else if (DependFound && (TC || SC)) { 8169 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8170 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8171 ErrorFound = true; 8172 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8173 Diag(DependFound->getBeginLoc(), 8174 diag::err_omp_ordered_directive_without_param); 8175 ErrorFound = true; 8176 } else if (TC || Clauses.empty()) { 8177 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8178 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8179 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8180 << (TC != nullptr); 8181 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8182 ErrorFound = true; 8183 } 8184 } 8185 if ((!AStmt && !DependFound) || ErrorFound) 8186 return StmtError(); 8187 8188 if (AStmt) { 8189 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8190 8191 setFunctionHasBranchProtectedScope(); 8192 } 8193 8194 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8195 } 8196 8197 namespace { 8198 /// Helper class for checking expression in 'omp atomic [update]' 8199 /// construct. 8200 class OpenMPAtomicUpdateChecker { 8201 /// Error results for atomic update expressions. 8202 enum ExprAnalysisErrorCode { 8203 /// A statement is not an expression statement. 8204 NotAnExpression, 8205 /// Expression is not builtin binary or unary operation. 8206 NotABinaryOrUnaryExpression, 8207 /// Unary operation is not post-/pre- increment/decrement operation. 8208 NotAnUnaryIncDecExpression, 8209 /// An expression is not of scalar type. 8210 NotAScalarType, 8211 /// A binary operation is not an assignment operation. 8212 NotAnAssignmentOp, 8213 /// RHS part of the binary operation is not a binary expression. 8214 NotABinaryExpression, 8215 /// RHS part is not additive/multiplicative/shift/biwise binary 8216 /// expression. 8217 NotABinaryOperator, 8218 /// RHS binary operation does not have reference to the updated LHS 8219 /// part. 8220 NotAnUpdateExpression, 8221 /// No errors is found. 8222 NoError 8223 }; 8224 /// Reference to Sema. 8225 Sema &SemaRef; 8226 /// A location for note diagnostics (when error is found). 8227 SourceLocation NoteLoc; 8228 /// 'x' lvalue part of the source atomic expression. 8229 Expr *X; 8230 /// 'expr' rvalue part of the source atomic expression. 8231 Expr *E; 8232 /// Helper expression of the form 8233 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8234 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8235 Expr *UpdateExpr; 8236 /// Is 'x' a LHS in a RHS part of full update expression. It is 8237 /// important for non-associative operations. 8238 bool IsXLHSInRHSPart; 8239 BinaryOperatorKind Op; 8240 SourceLocation OpLoc; 8241 /// true if the source expression is a postfix unary operation, false 8242 /// if it is a prefix unary operation. 8243 bool IsPostfixUpdate; 8244 8245 public: 8246 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8247 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8248 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8249 /// Check specified statement that it is suitable for 'atomic update' 8250 /// constructs and extract 'x', 'expr' and Operation from the original 8251 /// expression. If DiagId and NoteId == 0, then only check is performed 8252 /// without error notification. 8253 /// \param DiagId Diagnostic which should be emitted if error is found. 8254 /// \param NoteId Diagnostic note for the main error message. 8255 /// \return true if statement is not an update expression, false otherwise. 8256 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8257 /// Return the 'x' lvalue part of the source atomic expression. 8258 Expr *getX() const { return X; } 8259 /// Return the 'expr' rvalue part of the source atomic expression. 8260 Expr *getExpr() const { return E; } 8261 /// Return the update expression used in calculation of the updated 8262 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8263 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8264 Expr *getUpdateExpr() const { return UpdateExpr; } 8265 /// Return true if 'x' is LHS in RHS part of full update expression, 8266 /// false otherwise. 8267 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8268 8269 /// true if the source expression is a postfix unary operation, false 8270 /// if it is a prefix unary operation. 8271 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8272 8273 private: 8274 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8275 unsigned NoteId = 0); 8276 }; 8277 } // namespace 8278 8279 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8280 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8281 ExprAnalysisErrorCode ErrorFound = NoError; 8282 SourceLocation ErrorLoc, NoteLoc; 8283 SourceRange ErrorRange, NoteRange; 8284 // Allowed constructs are: 8285 // x = x binop expr; 8286 // x = expr binop x; 8287 if (AtomicBinOp->getOpcode() == BO_Assign) { 8288 X = AtomicBinOp->getLHS(); 8289 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8290 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8291 if (AtomicInnerBinOp->isMultiplicativeOp() || 8292 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8293 AtomicInnerBinOp->isBitwiseOp()) { 8294 Op = AtomicInnerBinOp->getOpcode(); 8295 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8296 Expr *LHS = AtomicInnerBinOp->getLHS(); 8297 Expr *RHS = AtomicInnerBinOp->getRHS(); 8298 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8299 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8300 /*Canonical=*/true); 8301 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8302 /*Canonical=*/true); 8303 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8304 /*Canonical=*/true); 8305 if (XId == LHSId) { 8306 E = RHS; 8307 IsXLHSInRHSPart = true; 8308 } else if (XId == RHSId) { 8309 E = LHS; 8310 IsXLHSInRHSPart = false; 8311 } else { 8312 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8313 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8314 NoteLoc = X->getExprLoc(); 8315 NoteRange = X->getSourceRange(); 8316 ErrorFound = NotAnUpdateExpression; 8317 } 8318 } else { 8319 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8320 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8321 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8322 NoteRange = SourceRange(NoteLoc, NoteLoc); 8323 ErrorFound = NotABinaryOperator; 8324 } 8325 } else { 8326 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8327 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8328 ErrorFound = NotABinaryExpression; 8329 } 8330 } else { 8331 ErrorLoc = AtomicBinOp->getExprLoc(); 8332 ErrorRange = AtomicBinOp->getSourceRange(); 8333 NoteLoc = AtomicBinOp->getOperatorLoc(); 8334 NoteRange = SourceRange(NoteLoc, NoteLoc); 8335 ErrorFound = NotAnAssignmentOp; 8336 } 8337 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8338 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8339 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8340 return true; 8341 } 8342 if (SemaRef.CurContext->isDependentContext()) 8343 E = X = UpdateExpr = nullptr; 8344 return ErrorFound != NoError; 8345 } 8346 8347 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8348 unsigned NoteId) { 8349 ExprAnalysisErrorCode ErrorFound = NoError; 8350 SourceLocation ErrorLoc, NoteLoc; 8351 SourceRange ErrorRange, NoteRange; 8352 // Allowed constructs are: 8353 // x++; 8354 // x--; 8355 // ++x; 8356 // --x; 8357 // x binop= expr; 8358 // x = x binop expr; 8359 // x = expr binop x; 8360 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8361 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8362 if (AtomicBody->getType()->isScalarType() || 8363 AtomicBody->isInstantiationDependent()) { 8364 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8365 AtomicBody->IgnoreParenImpCasts())) { 8366 // Check for Compound Assignment Operation 8367 Op = BinaryOperator::getOpForCompoundAssignment( 8368 AtomicCompAssignOp->getOpcode()); 8369 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8370 E = AtomicCompAssignOp->getRHS(); 8371 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8372 IsXLHSInRHSPart = true; 8373 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8374 AtomicBody->IgnoreParenImpCasts())) { 8375 // Check for Binary Operation 8376 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8377 return true; 8378 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8379 AtomicBody->IgnoreParenImpCasts())) { 8380 // Check for Unary Operation 8381 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8382 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8383 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8384 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8385 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8386 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8387 IsXLHSInRHSPart = true; 8388 } else { 8389 ErrorFound = NotAnUnaryIncDecExpression; 8390 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8391 ErrorRange = AtomicUnaryOp->getSourceRange(); 8392 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8393 NoteRange = SourceRange(NoteLoc, NoteLoc); 8394 } 8395 } else if (!AtomicBody->isInstantiationDependent()) { 8396 ErrorFound = NotABinaryOrUnaryExpression; 8397 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8398 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8399 } 8400 } else { 8401 ErrorFound = NotAScalarType; 8402 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8403 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8404 } 8405 } else { 8406 ErrorFound = NotAnExpression; 8407 NoteLoc = ErrorLoc = S->getBeginLoc(); 8408 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8409 } 8410 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8411 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8412 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8413 return true; 8414 } 8415 if (SemaRef.CurContext->isDependentContext()) 8416 E = X = UpdateExpr = nullptr; 8417 if (ErrorFound == NoError && E && X) { 8418 // Build an update expression of form 'OpaqueValueExpr(x) binop 8419 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8420 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8421 auto *OVEX = new (SemaRef.getASTContext()) 8422 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8423 auto *OVEExpr = new (SemaRef.getASTContext()) 8424 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8425 ExprResult Update = 8426 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8427 IsXLHSInRHSPart ? OVEExpr : OVEX); 8428 if (Update.isInvalid()) 8429 return true; 8430 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8431 Sema::AA_Casting); 8432 if (Update.isInvalid()) 8433 return true; 8434 UpdateExpr = Update.get(); 8435 } 8436 return ErrorFound != NoError; 8437 } 8438 8439 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8440 Stmt *AStmt, 8441 SourceLocation StartLoc, 8442 SourceLocation EndLoc) { 8443 if (!AStmt) 8444 return StmtError(); 8445 8446 auto *CS = cast<CapturedStmt>(AStmt); 8447 // 1.2.2 OpenMP Language Terminology 8448 // Structured block - An executable statement with a single entry at the 8449 // top and a single exit at the bottom. 8450 // The point of exit cannot be a branch out of the structured block. 8451 // longjmp() and throw() must not violate the entry/exit criteria. 8452 OpenMPClauseKind AtomicKind = OMPC_unknown; 8453 SourceLocation AtomicKindLoc; 8454 for (const OMPClause *C : Clauses) { 8455 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8456 C->getClauseKind() == OMPC_update || 8457 C->getClauseKind() == OMPC_capture) { 8458 if (AtomicKind != OMPC_unknown) { 8459 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8460 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8461 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8462 << getOpenMPClauseName(AtomicKind); 8463 } else { 8464 AtomicKind = C->getClauseKind(); 8465 AtomicKindLoc = C->getBeginLoc(); 8466 } 8467 } 8468 } 8469 8470 Stmt *Body = CS->getCapturedStmt(); 8471 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8472 Body = EWC->getSubExpr(); 8473 8474 Expr *X = nullptr; 8475 Expr *V = nullptr; 8476 Expr *E = nullptr; 8477 Expr *UE = nullptr; 8478 bool IsXLHSInRHSPart = false; 8479 bool IsPostfixUpdate = false; 8480 // OpenMP [2.12.6, atomic Construct] 8481 // In the next expressions: 8482 // * x and v (as applicable) are both l-value expressions with scalar type. 8483 // * During the execution of an atomic region, multiple syntactic 8484 // occurrences of x must designate the same storage location. 8485 // * Neither of v and expr (as applicable) may access the storage location 8486 // designated by x. 8487 // * Neither of x and expr (as applicable) may access the storage location 8488 // designated by v. 8489 // * expr is an expression with scalar type. 8490 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8491 // * binop, binop=, ++, and -- are not overloaded operators. 8492 // * The expression x binop expr must be numerically equivalent to x binop 8493 // (expr). This requirement is satisfied if the operators in expr have 8494 // precedence greater than binop, or by using parentheses around expr or 8495 // subexpressions of expr. 8496 // * The expression expr binop x must be numerically equivalent to (expr) 8497 // binop x. This requirement is satisfied if the operators in expr have 8498 // precedence equal to or greater than binop, or by using parentheses around 8499 // expr or subexpressions of expr. 8500 // * For forms that allow multiple occurrences of x, the number of times 8501 // that x is evaluated is unspecified. 8502 if (AtomicKind == OMPC_read) { 8503 enum { 8504 NotAnExpression, 8505 NotAnAssignmentOp, 8506 NotAScalarType, 8507 NotAnLValue, 8508 NoError 8509 } ErrorFound = NoError; 8510 SourceLocation ErrorLoc, NoteLoc; 8511 SourceRange ErrorRange, NoteRange; 8512 // If clause is read: 8513 // v = x; 8514 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8515 const auto *AtomicBinOp = 8516 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8517 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8518 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8519 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8520 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8521 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8522 if (!X->isLValue() || !V->isLValue()) { 8523 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8524 ErrorFound = NotAnLValue; 8525 ErrorLoc = AtomicBinOp->getExprLoc(); 8526 ErrorRange = AtomicBinOp->getSourceRange(); 8527 NoteLoc = NotLValueExpr->getExprLoc(); 8528 NoteRange = NotLValueExpr->getSourceRange(); 8529 } 8530 } else if (!X->isInstantiationDependent() || 8531 !V->isInstantiationDependent()) { 8532 const Expr *NotScalarExpr = 8533 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8534 ? V 8535 : X; 8536 ErrorFound = NotAScalarType; 8537 ErrorLoc = AtomicBinOp->getExprLoc(); 8538 ErrorRange = AtomicBinOp->getSourceRange(); 8539 NoteLoc = NotScalarExpr->getExprLoc(); 8540 NoteRange = NotScalarExpr->getSourceRange(); 8541 } 8542 } else if (!AtomicBody->isInstantiationDependent()) { 8543 ErrorFound = NotAnAssignmentOp; 8544 ErrorLoc = AtomicBody->getExprLoc(); 8545 ErrorRange = AtomicBody->getSourceRange(); 8546 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8547 : AtomicBody->getExprLoc(); 8548 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8549 : AtomicBody->getSourceRange(); 8550 } 8551 } else { 8552 ErrorFound = NotAnExpression; 8553 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8554 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8555 } 8556 if (ErrorFound != NoError) { 8557 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8558 << ErrorRange; 8559 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8560 << NoteRange; 8561 return StmtError(); 8562 } 8563 if (CurContext->isDependentContext()) 8564 V = X = nullptr; 8565 } else if (AtomicKind == OMPC_write) { 8566 enum { 8567 NotAnExpression, 8568 NotAnAssignmentOp, 8569 NotAScalarType, 8570 NotAnLValue, 8571 NoError 8572 } ErrorFound = NoError; 8573 SourceLocation ErrorLoc, NoteLoc; 8574 SourceRange ErrorRange, NoteRange; 8575 // If clause is write: 8576 // x = expr; 8577 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8578 const auto *AtomicBinOp = 8579 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8580 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8581 X = AtomicBinOp->getLHS(); 8582 E = AtomicBinOp->getRHS(); 8583 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8584 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8585 if (!X->isLValue()) { 8586 ErrorFound = NotAnLValue; 8587 ErrorLoc = AtomicBinOp->getExprLoc(); 8588 ErrorRange = AtomicBinOp->getSourceRange(); 8589 NoteLoc = X->getExprLoc(); 8590 NoteRange = X->getSourceRange(); 8591 } 8592 } else if (!X->isInstantiationDependent() || 8593 !E->isInstantiationDependent()) { 8594 const Expr *NotScalarExpr = 8595 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8596 ? E 8597 : X; 8598 ErrorFound = NotAScalarType; 8599 ErrorLoc = AtomicBinOp->getExprLoc(); 8600 ErrorRange = AtomicBinOp->getSourceRange(); 8601 NoteLoc = NotScalarExpr->getExprLoc(); 8602 NoteRange = NotScalarExpr->getSourceRange(); 8603 } 8604 } else if (!AtomicBody->isInstantiationDependent()) { 8605 ErrorFound = NotAnAssignmentOp; 8606 ErrorLoc = AtomicBody->getExprLoc(); 8607 ErrorRange = AtomicBody->getSourceRange(); 8608 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8609 : AtomicBody->getExprLoc(); 8610 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8611 : AtomicBody->getSourceRange(); 8612 } 8613 } else { 8614 ErrorFound = NotAnExpression; 8615 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8616 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8617 } 8618 if (ErrorFound != NoError) { 8619 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8620 << ErrorRange; 8621 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8622 << NoteRange; 8623 return StmtError(); 8624 } 8625 if (CurContext->isDependentContext()) 8626 E = X = nullptr; 8627 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8628 // If clause is update: 8629 // x++; 8630 // x--; 8631 // ++x; 8632 // --x; 8633 // x binop= expr; 8634 // x = x binop expr; 8635 // x = expr binop x; 8636 OpenMPAtomicUpdateChecker Checker(*this); 8637 if (Checker.checkStatement( 8638 Body, (AtomicKind == OMPC_update) 8639 ? diag::err_omp_atomic_update_not_expression_statement 8640 : diag::err_omp_atomic_not_expression_statement, 8641 diag::note_omp_atomic_update)) 8642 return StmtError(); 8643 if (!CurContext->isDependentContext()) { 8644 E = Checker.getExpr(); 8645 X = Checker.getX(); 8646 UE = Checker.getUpdateExpr(); 8647 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8648 } 8649 } else if (AtomicKind == OMPC_capture) { 8650 enum { 8651 NotAnAssignmentOp, 8652 NotACompoundStatement, 8653 NotTwoSubstatements, 8654 NotASpecificExpression, 8655 NoError 8656 } ErrorFound = NoError; 8657 SourceLocation ErrorLoc, NoteLoc; 8658 SourceRange ErrorRange, NoteRange; 8659 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8660 // If clause is a capture: 8661 // v = x++; 8662 // v = x--; 8663 // v = ++x; 8664 // v = --x; 8665 // v = x binop= expr; 8666 // v = x = x binop expr; 8667 // v = x = expr binop x; 8668 const auto *AtomicBinOp = 8669 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8670 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8671 V = AtomicBinOp->getLHS(); 8672 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8673 OpenMPAtomicUpdateChecker Checker(*this); 8674 if (Checker.checkStatement( 8675 Body, diag::err_omp_atomic_capture_not_expression_statement, 8676 diag::note_omp_atomic_update)) 8677 return StmtError(); 8678 E = Checker.getExpr(); 8679 X = Checker.getX(); 8680 UE = Checker.getUpdateExpr(); 8681 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8682 IsPostfixUpdate = Checker.isPostfixUpdate(); 8683 } else if (!AtomicBody->isInstantiationDependent()) { 8684 ErrorLoc = AtomicBody->getExprLoc(); 8685 ErrorRange = AtomicBody->getSourceRange(); 8686 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8687 : AtomicBody->getExprLoc(); 8688 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8689 : AtomicBody->getSourceRange(); 8690 ErrorFound = NotAnAssignmentOp; 8691 } 8692 if (ErrorFound != NoError) { 8693 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8694 << ErrorRange; 8695 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8696 return StmtError(); 8697 } 8698 if (CurContext->isDependentContext()) 8699 UE = V = E = X = nullptr; 8700 } else { 8701 // If clause is a capture: 8702 // { v = x; x = expr; } 8703 // { v = x; x++; } 8704 // { v = x; x--; } 8705 // { v = x; ++x; } 8706 // { v = x; --x; } 8707 // { v = x; x binop= expr; } 8708 // { v = x; x = x binop expr; } 8709 // { v = x; x = expr binop x; } 8710 // { x++; v = x; } 8711 // { x--; v = x; } 8712 // { ++x; v = x; } 8713 // { --x; v = x; } 8714 // { x binop= expr; v = x; } 8715 // { x = x binop expr; v = x; } 8716 // { x = expr binop x; v = x; } 8717 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8718 // Check that this is { expr1; expr2; } 8719 if (CS->size() == 2) { 8720 Stmt *First = CS->body_front(); 8721 Stmt *Second = CS->body_back(); 8722 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8723 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8724 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8725 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8726 // Need to find what subexpression is 'v' and what is 'x'. 8727 OpenMPAtomicUpdateChecker Checker(*this); 8728 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8729 BinaryOperator *BinOp = nullptr; 8730 if (IsUpdateExprFound) { 8731 BinOp = dyn_cast<BinaryOperator>(First); 8732 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8733 } 8734 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8735 // { v = x; x++; } 8736 // { v = x; x--; } 8737 // { v = x; ++x; } 8738 // { v = x; --x; } 8739 // { v = x; x binop= expr; } 8740 // { v = x; x = x binop expr; } 8741 // { v = x; x = expr binop x; } 8742 // Check that the first expression has form v = x. 8743 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8744 llvm::FoldingSetNodeID XId, PossibleXId; 8745 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8746 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8747 IsUpdateExprFound = XId == PossibleXId; 8748 if (IsUpdateExprFound) { 8749 V = BinOp->getLHS(); 8750 X = Checker.getX(); 8751 E = Checker.getExpr(); 8752 UE = Checker.getUpdateExpr(); 8753 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8754 IsPostfixUpdate = true; 8755 } 8756 } 8757 if (!IsUpdateExprFound) { 8758 IsUpdateExprFound = !Checker.checkStatement(First); 8759 BinOp = nullptr; 8760 if (IsUpdateExprFound) { 8761 BinOp = dyn_cast<BinaryOperator>(Second); 8762 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8763 } 8764 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8765 // { x++; v = x; } 8766 // { x--; v = x; } 8767 // { ++x; v = x; } 8768 // { --x; v = x; } 8769 // { x binop= expr; v = x; } 8770 // { x = x binop expr; v = x; } 8771 // { x = expr binop x; v = x; } 8772 // Check that the second expression has form v = x. 8773 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8774 llvm::FoldingSetNodeID XId, PossibleXId; 8775 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8776 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8777 IsUpdateExprFound = XId == PossibleXId; 8778 if (IsUpdateExprFound) { 8779 V = BinOp->getLHS(); 8780 X = Checker.getX(); 8781 E = Checker.getExpr(); 8782 UE = Checker.getUpdateExpr(); 8783 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8784 IsPostfixUpdate = false; 8785 } 8786 } 8787 } 8788 if (!IsUpdateExprFound) { 8789 // { v = x; x = expr; } 8790 auto *FirstExpr = dyn_cast<Expr>(First); 8791 auto *SecondExpr = dyn_cast<Expr>(Second); 8792 if (!FirstExpr || !SecondExpr || 8793 !(FirstExpr->isInstantiationDependent() || 8794 SecondExpr->isInstantiationDependent())) { 8795 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8796 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8797 ErrorFound = NotAnAssignmentOp; 8798 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8799 : First->getBeginLoc(); 8800 NoteRange = ErrorRange = FirstBinOp 8801 ? FirstBinOp->getSourceRange() 8802 : SourceRange(ErrorLoc, ErrorLoc); 8803 } else { 8804 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8805 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8806 ErrorFound = NotAnAssignmentOp; 8807 NoteLoc = ErrorLoc = SecondBinOp 8808 ? SecondBinOp->getOperatorLoc() 8809 : Second->getBeginLoc(); 8810 NoteRange = ErrorRange = 8811 SecondBinOp ? SecondBinOp->getSourceRange() 8812 : SourceRange(ErrorLoc, ErrorLoc); 8813 } else { 8814 Expr *PossibleXRHSInFirst = 8815 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8816 Expr *PossibleXLHSInSecond = 8817 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8818 llvm::FoldingSetNodeID X1Id, X2Id; 8819 PossibleXRHSInFirst->Profile(X1Id, Context, 8820 /*Canonical=*/true); 8821 PossibleXLHSInSecond->Profile(X2Id, Context, 8822 /*Canonical=*/true); 8823 IsUpdateExprFound = X1Id == X2Id; 8824 if (IsUpdateExprFound) { 8825 V = FirstBinOp->getLHS(); 8826 X = SecondBinOp->getLHS(); 8827 E = SecondBinOp->getRHS(); 8828 UE = nullptr; 8829 IsXLHSInRHSPart = false; 8830 IsPostfixUpdate = true; 8831 } else { 8832 ErrorFound = NotASpecificExpression; 8833 ErrorLoc = FirstBinOp->getExprLoc(); 8834 ErrorRange = FirstBinOp->getSourceRange(); 8835 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8836 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8837 } 8838 } 8839 } 8840 } 8841 } 8842 } else { 8843 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8844 NoteRange = ErrorRange = 8845 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8846 ErrorFound = NotTwoSubstatements; 8847 } 8848 } else { 8849 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8850 NoteRange = ErrorRange = 8851 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8852 ErrorFound = NotACompoundStatement; 8853 } 8854 if (ErrorFound != NoError) { 8855 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8856 << ErrorRange; 8857 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8858 return StmtError(); 8859 } 8860 if (CurContext->isDependentContext()) 8861 UE = V = E = X = nullptr; 8862 } 8863 } 8864 8865 setFunctionHasBranchProtectedScope(); 8866 8867 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8868 X, V, E, UE, IsXLHSInRHSPart, 8869 IsPostfixUpdate); 8870 } 8871 8872 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8873 Stmt *AStmt, 8874 SourceLocation StartLoc, 8875 SourceLocation EndLoc) { 8876 if (!AStmt) 8877 return StmtError(); 8878 8879 auto *CS = cast<CapturedStmt>(AStmt); 8880 // 1.2.2 OpenMP Language Terminology 8881 // Structured block - An executable statement with a single entry at the 8882 // top and a single exit at the bottom. 8883 // The point of exit cannot be a branch out of the structured block. 8884 // longjmp() and throw() must not violate the entry/exit criteria. 8885 CS->getCapturedDecl()->setNothrow(); 8886 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8887 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8888 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8889 // 1.2.2 OpenMP Language Terminology 8890 // Structured block - An executable statement with a single entry at the 8891 // top and a single exit at the bottom. 8892 // The point of exit cannot be a branch out of the structured block. 8893 // longjmp() and throw() must not violate the entry/exit criteria. 8894 CS->getCapturedDecl()->setNothrow(); 8895 } 8896 8897 // OpenMP [2.16, Nesting of Regions] 8898 // If specified, a teams construct must be contained within a target 8899 // construct. That target construct must contain no statements or directives 8900 // outside of the teams construct. 8901 if (DSAStack->hasInnerTeamsRegion()) { 8902 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8903 bool OMPTeamsFound = true; 8904 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8905 auto I = CS->body_begin(); 8906 while (I != CS->body_end()) { 8907 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8908 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8909 OMPTeamsFound) { 8910 8911 OMPTeamsFound = false; 8912 break; 8913 } 8914 ++I; 8915 } 8916 assert(I != CS->body_end() && "Not found statement"); 8917 S = *I; 8918 } else { 8919 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8920 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8921 } 8922 if (!OMPTeamsFound) { 8923 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8924 Diag(DSAStack->getInnerTeamsRegionLoc(), 8925 diag::note_omp_nested_teams_construct_here); 8926 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8927 << isa<OMPExecutableDirective>(S); 8928 return StmtError(); 8929 } 8930 } 8931 8932 setFunctionHasBranchProtectedScope(); 8933 8934 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8935 } 8936 8937 StmtResult 8938 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8939 Stmt *AStmt, SourceLocation StartLoc, 8940 SourceLocation EndLoc) { 8941 if (!AStmt) 8942 return StmtError(); 8943 8944 auto *CS = cast<CapturedStmt>(AStmt); 8945 // 1.2.2 OpenMP Language Terminology 8946 // Structured block - An executable statement with a single entry at the 8947 // top and a single exit at the bottom. 8948 // The point of exit cannot be a branch out of the structured block. 8949 // longjmp() and throw() must not violate the entry/exit criteria. 8950 CS->getCapturedDecl()->setNothrow(); 8951 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8952 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8953 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8954 // 1.2.2 OpenMP Language Terminology 8955 // Structured block - An executable statement with a single entry at the 8956 // top and a single exit at the bottom. 8957 // The point of exit cannot be a branch out of the structured block. 8958 // longjmp() and throw() must not violate the entry/exit criteria. 8959 CS->getCapturedDecl()->setNothrow(); 8960 } 8961 8962 setFunctionHasBranchProtectedScope(); 8963 8964 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8965 AStmt); 8966 } 8967 8968 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8969 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8970 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8971 if (!AStmt) 8972 return StmtError(); 8973 8974 auto *CS = cast<CapturedStmt>(AStmt); 8975 // 1.2.2 OpenMP Language Terminology 8976 // Structured block - An executable statement with a single entry at the 8977 // top and a single exit at the bottom. 8978 // The point of exit cannot be a branch out of the structured block. 8979 // longjmp() and throw() must not violate the entry/exit criteria. 8980 CS->getCapturedDecl()->setNothrow(); 8981 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8982 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8983 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8984 // 1.2.2 OpenMP Language Terminology 8985 // Structured block - An executable statement with a single entry at the 8986 // top and a single exit at the bottom. 8987 // The point of exit cannot be a branch out of the structured block. 8988 // longjmp() and throw() must not violate the entry/exit criteria. 8989 CS->getCapturedDecl()->setNothrow(); 8990 } 8991 8992 OMPLoopDirective::HelperExprs B; 8993 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8994 // define the nested loops number. 8995 unsigned NestedLoopCount = 8996 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8997 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8998 VarsWithImplicitDSA, B); 8999 if (NestedLoopCount == 0) 9000 return StmtError(); 9001 9002 assert((CurContext->isDependentContext() || B.builtAll()) && 9003 "omp target parallel for loop exprs were not built"); 9004 9005 if (!CurContext->isDependentContext()) { 9006 // Finalize the clauses that need pre-built expressions for CodeGen. 9007 for (OMPClause *C : Clauses) { 9008 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9009 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9010 B.NumIterations, *this, CurScope, 9011 DSAStack)) 9012 return StmtError(); 9013 } 9014 } 9015 9016 setFunctionHasBranchProtectedScope(); 9017 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9018 NestedLoopCount, Clauses, AStmt, 9019 B, DSAStack->isCancelRegion()); 9020 } 9021 9022 /// Check for existence of a map clause in the list of clauses. 9023 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9024 const OpenMPClauseKind K) { 9025 return llvm::any_of( 9026 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9027 } 9028 9029 template <typename... Params> 9030 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9031 const Params... ClauseTypes) { 9032 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9033 } 9034 9035 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9036 Stmt *AStmt, 9037 SourceLocation StartLoc, 9038 SourceLocation EndLoc) { 9039 if (!AStmt) 9040 return StmtError(); 9041 9042 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9043 9044 // OpenMP [2.10.1, Restrictions, p. 97] 9045 // At least one map clause must appear on the directive. 9046 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9047 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9048 << "'map' or 'use_device_ptr'" 9049 << getOpenMPDirectiveName(OMPD_target_data); 9050 return StmtError(); 9051 } 9052 9053 setFunctionHasBranchProtectedScope(); 9054 9055 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9056 AStmt); 9057 } 9058 9059 StmtResult 9060 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9061 SourceLocation StartLoc, 9062 SourceLocation EndLoc, Stmt *AStmt) { 9063 if (!AStmt) 9064 return StmtError(); 9065 9066 auto *CS = cast<CapturedStmt>(AStmt); 9067 // 1.2.2 OpenMP Language Terminology 9068 // Structured block - An executable statement with a single entry at the 9069 // top and a single exit at the bottom. 9070 // The point of exit cannot be a branch out of the structured block. 9071 // longjmp() and throw() must not violate the entry/exit criteria. 9072 CS->getCapturedDecl()->setNothrow(); 9073 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9074 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9075 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9076 // 1.2.2 OpenMP Language Terminology 9077 // Structured block - An executable statement with a single entry at the 9078 // top and a single exit at the bottom. 9079 // The point of exit cannot be a branch out of the structured block. 9080 // longjmp() and throw() must not violate the entry/exit criteria. 9081 CS->getCapturedDecl()->setNothrow(); 9082 } 9083 9084 // OpenMP [2.10.2, Restrictions, p. 99] 9085 // At least one map clause must appear on the directive. 9086 if (!hasClauses(Clauses, OMPC_map)) { 9087 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9088 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9089 return StmtError(); 9090 } 9091 9092 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9093 AStmt); 9094 } 9095 9096 StmtResult 9097 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9098 SourceLocation StartLoc, 9099 SourceLocation EndLoc, Stmt *AStmt) { 9100 if (!AStmt) 9101 return StmtError(); 9102 9103 auto *CS = cast<CapturedStmt>(AStmt); 9104 // 1.2.2 OpenMP Language Terminology 9105 // Structured block - An executable statement with a single entry at the 9106 // top and a single exit at the bottom. 9107 // The point of exit cannot be a branch out of the structured block. 9108 // longjmp() and throw() must not violate the entry/exit criteria. 9109 CS->getCapturedDecl()->setNothrow(); 9110 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9111 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9112 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9113 // 1.2.2 OpenMP Language Terminology 9114 // Structured block - An executable statement with a single entry at the 9115 // top and a single exit at the bottom. 9116 // The point of exit cannot be a branch out of the structured block. 9117 // longjmp() and throw() must not violate the entry/exit criteria. 9118 CS->getCapturedDecl()->setNothrow(); 9119 } 9120 9121 // OpenMP [2.10.3, Restrictions, p. 102] 9122 // At least one map clause must appear on the directive. 9123 if (!hasClauses(Clauses, OMPC_map)) { 9124 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9125 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9126 return StmtError(); 9127 } 9128 9129 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9130 AStmt); 9131 } 9132 9133 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9134 SourceLocation StartLoc, 9135 SourceLocation EndLoc, 9136 Stmt *AStmt) { 9137 if (!AStmt) 9138 return StmtError(); 9139 9140 auto *CS = cast<CapturedStmt>(AStmt); 9141 // 1.2.2 OpenMP Language Terminology 9142 // Structured block - An executable statement with a single entry at the 9143 // top and a single exit at the bottom. 9144 // The point of exit cannot be a branch out of the structured block. 9145 // longjmp() and throw() must not violate the entry/exit criteria. 9146 CS->getCapturedDecl()->setNothrow(); 9147 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9148 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9149 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9150 // 1.2.2 OpenMP Language Terminology 9151 // Structured block - An executable statement with a single entry at the 9152 // top and a single exit at the bottom. 9153 // The point of exit cannot be a branch out of the structured block. 9154 // longjmp() and throw() must not violate the entry/exit criteria. 9155 CS->getCapturedDecl()->setNothrow(); 9156 } 9157 9158 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9159 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9160 return StmtError(); 9161 } 9162 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9163 AStmt); 9164 } 9165 9166 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9167 Stmt *AStmt, SourceLocation StartLoc, 9168 SourceLocation EndLoc) { 9169 if (!AStmt) 9170 return StmtError(); 9171 9172 auto *CS = cast<CapturedStmt>(AStmt); 9173 // 1.2.2 OpenMP Language Terminology 9174 // Structured block - An executable statement with a single entry at the 9175 // top and a single exit at the bottom. 9176 // The point of exit cannot be a branch out of the structured block. 9177 // longjmp() and throw() must not violate the entry/exit criteria. 9178 CS->getCapturedDecl()->setNothrow(); 9179 9180 setFunctionHasBranchProtectedScope(); 9181 9182 DSAStack->setParentTeamsRegionLoc(StartLoc); 9183 9184 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9185 } 9186 9187 StmtResult 9188 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9189 SourceLocation EndLoc, 9190 OpenMPDirectiveKind CancelRegion) { 9191 if (DSAStack->isParentNowaitRegion()) { 9192 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9193 return StmtError(); 9194 } 9195 if (DSAStack->isParentOrderedRegion()) { 9196 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9197 return StmtError(); 9198 } 9199 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9200 CancelRegion); 9201 } 9202 9203 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9204 SourceLocation StartLoc, 9205 SourceLocation EndLoc, 9206 OpenMPDirectiveKind CancelRegion) { 9207 if (DSAStack->isParentNowaitRegion()) { 9208 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9209 return StmtError(); 9210 } 9211 if (DSAStack->isParentOrderedRegion()) { 9212 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9213 return StmtError(); 9214 } 9215 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9216 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9217 CancelRegion); 9218 } 9219 9220 static bool checkGrainsizeNumTasksClauses(Sema &S, 9221 ArrayRef<OMPClause *> Clauses) { 9222 const OMPClause *PrevClause = nullptr; 9223 bool ErrorFound = false; 9224 for (const OMPClause *C : Clauses) { 9225 if (C->getClauseKind() == OMPC_grainsize || 9226 C->getClauseKind() == OMPC_num_tasks) { 9227 if (!PrevClause) 9228 PrevClause = C; 9229 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9230 S.Diag(C->getBeginLoc(), 9231 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9232 << getOpenMPClauseName(C->getClauseKind()) 9233 << getOpenMPClauseName(PrevClause->getClauseKind()); 9234 S.Diag(PrevClause->getBeginLoc(), 9235 diag::note_omp_previous_grainsize_num_tasks) 9236 << getOpenMPClauseName(PrevClause->getClauseKind()); 9237 ErrorFound = true; 9238 } 9239 } 9240 } 9241 return ErrorFound; 9242 } 9243 9244 static bool checkReductionClauseWithNogroup(Sema &S, 9245 ArrayRef<OMPClause *> Clauses) { 9246 const OMPClause *ReductionClause = nullptr; 9247 const OMPClause *NogroupClause = nullptr; 9248 for (const OMPClause *C : Clauses) { 9249 if (C->getClauseKind() == OMPC_reduction) { 9250 ReductionClause = C; 9251 if (NogroupClause) 9252 break; 9253 continue; 9254 } 9255 if (C->getClauseKind() == OMPC_nogroup) { 9256 NogroupClause = C; 9257 if (ReductionClause) 9258 break; 9259 continue; 9260 } 9261 } 9262 if (ReductionClause && NogroupClause) { 9263 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9264 << SourceRange(NogroupClause->getBeginLoc(), 9265 NogroupClause->getEndLoc()); 9266 return true; 9267 } 9268 return false; 9269 } 9270 9271 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9272 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9273 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9274 if (!AStmt) 9275 return StmtError(); 9276 9277 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9278 OMPLoopDirective::HelperExprs B; 9279 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9280 // define the nested loops number. 9281 unsigned NestedLoopCount = 9282 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9283 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9284 VarsWithImplicitDSA, B); 9285 if (NestedLoopCount == 0) 9286 return StmtError(); 9287 9288 assert((CurContext->isDependentContext() || B.builtAll()) && 9289 "omp for loop exprs were not built"); 9290 9291 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9292 // The grainsize clause and num_tasks clause are mutually exclusive and may 9293 // not appear on the same taskloop directive. 9294 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9295 return StmtError(); 9296 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9297 // If a reduction clause is present on the taskloop directive, the nogroup 9298 // clause must not be specified. 9299 if (checkReductionClauseWithNogroup(*this, Clauses)) 9300 return StmtError(); 9301 9302 setFunctionHasBranchProtectedScope(); 9303 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9304 NestedLoopCount, Clauses, AStmt, B); 9305 } 9306 9307 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9308 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9309 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9310 if (!AStmt) 9311 return StmtError(); 9312 9313 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9314 OMPLoopDirective::HelperExprs B; 9315 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9316 // define the nested loops number. 9317 unsigned NestedLoopCount = 9318 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9319 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9320 VarsWithImplicitDSA, B); 9321 if (NestedLoopCount == 0) 9322 return StmtError(); 9323 9324 assert((CurContext->isDependentContext() || B.builtAll()) && 9325 "omp for loop exprs were not built"); 9326 9327 if (!CurContext->isDependentContext()) { 9328 // Finalize the clauses that need pre-built expressions for CodeGen. 9329 for (OMPClause *C : Clauses) { 9330 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9331 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9332 B.NumIterations, *this, CurScope, 9333 DSAStack)) 9334 return StmtError(); 9335 } 9336 } 9337 9338 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9339 // The grainsize clause and num_tasks clause are mutually exclusive and may 9340 // not appear on the same taskloop directive. 9341 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9342 return StmtError(); 9343 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9344 // If a reduction clause is present on the taskloop directive, the nogroup 9345 // clause must not be specified. 9346 if (checkReductionClauseWithNogroup(*this, Clauses)) 9347 return StmtError(); 9348 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9349 return StmtError(); 9350 9351 setFunctionHasBranchProtectedScope(); 9352 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9353 NestedLoopCount, Clauses, AStmt, B); 9354 } 9355 9356 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9357 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9358 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9359 if (!AStmt) 9360 return StmtError(); 9361 9362 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9363 OMPLoopDirective::HelperExprs B; 9364 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9365 // define the nested loops number. 9366 unsigned NestedLoopCount = 9367 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9368 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9369 VarsWithImplicitDSA, B); 9370 if (NestedLoopCount == 0) 9371 return StmtError(); 9372 9373 assert((CurContext->isDependentContext() || B.builtAll()) && 9374 "omp for loop exprs were not built"); 9375 9376 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9377 // The grainsize clause and num_tasks clause are mutually exclusive and may 9378 // not appear on the same taskloop directive. 9379 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9380 return StmtError(); 9381 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9382 // If a reduction clause is present on the taskloop directive, the nogroup 9383 // clause must not be specified. 9384 if (checkReductionClauseWithNogroup(*this, Clauses)) 9385 return StmtError(); 9386 9387 setFunctionHasBranchProtectedScope(); 9388 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9389 NestedLoopCount, Clauses, AStmt, B); 9390 } 9391 9392 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9393 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9394 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9395 if (!AStmt) 9396 return StmtError(); 9397 9398 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9399 OMPLoopDirective::HelperExprs B; 9400 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9401 // define the nested loops number. 9402 unsigned NestedLoopCount = 9403 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9404 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9405 VarsWithImplicitDSA, B); 9406 if (NestedLoopCount == 0) 9407 return StmtError(); 9408 9409 assert((CurContext->isDependentContext() || B.builtAll()) && 9410 "omp for loop exprs were not built"); 9411 9412 if (!CurContext->isDependentContext()) { 9413 // Finalize the clauses that need pre-built expressions for CodeGen. 9414 for (OMPClause *C : Clauses) { 9415 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9416 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9417 B.NumIterations, *this, CurScope, 9418 DSAStack)) 9419 return StmtError(); 9420 } 9421 } 9422 9423 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9424 // The grainsize clause and num_tasks clause are mutually exclusive and may 9425 // not appear on the same taskloop directive. 9426 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9427 return StmtError(); 9428 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9429 // If a reduction clause is present on the taskloop directive, the nogroup 9430 // clause must not be specified. 9431 if (checkReductionClauseWithNogroup(*this, Clauses)) 9432 return StmtError(); 9433 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9434 return StmtError(); 9435 9436 setFunctionHasBranchProtectedScope(); 9437 return OMPMasterTaskLoopSimdDirective::Create( 9438 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9439 } 9440 9441 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9442 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9443 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9444 if (!AStmt) 9445 return StmtError(); 9446 9447 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9448 auto *CS = cast<CapturedStmt>(AStmt); 9449 // 1.2.2 OpenMP Language Terminology 9450 // Structured block - An executable statement with a single entry at the 9451 // top and a single exit at the bottom. 9452 // The point of exit cannot be a branch out of the structured block. 9453 // longjmp() and throw() must not violate the entry/exit criteria. 9454 CS->getCapturedDecl()->setNothrow(); 9455 for (int ThisCaptureLevel = 9456 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9457 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9458 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9459 // 1.2.2 OpenMP Language Terminology 9460 // Structured block - An executable statement with a single entry at the 9461 // top and a single exit at the bottom. 9462 // The point of exit cannot be a branch out of the structured block. 9463 // longjmp() and throw() must not violate the entry/exit criteria. 9464 CS->getCapturedDecl()->setNothrow(); 9465 } 9466 9467 OMPLoopDirective::HelperExprs B; 9468 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9469 // define the nested loops number. 9470 unsigned NestedLoopCount = checkOpenMPLoop( 9471 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9472 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9473 VarsWithImplicitDSA, B); 9474 if (NestedLoopCount == 0) 9475 return StmtError(); 9476 9477 assert((CurContext->isDependentContext() || B.builtAll()) && 9478 "omp for loop exprs were not built"); 9479 9480 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9481 // The grainsize clause and num_tasks clause are mutually exclusive and may 9482 // not appear on the same taskloop directive. 9483 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9484 return StmtError(); 9485 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9486 // If a reduction clause is present on the taskloop directive, the nogroup 9487 // clause must not be specified. 9488 if (checkReductionClauseWithNogroup(*this, Clauses)) 9489 return StmtError(); 9490 9491 setFunctionHasBranchProtectedScope(); 9492 return OMPParallelMasterTaskLoopDirective::Create( 9493 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9494 } 9495 9496 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 9497 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9498 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9499 if (!AStmt) 9500 return StmtError(); 9501 9502 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9503 auto *CS = cast<CapturedStmt>(AStmt); 9504 // 1.2.2 OpenMP Language Terminology 9505 // Structured block - An executable statement with a single entry at the 9506 // top and a single exit at the bottom. 9507 // The point of exit cannot be a branch out of the structured block. 9508 // longjmp() and throw() must not violate the entry/exit criteria. 9509 CS->getCapturedDecl()->setNothrow(); 9510 for (int ThisCaptureLevel = 9511 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 9512 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9513 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9514 // 1.2.2 OpenMP Language Terminology 9515 // Structured block - An executable statement with a single entry at the 9516 // top and a single exit at the bottom. 9517 // The point of exit cannot be a branch out of the structured block. 9518 // longjmp() and throw() must not violate the entry/exit criteria. 9519 CS->getCapturedDecl()->setNothrow(); 9520 } 9521 9522 OMPLoopDirective::HelperExprs B; 9523 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9524 // define the nested loops number. 9525 unsigned NestedLoopCount = checkOpenMPLoop( 9526 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9527 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9528 VarsWithImplicitDSA, B); 9529 if (NestedLoopCount == 0) 9530 return StmtError(); 9531 9532 assert((CurContext->isDependentContext() || B.builtAll()) && 9533 "omp for loop exprs were not built"); 9534 9535 if (!CurContext->isDependentContext()) { 9536 // Finalize the clauses that need pre-built expressions for CodeGen. 9537 for (OMPClause *C : Clauses) { 9538 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9539 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9540 B.NumIterations, *this, CurScope, 9541 DSAStack)) 9542 return StmtError(); 9543 } 9544 } 9545 9546 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9547 // The grainsize clause and num_tasks clause are mutually exclusive and may 9548 // not appear on the same taskloop directive. 9549 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9550 return StmtError(); 9551 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9552 // If a reduction clause is present on the taskloop directive, the nogroup 9553 // clause must not be specified. 9554 if (checkReductionClauseWithNogroup(*this, Clauses)) 9555 return StmtError(); 9556 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9557 return StmtError(); 9558 9559 setFunctionHasBranchProtectedScope(); 9560 return OMPParallelMasterTaskLoopSimdDirective::Create( 9561 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9562 } 9563 9564 StmtResult Sema::ActOnOpenMPDistributeDirective( 9565 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9566 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9567 if (!AStmt) 9568 return StmtError(); 9569 9570 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9571 OMPLoopDirective::HelperExprs B; 9572 // In presence of clause 'collapse' with number of loops, it will 9573 // define the nested loops number. 9574 unsigned NestedLoopCount = 9575 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9576 nullptr /*ordered not a clause on distribute*/, AStmt, 9577 *this, *DSAStack, VarsWithImplicitDSA, B); 9578 if (NestedLoopCount == 0) 9579 return StmtError(); 9580 9581 assert((CurContext->isDependentContext() || B.builtAll()) && 9582 "omp for loop exprs were not built"); 9583 9584 setFunctionHasBranchProtectedScope(); 9585 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9586 NestedLoopCount, Clauses, AStmt, B); 9587 } 9588 9589 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9590 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9591 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9592 if (!AStmt) 9593 return StmtError(); 9594 9595 auto *CS = cast<CapturedStmt>(AStmt); 9596 // 1.2.2 OpenMP Language Terminology 9597 // Structured block - An executable statement with a single entry at the 9598 // top and a single exit at the bottom. 9599 // The point of exit cannot be a branch out of the structured block. 9600 // longjmp() and throw() must not violate the entry/exit criteria. 9601 CS->getCapturedDecl()->setNothrow(); 9602 for (int ThisCaptureLevel = 9603 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9604 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9605 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9606 // 1.2.2 OpenMP Language Terminology 9607 // Structured block - An executable statement with a single entry at the 9608 // top and a single exit at the bottom. 9609 // The point of exit cannot be a branch out of the structured block. 9610 // longjmp() and throw() must not violate the entry/exit criteria. 9611 CS->getCapturedDecl()->setNothrow(); 9612 } 9613 9614 OMPLoopDirective::HelperExprs B; 9615 // In presence of clause 'collapse' with number of loops, it will 9616 // define the nested loops number. 9617 unsigned NestedLoopCount = checkOpenMPLoop( 9618 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9619 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9620 VarsWithImplicitDSA, B); 9621 if (NestedLoopCount == 0) 9622 return StmtError(); 9623 9624 assert((CurContext->isDependentContext() || B.builtAll()) && 9625 "omp for loop exprs were not built"); 9626 9627 setFunctionHasBranchProtectedScope(); 9628 return OMPDistributeParallelForDirective::Create( 9629 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9630 DSAStack->isCancelRegion()); 9631 } 9632 9633 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9634 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9635 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9636 if (!AStmt) 9637 return StmtError(); 9638 9639 auto *CS = cast<CapturedStmt>(AStmt); 9640 // 1.2.2 OpenMP Language Terminology 9641 // Structured block - An executable statement with a single entry at the 9642 // top and a single exit at the bottom. 9643 // The point of exit cannot be a branch out of the structured block. 9644 // longjmp() and throw() must not violate the entry/exit criteria. 9645 CS->getCapturedDecl()->setNothrow(); 9646 for (int ThisCaptureLevel = 9647 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9648 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9649 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9650 // 1.2.2 OpenMP Language Terminology 9651 // Structured block - An executable statement with a single entry at the 9652 // top and a single exit at the bottom. 9653 // The point of exit cannot be a branch out of the structured block. 9654 // longjmp() and throw() must not violate the entry/exit criteria. 9655 CS->getCapturedDecl()->setNothrow(); 9656 } 9657 9658 OMPLoopDirective::HelperExprs B; 9659 // In presence of clause 'collapse' with number of loops, it will 9660 // define the nested loops number. 9661 unsigned NestedLoopCount = checkOpenMPLoop( 9662 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9663 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9664 VarsWithImplicitDSA, B); 9665 if (NestedLoopCount == 0) 9666 return StmtError(); 9667 9668 assert((CurContext->isDependentContext() || B.builtAll()) && 9669 "omp for loop exprs were not built"); 9670 9671 if (!CurContext->isDependentContext()) { 9672 // Finalize the clauses that need pre-built expressions for CodeGen. 9673 for (OMPClause *C : Clauses) { 9674 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9675 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9676 B.NumIterations, *this, CurScope, 9677 DSAStack)) 9678 return StmtError(); 9679 } 9680 } 9681 9682 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9683 return StmtError(); 9684 9685 setFunctionHasBranchProtectedScope(); 9686 return OMPDistributeParallelForSimdDirective::Create( 9687 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9688 } 9689 9690 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9691 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9692 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9693 if (!AStmt) 9694 return StmtError(); 9695 9696 auto *CS = cast<CapturedStmt>(AStmt); 9697 // 1.2.2 OpenMP Language Terminology 9698 // Structured block - An executable statement with a single entry at the 9699 // top and a single exit at the bottom. 9700 // The point of exit cannot be a branch out of the structured block. 9701 // longjmp() and throw() must not violate the entry/exit criteria. 9702 CS->getCapturedDecl()->setNothrow(); 9703 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9704 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9705 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9706 // 1.2.2 OpenMP Language Terminology 9707 // Structured block - An executable statement with a single entry at the 9708 // top and a single exit at the bottom. 9709 // The point of exit cannot be a branch out of the structured block. 9710 // longjmp() and throw() must not violate the entry/exit criteria. 9711 CS->getCapturedDecl()->setNothrow(); 9712 } 9713 9714 OMPLoopDirective::HelperExprs B; 9715 // In presence of clause 'collapse' with number of loops, it will 9716 // define the nested loops number. 9717 unsigned NestedLoopCount = 9718 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9719 nullptr /*ordered not a clause on distribute*/, CS, *this, 9720 *DSAStack, VarsWithImplicitDSA, B); 9721 if (NestedLoopCount == 0) 9722 return StmtError(); 9723 9724 assert((CurContext->isDependentContext() || B.builtAll()) && 9725 "omp for loop exprs were not built"); 9726 9727 if (!CurContext->isDependentContext()) { 9728 // Finalize the clauses that need pre-built expressions for CodeGen. 9729 for (OMPClause *C : Clauses) { 9730 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9731 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9732 B.NumIterations, *this, CurScope, 9733 DSAStack)) 9734 return StmtError(); 9735 } 9736 } 9737 9738 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9739 return StmtError(); 9740 9741 setFunctionHasBranchProtectedScope(); 9742 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9743 NestedLoopCount, Clauses, AStmt, B); 9744 } 9745 9746 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9747 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9748 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9749 if (!AStmt) 9750 return StmtError(); 9751 9752 auto *CS = cast<CapturedStmt>(AStmt); 9753 // 1.2.2 OpenMP Language Terminology 9754 // Structured block - An executable statement with a single entry at the 9755 // top and a single exit at the bottom. 9756 // The point of exit cannot be a branch out of the structured block. 9757 // longjmp() and throw() must not violate the entry/exit criteria. 9758 CS->getCapturedDecl()->setNothrow(); 9759 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9760 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9761 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9762 // 1.2.2 OpenMP Language Terminology 9763 // Structured block - An executable statement with a single entry at the 9764 // top and a single exit at the bottom. 9765 // The point of exit cannot be a branch out of the structured block. 9766 // longjmp() and throw() must not violate the entry/exit criteria. 9767 CS->getCapturedDecl()->setNothrow(); 9768 } 9769 9770 OMPLoopDirective::HelperExprs B; 9771 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9772 // define the nested loops number. 9773 unsigned NestedLoopCount = checkOpenMPLoop( 9774 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9775 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9776 VarsWithImplicitDSA, B); 9777 if (NestedLoopCount == 0) 9778 return StmtError(); 9779 9780 assert((CurContext->isDependentContext() || B.builtAll()) && 9781 "omp target parallel for simd loop exprs were not built"); 9782 9783 if (!CurContext->isDependentContext()) { 9784 // Finalize the clauses that need pre-built expressions for CodeGen. 9785 for (OMPClause *C : Clauses) { 9786 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9787 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9788 B.NumIterations, *this, CurScope, 9789 DSAStack)) 9790 return StmtError(); 9791 } 9792 } 9793 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9794 return StmtError(); 9795 9796 setFunctionHasBranchProtectedScope(); 9797 return OMPTargetParallelForSimdDirective::Create( 9798 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9799 } 9800 9801 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9802 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9803 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9804 if (!AStmt) 9805 return StmtError(); 9806 9807 auto *CS = cast<CapturedStmt>(AStmt); 9808 // 1.2.2 OpenMP Language Terminology 9809 // Structured block - An executable statement with a single entry at the 9810 // top and a single exit at the bottom. 9811 // The point of exit cannot be a branch out of the structured block. 9812 // longjmp() and throw() must not violate the entry/exit criteria. 9813 CS->getCapturedDecl()->setNothrow(); 9814 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9815 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9816 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9817 // 1.2.2 OpenMP Language Terminology 9818 // Structured block - An executable statement with a single entry at the 9819 // top and a single exit at the bottom. 9820 // The point of exit cannot be a branch out of the structured block. 9821 // longjmp() and throw() must not violate the entry/exit criteria. 9822 CS->getCapturedDecl()->setNothrow(); 9823 } 9824 9825 OMPLoopDirective::HelperExprs B; 9826 // In presence of clause 'collapse' with number of loops, it will define the 9827 // nested loops number. 9828 unsigned NestedLoopCount = 9829 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9830 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9831 VarsWithImplicitDSA, B); 9832 if (NestedLoopCount == 0) 9833 return StmtError(); 9834 9835 assert((CurContext->isDependentContext() || B.builtAll()) && 9836 "omp target simd loop exprs were not built"); 9837 9838 if (!CurContext->isDependentContext()) { 9839 // Finalize the clauses that need pre-built expressions for CodeGen. 9840 for (OMPClause *C : Clauses) { 9841 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9842 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9843 B.NumIterations, *this, CurScope, 9844 DSAStack)) 9845 return StmtError(); 9846 } 9847 } 9848 9849 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9850 return StmtError(); 9851 9852 setFunctionHasBranchProtectedScope(); 9853 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9854 NestedLoopCount, Clauses, AStmt, B); 9855 } 9856 9857 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9858 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9859 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9860 if (!AStmt) 9861 return StmtError(); 9862 9863 auto *CS = cast<CapturedStmt>(AStmt); 9864 // 1.2.2 OpenMP Language Terminology 9865 // Structured block - An executable statement with a single entry at the 9866 // top and a single exit at the bottom. 9867 // The point of exit cannot be a branch out of the structured block. 9868 // longjmp() and throw() must not violate the entry/exit criteria. 9869 CS->getCapturedDecl()->setNothrow(); 9870 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9871 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9872 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9873 // 1.2.2 OpenMP Language Terminology 9874 // Structured block - An executable statement with a single entry at the 9875 // top and a single exit at the bottom. 9876 // The point of exit cannot be a branch out of the structured block. 9877 // longjmp() and throw() must not violate the entry/exit criteria. 9878 CS->getCapturedDecl()->setNothrow(); 9879 } 9880 9881 OMPLoopDirective::HelperExprs B; 9882 // In presence of clause 'collapse' with number of loops, it will 9883 // define the nested loops number. 9884 unsigned NestedLoopCount = 9885 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9886 nullptr /*ordered not a clause on distribute*/, CS, *this, 9887 *DSAStack, VarsWithImplicitDSA, B); 9888 if (NestedLoopCount == 0) 9889 return StmtError(); 9890 9891 assert((CurContext->isDependentContext() || B.builtAll()) && 9892 "omp teams distribute loop exprs were not built"); 9893 9894 setFunctionHasBranchProtectedScope(); 9895 9896 DSAStack->setParentTeamsRegionLoc(StartLoc); 9897 9898 return OMPTeamsDistributeDirective::Create( 9899 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9900 } 9901 9902 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9903 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9904 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9905 if (!AStmt) 9906 return StmtError(); 9907 9908 auto *CS = cast<CapturedStmt>(AStmt); 9909 // 1.2.2 OpenMP Language Terminology 9910 // Structured block - An executable statement with a single entry at the 9911 // top and a single exit at the bottom. 9912 // The point of exit cannot be a branch out of the structured block. 9913 // longjmp() and throw() must not violate the entry/exit criteria. 9914 CS->getCapturedDecl()->setNothrow(); 9915 for (int ThisCaptureLevel = 9916 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9917 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9918 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9919 // 1.2.2 OpenMP Language Terminology 9920 // Structured block - An executable statement with a single entry at the 9921 // top and a single exit at the bottom. 9922 // The point of exit cannot be a branch out of the structured block. 9923 // longjmp() and throw() must not violate the entry/exit criteria. 9924 CS->getCapturedDecl()->setNothrow(); 9925 } 9926 9927 9928 OMPLoopDirective::HelperExprs B; 9929 // In presence of clause 'collapse' with number of loops, it will 9930 // define the nested loops number. 9931 unsigned NestedLoopCount = checkOpenMPLoop( 9932 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9933 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9934 VarsWithImplicitDSA, B); 9935 9936 if (NestedLoopCount == 0) 9937 return StmtError(); 9938 9939 assert((CurContext->isDependentContext() || B.builtAll()) && 9940 "omp teams distribute simd loop exprs were not built"); 9941 9942 if (!CurContext->isDependentContext()) { 9943 // Finalize the clauses that need pre-built expressions for CodeGen. 9944 for (OMPClause *C : Clauses) { 9945 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9946 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9947 B.NumIterations, *this, CurScope, 9948 DSAStack)) 9949 return StmtError(); 9950 } 9951 } 9952 9953 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9954 return StmtError(); 9955 9956 setFunctionHasBranchProtectedScope(); 9957 9958 DSAStack->setParentTeamsRegionLoc(StartLoc); 9959 9960 return OMPTeamsDistributeSimdDirective::Create( 9961 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9962 } 9963 9964 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9965 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9966 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9967 if (!AStmt) 9968 return StmtError(); 9969 9970 auto *CS = cast<CapturedStmt>(AStmt); 9971 // 1.2.2 OpenMP Language Terminology 9972 // Structured block - An executable statement with a single entry at the 9973 // top and a single exit at the bottom. 9974 // The point of exit cannot be a branch out of the structured block. 9975 // longjmp() and throw() must not violate the entry/exit criteria. 9976 CS->getCapturedDecl()->setNothrow(); 9977 9978 for (int ThisCaptureLevel = 9979 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9980 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9981 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9982 // 1.2.2 OpenMP Language Terminology 9983 // Structured block - An executable statement with a single entry at the 9984 // top and a single exit at the bottom. 9985 // The point of exit cannot be a branch out of the structured block. 9986 // longjmp() and throw() must not violate the entry/exit criteria. 9987 CS->getCapturedDecl()->setNothrow(); 9988 } 9989 9990 OMPLoopDirective::HelperExprs B; 9991 // In presence of clause 'collapse' with number of loops, it will 9992 // define the nested loops number. 9993 unsigned NestedLoopCount = checkOpenMPLoop( 9994 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9995 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9996 VarsWithImplicitDSA, B); 9997 9998 if (NestedLoopCount == 0) 9999 return StmtError(); 10000 10001 assert((CurContext->isDependentContext() || B.builtAll()) && 10002 "omp for loop exprs were not built"); 10003 10004 if (!CurContext->isDependentContext()) { 10005 // Finalize the clauses that need pre-built expressions for CodeGen. 10006 for (OMPClause *C : Clauses) { 10007 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10008 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10009 B.NumIterations, *this, CurScope, 10010 DSAStack)) 10011 return StmtError(); 10012 } 10013 } 10014 10015 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10016 return StmtError(); 10017 10018 setFunctionHasBranchProtectedScope(); 10019 10020 DSAStack->setParentTeamsRegionLoc(StartLoc); 10021 10022 return OMPTeamsDistributeParallelForSimdDirective::Create( 10023 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10024 } 10025 10026 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10027 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10028 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10029 if (!AStmt) 10030 return StmtError(); 10031 10032 auto *CS = cast<CapturedStmt>(AStmt); 10033 // 1.2.2 OpenMP Language Terminology 10034 // Structured block - An executable statement with a single entry at the 10035 // top and a single exit at the bottom. 10036 // The point of exit cannot be a branch out of the structured block. 10037 // longjmp() and throw() must not violate the entry/exit criteria. 10038 CS->getCapturedDecl()->setNothrow(); 10039 10040 for (int ThisCaptureLevel = 10041 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10042 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10043 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10044 // 1.2.2 OpenMP Language Terminology 10045 // Structured block - An executable statement with a single entry at the 10046 // top and a single exit at the bottom. 10047 // The point of exit cannot be a branch out of the structured block. 10048 // longjmp() and throw() must not violate the entry/exit criteria. 10049 CS->getCapturedDecl()->setNothrow(); 10050 } 10051 10052 OMPLoopDirective::HelperExprs B; 10053 // In presence of clause 'collapse' with number of loops, it will 10054 // define the nested loops number. 10055 unsigned NestedLoopCount = checkOpenMPLoop( 10056 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10057 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10058 VarsWithImplicitDSA, B); 10059 10060 if (NestedLoopCount == 0) 10061 return StmtError(); 10062 10063 assert((CurContext->isDependentContext() || B.builtAll()) && 10064 "omp for loop exprs were not built"); 10065 10066 setFunctionHasBranchProtectedScope(); 10067 10068 DSAStack->setParentTeamsRegionLoc(StartLoc); 10069 10070 return OMPTeamsDistributeParallelForDirective::Create( 10071 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10072 DSAStack->isCancelRegion()); 10073 } 10074 10075 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10076 Stmt *AStmt, 10077 SourceLocation StartLoc, 10078 SourceLocation EndLoc) { 10079 if (!AStmt) 10080 return StmtError(); 10081 10082 auto *CS = cast<CapturedStmt>(AStmt); 10083 // 1.2.2 OpenMP Language Terminology 10084 // Structured block - An executable statement with a single entry at the 10085 // top and a single exit at the bottom. 10086 // The point of exit cannot be a branch out of the structured block. 10087 // longjmp() and throw() must not violate the entry/exit criteria. 10088 CS->getCapturedDecl()->setNothrow(); 10089 10090 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10091 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10092 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10093 // 1.2.2 OpenMP Language Terminology 10094 // Structured block - An executable statement with a single entry at the 10095 // top and a single exit at the bottom. 10096 // The point of exit cannot be a branch out of the structured block. 10097 // longjmp() and throw() must not violate the entry/exit criteria. 10098 CS->getCapturedDecl()->setNothrow(); 10099 } 10100 setFunctionHasBranchProtectedScope(); 10101 10102 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10103 AStmt); 10104 } 10105 10106 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10107 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10108 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10109 if (!AStmt) 10110 return StmtError(); 10111 10112 auto *CS = cast<CapturedStmt>(AStmt); 10113 // 1.2.2 OpenMP Language Terminology 10114 // Structured block - An executable statement with a single entry at the 10115 // top and a single exit at the bottom. 10116 // The point of exit cannot be a branch out of the structured block. 10117 // longjmp() and throw() must not violate the entry/exit criteria. 10118 CS->getCapturedDecl()->setNothrow(); 10119 for (int ThisCaptureLevel = 10120 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10121 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10122 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10123 // 1.2.2 OpenMP Language Terminology 10124 // Structured block - An executable statement with a single entry at the 10125 // top and a single exit at the bottom. 10126 // The point of exit cannot be a branch out of the structured block. 10127 // longjmp() and throw() must not violate the entry/exit criteria. 10128 CS->getCapturedDecl()->setNothrow(); 10129 } 10130 10131 OMPLoopDirective::HelperExprs B; 10132 // In presence of clause 'collapse' with number of loops, it will 10133 // define the nested loops number. 10134 unsigned NestedLoopCount = checkOpenMPLoop( 10135 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10136 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10137 VarsWithImplicitDSA, B); 10138 if (NestedLoopCount == 0) 10139 return StmtError(); 10140 10141 assert((CurContext->isDependentContext() || B.builtAll()) && 10142 "omp target teams distribute loop exprs were not built"); 10143 10144 setFunctionHasBranchProtectedScope(); 10145 return OMPTargetTeamsDistributeDirective::Create( 10146 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10147 } 10148 10149 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10150 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10151 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10152 if (!AStmt) 10153 return StmtError(); 10154 10155 auto *CS = cast<CapturedStmt>(AStmt); 10156 // 1.2.2 OpenMP Language Terminology 10157 // Structured block - An executable statement with a single entry at the 10158 // top and a single exit at the bottom. 10159 // The point of exit cannot be a branch out of the structured block. 10160 // longjmp() and throw() must not violate the entry/exit criteria. 10161 CS->getCapturedDecl()->setNothrow(); 10162 for (int ThisCaptureLevel = 10163 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10164 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10165 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10166 // 1.2.2 OpenMP Language Terminology 10167 // Structured block - An executable statement with a single entry at the 10168 // top and a single exit at the bottom. 10169 // The point of exit cannot be a branch out of the structured block. 10170 // longjmp() and throw() must not violate the entry/exit criteria. 10171 CS->getCapturedDecl()->setNothrow(); 10172 } 10173 10174 OMPLoopDirective::HelperExprs B; 10175 // In presence of clause 'collapse' with number of loops, it will 10176 // define the nested loops number. 10177 unsigned NestedLoopCount = checkOpenMPLoop( 10178 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10179 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10180 VarsWithImplicitDSA, B); 10181 if (NestedLoopCount == 0) 10182 return StmtError(); 10183 10184 assert((CurContext->isDependentContext() || B.builtAll()) && 10185 "omp target teams distribute parallel for loop exprs were not built"); 10186 10187 if (!CurContext->isDependentContext()) { 10188 // Finalize the clauses that need pre-built expressions for CodeGen. 10189 for (OMPClause *C : Clauses) { 10190 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10191 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10192 B.NumIterations, *this, CurScope, 10193 DSAStack)) 10194 return StmtError(); 10195 } 10196 } 10197 10198 setFunctionHasBranchProtectedScope(); 10199 return OMPTargetTeamsDistributeParallelForDirective::Create( 10200 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10201 DSAStack->isCancelRegion()); 10202 } 10203 10204 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10205 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10206 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10207 if (!AStmt) 10208 return StmtError(); 10209 10210 auto *CS = cast<CapturedStmt>(AStmt); 10211 // 1.2.2 OpenMP Language Terminology 10212 // Structured block - An executable statement with a single entry at the 10213 // top and a single exit at the bottom. 10214 // The point of exit cannot be a branch out of the structured block. 10215 // longjmp() and throw() must not violate the entry/exit criteria. 10216 CS->getCapturedDecl()->setNothrow(); 10217 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10218 OMPD_target_teams_distribute_parallel_for_simd); 10219 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10220 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10221 // 1.2.2 OpenMP Language Terminology 10222 // Structured block - An executable statement with a single entry at the 10223 // top and a single exit at the bottom. 10224 // The point of exit cannot be a branch out of the structured block. 10225 // longjmp() and throw() must not violate the entry/exit criteria. 10226 CS->getCapturedDecl()->setNothrow(); 10227 } 10228 10229 OMPLoopDirective::HelperExprs B; 10230 // In presence of clause 'collapse' with number of loops, it will 10231 // define the nested loops number. 10232 unsigned NestedLoopCount = 10233 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10234 getCollapseNumberExpr(Clauses), 10235 nullptr /*ordered not a clause on distribute*/, CS, *this, 10236 *DSAStack, VarsWithImplicitDSA, B); 10237 if (NestedLoopCount == 0) 10238 return StmtError(); 10239 10240 assert((CurContext->isDependentContext() || B.builtAll()) && 10241 "omp target teams distribute parallel for simd loop exprs were not " 10242 "built"); 10243 10244 if (!CurContext->isDependentContext()) { 10245 // Finalize the clauses that need pre-built expressions for CodeGen. 10246 for (OMPClause *C : Clauses) { 10247 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10248 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10249 B.NumIterations, *this, CurScope, 10250 DSAStack)) 10251 return StmtError(); 10252 } 10253 } 10254 10255 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10256 return StmtError(); 10257 10258 setFunctionHasBranchProtectedScope(); 10259 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10260 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10261 } 10262 10263 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10264 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10265 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10266 if (!AStmt) 10267 return StmtError(); 10268 10269 auto *CS = cast<CapturedStmt>(AStmt); 10270 // 1.2.2 OpenMP Language Terminology 10271 // Structured block - An executable statement with a single entry at the 10272 // top and a single exit at the bottom. 10273 // The point of exit cannot be a branch out of the structured block. 10274 // longjmp() and throw() must not violate the entry/exit criteria. 10275 CS->getCapturedDecl()->setNothrow(); 10276 for (int ThisCaptureLevel = 10277 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10278 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10279 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10280 // 1.2.2 OpenMP Language Terminology 10281 // Structured block - An executable statement with a single entry at the 10282 // top and a single exit at the bottom. 10283 // The point of exit cannot be a branch out of the structured block. 10284 // longjmp() and throw() must not violate the entry/exit criteria. 10285 CS->getCapturedDecl()->setNothrow(); 10286 } 10287 10288 OMPLoopDirective::HelperExprs B; 10289 // In presence of clause 'collapse' with number of loops, it will 10290 // define the nested loops number. 10291 unsigned NestedLoopCount = checkOpenMPLoop( 10292 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10293 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10294 VarsWithImplicitDSA, B); 10295 if (NestedLoopCount == 0) 10296 return StmtError(); 10297 10298 assert((CurContext->isDependentContext() || B.builtAll()) && 10299 "omp target teams distribute simd loop exprs were not built"); 10300 10301 if (!CurContext->isDependentContext()) { 10302 // Finalize the clauses that need pre-built expressions for CodeGen. 10303 for (OMPClause *C : Clauses) { 10304 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10305 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10306 B.NumIterations, *this, CurScope, 10307 DSAStack)) 10308 return StmtError(); 10309 } 10310 } 10311 10312 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10313 return StmtError(); 10314 10315 setFunctionHasBranchProtectedScope(); 10316 return OMPTargetTeamsDistributeSimdDirective::Create( 10317 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10318 } 10319 10320 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10321 SourceLocation StartLoc, 10322 SourceLocation LParenLoc, 10323 SourceLocation EndLoc) { 10324 OMPClause *Res = nullptr; 10325 switch (Kind) { 10326 case OMPC_final: 10327 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10328 break; 10329 case OMPC_num_threads: 10330 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10331 break; 10332 case OMPC_safelen: 10333 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10334 break; 10335 case OMPC_simdlen: 10336 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10337 break; 10338 case OMPC_allocator: 10339 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10340 break; 10341 case OMPC_collapse: 10342 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10343 break; 10344 case OMPC_ordered: 10345 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10346 break; 10347 case OMPC_device: 10348 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10349 break; 10350 case OMPC_num_teams: 10351 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10352 break; 10353 case OMPC_thread_limit: 10354 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10355 break; 10356 case OMPC_priority: 10357 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10358 break; 10359 case OMPC_grainsize: 10360 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10361 break; 10362 case OMPC_num_tasks: 10363 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10364 break; 10365 case OMPC_hint: 10366 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10367 break; 10368 case OMPC_if: 10369 case OMPC_default: 10370 case OMPC_proc_bind: 10371 case OMPC_schedule: 10372 case OMPC_private: 10373 case OMPC_firstprivate: 10374 case OMPC_lastprivate: 10375 case OMPC_shared: 10376 case OMPC_reduction: 10377 case OMPC_task_reduction: 10378 case OMPC_in_reduction: 10379 case OMPC_linear: 10380 case OMPC_aligned: 10381 case OMPC_copyin: 10382 case OMPC_copyprivate: 10383 case OMPC_nowait: 10384 case OMPC_untied: 10385 case OMPC_mergeable: 10386 case OMPC_threadprivate: 10387 case OMPC_allocate: 10388 case OMPC_flush: 10389 case OMPC_read: 10390 case OMPC_write: 10391 case OMPC_update: 10392 case OMPC_capture: 10393 case OMPC_seq_cst: 10394 case OMPC_depend: 10395 case OMPC_threads: 10396 case OMPC_simd: 10397 case OMPC_map: 10398 case OMPC_nogroup: 10399 case OMPC_dist_schedule: 10400 case OMPC_defaultmap: 10401 case OMPC_unknown: 10402 case OMPC_uniform: 10403 case OMPC_to: 10404 case OMPC_from: 10405 case OMPC_use_device_ptr: 10406 case OMPC_is_device_ptr: 10407 case OMPC_unified_address: 10408 case OMPC_unified_shared_memory: 10409 case OMPC_reverse_offload: 10410 case OMPC_dynamic_allocators: 10411 case OMPC_atomic_default_mem_order: 10412 case OMPC_device_type: 10413 case OMPC_match: 10414 llvm_unreachable("Clause is not allowed."); 10415 } 10416 return Res; 10417 } 10418 10419 // An OpenMP directive such as 'target parallel' has two captured regions: 10420 // for the 'target' and 'parallel' respectively. This function returns 10421 // the region in which to capture expressions associated with a clause. 10422 // A return value of OMPD_unknown signifies that the expression should not 10423 // be captured. 10424 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10425 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10426 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10427 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10428 switch (CKind) { 10429 case OMPC_if: 10430 switch (DKind) { 10431 case OMPD_target_parallel: 10432 case OMPD_target_parallel_for: 10433 case OMPD_target_parallel_for_simd: 10434 // If this clause applies to the nested 'parallel' region, capture within 10435 // the 'target' region, otherwise do not capture. 10436 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10437 CaptureRegion = OMPD_target; 10438 break; 10439 case OMPD_target_teams_distribute_parallel_for: 10440 case OMPD_target_teams_distribute_parallel_for_simd: 10441 // If this clause applies to the nested 'parallel' region, capture within 10442 // the 'teams' region, otherwise do not capture. 10443 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10444 CaptureRegion = OMPD_teams; 10445 break; 10446 case OMPD_teams_distribute_parallel_for: 10447 case OMPD_teams_distribute_parallel_for_simd: 10448 CaptureRegion = OMPD_teams; 10449 break; 10450 case OMPD_target_update: 10451 case OMPD_target_enter_data: 10452 case OMPD_target_exit_data: 10453 CaptureRegion = OMPD_task; 10454 break; 10455 case OMPD_parallel_master_taskloop: 10456 case OMPD_parallel_master_taskloop_simd: 10457 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10458 CaptureRegion = OMPD_parallel; 10459 break; 10460 case OMPD_cancel: 10461 case OMPD_parallel: 10462 case OMPD_parallel_sections: 10463 case OMPD_parallel_for: 10464 case OMPD_parallel_for_simd: 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_distribute_parallel_for: 10471 case OMPD_distribute_parallel_for_simd: 10472 case OMPD_task: 10473 case OMPD_taskloop: 10474 case OMPD_taskloop_simd: 10475 case OMPD_master_taskloop: 10476 case OMPD_master_taskloop_simd: 10477 case OMPD_target_data: 10478 // Do not capture if-clause expressions. 10479 break; 10480 case OMPD_threadprivate: 10481 case OMPD_allocate: 10482 case OMPD_taskyield: 10483 case OMPD_barrier: 10484 case OMPD_taskwait: 10485 case OMPD_cancellation_point: 10486 case OMPD_flush: 10487 case OMPD_declare_reduction: 10488 case OMPD_declare_mapper: 10489 case OMPD_declare_simd: 10490 case OMPD_declare_variant: 10491 case OMPD_declare_target: 10492 case OMPD_end_declare_target: 10493 case OMPD_teams: 10494 case OMPD_simd: 10495 case OMPD_for: 10496 case OMPD_for_simd: 10497 case OMPD_sections: 10498 case OMPD_section: 10499 case OMPD_single: 10500 case OMPD_master: 10501 case OMPD_critical: 10502 case OMPD_taskgroup: 10503 case OMPD_distribute: 10504 case OMPD_ordered: 10505 case OMPD_atomic: 10506 case OMPD_distribute_simd: 10507 case OMPD_teams_distribute: 10508 case OMPD_teams_distribute_simd: 10509 case OMPD_requires: 10510 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10511 case OMPD_unknown: 10512 llvm_unreachable("Unknown OpenMP directive"); 10513 } 10514 break; 10515 case OMPC_num_threads: 10516 switch (DKind) { 10517 case OMPD_target_parallel: 10518 case OMPD_target_parallel_for: 10519 case OMPD_target_parallel_for_simd: 10520 CaptureRegion = OMPD_target; 10521 break; 10522 case OMPD_teams_distribute_parallel_for: 10523 case OMPD_teams_distribute_parallel_for_simd: 10524 case OMPD_target_teams_distribute_parallel_for: 10525 case OMPD_target_teams_distribute_parallel_for_simd: 10526 CaptureRegion = OMPD_teams; 10527 break; 10528 case OMPD_parallel: 10529 case OMPD_parallel_sections: 10530 case OMPD_parallel_for: 10531 case OMPD_parallel_for_simd: 10532 case OMPD_distribute_parallel_for: 10533 case OMPD_distribute_parallel_for_simd: 10534 case OMPD_parallel_master_taskloop: 10535 case OMPD_parallel_master_taskloop_simd: 10536 // Do not capture num_threads-clause expressions. 10537 break; 10538 case OMPD_target_data: 10539 case OMPD_target_enter_data: 10540 case OMPD_target_exit_data: 10541 case OMPD_target_update: 10542 case OMPD_target: 10543 case OMPD_target_simd: 10544 case OMPD_target_teams: 10545 case OMPD_target_teams_distribute: 10546 case OMPD_target_teams_distribute_simd: 10547 case OMPD_cancel: 10548 case OMPD_task: 10549 case OMPD_taskloop: 10550 case OMPD_taskloop_simd: 10551 case OMPD_master_taskloop: 10552 case OMPD_master_taskloop_simd: 10553 case OMPD_threadprivate: 10554 case OMPD_allocate: 10555 case OMPD_taskyield: 10556 case OMPD_barrier: 10557 case OMPD_taskwait: 10558 case OMPD_cancellation_point: 10559 case OMPD_flush: 10560 case OMPD_declare_reduction: 10561 case OMPD_declare_mapper: 10562 case OMPD_declare_simd: 10563 case OMPD_declare_variant: 10564 case OMPD_declare_target: 10565 case OMPD_end_declare_target: 10566 case OMPD_teams: 10567 case OMPD_simd: 10568 case OMPD_for: 10569 case OMPD_for_simd: 10570 case OMPD_sections: 10571 case OMPD_section: 10572 case OMPD_single: 10573 case OMPD_master: 10574 case OMPD_critical: 10575 case OMPD_taskgroup: 10576 case OMPD_distribute: 10577 case OMPD_ordered: 10578 case OMPD_atomic: 10579 case OMPD_distribute_simd: 10580 case OMPD_teams_distribute: 10581 case OMPD_teams_distribute_simd: 10582 case OMPD_requires: 10583 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10584 case OMPD_unknown: 10585 llvm_unreachable("Unknown OpenMP directive"); 10586 } 10587 break; 10588 case OMPC_num_teams: 10589 switch (DKind) { 10590 case OMPD_target_teams: 10591 case OMPD_target_teams_distribute: 10592 case OMPD_target_teams_distribute_simd: 10593 case OMPD_target_teams_distribute_parallel_for: 10594 case OMPD_target_teams_distribute_parallel_for_simd: 10595 CaptureRegion = OMPD_target; 10596 break; 10597 case OMPD_teams_distribute_parallel_for: 10598 case OMPD_teams_distribute_parallel_for_simd: 10599 case OMPD_teams: 10600 case OMPD_teams_distribute: 10601 case OMPD_teams_distribute_simd: 10602 // Do not capture num_teams-clause expressions. 10603 break; 10604 case OMPD_distribute_parallel_for: 10605 case OMPD_distribute_parallel_for_simd: 10606 case OMPD_task: 10607 case OMPD_taskloop: 10608 case OMPD_taskloop_simd: 10609 case OMPD_master_taskloop: 10610 case OMPD_master_taskloop_simd: 10611 case OMPD_parallel_master_taskloop: 10612 case OMPD_parallel_master_taskloop_simd: 10613 case OMPD_target_data: 10614 case OMPD_target_enter_data: 10615 case OMPD_target_exit_data: 10616 case OMPD_target_update: 10617 case OMPD_cancel: 10618 case OMPD_parallel: 10619 case OMPD_parallel_sections: 10620 case OMPD_parallel_for: 10621 case OMPD_parallel_for_simd: 10622 case OMPD_target: 10623 case OMPD_target_simd: 10624 case OMPD_target_parallel: 10625 case OMPD_target_parallel_for: 10626 case OMPD_target_parallel_for_simd: 10627 case OMPD_threadprivate: 10628 case OMPD_allocate: 10629 case OMPD_taskyield: 10630 case OMPD_barrier: 10631 case OMPD_taskwait: 10632 case OMPD_cancellation_point: 10633 case OMPD_flush: 10634 case OMPD_declare_reduction: 10635 case OMPD_declare_mapper: 10636 case OMPD_declare_simd: 10637 case OMPD_declare_variant: 10638 case OMPD_declare_target: 10639 case OMPD_end_declare_target: 10640 case OMPD_simd: 10641 case OMPD_for: 10642 case OMPD_for_simd: 10643 case OMPD_sections: 10644 case OMPD_section: 10645 case OMPD_single: 10646 case OMPD_master: 10647 case OMPD_critical: 10648 case OMPD_taskgroup: 10649 case OMPD_distribute: 10650 case OMPD_ordered: 10651 case OMPD_atomic: 10652 case OMPD_distribute_simd: 10653 case OMPD_requires: 10654 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10655 case OMPD_unknown: 10656 llvm_unreachable("Unknown OpenMP directive"); 10657 } 10658 break; 10659 case OMPC_thread_limit: 10660 switch (DKind) { 10661 case OMPD_target_teams: 10662 case OMPD_target_teams_distribute: 10663 case OMPD_target_teams_distribute_simd: 10664 case OMPD_target_teams_distribute_parallel_for: 10665 case OMPD_target_teams_distribute_parallel_for_simd: 10666 CaptureRegion = OMPD_target; 10667 break; 10668 case OMPD_teams_distribute_parallel_for: 10669 case OMPD_teams_distribute_parallel_for_simd: 10670 case OMPD_teams: 10671 case OMPD_teams_distribute: 10672 case OMPD_teams_distribute_simd: 10673 // Do not capture thread_limit-clause expressions. 10674 break; 10675 case OMPD_distribute_parallel_for: 10676 case OMPD_distribute_parallel_for_simd: 10677 case OMPD_task: 10678 case OMPD_taskloop: 10679 case OMPD_taskloop_simd: 10680 case OMPD_master_taskloop: 10681 case OMPD_master_taskloop_simd: 10682 case OMPD_parallel_master_taskloop: 10683 case OMPD_parallel_master_taskloop_simd: 10684 case OMPD_target_data: 10685 case OMPD_target_enter_data: 10686 case OMPD_target_exit_data: 10687 case OMPD_target_update: 10688 case OMPD_cancel: 10689 case OMPD_parallel: 10690 case OMPD_parallel_sections: 10691 case OMPD_parallel_for: 10692 case OMPD_parallel_for_simd: 10693 case OMPD_target: 10694 case OMPD_target_simd: 10695 case OMPD_target_parallel: 10696 case OMPD_target_parallel_for: 10697 case OMPD_target_parallel_for_simd: 10698 case OMPD_threadprivate: 10699 case OMPD_allocate: 10700 case OMPD_taskyield: 10701 case OMPD_barrier: 10702 case OMPD_taskwait: 10703 case OMPD_cancellation_point: 10704 case OMPD_flush: 10705 case OMPD_declare_reduction: 10706 case OMPD_declare_mapper: 10707 case OMPD_declare_simd: 10708 case OMPD_declare_variant: 10709 case OMPD_declare_target: 10710 case OMPD_end_declare_target: 10711 case OMPD_simd: 10712 case OMPD_for: 10713 case OMPD_for_simd: 10714 case OMPD_sections: 10715 case OMPD_section: 10716 case OMPD_single: 10717 case OMPD_master: 10718 case OMPD_critical: 10719 case OMPD_taskgroup: 10720 case OMPD_distribute: 10721 case OMPD_ordered: 10722 case OMPD_atomic: 10723 case OMPD_distribute_simd: 10724 case OMPD_requires: 10725 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10726 case OMPD_unknown: 10727 llvm_unreachable("Unknown OpenMP directive"); 10728 } 10729 break; 10730 case OMPC_schedule: 10731 switch (DKind) { 10732 case OMPD_parallel_for: 10733 case OMPD_parallel_for_simd: 10734 case OMPD_distribute_parallel_for: 10735 case OMPD_distribute_parallel_for_simd: 10736 case OMPD_teams_distribute_parallel_for: 10737 case OMPD_teams_distribute_parallel_for_simd: 10738 case OMPD_target_parallel_for: 10739 case OMPD_target_parallel_for_simd: 10740 case OMPD_target_teams_distribute_parallel_for: 10741 case OMPD_target_teams_distribute_parallel_for_simd: 10742 CaptureRegion = OMPD_parallel; 10743 break; 10744 case OMPD_for: 10745 case OMPD_for_simd: 10746 // Do not capture schedule-clause expressions. 10747 break; 10748 case OMPD_task: 10749 case OMPD_taskloop: 10750 case OMPD_taskloop_simd: 10751 case OMPD_master_taskloop: 10752 case OMPD_master_taskloop_simd: 10753 case OMPD_parallel_master_taskloop: 10754 case OMPD_parallel_master_taskloop_simd: 10755 case OMPD_target_data: 10756 case OMPD_target_enter_data: 10757 case OMPD_target_exit_data: 10758 case OMPD_target_update: 10759 case OMPD_teams: 10760 case OMPD_teams_distribute: 10761 case OMPD_teams_distribute_simd: 10762 case OMPD_target_teams_distribute: 10763 case OMPD_target_teams_distribute_simd: 10764 case OMPD_target: 10765 case OMPD_target_simd: 10766 case OMPD_target_parallel: 10767 case OMPD_cancel: 10768 case OMPD_parallel: 10769 case OMPD_parallel_sections: 10770 case OMPD_threadprivate: 10771 case OMPD_allocate: 10772 case OMPD_taskyield: 10773 case OMPD_barrier: 10774 case OMPD_taskwait: 10775 case OMPD_cancellation_point: 10776 case OMPD_flush: 10777 case OMPD_declare_reduction: 10778 case OMPD_declare_mapper: 10779 case OMPD_declare_simd: 10780 case OMPD_declare_variant: 10781 case OMPD_declare_target: 10782 case OMPD_end_declare_target: 10783 case OMPD_simd: 10784 case OMPD_sections: 10785 case OMPD_section: 10786 case OMPD_single: 10787 case OMPD_master: 10788 case OMPD_critical: 10789 case OMPD_taskgroup: 10790 case OMPD_distribute: 10791 case OMPD_ordered: 10792 case OMPD_atomic: 10793 case OMPD_distribute_simd: 10794 case OMPD_target_teams: 10795 case OMPD_requires: 10796 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10797 case OMPD_unknown: 10798 llvm_unreachable("Unknown OpenMP directive"); 10799 } 10800 break; 10801 case OMPC_dist_schedule: 10802 switch (DKind) { 10803 case OMPD_teams_distribute_parallel_for: 10804 case OMPD_teams_distribute_parallel_for_simd: 10805 case OMPD_teams_distribute: 10806 case OMPD_teams_distribute_simd: 10807 case OMPD_target_teams_distribute_parallel_for: 10808 case OMPD_target_teams_distribute_parallel_for_simd: 10809 case OMPD_target_teams_distribute: 10810 case OMPD_target_teams_distribute_simd: 10811 CaptureRegion = OMPD_teams; 10812 break; 10813 case OMPD_distribute_parallel_for: 10814 case OMPD_distribute_parallel_for_simd: 10815 case OMPD_distribute: 10816 case OMPD_distribute_simd: 10817 // Do not capture thread_limit-clause expressions. 10818 break; 10819 case OMPD_parallel_for: 10820 case OMPD_parallel_for_simd: 10821 case OMPD_target_parallel_for_simd: 10822 case OMPD_target_parallel_for: 10823 case OMPD_task: 10824 case OMPD_taskloop: 10825 case OMPD_taskloop_simd: 10826 case OMPD_master_taskloop: 10827 case OMPD_master_taskloop_simd: 10828 case OMPD_parallel_master_taskloop: 10829 case OMPD_parallel_master_taskloop_simd: 10830 case OMPD_target_data: 10831 case OMPD_target_enter_data: 10832 case OMPD_target_exit_data: 10833 case OMPD_target_update: 10834 case OMPD_teams: 10835 case OMPD_target: 10836 case OMPD_target_simd: 10837 case OMPD_target_parallel: 10838 case OMPD_cancel: 10839 case OMPD_parallel: 10840 case OMPD_parallel_sections: 10841 case OMPD_threadprivate: 10842 case OMPD_allocate: 10843 case OMPD_taskyield: 10844 case OMPD_barrier: 10845 case OMPD_taskwait: 10846 case OMPD_cancellation_point: 10847 case OMPD_flush: 10848 case OMPD_declare_reduction: 10849 case OMPD_declare_mapper: 10850 case OMPD_declare_simd: 10851 case OMPD_declare_variant: 10852 case OMPD_declare_target: 10853 case OMPD_end_declare_target: 10854 case OMPD_simd: 10855 case OMPD_for: 10856 case OMPD_for_simd: 10857 case OMPD_sections: 10858 case OMPD_section: 10859 case OMPD_single: 10860 case OMPD_master: 10861 case OMPD_critical: 10862 case OMPD_taskgroup: 10863 case OMPD_ordered: 10864 case OMPD_atomic: 10865 case OMPD_target_teams: 10866 case OMPD_requires: 10867 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10868 case OMPD_unknown: 10869 llvm_unreachable("Unknown OpenMP directive"); 10870 } 10871 break; 10872 case OMPC_device: 10873 switch (DKind) { 10874 case OMPD_target_update: 10875 case OMPD_target_enter_data: 10876 case OMPD_target_exit_data: 10877 case OMPD_target: 10878 case OMPD_target_simd: 10879 case OMPD_target_teams: 10880 case OMPD_target_parallel: 10881 case OMPD_target_teams_distribute: 10882 case OMPD_target_teams_distribute_simd: 10883 case OMPD_target_parallel_for: 10884 case OMPD_target_parallel_for_simd: 10885 case OMPD_target_teams_distribute_parallel_for: 10886 case OMPD_target_teams_distribute_parallel_for_simd: 10887 CaptureRegion = OMPD_task; 10888 break; 10889 case OMPD_target_data: 10890 // Do not capture device-clause expressions. 10891 break; 10892 case OMPD_teams_distribute_parallel_for: 10893 case OMPD_teams_distribute_parallel_for_simd: 10894 case OMPD_teams: 10895 case OMPD_teams_distribute: 10896 case OMPD_teams_distribute_simd: 10897 case OMPD_distribute_parallel_for: 10898 case OMPD_distribute_parallel_for_simd: 10899 case OMPD_task: 10900 case OMPD_taskloop: 10901 case OMPD_taskloop_simd: 10902 case OMPD_master_taskloop: 10903 case OMPD_master_taskloop_simd: 10904 case OMPD_parallel_master_taskloop: 10905 case OMPD_parallel_master_taskloop_simd: 10906 case OMPD_cancel: 10907 case OMPD_parallel: 10908 case OMPD_parallel_sections: 10909 case OMPD_parallel_for: 10910 case OMPD_parallel_for_simd: 10911 case OMPD_threadprivate: 10912 case OMPD_allocate: 10913 case OMPD_taskyield: 10914 case OMPD_barrier: 10915 case OMPD_taskwait: 10916 case OMPD_cancellation_point: 10917 case OMPD_flush: 10918 case OMPD_declare_reduction: 10919 case OMPD_declare_mapper: 10920 case OMPD_declare_simd: 10921 case OMPD_declare_variant: 10922 case OMPD_declare_target: 10923 case OMPD_end_declare_target: 10924 case OMPD_simd: 10925 case OMPD_for: 10926 case OMPD_for_simd: 10927 case OMPD_sections: 10928 case OMPD_section: 10929 case OMPD_single: 10930 case OMPD_master: 10931 case OMPD_critical: 10932 case OMPD_taskgroup: 10933 case OMPD_distribute: 10934 case OMPD_ordered: 10935 case OMPD_atomic: 10936 case OMPD_distribute_simd: 10937 case OMPD_requires: 10938 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10939 case OMPD_unknown: 10940 llvm_unreachable("Unknown OpenMP directive"); 10941 } 10942 break; 10943 case OMPC_grainsize: 10944 case OMPC_num_tasks: 10945 case OMPC_final: 10946 case OMPC_priority: 10947 switch (DKind) { 10948 case OMPD_task: 10949 case OMPD_taskloop: 10950 case OMPD_taskloop_simd: 10951 case OMPD_master_taskloop: 10952 case OMPD_master_taskloop_simd: 10953 break; 10954 case OMPD_parallel_master_taskloop: 10955 case OMPD_parallel_master_taskloop_simd: 10956 CaptureRegion = OMPD_parallel; 10957 break; 10958 case OMPD_target_update: 10959 case OMPD_target_enter_data: 10960 case OMPD_target_exit_data: 10961 case OMPD_target: 10962 case OMPD_target_simd: 10963 case OMPD_target_teams: 10964 case OMPD_target_parallel: 10965 case OMPD_target_teams_distribute: 10966 case OMPD_target_teams_distribute_simd: 10967 case OMPD_target_parallel_for: 10968 case OMPD_target_parallel_for_simd: 10969 case OMPD_target_teams_distribute_parallel_for: 10970 case OMPD_target_teams_distribute_parallel_for_simd: 10971 case OMPD_target_data: 10972 case OMPD_teams_distribute_parallel_for: 10973 case OMPD_teams_distribute_parallel_for_simd: 10974 case OMPD_teams: 10975 case OMPD_teams_distribute: 10976 case OMPD_teams_distribute_simd: 10977 case OMPD_distribute_parallel_for: 10978 case OMPD_distribute_parallel_for_simd: 10979 case OMPD_cancel: 10980 case OMPD_parallel: 10981 case OMPD_parallel_sections: 10982 case OMPD_parallel_for: 10983 case OMPD_parallel_for_simd: 10984 case OMPD_threadprivate: 10985 case OMPD_allocate: 10986 case OMPD_taskyield: 10987 case OMPD_barrier: 10988 case OMPD_taskwait: 10989 case OMPD_cancellation_point: 10990 case OMPD_flush: 10991 case OMPD_declare_reduction: 10992 case OMPD_declare_mapper: 10993 case OMPD_declare_simd: 10994 case OMPD_declare_variant: 10995 case OMPD_declare_target: 10996 case OMPD_end_declare_target: 10997 case OMPD_simd: 10998 case OMPD_for: 10999 case OMPD_for_simd: 11000 case OMPD_sections: 11001 case OMPD_section: 11002 case OMPD_single: 11003 case OMPD_master: 11004 case OMPD_critical: 11005 case OMPD_taskgroup: 11006 case OMPD_distribute: 11007 case OMPD_ordered: 11008 case OMPD_atomic: 11009 case OMPD_distribute_simd: 11010 case OMPD_requires: 11011 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11012 case OMPD_unknown: 11013 llvm_unreachable("Unknown OpenMP directive"); 11014 } 11015 break; 11016 case OMPC_firstprivate: 11017 case OMPC_lastprivate: 11018 case OMPC_reduction: 11019 case OMPC_task_reduction: 11020 case OMPC_in_reduction: 11021 case OMPC_linear: 11022 case OMPC_default: 11023 case OMPC_proc_bind: 11024 case OMPC_safelen: 11025 case OMPC_simdlen: 11026 case OMPC_allocator: 11027 case OMPC_collapse: 11028 case OMPC_private: 11029 case OMPC_shared: 11030 case OMPC_aligned: 11031 case OMPC_copyin: 11032 case OMPC_copyprivate: 11033 case OMPC_ordered: 11034 case OMPC_nowait: 11035 case OMPC_untied: 11036 case OMPC_mergeable: 11037 case OMPC_threadprivate: 11038 case OMPC_allocate: 11039 case OMPC_flush: 11040 case OMPC_read: 11041 case OMPC_write: 11042 case OMPC_update: 11043 case OMPC_capture: 11044 case OMPC_seq_cst: 11045 case OMPC_depend: 11046 case OMPC_threads: 11047 case OMPC_simd: 11048 case OMPC_map: 11049 case OMPC_nogroup: 11050 case OMPC_hint: 11051 case OMPC_defaultmap: 11052 case OMPC_unknown: 11053 case OMPC_uniform: 11054 case OMPC_to: 11055 case OMPC_from: 11056 case OMPC_use_device_ptr: 11057 case OMPC_is_device_ptr: 11058 case OMPC_unified_address: 11059 case OMPC_unified_shared_memory: 11060 case OMPC_reverse_offload: 11061 case OMPC_dynamic_allocators: 11062 case OMPC_atomic_default_mem_order: 11063 case OMPC_device_type: 11064 case OMPC_match: 11065 llvm_unreachable("Unexpected OpenMP clause."); 11066 } 11067 return CaptureRegion; 11068 } 11069 11070 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11071 Expr *Condition, SourceLocation StartLoc, 11072 SourceLocation LParenLoc, 11073 SourceLocation NameModifierLoc, 11074 SourceLocation ColonLoc, 11075 SourceLocation EndLoc) { 11076 Expr *ValExpr = Condition; 11077 Stmt *HelperValStmt = nullptr; 11078 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11079 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11080 !Condition->isInstantiationDependent() && 11081 !Condition->containsUnexpandedParameterPack()) { 11082 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11083 if (Val.isInvalid()) 11084 return nullptr; 11085 11086 ValExpr = Val.get(); 11087 11088 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11089 CaptureRegion = 11090 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 11091 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11092 ValExpr = MakeFullExpr(ValExpr).get(); 11093 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11094 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11095 HelperValStmt = buildPreInits(Context, Captures); 11096 } 11097 } 11098 11099 return new (Context) 11100 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11101 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11102 } 11103 11104 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11105 SourceLocation StartLoc, 11106 SourceLocation LParenLoc, 11107 SourceLocation EndLoc) { 11108 Expr *ValExpr = Condition; 11109 Stmt *HelperValStmt = nullptr; 11110 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11111 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11112 !Condition->isInstantiationDependent() && 11113 !Condition->containsUnexpandedParameterPack()) { 11114 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11115 if (Val.isInvalid()) 11116 return nullptr; 11117 11118 ValExpr = MakeFullExpr(Val.get()).get(); 11119 11120 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11121 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final); 11122 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11123 ValExpr = MakeFullExpr(ValExpr).get(); 11124 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11125 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11126 HelperValStmt = buildPreInits(Context, Captures); 11127 } 11128 } 11129 11130 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11131 StartLoc, LParenLoc, EndLoc); 11132 } 11133 11134 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11135 Expr *Op) { 11136 if (!Op) 11137 return ExprError(); 11138 11139 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11140 public: 11141 IntConvertDiagnoser() 11142 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11143 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11144 QualType T) override { 11145 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11146 } 11147 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11148 QualType T) override { 11149 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11150 } 11151 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11152 QualType T, 11153 QualType ConvTy) override { 11154 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11155 } 11156 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11157 QualType ConvTy) override { 11158 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11159 << ConvTy->isEnumeralType() << ConvTy; 11160 } 11161 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11162 QualType T) override { 11163 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11164 } 11165 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11166 QualType ConvTy) override { 11167 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11168 << ConvTy->isEnumeralType() << ConvTy; 11169 } 11170 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11171 QualType) override { 11172 llvm_unreachable("conversion functions are permitted"); 11173 } 11174 } ConvertDiagnoser; 11175 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11176 } 11177 11178 static bool 11179 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11180 bool StrictlyPositive, bool BuildCapture = false, 11181 OpenMPDirectiveKind DKind = OMPD_unknown, 11182 OpenMPDirectiveKind *CaptureRegion = nullptr, 11183 Stmt **HelperValStmt = nullptr) { 11184 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11185 !ValExpr->isInstantiationDependent()) { 11186 SourceLocation Loc = ValExpr->getExprLoc(); 11187 ExprResult Value = 11188 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11189 if (Value.isInvalid()) 11190 return false; 11191 11192 ValExpr = Value.get(); 11193 // The expression must evaluate to a non-negative integer value. 11194 llvm::APSInt Result; 11195 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11196 Result.isSigned() && 11197 !((!StrictlyPositive && Result.isNonNegative()) || 11198 (StrictlyPositive && Result.isStrictlyPositive()))) { 11199 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11200 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11201 << ValExpr->getSourceRange(); 11202 return false; 11203 } 11204 if (!BuildCapture) 11205 return true; 11206 *CaptureRegion = getOpenMPCaptureRegionForClause(DKind, CKind); 11207 if (*CaptureRegion != OMPD_unknown && 11208 !SemaRef.CurContext->isDependentContext()) { 11209 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11210 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11211 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11212 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11213 } 11214 } 11215 return true; 11216 } 11217 11218 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11219 SourceLocation StartLoc, 11220 SourceLocation LParenLoc, 11221 SourceLocation EndLoc) { 11222 Expr *ValExpr = NumThreads; 11223 Stmt *HelperValStmt = nullptr; 11224 11225 // OpenMP [2.5, Restrictions] 11226 // The num_threads expression must evaluate to a positive integer value. 11227 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11228 /*StrictlyPositive=*/true)) 11229 return nullptr; 11230 11231 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11232 OpenMPDirectiveKind CaptureRegion = 11233 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 11234 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11235 ValExpr = MakeFullExpr(ValExpr).get(); 11236 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11237 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11238 HelperValStmt = buildPreInits(Context, Captures); 11239 } 11240 11241 return new (Context) OMPNumThreadsClause( 11242 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11243 } 11244 11245 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11246 OpenMPClauseKind CKind, 11247 bool StrictlyPositive) { 11248 if (!E) 11249 return ExprError(); 11250 if (E->isValueDependent() || E->isTypeDependent() || 11251 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11252 return E; 11253 llvm::APSInt Result; 11254 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11255 if (ICE.isInvalid()) 11256 return ExprError(); 11257 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11258 (!StrictlyPositive && !Result.isNonNegative())) { 11259 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11260 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11261 << E->getSourceRange(); 11262 return ExprError(); 11263 } 11264 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11265 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11266 << E->getSourceRange(); 11267 return ExprError(); 11268 } 11269 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11270 DSAStack->setAssociatedLoops(Result.getExtValue()); 11271 else if (CKind == OMPC_ordered) 11272 DSAStack->setAssociatedLoops(Result.getExtValue()); 11273 return ICE; 11274 } 11275 11276 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11277 SourceLocation LParenLoc, 11278 SourceLocation EndLoc) { 11279 // OpenMP [2.8.1, simd construct, Description] 11280 // The parameter of the safelen clause must be a constant 11281 // positive integer expression. 11282 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11283 if (Safelen.isInvalid()) 11284 return nullptr; 11285 return new (Context) 11286 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11287 } 11288 11289 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11290 SourceLocation LParenLoc, 11291 SourceLocation EndLoc) { 11292 // OpenMP [2.8.1, simd construct, Description] 11293 // The parameter of the simdlen clause must be a constant 11294 // positive integer expression. 11295 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11296 if (Simdlen.isInvalid()) 11297 return nullptr; 11298 return new (Context) 11299 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11300 } 11301 11302 /// Tries to find omp_allocator_handle_t type. 11303 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11304 DSAStackTy *Stack) { 11305 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11306 if (!OMPAllocatorHandleT.isNull()) 11307 return true; 11308 // Build the predefined allocator expressions. 11309 bool ErrorFound = false; 11310 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11311 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11312 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11313 StringRef Allocator = 11314 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11315 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11316 auto *VD = dyn_cast_or_null<ValueDecl>( 11317 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11318 if (!VD) { 11319 ErrorFound = true; 11320 break; 11321 } 11322 QualType AllocatorType = 11323 VD->getType().getNonLValueExprType(S.getASTContext()); 11324 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11325 if (!Res.isUsable()) { 11326 ErrorFound = true; 11327 break; 11328 } 11329 if (OMPAllocatorHandleT.isNull()) 11330 OMPAllocatorHandleT = AllocatorType; 11331 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11332 ErrorFound = true; 11333 break; 11334 } 11335 Stack->setAllocator(AllocatorKind, Res.get()); 11336 } 11337 if (ErrorFound) { 11338 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11339 return false; 11340 } 11341 OMPAllocatorHandleT.addConst(); 11342 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11343 return true; 11344 } 11345 11346 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11347 SourceLocation LParenLoc, 11348 SourceLocation EndLoc) { 11349 // OpenMP [2.11.3, allocate Directive, Description] 11350 // allocator is an expression of omp_allocator_handle_t type. 11351 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11352 return nullptr; 11353 11354 ExprResult Allocator = DefaultLvalueConversion(A); 11355 if (Allocator.isInvalid()) 11356 return nullptr; 11357 Allocator = PerformImplicitConversion(Allocator.get(), 11358 DSAStack->getOMPAllocatorHandleT(), 11359 Sema::AA_Initializing, 11360 /*AllowExplicit=*/true); 11361 if (Allocator.isInvalid()) 11362 return nullptr; 11363 return new (Context) 11364 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11365 } 11366 11367 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11368 SourceLocation StartLoc, 11369 SourceLocation LParenLoc, 11370 SourceLocation EndLoc) { 11371 // OpenMP [2.7.1, loop construct, Description] 11372 // OpenMP [2.8.1, simd construct, Description] 11373 // OpenMP [2.9.6, distribute construct, Description] 11374 // The parameter of the collapse clause must be a constant 11375 // positive integer expression. 11376 ExprResult NumForLoopsResult = 11377 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11378 if (NumForLoopsResult.isInvalid()) 11379 return nullptr; 11380 return new (Context) 11381 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11382 } 11383 11384 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11385 SourceLocation EndLoc, 11386 SourceLocation LParenLoc, 11387 Expr *NumForLoops) { 11388 // OpenMP [2.7.1, loop construct, Description] 11389 // OpenMP [2.8.1, simd construct, Description] 11390 // OpenMP [2.9.6, distribute construct, Description] 11391 // The parameter of the ordered clause must be a constant 11392 // positive integer expression if any. 11393 if (NumForLoops && LParenLoc.isValid()) { 11394 ExprResult NumForLoopsResult = 11395 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11396 if (NumForLoopsResult.isInvalid()) 11397 return nullptr; 11398 NumForLoops = NumForLoopsResult.get(); 11399 } else { 11400 NumForLoops = nullptr; 11401 } 11402 auto *Clause = OMPOrderedClause::Create( 11403 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11404 StartLoc, LParenLoc, EndLoc); 11405 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11406 return Clause; 11407 } 11408 11409 OMPClause *Sema::ActOnOpenMPSimpleClause( 11410 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11411 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11412 OMPClause *Res = nullptr; 11413 switch (Kind) { 11414 case OMPC_default: 11415 Res = 11416 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11417 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11418 break; 11419 case OMPC_proc_bind: 11420 Res = ActOnOpenMPProcBindClause( 11421 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11422 LParenLoc, EndLoc); 11423 break; 11424 case OMPC_atomic_default_mem_order: 11425 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11426 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11427 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11428 break; 11429 case OMPC_if: 11430 case OMPC_final: 11431 case OMPC_num_threads: 11432 case OMPC_safelen: 11433 case OMPC_simdlen: 11434 case OMPC_allocator: 11435 case OMPC_collapse: 11436 case OMPC_schedule: 11437 case OMPC_private: 11438 case OMPC_firstprivate: 11439 case OMPC_lastprivate: 11440 case OMPC_shared: 11441 case OMPC_reduction: 11442 case OMPC_task_reduction: 11443 case OMPC_in_reduction: 11444 case OMPC_linear: 11445 case OMPC_aligned: 11446 case OMPC_copyin: 11447 case OMPC_copyprivate: 11448 case OMPC_ordered: 11449 case OMPC_nowait: 11450 case OMPC_untied: 11451 case OMPC_mergeable: 11452 case OMPC_threadprivate: 11453 case OMPC_allocate: 11454 case OMPC_flush: 11455 case OMPC_read: 11456 case OMPC_write: 11457 case OMPC_update: 11458 case OMPC_capture: 11459 case OMPC_seq_cst: 11460 case OMPC_depend: 11461 case OMPC_device: 11462 case OMPC_threads: 11463 case OMPC_simd: 11464 case OMPC_map: 11465 case OMPC_num_teams: 11466 case OMPC_thread_limit: 11467 case OMPC_priority: 11468 case OMPC_grainsize: 11469 case OMPC_nogroup: 11470 case OMPC_num_tasks: 11471 case OMPC_hint: 11472 case OMPC_dist_schedule: 11473 case OMPC_defaultmap: 11474 case OMPC_unknown: 11475 case OMPC_uniform: 11476 case OMPC_to: 11477 case OMPC_from: 11478 case OMPC_use_device_ptr: 11479 case OMPC_is_device_ptr: 11480 case OMPC_unified_address: 11481 case OMPC_unified_shared_memory: 11482 case OMPC_reverse_offload: 11483 case OMPC_dynamic_allocators: 11484 case OMPC_device_type: 11485 case OMPC_match: 11486 llvm_unreachable("Clause is not allowed."); 11487 } 11488 return Res; 11489 } 11490 11491 static std::string 11492 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11493 ArrayRef<unsigned> Exclude = llvm::None) { 11494 SmallString<256> Buffer; 11495 llvm::raw_svector_ostream Out(Buffer); 11496 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11497 unsigned Skipped = Exclude.size(); 11498 auto S = Exclude.begin(), E = Exclude.end(); 11499 for (unsigned I = First; I < Last; ++I) { 11500 if (std::find(S, E, I) != E) { 11501 --Skipped; 11502 continue; 11503 } 11504 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11505 if (I == Bound - Skipped) 11506 Out << " or "; 11507 else if (I != Bound + 1 - Skipped) 11508 Out << ", "; 11509 } 11510 return Out.str(); 11511 } 11512 11513 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11514 SourceLocation KindKwLoc, 11515 SourceLocation StartLoc, 11516 SourceLocation LParenLoc, 11517 SourceLocation EndLoc) { 11518 if (Kind == OMPC_DEFAULT_unknown) { 11519 static_assert(OMPC_DEFAULT_unknown > 0, 11520 "OMPC_DEFAULT_unknown not greater than 0"); 11521 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11522 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11523 /*Last=*/OMPC_DEFAULT_unknown) 11524 << getOpenMPClauseName(OMPC_default); 11525 return nullptr; 11526 } 11527 switch (Kind) { 11528 case OMPC_DEFAULT_none: 11529 DSAStack->setDefaultDSANone(KindKwLoc); 11530 break; 11531 case OMPC_DEFAULT_shared: 11532 DSAStack->setDefaultDSAShared(KindKwLoc); 11533 break; 11534 case OMPC_DEFAULT_unknown: 11535 llvm_unreachable("Clause kind is not allowed."); 11536 break; 11537 } 11538 return new (Context) 11539 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11540 } 11541 11542 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11543 SourceLocation KindKwLoc, 11544 SourceLocation StartLoc, 11545 SourceLocation LParenLoc, 11546 SourceLocation EndLoc) { 11547 if (Kind == OMPC_PROC_BIND_unknown) { 11548 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11549 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11550 /*Last=*/OMPC_PROC_BIND_unknown) 11551 << getOpenMPClauseName(OMPC_proc_bind); 11552 return nullptr; 11553 } 11554 return new (Context) 11555 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11556 } 11557 11558 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11559 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11560 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11561 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11562 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11563 << getListOfPossibleValues( 11564 OMPC_atomic_default_mem_order, /*First=*/0, 11565 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11566 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11567 return nullptr; 11568 } 11569 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11570 LParenLoc, EndLoc); 11571 } 11572 11573 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11574 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11575 SourceLocation StartLoc, SourceLocation LParenLoc, 11576 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11577 SourceLocation EndLoc) { 11578 OMPClause *Res = nullptr; 11579 switch (Kind) { 11580 case OMPC_schedule: 11581 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11582 assert(Argument.size() == NumberOfElements && 11583 ArgumentLoc.size() == NumberOfElements); 11584 Res = ActOnOpenMPScheduleClause( 11585 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11586 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11587 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11588 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11589 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11590 break; 11591 case OMPC_if: 11592 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11593 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11594 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11595 DelimLoc, EndLoc); 11596 break; 11597 case OMPC_dist_schedule: 11598 Res = ActOnOpenMPDistScheduleClause( 11599 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11600 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11601 break; 11602 case OMPC_defaultmap: 11603 enum { Modifier, DefaultmapKind }; 11604 Res = ActOnOpenMPDefaultmapClause( 11605 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11606 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11607 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11608 EndLoc); 11609 break; 11610 case OMPC_final: 11611 case OMPC_num_threads: 11612 case OMPC_safelen: 11613 case OMPC_simdlen: 11614 case OMPC_allocator: 11615 case OMPC_collapse: 11616 case OMPC_default: 11617 case OMPC_proc_bind: 11618 case OMPC_private: 11619 case OMPC_firstprivate: 11620 case OMPC_lastprivate: 11621 case OMPC_shared: 11622 case OMPC_reduction: 11623 case OMPC_task_reduction: 11624 case OMPC_in_reduction: 11625 case OMPC_linear: 11626 case OMPC_aligned: 11627 case OMPC_copyin: 11628 case OMPC_copyprivate: 11629 case OMPC_ordered: 11630 case OMPC_nowait: 11631 case OMPC_untied: 11632 case OMPC_mergeable: 11633 case OMPC_threadprivate: 11634 case OMPC_allocate: 11635 case OMPC_flush: 11636 case OMPC_read: 11637 case OMPC_write: 11638 case OMPC_update: 11639 case OMPC_capture: 11640 case OMPC_seq_cst: 11641 case OMPC_depend: 11642 case OMPC_device: 11643 case OMPC_threads: 11644 case OMPC_simd: 11645 case OMPC_map: 11646 case OMPC_num_teams: 11647 case OMPC_thread_limit: 11648 case OMPC_priority: 11649 case OMPC_grainsize: 11650 case OMPC_nogroup: 11651 case OMPC_num_tasks: 11652 case OMPC_hint: 11653 case OMPC_unknown: 11654 case OMPC_uniform: 11655 case OMPC_to: 11656 case OMPC_from: 11657 case OMPC_use_device_ptr: 11658 case OMPC_is_device_ptr: 11659 case OMPC_unified_address: 11660 case OMPC_unified_shared_memory: 11661 case OMPC_reverse_offload: 11662 case OMPC_dynamic_allocators: 11663 case OMPC_atomic_default_mem_order: 11664 case OMPC_device_type: 11665 case OMPC_match: 11666 llvm_unreachable("Clause is not allowed."); 11667 } 11668 return Res; 11669 } 11670 11671 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11672 OpenMPScheduleClauseModifier M2, 11673 SourceLocation M1Loc, SourceLocation M2Loc) { 11674 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11675 SmallVector<unsigned, 2> Excluded; 11676 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11677 Excluded.push_back(M2); 11678 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11679 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11680 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11681 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11682 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11683 << getListOfPossibleValues(OMPC_schedule, 11684 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11685 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11686 Excluded) 11687 << getOpenMPClauseName(OMPC_schedule); 11688 return true; 11689 } 11690 return false; 11691 } 11692 11693 OMPClause *Sema::ActOnOpenMPScheduleClause( 11694 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11695 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11696 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11697 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11698 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11699 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11700 return nullptr; 11701 // OpenMP, 2.7.1, Loop Construct, Restrictions 11702 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11703 // but not both. 11704 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11705 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11706 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11707 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11708 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11709 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11710 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11711 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11712 return nullptr; 11713 } 11714 if (Kind == OMPC_SCHEDULE_unknown) { 11715 std::string Values; 11716 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11717 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11718 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11719 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11720 Exclude); 11721 } else { 11722 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11723 /*Last=*/OMPC_SCHEDULE_unknown); 11724 } 11725 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11726 << Values << getOpenMPClauseName(OMPC_schedule); 11727 return nullptr; 11728 } 11729 // OpenMP, 2.7.1, Loop Construct, Restrictions 11730 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11731 // schedule(guided). 11732 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11733 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11734 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11735 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11736 diag::err_omp_schedule_nonmonotonic_static); 11737 return nullptr; 11738 } 11739 Expr *ValExpr = ChunkSize; 11740 Stmt *HelperValStmt = nullptr; 11741 if (ChunkSize) { 11742 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11743 !ChunkSize->isInstantiationDependent() && 11744 !ChunkSize->containsUnexpandedParameterPack()) { 11745 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11746 ExprResult Val = 11747 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11748 if (Val.isInvalid()) 11749 return nullptr; 11750 11751 ValExpr = Val.get(); 11752 11753 // OpenMP [2.7.1, Restrictions] 11754 // chunk_size must be a loop invariant integer expression with a positive 11755 // value. 11756 llvm::APSInt Result; 11757 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11758 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11759 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11760 << "schedule" << 1 << ChunkSize->getSourceRange(); 11761 return nullptr; 11762 } 11763 } else if (getOpenMPCaptureRegionForClause( 11764 DSAStack->getCurrentDirective(), OMPC_schedule) != 11765 OMPD_unknown && 11766 !CurContext->isDependentContext()) { 11767 ValExpr = MakeFullExpr(ValExpr).get(); 11768 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11769 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11770 HelperValStmt = buildPreInits(Context, Captures); 11771 } 11772 } 11773 } 11774 11775 return new (Context) 11776 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11777 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11778 } 11779 11780 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11781 SourceLocation StartLoc, 11782 SourceLocation EndLoc) { 11783 OMPClause *Res = nullptr; 11784 switch (Kind) { 11785 case OMPC_ordered: 11786 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11787 break; 11788 case OMPC_nowait: 11789 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11790 break; 11791 case OMPC_untied: 11792 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11793 break; 11794 case OMPC_mergeable: 11795 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11796 break; 11797 case OMPC_read: 11798 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11799 break; 11800 case OMPC_write: 11801 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11802 break; 11803 case OMPC_update: 11804 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11805 break; 11806 case OMPC_capture: 11807 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11808 break; 11809 case OMPC_seq_cst: 11810 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11811 break; 11812 case OMPC_threads: 11813 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11814 break; 11815 case OMPC_simd: 11816 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11817 break; 11818 case OMPC_nogroup: 11819 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11820 break; 11821 case OMPC_unified_address: 11822 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11823 break; 11824 case OMPC_unified_shared_memory: 11825 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11826 break; 11827 case OMPC_reverse_offload: 11828 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11829 break; 11830 case OMPC_dynamic_allocators: 11831 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11832 break; 11833 case OMPC_if: 11834 case OMPC_final: 11835 case OMPC_num_threads: 11836 case OMPC_safelen: 11837 case OMPC_simdlen: 11838 case OMPC_allocator: 11839 case OMPC_collapse: 11840 case OMPC_schedule: 11841 case OMPC_private: 11842 case OMPC_firstprivate: 11843 case OMPC_lastprivate: 11844 case OMPC_shared: 11845 case OMPC_reduction: 11846 case OMPC_task_reduction: 11847 case OMPC_in_reduction: 11848 case OMPC_linear: 11849 case OMPC_aligned: 11850 case OMPC_copyin: 11851 case OMPC_copyprivate: 11852 case OMPC_default: 11853 case OMPC_proc_bind: 11854 case OMPC_threadprivate: 11855 case OMPC_allocate: 11856 case OMPC_flush: 11857 case OMPC_depend: 11858 case OMPC_device: 11859 case OMPC_map: 11860 case OMPC_num_teams: 11861 case OMPC_thread_limit: 11862 case OMPC_priority: 11863 case OMPC_grainsize: 11864 case OMPC_num_tasks: 11865 case OMPC_hint: 11866 case OMPC_dist_schedule: 11867 case OMPC_defaultmap: 11868 case OMPC_unknown: 11869 case OMPC_uniform: 11870 case OMPC_to: 11871 case OMPC_from: 11872 case OMPC_use_device_ptr: 11873 case OMPC_is_device_ptr: 11874 case OMPC_atomic_default_mem_order: 11875 case OMPC_device_type: 11876 case OMPC_match: 11877 llvm_unreachable("Clause is not allowed."); 11878 } 11879 return Res; 11880 } 11881 11882 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11883 SourceLocation EndLoc) { 11884 DSAStack->setNowaitRegion(); 11885 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11886 } 11887 11888 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11889 SourceLocation EndLoc) { 11890 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11891 } 11892 11893 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11894 SourceLocation EndLoc) { 11895 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11896 } 11897 11898 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11899 SourceLocation EndLoc) { 11900 return new (Context) OMPReadClause(StartLoc, EndLoc); 11901 } 11902 11903 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11904 SourceLocation EndLoc) { 11905 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11906 } 11907 11908 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11909 SourceLocation EndLoc) { 11910 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11911 } 11912 11913 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11914 SourceLocation EndLoc) { 11915 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11916 } 11917 11918 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11919 SourceLocation EndLoc) { 11920 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11921 } 11922 11923 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11924 SourceLocation EndLoc) { 11925 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11926 } 11927 11928 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11929 SourceLocation EndLoc) { 11930 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11931 } 11932 11933 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11934 SourceLocation EndLoc) { 11935 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11936 } 11937 11938 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11939 SourceLocation EndLoc) { 11940 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11941 } 11942 11943 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11944 SourceLocation EndLoc) { 11945 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11946 } 11947 11948 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11949 SourceLocation EndLoc) { 11950 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11951 } 11952 11953 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11954 SourceLocation EndLoc) { 11955 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11956 } 11957 11958 OMPClause *Sema::ActOnOpenMPVarListClause( 11959 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11960 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11961 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11962 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11963 OpenMPLinearClauseKind LinKind, 11964 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11965 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11966 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11967 SourceLocation StartLoc = Locs.StartLoc; 11968 SourceLocation LParenLoc = Locs.LParenLoc; 11969 SourceLocation EndLoc = Locs.EndLoc; 11970 OMPClause *Res = nullptr; 11971 switch (Kind) { 11972 case OMPC_private: 11973 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11974 break; 11975 case OMPC_firstprivate: 11976 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11977 break; 11978 case OMPC_lastprivate: 11979 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11980 break; 11981 case OMPC_shared: 11982 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11983 break; 11984 case OMPC_reduction: 11985 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11986 EndLoc, ReductionOrMapperIdScopeSpec, 11987 ReductionOrMapperId); 11988 break; 11989 case OMPC_task_reduction: 11990 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11991 EndLoc, ReductionOrMapperIdScopeSpec, 11992 ReductionOrMapperId); 11993 break; 11994 case OMPC_in_reduction: 11995 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11996 EndLoc, ReductionOrMapperIdScopeSpec, 11997 ReductionOrMapperId); 11998 break; 11999 case OMPC_linear: 12000 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 12001 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 12002 break; 12003 case OMPC_aligned: 12004 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12005 ColonLoc, EndLoc); 12006 break; 12007 case OMPC_copyin: 12008 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12009 break; 12010 case OMPC_copyprivate: 12011 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12012 break; 12013 case OMPC_flush: 12014 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12015 break; 12016 case OMPC_depend: 12017 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 12018 StartLoc, LParenLoc, EndLoc); 12019 break; 12020 case OMPC_map: 12021 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 12022 ReductionOrMapperIdScopeSpec, 12023 ReductionOrMapperId, MapType, IsMapTypeImplicit, 12024 DepLinMapLoc, ColonLoc, VarList, Locs); 12025 break; 12026 case OMPC_to: 12027 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12028 ReductionOrMapperId, Locs); 12029 break; 12030 case OMPC_from: 12031 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12032 ReductionOrMapperId, Locs); 12033 break; 12034 case OMPC_use_device_ptr: 12035 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12036 break; 12037 case OMPC_is_device_ptr: 12038 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12039 break; 12040 case OMPC_allocate: 12041 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12042 ColonLoc, EndLoc); 12043 break; 12044 case OMPC_if: 12045 case OMPC_final: 12046 case OMPC_num_threads: 12047 case OMPC_safelen: 12048 case OMPC_simdlen: 12049 case OMPC_allocator: 12050 case OMPC_collapse: 12051 case OMPC_default: 12052 case OMPC_proc_bind: 12053 case OMPC_schedule: 12054 case OMPC_ordered: 12055 case OMPC_nowait: 12056 case OMPC_untied: 12057 case OMPC_mergeable: 12058 case OMPC_threadprivate: 12059 case OMPC_read: 12060 case OMPC_write: 12061 case OMPC_update: 12062 case OMPC_capture: 12063 case OMPC_seq_cst: 12064 case OMPC_device: 12065 case OMPC_threads: 12066 case OMPC_simd: 12067 case OMPC_num_teams: 12068 case OMPC_thread_limit: 12069 case OMPC_priority: 12070 case OMPC_grainsize: 12071 case OMPC_nogroup: 12072 case OMPC_num_tasks: 12073 case OMPC_hint: 12074 case OMPC_dist_schedule: 12075 case OMPC_defaultmap: 12076 case OMPC_unknown: 12077 case OMPC_uniform: 12078 case OMPC_unified_address: 12079 case OMPC_unified_shared_memory: 12080 case OMPC_reverse_offload: 12081 case OMPC_dynamic_allocators: 12082 case OMPC_atomic_default_mem_order: 12083 case OMPC_device_type: 12084 case OMPC_match: 12085 llvm_unreachable("Clause is not allowed."); 12086 } 12087 return Res; 12088 } 12089 12090 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12091 ExprObjectKind OK, SourceLocation Loc) { 12092 ExprResult Res = BuildDeclRefExpr( 12093 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12094 if (!Res.isUsable()) 12095 return ExprError(); 12096 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12097 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12098 if (!Res.isUsable()) 12099 return ExprError(); 12100 } 12101 if (VK != VK_LValue && Res.get()->isGLValue()) { 12102 Res = DefaultLvalueConversion(Res.get()); 12103 if (!Res.isUsable()) 12104 return ExprError(); 12105 } 12106 return Res; 12107 } 12108 12109 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12110 SourceLocation StartLoc, 12111 SourceLocation LParenLoc, 12112 SourceLocation EndLoc) { 12113 SmallVector<Expr *, 8> Vars; 12114 SmallVector<Expr *, 8> PrivateCopies; 12115 for (Expr *RefExpr : VarList) { 12116 assert(RefExpr && "NULL expr in OpenMP private clause."); 12117 SourceLocation ELoc; 12118 SourceRange ERange; 12119 Expr *SimpleRefExpr = RefExpr; 12120 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12121 if (Res.second) { 12122 // It will be analyzed later. 12123 Vars.push_back(RefExpr); 12124 PrivateCopies.push_back(nullptr); 12125 } 12126 ValueDecl *D = Res.first; 12127 if (!D) 12128 continue; 12129 12130 QualType Type = D->getType(); 12131 auto *VD = dyn_cast<VarDecl>(D); 12132 12133 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12134 // A variable that appears in a private clause must not have an incomplete 12135 // type or a reference type. 12136 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12137 continue; 12138 Type = Type.getNonReferenceType(); 12139 12140 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12141 // A variable that is privatized must not have a const-qualified type 12142 // unless it is of class type with a mutable member. This restriction does 12143 // not apply to the firstprivate clause. 12144 // 12145 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12146 // A variable that appears in a private clause must not have a 12147 // const-qualified type unless it is of class type with a mutable member. 12148 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12149 continue; 12150 12151 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12152 // in a Construct] 12153 // Variables with the predetermined data-sharing attributes may not be 12154 // listed in data-sharing attributes clauses, except for the cases 12155 // listed below. For these exceptions only, listing a predetermined 12156 // variable in a data-sharing attribute clause is allowed and overrides 12157 // the variable's predetermined data-sharing attributes. 12158 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12159 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12160 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12161 << getOpenMPClauseName(OMPC_private); 12162 reportOriginalDsa(*this, DSAStack, D, DVar); 12163 continue; 12164 } 12165 12166 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12167 // Variably modified types are not supported for tasks. 12168 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12169 isOpenMPTaskingDirective(CurrDir)) { 12170 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12171 << getOpenMPClauseName(OMPC_private) << Type 12172 << getOpenMPDirectiveName(CurrDir); 12173 bool IsDecl = 12174 !VD || 12175 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12176 Diag(D->getLocation(), 12177 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12178 << D; 12179 continue; 12180 } 12181 12182 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12183 // A list item cannot appear in both a map clause and a data-sharing 12184 // attribute clause on the same construct 12185 // 12186 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12187 // A list item cannot appear in both a map clause and a data-sharing 12188 // attribute clause on the same construct unless the construct is a 12189 // combined construct. 12190 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12191 CurrDir == OMPD_target) { 12192 OpenMPClauseKind ConflictKind; 12193 if (DSAStack->checkMappableExprComponentListsForDecl( 12194 VD, /*CurrentRegionOnly=*/true, 12195 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12196 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12197 ConflictKind = WhereFoundClauseKind; 12198 return true; 12199 })) { 12200 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12201 << getOpenMPClauseName(OMPC_private) 12202 << getOpenMPClauseName(ConflictKind) 12203 << getOpenMPDirectiveName(CurrDir); 12204 reportOriginalDsa(*this, DSAStack, D, DVar); 12205 continue; 12206 } 12207 } 12208 12209 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12210 // A variable of class type (or array thereof) that appears in a private 12211 // clause requires an accessible, unambiguous default constructor for the 12212 // class type. 12213 // Generate helper private variable and initialize it with the default 12214 // value. The address of the original variable is replaced by the address of 12215 // the new private variable in CodeGen. This new variable is not added to 12216 // IdResolver, so the code in the OpenMP region uses original variable for 12217 // proper diagnostics. 12218 Type = Type.getUnqualifiedType(); 12219 VarDecl *VDPrivate = 12220 buildVarDecl(*this, ELoc, Type, D->getName(), 12221 D->hasAttrs() ? &D->getAttrs() : nullptr, 12222 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12223 ActOnUninitializedDecl(VDPrivate); 12224 if (VDPrivate->isInvalidDecl()) 12225 continue; 12226 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12227 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12228 12229 DeclRefExpr *Ref = nullptr; 12230 if (!VD && !CurContext->isDependentContext()) 12231 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12232 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12233 Vars.push_back((VD || CurContext->isDependentContext()) 12234 ? RefExpr->IgnoreParens() 12235 : Ref); 12236 PrivateCopies.push_back(VDPrivateRefExpr); 12237 } 12238 12239 if (Vars.empty()) 12240 return nullptr; 12241 12242 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12243 PrivateCopies); 12244 } 12245 12246 namespace { 12247 class DiagsUninitializedSeveretyRAII { 12248 private: 12249 DiagnosticsEngine &Diags; 12250 SourceLocation SavedLoc; 12251 bool IsIgnored = false; 12252 12253 public: 12254 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12255 bool IsIgnored) 12256 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12257 if (!IsIgnored) { 12258 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12259 /*Map*/ diag::Severity::Ignored, Loc); 12260 } 12261 } 12262 ~DiagsUninitializedSeveretyRAII() { 12263 if (!IsIgnored) 12264 Diags.popMappings(SavedLoc); 12265 } 12266 }; 12267 } 12268 12269 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12270 SourceLocation StartLoc, 12271 SourceLocation LParenLoc, 12272 SourceLocation EndLoc) { 12273 SmallVector<Expr *, 8> Vars; 12274 SmallVector<Expr *, 8> PrivateCopies; 12275 SmallVector<Expr *, 8> Inits; 12276 SmallVector<Decl *, 4> ExprCaptures; 12277 bool IsImplicitClause = 12278 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12279 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12280 12281 for (Expr *RefExpr : VarList) { 12282 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12283 SourceLocation ELoc; 12284 SourceRange ERange; 12285 Expr *SimpleRefExpr = RefExpr; 12286 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12287 if (Res.second) { 12288 // It will be analyzed later. 12289 Vars.push_back(RefExpr); 12290 PrivateCopies.push_back(nullptr); 12291 Inits.push_back(nullptr); 12292 } 12293 ValueDecl *D = Res.first; 12294 if (!D) 12295 continue; 12296 12297 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12298 QualType Type = D->getType(); 12299 auto *VD = dyn_cast<VarDecl>(D); 12300 12301 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12302 // A variable that appears in a private clause must not have an incomplete 12303 // type or a reference type. 12304 if (RequireCompleteType(ELoc, Type, 12305 diag::err_omp_firstprivate_incomplete_type)) 12306 continue; 12307 Type = Type.getNonReferenceType(); 12308 12309 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12310 // A variable of class type (or array thereof) that appears in a private 12311 // clause requires an accessible, unambiguous copy constructor for the 12312 // class type. 12313 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12314 12315 // If an implicit firstprivate variable found it was checked already. 12316 DSAStackTy::DSAVarData TopDVar; 12317 if (!IsImplicitClause) { 12318 DSAStackTy::DSAVarData DVar = 12319 DSAStack->getTopDSA(D, /*FromParent=*/false); 12320 TopDVar = DVar; 12321 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12322 bool IsConstant = ElemType.isConstant(Context); 12323 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12324 // A list item that specifies a given variable may not appear in more 12325 // than one clause on the same directive, except that a variable may be 12326 // specified in both firstprivate and lastprivate clauses. 12327 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12328 // A list item may appear in a firstprivate or lastprivate clause but not 12329 // both. 12330 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12331 (isOpenMPDistributeDirective(CurrDir) || 12332 DVar.CKind != OMPC_lastprivate) && 12333 DVar.RefExpr) { 12334 Diag(ELoc, diag::err_omp_wrong_dsa) 12335 << getOpenMPClauseName(DVar.CKind) 12336 << getOpenMPClauseName(OMPC_firstprivate); 12337 reportOriginalDsa(*this, DSAStack, D, DVar); 12338 continue; 12339 } 12340 12341 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12342 // in a Construct] 12343 // Variables with the predetermined data-sharing attributes may not be 12344 // listed in data-sharing attributes clauses, except for the cases 12345 // listed below. For these exceptions only, listing a predetermined 12346 // variable in a data-sharing attribute clause is allowed and overrides 12347 // the variable's predetermined data-sharing attributes. 12348 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12349 // in a Construct, C/C++, p.2] 12350 // Variables with const-qualified type having no mutable member may be 12351 // listed in a firstprivate clause, even if they are static data members. 12352 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12353 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12354 Diag(ELoc, diag::err_omp_wrong_dsa) 12355 << getOpenMPClauseName(DVar.CKind) 12356 << getOpenMPClauseName(OMPC_firstprivate); 12357 reportOriginalDsa(*this, DSAStack, D, DVar); 12358 continue; 12359 } 12360 12361 // OpenMP [2.9.3.4, Restrictions, p.2] 12362 // A list item that is private within a parallel region must not appear 12363 // in a firstprivate clause on a worksharing construct if any of the 12364 // worksharing regions arising from the worksharing construct ever bind 12365 // to any of the parallel regions arising from the parallel construct. 12366 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12367 // A list item that is private within a teams region must not appear in a 12368 // firstprivate clause on a distribute construct if any of the distribute 12369 // regions arising from the distribute construct ever bind to any of the 12370 // teams regions arising from the teams construct. 12371 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12372 // A list item that appears in a reduction clause of a teams construct 12373 // must not appear in a firstprivate clause on a distribute construct if 12374 // any of the distribute regions arising from the distribute construct 12375 // ever bind to any of the teams regions arising from the teams construct. 12376 if ((isOpenMPWorksharingDirective(CurrDir) || 12377 isOpenMPDistributeDirective(CurrDir)) && 12378 !isOpenMPParallelDirective(CurrDir) && 12379 !isOpenMPTeamsDirective(CurrDir)) { 12380 DVar = DSAStack->getImplicitDSA(D, true); 12381 if (DVar.CKind != OMPC_shared && 12382 (isOpenMPParallelDirective(DVar.DKind) || 12383 isOpenMPTeamsDirective(DVar.DKind) || 12384 DVar.DKind == OMPD_unknown)) { 12385 Diag(ELoc, diag::err_omp_required_access) 12386 << getOpenMPClauseName(OMPC_firstprivate) 12387 << getOpenMPClauseName(OMPC_shared); 12388 reportOriginalDsa(*this, DSAStack, D, DVar); 12389 continue; 12390 } 12391 } 12392 // OpenMP [2.9.3.4, Restrictions, p.3] 12393 // A list item that appears in a reduction clause of a parallel construct 12394 // must not appear in a firstprivate clause on a worksharing or task 12395 // construct if any of the worksharing or task regions arising from the 12396 // worksharing or task construct ever bind to any of the parallel regions 12397 // arising from the parallel construct. 12398 // OpenMP [2.9.3.4, Restrictions, p.4] 12399 // A list item that appears in a reduction clause in worksharing 12400 // construct must not appear in a firstprivate clause in a task construct 12401 // encountered during execution of any of the worksharing regions arising 12402 // from the worksharing construct. 12403 if (isOpenMPTaskingDirective(CurrDir)) { 12404 DVar = DSAStack->hasInnermostDSA( 12405 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12406 [](OpenMPDirectiveKind K) { 12407 return isOpenMPParallelDirective(K) || 12408 isOpenMPWorksharingDirective(K) || 12409 isOpenMPTeamsDirective(K); 12410 }, 12411 /*FromParent=*/true); 12412 if (DVar.CKind == OMPC_reduction && 12413 (isOpenMPParallelDirective(DVar.DKind) || 12414 isOpenMPWorksharingDirective(DVar.DKind) || 12415 isOpenMPTeamsDirective(DVar.DKind))) { 12416 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12417 << getOpenMPDirectiveName(DVar.DKind); 12418 reportOriginalDsa(*this, DSAStack, D, DVar); 12419 continue; 12420 } 12421 } 12422 12423 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12424 // A list item cannot appear in both a map clause and a data-sharing 12425 // attribute clause on the same construct 12426 // 12427 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12428 // A list item cannot appear in both a map clause and a data-sharing 12429 // attribute clause on the same construct unless the construct is a 12430 // combined construct. 12431 if ((LangOpts.OpenMP <= 45 && 12432 isOpenMPTargetExecutionDirective(CurrDir)) || 12433 CurrDir == OMPD_target) { 12434 OpenMPClauseKind ConflictKind; 12435 if (DSAStack->checkMappableExprComponentListsForDecl( 12436 VD, /*CurrentRegionOnly=*/true, 12437 [&ConflictKind]( 12438 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12439 OpenMPClauseKind WhereFoundClauseKind) { 12440 ConflictKind = WhereFoundClauseKind; 12441 return true; 12442 })) { 12443 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12444 << getOpenMPClauseName(OMPC_firstprivate) 12445 << getOpenMPClauseName(ConflictKind) 12446 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12447 reportOriginalDsa(*this, DSAStack, D, DVar); 12448 continue; 12449 } 12450 } 12451 } 12452 12453 // Variably modified types are not supported for tasks. 12454 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12455 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12456 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12457 << getOpenMPClauseName(OMPC_firstprivate) << Type 12458 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12459 bool IsDecl = 12460 !VD || 12461 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12462 Diag(D->getLocation(), 12463 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12464 << D; 12465 continue; 12466 } 12467 12468 Type = Type.getUnqualifiedType(); 12469 VarDecl *VDPrivate = 12470 buildVarDecl(*this, ELoc, Type, D->getName(), 12471 D->hasAttrs() ? &D->getAttrs() : nullptr, 12472 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12473 // Generate helper private variable and initialize it with the value of the 12474 // original variable. The address of the original variable is replaced by 12475 // the address of the new private variable in the CodeGen. This new variable 12476 // is not added to IdResolver, so the code in the OpenMP region uses 12477 // original variable for proper diagnostics and variable capturing. 12478 Expr *VDInitRefExpr = nullptr; 12479 // For arrays generate initializer for single element and replace it by the 12480 // original array element in CodeGen. 12481 if (Type->isArrayType()) { 12482 VarDecl *VDInit = 12483 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12484 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12485 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12486 ElemType = ElemType.getUnqualifiedType(); 12487 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12488 ".firstprivate.temp"); 12489 InitializedEntity Entity = 12490 InitializedEntity::InitializeVariable(VDInitTemp); 12491 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12492 12493 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12494 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12495 if (Result.isInvalid()) 12496 VDPrivate->setInvalidDecl(); 12497 else 12498 VDPrivate->setInit(Result.getAs<Expr>()); 12499 // Remove temp variable declaration. 12500 Context.Deallocate(VDInitTemp); 12501 } else { 12502 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12503 ".firstprivate.temp"); 12504 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12505 RefExpr->getExprLoc()); 12506 AddInitializerToDecl(VDPrivate, 12507 DefaultLvalueConversion(VDInitRefExpr).get(), 12508 /*DirectInit=*/false); 12509 } 12510 if (VDPrivate->isInvalidDecl()) { 12511 if (IsImplicitClause) { 12512 Diag(RefExpr->getExprLoc(), 12513 diag::note_omp_task_predetermined_firstprivate_here); 12514 } 12515 continue; 12516 } 12517 CurContext->addDecl(VDPrivate); 12518 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12519 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12520 RefExpr->getExprLoc()); 12521 DeclRefExpr *Ref = nullptr; 12522 if (!VD && !CurContext->isDependentContext()) { 12523 if (TopDVar.CKind == OMPC_lastprivate) { 12524 Ref = TopDVar.PrivateCopy; 12525 } else { 12526 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12527 if (!isOpenMPCapturedDecl(D)) 12528 ExprCaptures.push_back(Ref->getDecl()); 12529 } 12530 } 12531 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12532 Vars.push_back((VD || CurContext->isDependentContext()) 12533 ? RefExpr->IgnoreParens() 12534 : Ref); 12535 PrivateCopies.push_back(VDPrivateRefExpr); 12536 Inits.push_back(VDInitRefExpr); 12537 } 12538 12539 if (Vars.empty()) 12540 return nullptr; 12541 12542 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12543 Vars, PrivateCopies, Inits, 12544 buildPreInits(Context, ExprCaptures)); 12545 } 12546 12547 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12548 SourceLocation StartLoc, 12549 SourceLocation LParenLoc, 12550 SourceLocation EndLoc) { 12551 SmallVector<Expr *, 8> Vars; 12552 SmallVector<Expr *, 8> SrcExprs; 12553 SmallVector<Expr *, 8> DstExprs; 12554 SmallVector<Expr *, 8> AssignmentOps; 12555 SmallVector<Decl *, 4> ExprCaptures; 12556 SmallVector<Expr *, 4> ExprPostUpdates; 12557 for (Expr *RefExpr : VarList) { 12558 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12559 SourceLocation ELoc; 12560 SourceRange ERange; 12561 Expr *SimpleRefExpr = RefExpr; 12562 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12563 if (Res.second) { 12564 // It will be analyzed later. 12565 Vars.push_back(RefExpr); 12566 SrcExprs.push_back(nullptr); 12567 DstExprs.push_back(nullptr); 12568 AssignmentOps.push_back(nullptr); 12569 } 12570 ValueDecl *D = Res.first; 12571 if (!D) 12572 continue; 12573 12574 QualType Type = D->getType(); 12575 auto *VD = dyn_cast<VarDecl>(D); 12576 12577 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12578 // A variable that appears in a lastprivate clause must not have an 12579 // incomplete type or a reference type. 12580 if (RequireCompleteType(ELoc, Type, 12581 diag::err_omp_lastprivate_incomplete_type)) 12582 continue; 12583 Type = Type.getNonReferenceType(); 12584 12585 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12586 // A variable that is privatized must not have a const-qualified type 12587 // unless it is of class type with a mutable member. This restriction does 12588 // not apply to the firstprivate clause. 12589 // 12590 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12591 // A variable that appears in a lastprivate clause must not have a 12592 // const-qualified type unless it is of class type with a mutable member. 12593 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12594 continue; 12595 12596 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12597 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12598 // in a Construct] 12599 // Variables with the predetermined data-sharing attributes may not be 12600 // listed in data-sharing attributes clauses, except for the cases 12601 // listed below. 12602 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12603 // A list item may appear in a firstprivate or lastprivate clause but not 12604 // both. 12605 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12606 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12607 (isOpenMPDistributeDirective(CurrDir) || 12608 DVar.CKind != OMPC_firstprivate) && 12609 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12610 Diag(ELoc, diag::err_omp_wrong_dsa) 12611 << getOpenMPClauseName(DVar.CKind) 12612 << getOpenMPClauseName(OMPC_lastprivate); 12613 reportOriginalDsa(*this, DSAStack, D, DVar); 12614 continue; 12615 } 12616 12617 // OpenMP [2.14.3.5, Restrictions, p.2] 12618 // A list item that is private within a parallel region, or that appears in 12619 // the reduction clause of a parallel construct, must not appear in a 12620 // lastprivate clause on a worksharing construct if any of the corresponding 12621 // worksharing regions ever binds to any of the corresponding parallel 12622 // regions. 12623 DSAStackTy::DSAVarData TopDVar = DVar; 12624 if (isOpenMPWorksharingDirective(CurrDir) && 12625 !isOpenMPParallelDirective(CurrDir) && 12626 !isOpenMPTeamsDirective(CurrDir)) { 12627 DVar = DSAStack->getImplicitDSA(D, true); 12628 if (DVar.CKind != OMPC_shared) { 12629 Diag(ELoc, diag::err_omp_required_access) 12630 << getOpenMPClauseName(OMPC_lastprivate) 12631 << getOpenMPClauseName(OMPC_shared); 12632 reportOriginalDsa(*this, DSAStack, D, DVar); 12633 continue; 12634 } 12635 } 12636 12637 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12638 // A variable of class type (or array thereof) that appears in a 12639 // lastprivate clause requires an accessible, unambiguous default 12640 // constructor for the class type, unless the list item is also specified 12641 // in a firstprivate clause. 12642 // A variable of class type (or array thereof) that appears in a 12643 // lastprivate clause requires an accessible, unambiguous copy assignment 12644 // operator for the class type. 12645 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12646 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12647 Type.getUnqualifiedType(), ".lastprivate.src", 12648 D->hasAttrs() ? &D->getAttrs() : nullptr); 12649 DeclRefExpr *PseudoSrcExpr = 12650 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12651 VarDecl *DstVD = 12652 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12653 D->hasAttrs() ? &D->getAttrs() : nullptr); 12654 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12655 // For arrays generate assignment operation for single element and replace 12656 // it by the original array element in CodeGen. 12657 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12658 PseudoDstExpr, PseudoSrcExpr); 12659 if (AssignmentOp.isInvalid()) 12660 continue; 12661 AssignmentOp = 12662 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12663 if (AssignmentOp.isInvalid()) 12664 continue; 12665 12666 DeclRefExpr *Ref = nullptr; 12667 if (!VD && !CurContext->isDependentContext()) { 12668 if (TopDVar.CKind == OMPC_firstprivate) { 12669 Ref = TopDVar.PrivateCopy; 12670 } else { 12671 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12672 if (!isOpenMPCapturedDecl(D)) 12673 ExprCaptures.push_back(Ref->getDecl()); 12674 } 12675 if (TopDVar.CKind == OMPC_firstprivate || 12676 (!isOpenMPCapturedDecl(D) && 12677 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12678 ExprResult RefRes = DefaultLvalueConversion(Ref); 12679 if (!RefRes.isUsable()) 12680 continue; 12681 ExprResult PostUpdateRes = 12682 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12683 RefRes.get()); 12684 if (!PostUpdateRes.isUsable()) 12685 continue; 12686 ExprPostUpdates.push_back( 12687 IgnoredValueConversions(PostUpdateRes.get()).get()); 12688 } 12689 } 12690 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12691 Vars.push_back((VD || CurContext->isDependentContext()) 12692 ? RefExpr->IgnoreParens() 12693 : Ref); 12694 SrcExprs.push_back(PseudoSrcExpr); 12695 DstExprs.push_back(PseudoDstExpr); 12696 AssignmentOps.push_back(AssignmentOp.get()); 12697 } 12698 12699 if (Vars.empty()) 12700 return nullptr; 12701 12702 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12703 Vars, SrcExprs, DstExprs, AssignmentOps, 12704 buildPreInits(Context, ExprCaptures), 12705 buildPostUpdate(*this, ExprPostUpdates)); 12706 } 12707 12708 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12709 SourceLocation StartLoc, 12710 SourceLocation LParenLoc, 12711 SourceLocation EndLoc) { 12712 SmallVector<Expr *, 8> Vars; 12713 for (Expr *RefExpr : VarList) { 12714 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12715 SourceLocation ELoc; 12716 SourceRange ERange; 12717 Expr *SimpleRefExpr = RefExpr; 12718 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12719 if (Res.second) { 12720 // It will be analyzed later. 12721 Vars.push_back(RefExpr); 12722 } 12723 ValueDecl *D = Res.first; 12724 if (!D) 12725 continue; 12726 12727 auto *VD = dyn_cast<VarDecl>(D); 12728 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12729 // in a Construct] 12730 // Variables with the predetermined data-sharing attributes may not be 12731 // listed in data-sharing attributes clauses, except for the cases 12732 // listed below. For these exceptions only, listing a predetermined 12733 // variable in a data-sharing attribute clause is allowed and overrides 12734 // the variable's predetermined data-sharing attributes. 12735 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12736 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12737 DVar.RefExpr) { 12738 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12739 << getOpenMPClauseName(OMPC_shared); 12740 reportOriginalDsa(*this, DSAStack, D, DVar); 12741 continue; 12742 } 12743 12744 DeclRefExpr *Ref = nullptr; 12745 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12746 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12747 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12748 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12749 ? RefExpr->IgnoreParens() 12750 : Ref); 12751 } 12752 12753 if (Vars.empty()) 12754 return nullptr; 12755 12756 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12757 } 12758 12759 namespace { 12760 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12761 DSAStackTy *Stack; 12762 12763 public: 12764 bool VisitDeclRefExpr(DeclRefExpr *E) { 12765 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12766 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12767 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12768 return false; 12769 if (DVar.CKind != OMPC_unknown) 12770 return true; 12771 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12772 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12773 /*FromParent=*/true); 12774 return DVarPrivate.CKind != OMPC_unknown; 12775 } 12776 return false; 12777 } 12778 bool VisitStmt(Stmt *S) { 12779 for (Stmt *Child : S->children()) { 12780 if (Child && Visit(Child)) 12781 return true; 12782 } 12783 return false; 12784 } 12785 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12786 }; 12787 } // namespace 12788 12789 namespace { 12790 // Transform MemberExpression for specified FieldDecl of current class to 12791 // DeclRefExpr to specified OMPCapturedExprDecl. 12792 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12793 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12794 ValueDecl *Field = nullptr; 12795 DeclRefExpr *CapturedExpr = nullptr; 12796 12797 public: 12798 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12799 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12800 12801 ExprResult TransformMemberExpr(MemberExpr *E) { 12802 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12803 E->getMemberDecl() == Field) { 12804 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12805 return CapturedExpr; 12806 } 12807 return BaseTransform::TransformMemberExpr(E); 12808 } 12809 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12810 }; 12811 } // namespace 12812 12813 template <typename T, typename U> 12814 static T filterLookupForUDReductionAndMapper( 12815 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12816 for (U &Set : Lookups) { 12817 for (auto *D : Set) { 12818 if (T Res = Gen(cast<ValueDecl>(D))) 12819 return Res; 12820 } 12821 } 12822 return T(); 12823 } 12824 12825 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12826 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12827 12828 for (auto RD : D->redecls()) { 12829 // Don't bother with extra checks if we already know this one isn't visible. 12830 if (RD == D) 12831 continue; 12832 12833 auto ND = cast<NamedDecl>(RD); 12834 if (LookupResult::isVisible(SemaRef, ND)) 12835 return ND; 12836 } 12837 12838 return nullptr; 12839 } 12840 12841 static void 12842 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12843 SourceLocation Loc, QualType Ty, 12844 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12845 // Find all of the associated namespaces and classes based on the 12846 // arguments we have. 12847 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12848 Sema::AssociatedClassSet AssociatedClasses; 12849 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12850 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12851 AssociatedClasses); 12852 12853 // C++ [basic.lookup.argdep]p3: 12854 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12855 // and let Y be the lookup set produced by argument dependent 12856 // lookup (defined as follows). If X contains [...] then Y is 12857 // empty. Otherwise Y is the set of declarations found in the 12858 // namespaces associated with the argument types as described 12859 // below. The set of declarations found by the lookup of the name 12860 // is the union of X and Y. 12861 // 12862 // Here, we compute Y and add its members to the overloaded 12863 // candidate set. 12864 for (auto *NS : AssociatedNamespaces) { 12865 // When considering an associated namespace, the lookup is the 12866 // same as the lookup performed when the associated namespace is 12867 // used as a qualifier (3.4.3.2) except that: 12868 // 12869 // -- Any using-directives in the associated namespace are 12870 // ignored. 12871 // 12872 // -- Any namespace-scope friend functions declared in 12873 // associated classes are visible within their respective 12874 // namespaces even if they are not visible during an ordinary 12875 // lookup (11.4). 12876 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12877 for (auto *D : R) { 12878 auto *Underlying = D; 12879 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12880 Underlying = USD->getTargetDecl(); 12881 12882 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12883 !isa<OMPDeclareMapperDecl>(Underlying)) 12884 continue; 12885 12886 if (!SemaRef.isVisible(D)) { 12887 D = findAcceptableDecl(SemaRef, D); 12888 if (!D) 12889 continue; 12890 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12891 Underlying = USD->getTargetDecl(); 12892 } 12893 Lookups.emplace_back(); 12894 Lookups.back().addDecl(Underlying); 12895 } 12896 } 12897 } 12898 12899 static ExprResult 12900 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12901 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12902 const DeclarationNameInfo &ReductionId, QualType Ty, 12903 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12904 if (ReductionIdScopeSpec.isInvalid()) 12905 return ExprError(); 12906 SmallVector<UnresolvedSet<8>, 4> Lookups; 12907 if (S) { 12908 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12909 Lookup.suppressDiagnostics(); 12910 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12911 NamedDecl *D = Lookup.getRepresentativeDecl(); 12912 do { 12913 S = S->getParent(); 12914 } while (S && !S->isDeclScope(D)); 12915 if (S) 12916 S = S->getParent(); 12917 Lookups.emplace_back(); 12918 Lookups.back().append(Lookup.begin(), Lookup.end()); 12919 Lookup.clear(); 12920 } 12921 } else if (auto *ULE = 12922 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12923 Lookups.push_back(UnresolvedSet<8>()); 12924 Decl *PrevD = nullptr; 12925 for (NamedDecl *D : ULE->decls()) { 12926 if (D == PrevD) 12927 Lookups.push_back(UnresolvedSet<8>()); 12928 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12929 Lookups.back().addDecl(DRD); 12930 PrevD = D; 12931 } 12932 } 12933 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12934 Ty->isInstantiationDependentType() || 12935 Ty->containsUnexpandedParameterPack() || 12936 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12937 return !D->isInvalidDecl() && 12938 (D->getType()->isDependentType() || 12939 D->getType()->isInstantiationDependentType() || 12940 D->getType()->containsUnexpandedParameterPack()); 12941 })) { 12942 UnresolvedSet<8> ResSet; 12943 for (const UnresolvedSet<8> &Set : Lookups) { 12944 if (Set.empty()) 12945 continue; 12946 ResSet.append(Set.begin(), Set.end()); 12947 // The last item marks the end of all declarations at the specified scope. 12948 ResSet.addDecl(Set[Set.size() - 1]); 12949 } 12950 return UnresolvedLookupExpr::Create( 12951 SemaRef.Context, /*NamingClass=*/nullptr, 12952 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12953 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12954 } 12955 // Lookup inside the classes. 12956 // C++ [over.match.oper]p3: 12957 // For a unary operator @ with an operand of a type whose 12958 // cv-unqualified version is T1, and for a binary operator @ with 12959 // a left operand of a type whose cv-unqualified version is T1 and 12960 // a right operand of a type whose cv-unqualified version is T2, 12961 // three sets of candidate functions, designated member 12962 // candidates, non-member candidates and built-in candidates, are 12963 // constructed as follows: 12964 // -- If T1 is a complete class type or a class currently being 12965 // defined, the set of member candidates is the result of the 12966 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12967 // the set of member candidates is empty. 12968 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12969 Lookup.suppressDiagnostics(); 12970 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12971 // Complete the type if it can be completed. 12972 // If the type is neither complete nor being defined, bail out now. 12973 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12974 TyRec->getDecl()->getDefinition()) { 12975 Lookup.clear(); 12976 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12977 if (Lookup.empty()) { 12978 Lookups.emplace_back(); 12979 Lookups.back().append(Lookup.begin(), Lookup.end()); 12980 } 12981 } 12982 } 12983 // Perform ADL. 12984 if (SemaRef.getLangOpts().CPlusPlus) 12985 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12986 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12987 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12988 if (!D->isInvalidDecl() && 12989 SemaRef.Context.hasSameType(D->getType(), Ty)) 12990 return D; 12991 return nullptr; 12992 })) 12993 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12994 VK_LValue, Loc); 12995 if (SemaRef.getLangOpts().CPlusPlus) { 12996 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12997 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12998 if (!D->isInvalidDecl() && 12999 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13000 !Ty.isMoreQualifiedThan(D->getType())) 13001 return D; 13002 return nullptr; 13003 })) { 13004 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13005 /*DetectVirtual=*/false); 13006 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13007 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13008 VD->getType().getUnqualifiedType()))) { 13009 if (SemaRef.CheckBaseClassAccess( 13010 Loc, VD->getType(), Ty, Paths.front(), 13011 /*DiagID=*/0) != Sema::AR_inaccessible) { 13012 SemaRef.BuildBasePathArray(Paths, BasePath); 13013 return SemaRef.BuildDeclRefExpr( 13014 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13015 } 13016 } 13017 } 13018 } 13019 } 13020 if (ReductionIdScopeSpec.isSet()) { 13021 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 13022 return ExprError(); 13023 } 13024 return ExprEmpty(); 13025 } 13026 13027 namespace { 13028 /// Data for the reduction-based clauses. 13029 struct ReductionData { 13030 /// List of original reduction items. 13031 SmallVector<Expr *, 8> Vars; 13032 /// List of private copies of the reduction items. 13033 SmallVector<Expr *, 8> Privates; 13034 /// LHS expressions for the reduction_op expressions. 13035 SmallVector<Expr *, 8> LHSs; 13036 /// RHS expressions for the reduction_op expressions. 13037 SmallVector<Expr *, 8> RHSs; 13038 /// Reduction operation expression. 13039 SmallVector<Expr *, 8> ReductionOps; 13040 /// Taskgroup descriptors for the corresponding reduction items in 13041 /// in_reduction clauses. 13042 SmallVector<Expr *, 8> TaskgroupDescriptors; 13043 /// List of captures for clause. 13044 SmallVector<Decl *, 4> ExprCaptures; 13045 /// List of postupdate expressions. 13046 SmallVector<Expr *, 4> ExprPostUpdates; 13047 ReductionData() = delete; 13048 /// Reserves required memory for the reduction data. 13049 ReductionData(unsigned Size) { 13050 Vars.reserve(Size); 13051 Privates.reserve(Size); 13052 LHSs.reserve(Size); 13053 RHSs.reserve(Size); 13054 ReductionOps.reserve(Size); 13055 TaskgroupDescriptors.reserve(Size); 13056 ExprCaptures.reserve(Size); 13057 ExprPostUpdates.reserve(Size); 13058 } 13059 /// Stores reduction item and reduction operation only (required for dependent 13060 /// reduction item). 13061 void push(Expr *Item, Expr *ReductionOp) { 13062 Vars.emplace_back(Item); 13063 Privates.emplace_back(nullptr); 13064 LHSs.emplace_back(nullptr); 13065 RHSs.emplace_back(nullptr); 13066 ReductionOps.emplace_back(ReductionOp); 13067 TaskgroupDescriptors.emplace_back(nullptr); 13068 } 13069 /// Stores reduction data. 13070 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13071 Expr *TaskgroupDescriptor) { 13072 Vars.emplace_back(Item); 13073 Privates.emplace_back(Private); 13074 LHSs.emplace_back(LHS); 13075 RHSs.emplace_back(RHS); 13076 ReductionOps.emplace_back(ReductionOp); 13077 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13078 } 13079 }; 13080 } // namespace 13081 13082 static bool checkOMPArraySectionConstantForReduction( 13083 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13084 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13085 const Expr *Length = OASE->getLength(); 13086 if (Length == nullptr) { 13087 // For array sections of the form [1:] or [:], we would need to analyze 13088 // the lower bound... 13089 if (OASE->getColonLoc().isValid()) 13090 return false; 13091 13092 // This is an array subscript which has implicit length 1! 13093 SingleElement = true; 13094 ArraySizes.push_back(llvm::APSInt::get(1)); 13095 } else { 13096 Expr::EvalResult Result; 13097 if (!Length->EvaluateAsInt(Result, Context)) 13098 return false; 13099 13100 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13101 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13102 ArraySizes.push_back(ConstantLengthValue); 13103 } 13104 13105 // Get the base of this array section and walk up from there. 13106 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13107 13108 // We require length = 1 for all array sections except the right-most to 13109 // guarantee that the memory region is contiguous and has no holes in it. 13110 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13111 Length = TempOASE->getLength(); 13112 if (Length == nullptr) { 13113 // For array sections of the form [1:] or [:], we would need to analyze 13114 // the lower bound... 13115 if (OASE->getColonLoc().isValid()) 13116 return false; 13117 13118 // This is an array subscript which has implicit length 1! 13119 ArraySizes.push_back(llvm::APSInt::get(1)); 13120 } else { 13121 Expr::EvalResult Result; 13122 if (!Length->EvaluateAsInt(Result, Context)) 13123 return false; 13124 13125 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13126 if (ConstantLengthValue.getSExtValue() != 1) 13127 return false; 13128 13129 ArraySizes.push_back(ConstantLengthValue); 13130 } 13131 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13132 } 13133 13134 // If we have a single element, we don't need to add the implicit lengths. 13135 if (!SingleElement) { 13136 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13137 // Has implicit length 1! 13138 ArraySizes.push_back(llvm::APSInt::get(1)); 13139 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13140 } 13141 } 13142 13143 // This array section can be privatized as a single value or as a constant 13144 // sized array. 13145 return true; 13146 } 13147 13148 static bool actOnOMPReductionKindClause( 13149 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13150 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13151 SourceLocation ColonLoc, SourceLocation EndLoc, 13152 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13153 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13154 DeclarationName DN = ReductionId.getName(); 13155 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13156 BinaryOperatorKind BOK = BO_Comma; 13157 13158 ASTContext &Context = S.Context; 13159 // OpenMP [2.14.3.6, reduction clause] 13160 // C 13161 // reduction-identifier is either an identifier or one of the following 13162 // operators: +, -, *, &, |, ^, && and || 13163 // C++ 13164 // reduction-identifier is either an id-expression or one of the following 13165 // operators: +, -, *, &, |, ^, && and || 13166 switch (OOK) { 13167 case OO_Plus: 13168 case OO_Minus: 13169 BOK = BO_Add; 13170 break; 13171 case OO_Star: 13172 BOK = BO_Mul; 13173 break; 13174 case OO_Amp: 13175 BOK = BO_And; 13176 break; 13177 case OO_Pipe: 13178 BOK = BO_Or; 13179 break; 13180 case OO_Caret: 13181 BOK = BO_Xor; 13182 break; 13183 case OO_AmpAmp: 13184 BOK = BO_LAnd; 13185 break; 13186 case OO_PipePipe: 13187 BOK = BO_LOr; 13188 break; 13189 case OO_New: 13190 case OO_Delete: 13191 case OO_Array_New: 13192 case OO_Array_Delete: 13193 case OO_Slash: 13194 case OO_Percent: 13195 case OO_Tilde: 13196 case OO_Exclaim: 13197 case OO_Equal: 13198 case OO_Less: 13199 case OO_Greater: 13200 case OO_LessEqual: 13201 case OO_GreaterEqual: 13202 case OO_PlusEqual: 13203 case OO_MinusEqual: 13204 case OO_StarEqual: 13205 case OO_SlashEqual: 13206 case OO_PercentEqual: 13207 case OO_CaretEqual: 13208 case OO_AmpEqual: 13209 case OO_PipeEqual: 13210 case OO_LessLess: 13211 case OO_GreaterGreater: 13212 case OO_LessLessEqual: 13213 case OO_GreaterGreaterEqual: 13214 case OO_EqualEqual: 13215 case OO_ExclaimEqual: 13216 case OO_Spaceship: 13217 case OO_PlusPlus: 13218 case OO_MinusMinus: 13219 case OO_Comma: 13220 case OO_ArrowStar: 13221 case OO_Arrow: 13222 case OO_Call: 13223 case OO_Subscript: 13224 case OO_Conditional: 13225 case OO_Coawait: 13226 case NUM_OVERLOADED_OPERATORS: 13227 llvm_unreachable("Unexpected reduction identifier"); 13228 case OO_None: 13229 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13230 if (II->isStr("max")) 13231 BOK = BO_GT; 13232 else if (II->isStr("min")) 13233 BOK = BO_LT; 13234 } 13235 break; 13236 } 13237 SourceRange ReductionIdRange; 13238 if (ReductionIdScopeSpec.isValid()) 13239 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13240 else 13241 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13242 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13243 13244 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13245 bool FirstIter = true; 13246 for (Expr *RefExpr : VarList) { 13247 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13248 // OpenMP [2.1, C/C++] 13249 // A list item is a variable or array section, subject to the restrictions 13250 // specified in Section 2.4 on page 42 and in each of the sections 13251 // describing clauses and directives for which a list appears. 13252 // OpenMP [2.14.3.3, Restrictions, p.1] 13253 // A variable that is part of another variable (as an array or 13254 // structure element) cannot appear in a private clause. 13255 if (!FirstIter && IR != ER) 13256 ++IR; 13257 FirstIter = false; 13258 SourceLocation ELoc; 13259 SourceRange ERange; 13260 Expr *SimpleRefExpr = RefExpr; 13261 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13262 /*AllowArraySection=*/true); 13263 if (Res.second) { 13264 // Try to find 'declare reduction' corresponding construct before using 13265 // builtin/overloaded operators. 13266 QualType Type = Context.DependentTy; 13267 CXXCastPath BasePath; 13268 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13269 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13270 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13271 Expr *ReductionOp = nullptr; 13272 if (S.CurContext->isDependentContext() && 13273 (DeclareReductionRef.isUnset() || 13274 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13275 ReductionOp = DeclareReductionRef.get(); 13276 // It will be analyzed later. 13277 RD.push(RefExpr, ReductionOp); 13278 } 13279 ValueDecl *D = Res.first; 13280 if (!D) 13281 continue; 13282 13283 Expr *TaskgroupDescriptor = nullptr; 13284 QualType Type; 13285 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13286 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13287 if (ASE) { 13288 Type = ASE->getType().getNonReferenceType(); 13289 } else if (OASE) { 13290 QualType BaseType = 13291 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13292 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13293 Type = ATy->getElementType(); 13294 else 13295 Type = BaseType->getPointeeType(); 13296 Type = Type.getNonReferenceType(); 13297 } else { 13298 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13299 } 13300 auto *VD = dyn_cast<VarDecl>(D); 13301 13302 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13303 // A variable that appears in a private clause must not have an incomplete 13304 // type or a reference type. 13305 if (S.RequireCompleteType(ELoc, D->getType(), 13306 diag::err_omp_reduction_incomplete_type)) 13307 continue; 13308 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13309 // A list item that appears in a reduction clause must not be 13310 // const-qualified. 13311 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13312 /*AcceptIfMutable*/ false, ASE || OASE)) 13313 continue; 13314 13315 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13316 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13317 // If a list-item is a reference type then it must bind to the same object 13318 // for all threads of the team. 13319 if (!ASE && !OASE) { 13320 if (VD) { 13321 VarDecl *VDDef = VD->getDefinition(); 13322 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13323 DSARefChecker Check(Stack); 13324 if (Check.Visit(VDDef->getInit())) { 13325 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13326 << getOpenMPClauseName(ClauseKind) << ERange; 13327 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13328 continue; 13329 } 13330 } 13331 } 13332 13333 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13334 // in a Construct] 13335 // Variables with the predetermined data-sharing attributes may not be 13336 // listed in data-sharing attributes clauses, except for the cases 13337 // listed below. For these exceptions only, listing a predetermined 13338 // variable in a data-sharing attribute clause is allowed and overrides 13339 // the variable's predetermined data-sharing attributes. 13340 // OpenMP [2.14.3.6, Restrictions, p.3] 13341 // Any number of reduction clauses can be specified on the directive, 13342 // but a list item can appear only once in the reduction clauses for that 13343 // directive. 13344 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13345 if (DVar.CKind == OMPC_reduction) { 13346 S.Diag(ELoc, diag::err_omp_once_referenced) 13347 << getOpenMPClauseName(ClauseKind); 13348 if (DVar.RefExpr) 13349 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13350 continue; 13351 } 13352 if (DVar.CKind != OMPC_unknown) { 13353 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13354 << getOpenMPClauseName(DVar.CKind) 13355 << getOpenMPClauseName(OMPC_reduction); 13356 reportOriginalDsa(S, Stack, D, DVar); 13357 continue; 13358 } 13359 13360 // OpenMP [2.14.3.6, Restrictions, p.1] 13361 // A list item that appears in a reduction clause of a worksharing 13362 // construct must be shared in the parallel regions to which any of the 13363 // worksharing regions arising from the worksharing construct bind. 13364 if (isOpenMPWorksharingDirective(CurrDir) && 13365 !isOpenMPParallelDirective(CurrDir) && 13366 !isOpenMPTeamsDirective(CurrDir)) { 13367 DVar = Stack->getImplicitDSA(D, true); 13368 if (DVar.CKind != OMPC_shared) { 13369 S.Diag(ELoc, diag::err_omp_required_access) 13370 << getOpenMPClauseName(OMPC_reduction) 13371 << getOpenMPClauseName(OMPC_shared); 13372 reportOriginalDsa(S, Stack, D, DVar); 13373 continue; 13374 } 13375 } 13376 } 13377 13378 // Try to find 'declare reduction' corresponding construct before using 13379 // builtin/overloaded operators. 13380 CXXCastPath BasePath; 13381 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13382 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13383 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13384 if (DeclareReductionRef.isInvalid()) 13385 continue; 13386 if (S.CurContext->isDependentContext() && 13387 (DeclareReductionRef.isUnset() || 13388 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13389 RD.push(RefExpr, DeclareReductionRef.get()); 13390 continue; 13391 } 13392 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13393 // Not allowed reduction identifier is found. 13394 S.Diag(ReductionId.getBeginLoc(), 13395 diag::err_omp_unknown_reduction_identifier) 13396 << Type << ReductionIdRange; 13397 continue; 13398 } 13399 13400 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13401 // The type of a list item that appears in a reduction clause must be valid 13402 // for the reduction-identifier. For a max or min reduction in C, the type 13403 // of the list item must be an allowed arithmetic data type: char, int, 13404 // float, double, or _Bool, possibly modified with long, short, signed, or 13405 // unsigned. For a max or min reduction in C++, the type of the list item 13406 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13407 // double, or bool, possibly modified with long, short, signed, or unsigned. 13408 if (DeclareReductionRef.isUnset()) { 13409 if ((BOK == BO_GT || BOK == BO_LT) && 13410 !(Type->isScalarType() || 13411 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13412 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13413 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13414 if (!ASE && !OASE) { 13415 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13416 VarDecl::DeclarationOnly; 13417 S.Diag(D->getLocation(), 13418 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13419 << D; 13420 } 13421 continue; 13422 } 13423 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13424 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13425 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13426 << getOpenMPClauseName(ClauseKind); 13427 if (!ASE && !OASE) { 13428 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13429 VarDecl::DeclarationOnly; 13430 S.Diag(D->getLocation(), 13431 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13432 << D; 13433 } 13434 continue; 13435 } 13436 } 13437 13438 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13439 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13440 D->hasAttrs() ? &D->getAttrs() : nullptr); 13441 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13442 D->hasAttrs() ? &D->getAttrs() : nullptr); 13443 QualType PrivateTy = Type; 13444 13445 // Try if we can determine constant lengths for all array sections and avoid 13446 // the VLA. 13447 bool ConstantLengthOASE = false; 13448 if (OASE) { 13449 bool SingleElement; 13450 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13451 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13452 Context, OASE, SingleElement, ArraySizes); 13453 13454 // If we don't have a single element, we must emit a constant array type. 13455 if (ConstantLengthOASE && !SingleElement) { 13456 for (llvm::APSInt &Size : ArraySizes) 13457 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13458 ArrayType::Normal, 13459 /*IndexTypeQuals=*/0); 13460 } 13461 } 13462 13463 if ((OASE && !ConstantLengthOASE) || 13464 (!OASE && !ASE && 13465 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13466 if (!Context.getTargetInfo().isVLASupported()) { 13467 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13468 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13469 S.Diag(ELoc, diag::note_vla_unsupported); 13470 } else { 13471 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13472 S.targetDiag(ELoc, diag::note_vla_unsupported); 13473 } 13474 continue; 13475 } 13476 // For arrays/array sections only: 13477 // Create pseudo array type for private copy. The size for this array will 13478 // be generated during codegen. 13479 // For array subscripts or single variables Private Ty is the same as Type 13480 // (type of the variable or single array element). 13481 PrivateTy = Context.getVariableArrayType( 13482 Type, 13483 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13484 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13485 } else if (!ASE && !OASE && 13486 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13487 PrivateTy = D->getType().getNonReferenceType(); 13488 } 13489 // Private copy. 13490 VarDecl *PrivateVD = 13491 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13492 D->hasAttrs() ? &D->getAttrs() : nullptr, 13493 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13494 // Add initializer for private variable. 13495 Expr *Init = nullptr; 13496 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13497 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13498 if (DeclareReductionRef.isUsable()) { 13499 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13500 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13501 if (DRD->getInitializer()) { 13502 Init = DRDRef; 13503 RHSVD->setInit(DRDRef); 13504 RHSVD->setInitStyle(VarDecl::CallInit); 13505 } 13506 } else { 13507 switch (BOK) { 13508 case BO_Add: 13509 case BO_Xor: 13510 case BO_Or: 13511 case BO_LOr: 13512 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13513 if (Type->isScalarType() || Type->isAnyComplexType()) 13514 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13515 break; 13516 case BO_Mul: 13517 case BO_LAnd: 13518 if (Type->isScalarType() || Type->isAnyComplexType()) { 13519 // '*' and '&&' reduction ops - initializer is '1'. 13520 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13521 } 13522 break; 13523 case BO_And: { 13524 // '&' reduction op - initializer is '~0'. 13525 QualType OrigType = Type; 13526 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13527 Type = ComplexTy->getElementType(); 13528 if (Type->isRealFloatingType()) { 13529 llvm::APFloat InitValue = 13530 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13531 /*isIEEE=*/true); 13532 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13533 Type, ELoc); 13534 } else if (Type->isScalarType()) { 13535 uint64_t Size = Context.getTypeSize(Type); 13536 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13537 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13538 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13539 } 13540 if (Init && OrigType->isAnyComplexType()) { 13541 // Init = 0xFFFF + 0xFFFFi; 13542 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13543 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13544 } 13545 Type = OrigType; 13546 break; 13547 } 13548 case BO_LT: 13549 case BO_GT: { 13550 // 'min' reduction op - initializer is 'Largest representable number in 13551 // the reduction list item type'. 13552 // 'max' reduction op - initializer is 'Least representable number in 13553 // the reduction list item type'. 13554 if (Type->isIntegerType() || Type->isPointerType()) { 13555 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13556 uint64_t Size = Context.getTypeSize(Type); 13557 QualType IntTy = 13558 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13559 llvm::APInt InitValue = 13560 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13561 : llvm::APInt::getMinValue(Size) 13562 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13563 : llvm::APInt::getMaxValue(Size); 13564 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13565 if (Type->isPointerType()) { 13566 // Cast to pointer type. 13567 ExprResult CastExpr = S.BuildCStyleCastExpr( 13568 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13569 if (CastExpr.isInvalid()) 13570 continue; 13571 Init = CastExpr.get(); 13572 } 13573 } else if (Type->isRealFloatingType()) { 13574 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13575 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13576 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13577 Type, ELoc); 13578 } 13579 break; 13580 } 13581 case BO_PtrMemD: 13582 case BO_PtrMemI: 13583 case BO_MulAssign: 13584 case BO_Div: 13585 case BO_Rem: 13586 case BO_Sub: 13587 case BO_Shl: 13588 case BO_Shr: 13589 case BO_LE: 13590 case BO_GE: 13591 case BO_EQ: 13592 case BO_NE: 13593 case BO_Cmp: 13594 case BO_AndAssign: 13595 case BO_XorAssign: 13596 case BO_OrAssign: 13597 case BO_Assign: 13598 case BO_AddAssign: 13599 case BO_SubAssign: 13600 case BO_DivAssign: 13601 case BO_RemAssign: 13602 case BO_ShlAssign: 13603 case BO_ShrAssign: 13604 case BO_Comma: 13605 llvm_unreachable("Unexpected reduction operation"); 13606 } 13607 } 13608 if (Init && DeclareReductionRef.isUnset()) 13609 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13610 else if (!Init) 13611 S.ActOnUninitializedDecl(RHSVD); 13612 if (RHSVD->isInvalidDecl()) 13613 continue; 13614 if (!RHSVD->hasInit() && 13615 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13616 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13617 << Type << ReductionIdRange; 13618 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13619 VarDecl::DeclarationOnly; 13620 S.Diag(D->getLocation(), 13621 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13622 << D; 13623 continue; 13624 } 13625 // Store initializer for single element in private copy. Will be used during 13626 // codegen. 13627 PrivateVD->setInit(RHSVD->getInit()); 13628 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13629 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13630 ExprResult ReductionOp; 13631 if (DeclareReductionRef.isUsable()) { 13632 QualType RedTy = DeclareReductionRef.get()->getType(); 13633 QualType PtrRedTy = Context.getPointerType(RedTy); 13634 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13635 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13636 if (!BasePath.empty()) { 13637 LHS = S.DefaultLvalueConversion(LHS.get()); 13638 RHS = S.DefaultLvalueConversion(RHS.get()); 13639 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13640 CK_UncheckedDerivedToBase, LHS.get(), 13641 &BasePath, LHS.get()->getValueKind()); 13642 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13643 CK_UncheckedDerivedToBase, RHS.get(), 13644 &BasePath, RHS.get()->getValueKind()); 13645 } 13646 FunctionProtoType::ExtProtoInfo EPI; 13647 QualType Params[] = {PtrRedTy, PtrRedTy}; 13648 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13649 auto *OVE = new (Context) OpaqueValueExpr( 13650 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13651 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13652 Expr *Args[] = {LHS.get(), RHS.get()}; 13653 ReductionOp = 13654 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13655 } else { 13656 ReductionOp = S.BuildBinOp( 13657 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13658 if (ReductionOp.isUsable()) { 13659 if (BOK != BO_LT && BOK != BO_GT) { 13660 ReductionOp = 13661 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13662 BO_Assign, LHSDRE, ReductionOp.get()); 13663 } else { 13664 auto *ConditionalOp = new (Context) 13665 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13666 Type, VK_LValue, OK_Ordinary); 13667 ReductionOp = 13668 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13669 BO_Assign, LHSDRE, ConditionalOp); 13670 } 13671 if (ReductionOp.isUsable()) 13672 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13673 /*DiscardedValue*/ false); 13674 } 13675 if (!ReductionOp.isUsable()) 13676 continue; 13677 } 13678 13679 // OpenMP [2.15.4.6, Restrictions, p.2] 13680 // A list item that appears in an in_reduction clause of a task construct 13681 // must appear in a task_reduction clause of a construct associated with a 13682 // taskgroup region that includes the participating task in its taskgroup 13683 // set. The construct associated with the innermost region that meets this 13684 // condition must specify the same reduction-identifier as the in_reduction 13685 // clause. 13686 if (ClauseKind == OMPC_in_reduction) { 13687 SourceRange ParentSR; 13688 BinaryOperatorKind ParentBOK; 13689 const Expr *ParentReductionOp; 13690 Expr *ParentBOKTD, *ParentReductionOpTD; 13691 DSAStackTy::DSAVarData ParentBOKDSA = 13692 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13693 ParentBOKTD); 13694 DSAStackTy::DSAVarData ParentReductionOpDSA = 13695 Stack->getTopMostTaskgroupReductionData( 13696 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13697 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13698 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13699 if (!IsParentBOK && !IsParentReductionOp) { 13700 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13701 continue; 13702 } 13703 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13704 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13705 IsParentReductionOp) { 13706 bool EmitError = true; 13707 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13708 llvm::FoldingSetNodeID RedId, ParentRedId; 13709 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13710 DeclareReductionRef.get()->Profile(RedId, Context, 13711 /*Canonical=*/true); 13712 EmitError = RedId != ParentRedId; 13713 } 13714 if (EmitError) { 13715 S.Diag(ReductionId.getBeginLoc(), 13716 diag::err_omp_reduction_identifier_mismatch) 13717 << ReductionIdRange << RefExpr->getSourceRange(); 13718 S.Diag(ParentSR.getBegin(), 13719 diag::note_omp_previous_reduction_identifier) 13720 << ParentSR 13721 << (IsParentBOK ? ParentBOKDSA.RefExpr 13722 : ParentReductionOpDSA.RefExpr) 13723 ->getSourceRange(); 13724 continue; 13725 } 13726 } 13727 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13728 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13729 } 13730 13731 DeclRefExpr *Ref = nullptr; 13732 Expr *VarsExpr = RefExpr->IgnoreParens(); 13733 if (!VD && !S.CurContext->isDependentContext()) { 13734 if (ASE || OASE) { 13735 TransformExprToCaptures RebuildToCapture(S, D); 13736 VarsExpr = 13737 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13738 Ref = RebuildToCapture.getCapturedExpr(); 13739 } else { 13740 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13741 } 13742 if (!S.isOpenMPCapturedDecl(D)) { 13743 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13744 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13745 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13746 if (!RefRes.isUsable()) 13747 continue; 13748 ExprResult PostUpdateRes = 13749 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13750 RefRes.get()); 13751 if (!PostUpdateRes.isUsable()) 13752 continue; 13753 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13754 Stack->getCurrentDirective() == OMPD_taskgroup) { 13755 S.Diag(RefExpr->getExprLoc(), 13756 diag::err_omp_reduction_non_addressable_expression) 13757 << RefExpr->getSourceRange(); 13758 continue; 13759 } 13760 RD.ExprPostUpdates.emplace_back( 13761 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13762 } 13763 } 13764 } 13765 // All reduction items are still marked as reduction (to do not increase 13766 // code base size). 13767 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13768 if (CurrDir == OMPD_taskgroup) { 13769 if (DeclareReductionRef.isUsable()) 13770 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13771 DeclareReductionRef.get()); 13772 else 13773 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13774 } 13775 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13776 TaskgroupDescriptor); 13777 } 13778 return RD.Vars.empty(); 13779 } 13780 13781 OMPClause *Sema::ActOnOpenMPReductionClause( 13782 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13783 SourceLocation ColonLoc, SourceLocation EndLoc, 13784 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13785 ArrayRef<Expr *> UnresolvedReductions) { 13786 ReductionData RD(VarList.size()); 13787 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13788 StartLoc, LParenLoc, ColonLoc, EndLoc, 13789 ReductionIdScopeSpec, ReductionId, 13790 UnresolvedReductions, RD)) 13791 return nullptr; 13792 13793 return OMPReductionClause::Create( 13794 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13795 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13796 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13797 buildPreInits(Context, RD.ExprCaptures), 13798 buildPostUpdate(*this, RD.ExprPostUpdates)); 13799 } 13800 13801 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13802 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13803 SourceLocation ColonLoc, SourceLocation EndLoc, 13804 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13805 ArrayRef<Expr *> UnresolvedReductions) { 13806 ReductionData RD(VarList.size()); 13807 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13808 StartLoc, LParenLoc, ColonLoc, EndLoc, 13809 ReductionIdScopeSpec, ReductionId, 13810 UnresolvedReductions, RD)) 13811 return nullptr; 13812 13813 return OMPTaskReductionClause::Create( 13814 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13815 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13816 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13817 buildPreInits(Context, RD.ExprCaptures), 13818 buildPostUpdate(*this, RD.ExprPostUpdates)); 13819 } 13820 13821 OMPClause *Sema::ActOnOpenMPInReductionClause( 13822 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13823 SourceLocation ColonLoc, SourceLocation EndLoc, 13824 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13825 ArrayRef<Expr *> UnresolvedReductions) { 13826 ReductionData RD(VarList.size()); 13827 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13828 StartLoc, LParenLoc, ColonLoc, EndLoc, 13829 ReductionIdScopeSpec, ReductionId, 13830 UnresolvedReductions, RD)) 13831 return nullptr; 13832 13833 return OMPInReductionClause::Create( 13834 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13835 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13836 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13837 buildPreInits(Context, RD.ExprCaptures), 13838 buildPostUpdate(*this, RD.ExprPostUpdates)); 13839 } 13840 13841 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13842 SourceLocation LinLoc) { 13843 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13844 LinKind == OMPC_LINEAR_unknown) { 13845 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13846 return true; 13847 } 13848 return false; 13849 } 13850 13851 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13852 OpenMPLinearClauseKind LinKind, 13853 QualType Type) { 13854 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13855 // A variable must not have an incomplete type or a reference type. 13856 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13857 return true; 13858 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13859 !Type->isReferenceType()) { 13860 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13861 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13862 return true; 13863 } 13864 Type = Type.getNonReferenceType(); 13865 13866 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13867 // A variable that is privatized must not have a const-qualified type 13868 // unless it is of class type with a mutable member. This restriction does 13869 // not apply to the firstprivate clause. 13870 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13871 return true; 13872 13873 // A list item must be of integral or pointer type. 13874 Type = Type.getUnqualifiedType().getCanonicalType(); 13875 const auto *Ty = Type.getTypePtrOrNull(); 13876 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13877 !Ty->isPointerType())) { 13878 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13879 if (D) { 13880 bool IsDecl = 13881 !VD || 13882 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13883 Diag(D->getLocation(), 13884 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13885 << D; 13886 } 13887 return true; 13888 } 13889 return false; 13890 } 13891 13892 OMPClause *Sema::ActOnOpenMPLinearClause( 13893 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13894 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13895 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13896 SmallVector<Expr *, 8> Vars; 13897 SmallVector<Expr *, 8> Privates; 13898 SmallVector<Expr *, 8> Inits; 13899 SmallVector<Decl *, 4> ExprCaptures; 13900 SmallVector<Expr *, 4> ExprPostUpdates; 13901 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13902 LinKind = OMPC_LINEAR_val; 13903 for (Expr *RefExpr : VarList) { 13904 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13905 SourceLocation ELoc; 13906 SourceRange ERange; 13907 Expr *SimpleRefExpr = RefExpr; 13908 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13909 if (Res.second) { 13910 // It will be analyzed later. 13911 Vars.push_back(RefExpr); 13912 Privates.push_back(nullptr); 13913 Inits.push_back(nullptr); 13914 } 13915 ValueDecl *D = Res.first; 13916 if (!D) 13917 continue; 13918 13919 QualType Type = D->getType(); 13920 auto *VD = dyn_cast<VarDecl>(D); 13921 13922 // OpenMP [2.14.3.7, linear clause] 13923 // A list-item cannot appear in more than one linear clause. 13924 // A list-item that appears in a linear clause cannot appear in any 13925 // other data-sharing attribute clause. 13926 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13927 if (DVar.RefExpr) { 13928 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13929 << getOpenMPClauseName(OMPC_linear); 13930 reportOriginalDsa(*this, DSAStack, D, DVar); 13931 continue; 13932 } 13933 13934 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13935 continue; 13936 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13937 13938 // Build private copy of original var. 13939 VarDecl *Private = 13940 buildVarDecl(*this, ELoc, Type, D->getName(), 13941 D->hasAttrs() ? &D->getAttrs() : nullptr, 13942 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13943 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13944 // Build var to save initial value. 13945 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13946 Expr *InitExpr; 13947 DeclRefExpr *Ref = nullptr; 13948 if (!VD && !CurContext->isDependentContext()) { 13949 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13950 if (!isOpenMPCapturedDecl(D)) { 13951 ExprCaptures.push_back(Ref->getDecl()); 13952 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13953 ExprResult RefRes = DefaultLvalueConversion(Ref); 13954 if (!RefRes.isUsable()) 13955 continue; 13956 ExprResult PostUpdateRes = 13957 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13958 SimpleRefExpr, RefRes.get()); 13959 if (!PostUpdateRes.isUsable()) 13960 continue; 13961 ExprPostUpdates.push_back( 13962 IgnoredValueConversions(PostUpdateRes.get()).get()); 13963 } 13964 } 13965 } 13966 if (LinKind == OMPC_LINEAR_uval) 13967 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13968 else 13969 InitExpr = VD ? SimpleRefExpr : Ref; 13970 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13971 /*DirectInit=*/false); 13972 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13973 13974 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13975 Vars.push_back((VD || CurContext->isDependentContext()) 13976 ? RefExpr->IgnoreParens() 13977 : Ref); 13978 Privates.push_back(PrivateRef); 13979 Inits.push_back(InitRef); 13980 } 13981 13982 if (Vars.empty()) 13983 return nullptr; 13984 13985 Expr *StepExpr = Step; 13986 Expr *CalcStepExpr = nullptr; 13987 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13988 !Step->isInstantiationDependent() && 13989 !Step->containsUnexpandedParameterPack()) { 13990 SourceLocation StepLoc = Step->getBeginLoc(); 13991 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13992 if (Val.isInvalid()) 13993 return nullptr; 13994 StepExpr = Val.get(); 13995 13996 // Build var to save the step value. 13997 VarDecl *SaveVar = 13998 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13999 ExprResult SaveRef = 14000 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14001 ExprResult CalcStep = 14002 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14003 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14004 14005 // Warn about zero linear step (it would be probably better specified as 14006 // making corresponding variables 'const'). 14007 llvm::APSInt Result; 14008 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14009 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14010 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14011 << (Vars.size() > 1); 14012 if (!IsConstant && CalcStep.isUsable()) { 14013 // Calculate the step beforehand instead of doing this on each iteration. 14014 // (This is not used if the number of iterations may be kfold-ed). 14015 CalcStepExpr = CalcStep.get(); 14016 } 14017 } 14018 14019 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14020 ColonLoc, EndLoc, Vars, Privates, Inits, 14021 StepExpr, CalcStepExpr, 14022 buildPreInits(Context, ExprCaptures), 14023 buildPostUpdate(*this, ExprPostUpdates)); 14024 } 14025 14026 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14027 Expr *NumIterations, Sema &SemaRef, 14028 Scope *S, DSAStackTy *Stack) { 14029 // Walk the vars and build update/final expressions for the CodeGen. 14030 SmallVector<Expr *, 8> Updates; 14031 SmallVector<Expr *, 8> Finals; 14032 SmallVector<Expr *, 8> UsedExprs; 14033 Expr *Step = Clause.getStep(); 14034 Expr *CalcStep = Clause.getCalcStep(); 14035 // OpenMP [2.14.3.7, linear clause] 14036 // If linear-step is not specified it is assumed to be 1. 14037 if (!Step) 14038 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14039 else if (CalcStep) 14040 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14041 bool HasErrors = false; 14042 auto CurInit = Clause.inits().begin(); 14043 auto CurPrivate = Clause.privates().begin(); 14044 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14045 for (Expr *RefExpr : Clause.varlists()) { 14046 SourceLocation ELoc; 14047 SourceRange ERange; 14048 Expr *SimpleRefExpr = RefExpr; 14049 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14050 ValueDecl *D = Res.first; 14051 if (Res.second || !D) { 14052 Updates.push_back(nullptr); 14053 Finals.push_back(nullptr); 14054 HasErrors = true; 14055 continue; 14056 } 14057 auto &&Info = Stack->isLoopControlVariable(D); 14058 // OpenMP [2.15.11, distribute simd Construct] 14059 // A list item may not appear in a linear clause, unless it is the loop 14060 // iteration variable. 14061 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14062 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14063 SemaRef.Diag(ELoc, 14064 diag::err_omp_linear_distribute_var_non_loop_iteration); 14065 Updates.push_back(nullptr); 14066 Finals.push_back(nullptr); 14067 HasErrors = true; 14068 continue; 14069 } 14070 Expr *InitExpr = *CurInit; 14071 14072 // Build privatized reference to the current linear var. 14073 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14074 Expr *CapturedRef; 14075 if (LinKind == OMPC_LINEAR_uval) 14076 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14077 else 14078 CapturedRef = 14079 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14080 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14081 /*RefersToCapture=*/true); 14082 14083 // Build update: Var = InitExpr + IV * Step 14084 ExprResult Update; 14085 if (!Info.first) 14086 Update = buildCounterUpdate( 14087 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14088 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14089 else 14090 Update = *CurPrivate; 14091 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14092 /*DiscardedValue*/ false); 14093 14094 // Build final: Var = InitExpr + NumIterations * Step 14095 ExprResult Final; 14096 if (!Info.first) 14097 Final = 14098 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14099 InitExpr, NumIterations, Step, /*Subtract=*/false, 14100 /*IsNonRectangularLB=*/false); 14101 else 14102 Final = *CurPrivate; 14103 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14104 /*DiscardedValue*/ false); 14105 14106 if (!Update.isUsable() || !Final.isUsable()) { 14107 Updates.push_back(nullptr); 14108 Finals.push_back(nullptr); 14109 UsedExprs.push_back(nullptr); 14110 HasErrors = true; 14111 } else { 14112 Updates.push_back(Update.get()); 14113 Finals.push_back(Final.get()); 14114 if (!Info.first) 14115 UsedExprs.push_back(SimpleRefExpr); 14116 } 14117 ++CurInit; 14118 ++CurPrivate; 14119 } 14120 if (Expr *S = Clause.getStep()) 14121 UsedExprs.push_back(S); 14122 // Fill the remaining part with the nullptr. 14123 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14124 Clause.setUpdates(Updates); 14125 Clause.setFinals(Finals); 14126 Clause.setUsedExprs(UsedExprs); 14127 return HasErrors; 14128 } 14129 14130 OMPClause *Sema::ActOnOpenMPAlignedClause( 14131 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14132 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14133 SmallVector<Expr *, 8> Vars; 14134 for (Expr *RefExpr : VarList) { 14135 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14136 SourceLocation ELoc; 14137 SourceRange ERange; 14138 Expr *SimpleRefExpr = RefExpr; 14139 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14140 if (Res.second) { 14141 // It will be analyzed later. 14142 Vars.push_back(RefExpr); 14143 } 14144 ValueDecl *D = Res.first; 14145 if (!D) 14146 continue; 14147 14148 QualType QType = D->getType(); 14149 auto *VD = dyn_cast<VarDecl>(D); 14150 14151 // OpenMP [2.8.1, simd construct, Restrictions] 14152 // The type of list items appearing in the aligned clause must be 14153 // array, pointer, reference to array, or reference to pointer. 14154 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14155 const Type *Ty = QType.getTypePtrOrNull(); 14156 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14157 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14158 << QType << getLangOpts().CPlusPlus << ERange; 14159 bool IsDecl = 14160 !VD || 14161 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14162 Diag(D->getLocation(), 14163 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14164 << D; 14165 continue; 14166 } 14167 14168 // OpenMP [2.8.1, simd construct, Restrictions] 14169 // A list-item cannot appear in more than one aligned clause. 14170 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14171 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 14172 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14173 << getOpenMPClauseName(OMPC_aligned); 14174 continue; 14175 } 14176 14177 DeclRefExpr *Ref = nullptr; 14178 if (!VD && isOpenMPCapturedDecl(D)) 14179 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14180 Vars.push_back(DefaultFunctionArrayConversion( 14181 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14182 .get()); 14183 } 14184 14185 // OpenMP [2.8.1, simd construct, Description] 14186 // The parameter of the aligned clause, alignment, must be a constant 14187 // positive integer expression. 14188 // If no optional parameter is specified, implementation-defined default 14189 // alignments for SIMD instructions on the target platforms are assumed. 14190 if (Alignment != nullptr) { 14191 ExprResult AlignResult = 14192 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14193 if (AlignResult.isInvalid()) 14194 return nullptr; 14195 Alignment = AlignResult.get(); 14196 } 14197 if (Vars.empty()) 14198 return nullptr; 14199 14200 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14201 EndLoc, Vars, Alignment); 14202 } 14203 14204 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14205 SourceLocation StartLoc, 14206 SourceLocation LParenLoc, 14207 SourceLocation EndLoc) { 14208 SmallVector<Expr *, 8> Vars; 14209 SmallVector<Expr *, 8> SrcExprs; 14210 SmallVector<Expr *, 8> DstExprs; 14211 SmallVector<Expr *, 8> AssignmentOps; 14212 for (Expr *RefExpr : VarList) { 14213 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14214 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14215 // It will be analyzed later. 14216 Vars.push_back(RefExpr); 14217 SrcExprs.push_back(nullptr); 14218 DstExprs.push_back(nullptr); 14219 AssignmentOps.push_back(nullptr); 14220 continue; 14221 } 14222 14223 SourceLocation ELoc = RefExpr->getExprLoc(); 14224 // OpenMP [2.1, C/C++] 14225 // A list item is a variable name. 14226 // OpenMP [2.14.4.1, Restrictions, p.1] 14227 // A list item that appears in a copyin clause must be threadprivate. 14228 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14229 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14230 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14231 << 0 << RefExpr->getSourceRange(); 14232 continue; 14233 } 14234 14235 Decl *D = DE->getDecl(); 14236 auto *VD = cast<VarDecl>(D); 14237 14238 QualType Type = VD->getType(); 14239 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14240 // It will be analyzed later. 14241 Vars.push_back(DE); 14242 SrcExprs.push_back(nullptr); 14243 DstExprs.push_back(nullptr); 14244 AssignmentOps.push_back(nullptr); 14245 continue; 14246 } 14247 14248 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14249 // A list item that appears in a copyin clause must be threadprivate. 14250 if (!DSAStack->isThreadPrivate(VD)) { 14251 Diag(ELoc, diag::err_omp_required_access) 14252 << getOpenMPClauseName(OMPC_copyin) 14253 << getOpenMPDirectiveName(OMPD_threadprivate); 14254 continue; 14255 } 14256 14257 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14258 // A variable of class type (or array thereof) that appears in a 14259 // copyin clause requires an accessible, unambiguous copy assignment 14260 // operator for the class type. 14261 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14262 VarDecl *SrcVD = 14263 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14264 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14265 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14266 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14267 VarDecl *DstVD = 14268 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14269 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14270 DeclRefExpr *PseudoDstExpr = 14271 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14272 // For arrays generate assignment operation for single element and replace 14273 // it by the original array element in CodeGen. 14274 ExprResult AssignmentOp = 14275 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14276 PseudoSrcExpr); 14277 if (AssignmentOp.isInvalid()) 14278 continue; 14279 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14280 /*DiscardedValue*/ false); 14281 if (AssignmentOp.isInvalid()) 14282 continue; 14283 14284 DSAStack->addDSA(VD, DE, OMPC_copyin); 14285 Vars.push_back(DE); 14286 SrcExprs.push_back(PseudoSrcExpr); 14287 DstExprs.push_back(PseudoDstExpr); 14288 AssignmentOps.push_back(AssignmentOp.get()); 14289 } 14290 14291 if (Vars.empty()) 14292 return nullptr; 14293 14294 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14295 SrcExprs, DstExprs, AssignmentOps); 14296 } 14297 14298 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14299 SourceLocation StartLoc, 14300 SourceLocation LParenLoc, 14301 SourceLocation EndLoc) { 14302 SmallVector<Expr *, 8> Vars; 14303 SmallVector<Expr *, 8> SrcExprs; 14304 SmallVector<Expr *, 8> DstExprs; 14305 SmallVector<Expr *, 8> AssignmentOps; 14306 for (Expr *RefExpr : VarList) { 14307 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14308 SourceLocation ELoc; 14309 SourceRange ERange; 14310 Expr *SimpleRefExpr = RefExpr; 14311 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14312 if (Res.second) { 14313 // It will be analyzed later. 14314 Vars.push_back(RefExpr); 14315 SrcExprs.push_back(nullptr); 14316 DstExprs.push_back(nullptr); 14317 AssignmentOps.push_back(nullptr); 14318 } 14319 ValueDecl *D = Res.first; 14320 if (!D) 14321 continue; 14322 14323 QualType Type = D->getType(); 14324 auto *VD = dyn_cast<VarDecl>(D); 14325 14326 // OpenMP [2.14.4.2, Restrictions, p.2] 14327 // A list item that appears in a copyprivate clause may not appear in a 14328 // private or firstprivate clause on the single construct. 14329 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14330 DSAStackTy::DSAVarData DVar = 14331 DSAStack->getTopDSA(D, /*FromParent=*/false); 14332 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14333 DVar.RefExpr) { 14334 Diag(ELoc, diag::err_omp_wrong_dsa) 14335 << getOpenMPClauseName(DVar.CKind) 14336 << getOpenMPClauseName(OMPC_copyprivate); 14337 reportOriginalDsa(*this, DSAStack, D, DVar); 14338 continue; 14339 } 14340 14341 // OpenMP [2.11.4.2, Restrictions, p.1] 14342 // All list items that appear in a copyprivate clause must be either 14343 // threadprivate or private in the enclosing context. 14344 if (DVar.CKind == OMPC_unknown) { 14345 DVar = DSAStack->getImplicitDSA(D, false); 14346 if (DVar.CKind == OMPC_shared) { 14347 Diag(ELoc, diag::err_omp_required_access) 14348 << getOpenMPClauseName(OMPC_copyprivate) 14349 << "threadprivate or private in the enclosing context"; 14350 reportOriginalDsa(*this, DSAStack, D, DVar); 14351 continue; 14352 } 14353 } 14354 } 14355 14356 // Variably modified types are not supported. 14357 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14358 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14359 << getOpenMPClauseName(OMPC_copyprivate) << Type 14360 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14361 bool IsDecl = 14362 !VD || 14363 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14364 Diag(D->getLocation(), 14365 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14366 << D; 14367 continue; 14368 } 14369 14370 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14371 // A variable of class type (or array thereof) that appears in a 14372 // copyin clause requires an accessible, unambiguous copy assignment 14373 // operator for the class type. 14374 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14375 .getUnqualifiedType(); 14376 VarDecl *SrcVD = 14377 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14378 D->hasAttrs() ? &D->getAttrs() : nullptr); 14379 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14380 VarDecl *DstVD = 14381 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14382 D->hasAttrs() ? &D->getAttrs() : nullptr); 14383 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14384 ExprResult AssignmentOp = BuildBinOp( 14385 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14386 if (AssignmentOp.isInvalid()) 14387 continue; 14388 AssignmentOp = 14389 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14390 if (AssignmentOp.isInvalid()) 14391 continue; 14392 14393 // No need to mark vars as copyprivate, they are already threadprivate or 14394 // implicitly private. 14395 assert(VD || isOpenMPCapturedDecl(D)); 14396 Vars.push_back( 14397 VD ? RefExpr->IgnoreParens() 14398 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14399 SrcExprs.push_back(PseudoSrcExpr); 14400 DstExprs.push_back(PseudoDstExpr); 14401 AssignmentOps.push_back(AssignmentOp.get()); 14402 } 14403 14404 if (Vars.empty()) 14405 return nullptr; 14406 14407 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14408 Vars, SrcExprs, DstExprs, AssignmentOps); 14409 } 14410 14411 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14412 SourceLocation StartLoc, 14413 SourceLocation LParenLoc, 14414 SourceLocation EndLoc) { 14415 if (VarList.empty()) 14416 return nullptr; 14417 14418 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14419 } 14420 14421 OMPClause * 14422 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14423 SourceLocation DepLoc, SourceLocation ColonLoc, 14424 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14425 SourceLocation LParenLoc, SourceLocation EndLoc) { 14426 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14427 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14428 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14429 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14430 return nullptr; 14431 } 14432 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14433 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14434 DepKind == OMPC_DEPEND_sink)) { 14435 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14436 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14437 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14438 /*Last=*/OMPC_DEPEND_unknown, Except) 14439 << getOpenMPClauseName(OMPC_depend); 14440 return nullptr; 14441 } 14442 SmallVector<Expr *, 8> Vars; 14443 DSAStackTy::OperatorOffsetTy OpsOffs; 14444 llvm::APSInt DepCounter(/*BitWidth=*/32); 14445 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14446 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14447 if (const Expr *OrderedCountExpr = 14448 DSAStack->getParentOrderedRegionParam().first) { 14449 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14450 TotalDepCount.setIsUnsigned(/*Val=*/true); 14451 } 14452 } 14453 for (Expr *RefExpr : VarList) { 14454 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14455 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14456 // It will be analyzed later. 14457 Vars.push_back(RefExpr); 14458 continue; 14459 } 14460 14461 SourceLocation ELoc = RefExpr->getExprLoc(); 14462 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14463 if (DepKind == OMPC_DEPEND_sink) { 14464 if (DSAStack->getParentOrderedRegionParam().first && 14465 DepCounter >= TotalDepCount) { 14466 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14467 continue; 14468 } 14469 ++DepCounter; 14470 // OpenMP [2.13.9, Summary] 14471 // depend(dependence-type : vec), where dependence-type is: 14472 // 'sink' and where vec is the iteration vector, which has the form: 14473 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14474 // where n is the value specified by the ordered clause in the loop 14475 // directive, xi denotes the loop iteration variable of the i-th nested 14476 // loop associated with the loop directive, and di is a constant 14477 // non-negative integer. 14478 if (CurContext->isDependentContext()) { 14479 // It will be analyzed later. 14480 Vars.push_back(RefExpr); 14481 continue; 14482 } 14483 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14484 OverloadedOperatorKind OOK = OO_None; 14485 SourceLocation OOLoc; 14486 Expr *LHS = SimpleExpr; 14487 Expr *RHS = nullptr; 14488 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14489 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14490 OOLoc = BO->getOperatorLoc(); 14491 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14492 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14493 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14494 OOK = OCE->getOperator(); 14495 OOLoc = OCE->getOperatorLoc(); 14496 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14497 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14498 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14499 OOK = MCE->getMethodDecl() 14500 ->getNameInfo() 14501 .getName() 14502 .getCXXOverloadedOperator(); 14503 OOLoc = MCE->getCallee()->getExprLoc(); 14504 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14505 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14506 } 14507 SourceLocation ELoc; 14508 SourceRange ERange; 14509 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14510 if (Res.second) { 14511 // It will be analyzed later. 14512 Vars.push_back(RefExpr); 14513 } 14514 ValueDecl *D = Res.first; 14515 if (!D) 14516 continue; 14517 14518 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14519 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14520 continue; 14521 } 14522 if (RHS) { 14523 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14524 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14525 if (RHSRes.isInvalid()) 14526 continue; 14527 } 14528 if (!CurContext->isDependentContext() && 14529 DSAStack->getParentOrderedRegionParam().first && 14530 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14531 const ValueDecl *VD = 14532 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14533 if (VD) 14534 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14535 << 1 << VD; 14536 else 14537 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14538 continue; 14539 } 14540 OpsOffs.emplace_back(RHS, OOK); 14541 } else { 14542 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14543 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14544 (ASE && 14545 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14546 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14547 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14548 << RefExpr->getSourceRange(); 14549 continue; 14550 } 14551 14552 ExprResult Res; 14553 { 14554 Sema::TentativeAnalysisScope Trap(*this); 14555 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14556 RefExpr->IgnoreParenImpCasts()); 14557 } 14558 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14559 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14560 << RefExpr->getSourceRange(); 14561 continue; 14562 } 14563 } 14564 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14565 } 14566 14567 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14568 TotalDepCount > VarList.size() && 14569 DSAStack->getParentOrderedRegionParam().first && 14570 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14571 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14572 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14573 } 14574 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14575 Vars.empty()) 14576 return nullptr; 14577 14578 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14579 DepKind, DepLoc, ColonLoc, Vars, 14580 TotalDepCount.getZExtValue()); 14581 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14582 DSAStack->isParentOrderedRegion()) 14583 DSAStack->addDoacrossDependClause(C, OpsOffs); 14584 return C; 14585 } 14586 14587 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14588 SourceLocation LParenLoc, 14589 SourceLocation EndLoc) { 14590 Expr *ValExpr = Device; 14591 Stmt *HelperValStmt = nullptr; 14592 14593 // OpenMP [2.9.1, Restrictions] 14594 // The device expression must evaluate to a non-negative integer value. 14595 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14596 /*StrictlyPositive=*/false)) 14597 return nullptr; 14598 14599 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14600 OpenMPDirectiveKind CaptureRegion = 14601 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14602 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14603 ValExpr = MakeFullExpr(ValExpr).get(); 14604 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14605 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14606 HelperValStmt = buildPreInits(Context, Captures); 14607 } 14608 14609 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14610 StartLoc, LParenLoc, EndLoc); 14611 } 14612 14613 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14614 DSAStackTy *Stack, QualType QTy, 14615 bool FullCheck = true) { 14616 NamedDecl *ND; 14617 if (QTy->isIncompleteType(&ND)) { 14618 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14619 return false; 14620 } 14621 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14622 !QTy.isTrivialType(SemaRef.Context)) 14623 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14624 return true; 14625 } 14626 14627 /// Return true if it can be proven that the provided array expression 14628 /// (array section or array subscript) does NOT specify the whole size of the 14629 /// array whose base type is \a BaseQTy. 14630 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14631 const Expr *E, 14632 QualType BaseQTy) { 14633 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14634 14635 // If this is an array subscript, it refers to the whole size if the size of 14636 // the dimension is constant and equals 1. Also, an array section assumes the 14637 // format of an array subscript if no colon is used. 14638 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14639 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14640 return ATy->getSize().getSExtValue() != 1; 14641 // Size can't be evaluated statically. 14642 return false; 14643 } 14644 14645 assert(OASE && "Expecting array section if not an array subscript."); 14646 const Expr *LowerBound = OASE->getLowerBound(); 14647 const Expr *Length = OASE->getLength(); 14648 14649 // If there is a lower bound that does not evaluates to zero, we are not 14650 // covering the whole dimension. 14651 if (LowerBound) { 14652 Expr::EvalResult Result; 14653 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14654 return false; // Can't get the integer value as a constant. 14655 14656 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14657 if (ConstLowerBound.getSExtValue()) 14658 return true; 14659 } 14660 14661 // If we don't have a length we covering the whole dimension. 14662 if (!Length) 14663 return false; 14664 14665 // If the base is a pointer, we don't have a way to get the size of the 14666 // pointee. 14667 if (BaseQTy->isPointerType()) 14668 return false; 14669 14670 // We can only check if the length is the same as the size of the dimension 14671 // if we have a constant array. 14672 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14673 if (!CATy) 14674 return false; 14675 14676 Expr::EvalResult Result; 14677 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14678 return false; // Can't get the integer value as a constant. 14679 14680 llvm::APSInt ConstLength = Result.Val.getInt(); 14681 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14682 } 14683 14684 // Return true if it can be proven that the provided array expression (array 14685 // section or array subscript) does NOT specify a single element of the array 14686 // whose base type is \a BaseQTy. 14687 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14688 const Expr *E, 14689 QualType BaseQTy) { 14690 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14691 14692 // An array subscript always refer to a single element. Also, an array section 14693 // assumes the format of an array subscript if no colon is used. 14694 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14695 return false; 14696 14697 assert(OASE && "Expecting array section if not an array subscript."); 14698 const Expr *Length = OASE->getLength(); 14699 14700 // If we don't have a length we have to check if the array has unitary size 14701 // for this dimension. Also, we should always expect a length if the base type 14702 // is pointer. 14703 if (!Length) { 14704 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14705 return ATy->getSize().getSExtValue() != 1; 14706 // We cannot assume anything. 14707 return false; 14708 } 14709 14710 // Check if the length evaluates to 1. 14711 Expr::EvalResult Result; 14712 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14713 return false; // Can't get the integer value as a constant. 14714 14715 llvm::APSInt ConstLength = Result.Val.getInt(); 14716 return ConstLength.getSExtValue() != 1; 14717 } 14718 14719 // Return the expression of the base of the mappable expression or null if it 14720 // cannot be determined and do all the necessary checks to see if the expression 14721 // is valid as a standalone mappable expression. In the process, record all the 14722 // components of the expression. 14723 static const Expr *checkMapClauseExpressionBase( 14724 Sema &SemaRef, Expr *E, 14725 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14726 OpenMPClauseKind CKind, bool NoDiagnose) { 14727 SourceLocation ELoc = E->getExprLoc(); 14728 SourceRange ERange = E->getSourceRange(); 14729 14730 // The base of elements of list in a map clause have to be either: 14731 // - a reference to variable or field. 14732 // - a member expression. 14733 // - an array expression. 14734 // 14735 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14736 // reference to 'r'. 14737 // 14738 // If we have: 14739 // 14740 // struct SS { 14741 // Bla S; 14742 // foo() { 14743 // #pragma omp target map (S.Arr[:12]); 14744 // } 14745 // } 14746 // 14747 // We want to retrieve the member expression 'this->S'; 14748 14749 const Expr *RelevantExpr = nullptr; 14750 14751 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14752 // If a list item is an array section, it must specify contiguous storage. 14753 // 14754 // For this restriction it is sufficient that we make sure only references 14755 // to variables or fields and array expressions, and that no array sections 14756 // exist except in the rightmost expression (unless they cover the whole 14757 // dimension of the array). E.g. these would be invalid: 14758 // 14759 // r.ArrS[3:5].Arr[6:7] 14760 // 14761 // r.ArrS[3:5].x 14762 // 14763 // but these would be valid: 14764 // r.ArrS[3].Arr[6:7] 14765 // 14766 // r.ArrS[3].x 14767 14768 bool AllowUnitySizeArraySection = true; 14769 bool AllowWholeSizeArraySection = true; 14770 14771 while (!RelevantExpr) { 14772 E = E->IgnoreParenImpCasts(); 14773 14774 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14775 if (!isa<VarDecl>(CurE->getDecl())) 14776 return nullptr; 14777 14778 RelevantExpr = CurE; 14779 14780 // If we got a reference to a declaration, we should not expect any array 14781 // section before that. 14782 AllowUnitySizeArraySection = false; 14783 AllowWholeSizeArraySection = false; 14784 14785 // Record the component. 14786 CurComponents.emplace_back(CurE, CurE->getDecl()); 14787 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14788 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14789 14790 if (isa<CXXThisExpr>(BaseE)) 14791 // We found a base expression: this->Val. 14792 RelevantExpr = CurE; 14793 else 14794 E = BaseE; 14795 14796 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14797 if (!NoDiagnose) { 14798 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14799 << CurE->getSourceRange(); 14800 return nullptr; 14801 } 14802 if (RelevantExpr) 14803 return nullptr; 14804 continue; 14805 } 14806 14807 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14808 14809 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14810 // A bit-field cannot appear in a map clause. 14811 // 14812 if (FD->isBitField()) { 14813 if (!NoDiagnose) { 14814 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14815 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14816 return nullptr; 14817 } 14818 if (RelevantExpr) 14819 return nullptr; 14820 continue; 14821 } 14822 14823 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14824 // If the type of a list item is a reference to a type T then the type 14825 // will be considered to be T for all purposes of this clause. 14826 QualType CurType = BaseE->getType().getNonReferenceType(); 14827 14828 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14829 // A list item cannot be a variable that is a member of a structure with 14830 // a union type. 14831 // 14832 if (CurType->isUnionType()) { 14833 if (!NoDiagnose) { 14834 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14835 << CurE->getSourceRange(); 14836 return nullptr; 14837 } 14838 continue; 14839 } 14840 14841 // If we got a member expression, we should not expect any array section 14842 // before that: 14843 // 14844 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14845 // If a list item is an element of a structure, only the rightmost symbol 14846 // of the variable reference can be an array section. 14847 // 14848 AllowUnitySizeArraySection = false; 14849 AllowWholeSizeArraySection = false; 14850 14851 // Record the component. 14852 CurComponents.emplace_back(CurE, FD); 14853 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14854 E = CurE->getBase()->IgnoreParenImpCasts(); 14855 14856 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14857 if (!NoDiagnose) { 14858 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14859 << 0 << CurE->getSourceRange(); 14860 return nullptr; 14861 } 14862 continue; 14863 } 14864 14865 // If we got an array subscript that express the whole dimension we 14866 // can have any array expressions before. If it only expressing part of 14867 // the dimension, we can only have unitary-size array expressions. 14868 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14869 E->getType())) 14870 AllowWholeSizeArraySection = false; 14871 14872 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14873 Expr::EvalResult Result; 14874 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14875 if (!Result.Val.getInt().isNullValue()) { 14876 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14877 diag::err_omp_invalid_map_this_expr); 14878 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14879 diag::note_omp_invalid_subscript_on_this_ptr_map); 14880 } 14881 } 14882 RelevantExpr = TE; 14883 } 14884 14885 // Record the component - we don't have any declaration associated. 14886 CurComponents.emplace_back(CurE, nullptr); 14887 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14888 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14889 E = CurE->getBase()->IgnoreParenImpCasts(); 14890 14891 QualType CurType = 14892 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14893 14894 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14895 // If the type of a list item is a reference to a type T then the type 14896 // will be considered to be T for all purposes of this clause. 14897 if (CurType->isReferenceType()) 14898 CurType = CurType->getPointeeType(); 14899 14900 bool IsPointer = CurType->isAnyPointerType(); 14901 14902 if (!IsPointer && !CurType->isArrayType()) { 14903 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14904 << 0 << CurE->getSourceRange(); 14905 return nullptr; 14906 } 14907 14908 bool NotWhole = 14909 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14910 bool NotUnity = 14911 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14912 14913 if (AllowWholeSizeArraySection) { 14914 // Any array section is currently allowed. Allowing a whole size array 14915 // section implies allowing a unity array section as well. 14916 // 14917 // If this array section refers to the whole dimension we can still 14918 // accept other array sections before this one, except if the base is a 14919 // pointer. Otherwise, only unitary sections are accepted. 14920 if (NotWhole || IsPointer) 14921 AllowWholeSizeArraySection = false; 14922 } else if (AllowUnitySizeArraySection && NotUnity) { 14923 // A unity or whole array section is not allowed and that is not 14924 // compatible with the properties of the current array section. 14925 SemaRef.Diag( 14926 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14927 << CurE->getSourceRange(); 14928 return nullptr; 14929 } 14930 14931 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14932 Expr::EvalResult ResultR; 14933 Expr::EvalResult ResultL; 14934 if (CurE->getLength()->EvaluateAsInt(ResultR, 14935 SemaRef.getASTContext())) { 14936 if (!ResultR.Val.getInt().isOneValue()) { 14937 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14938 diag::err_omp_invalid_map_this_expr); 14939 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14940 diag::note_omp_invalid_length_on_this_ptr_mapping); 14941 } 14942 } 14943 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14944 ResultL, SemaRef.getASTContext())) { 14945 if (!ResultL.Val.getInt().isNullValue()) { 14946 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14947 diag::err_omp_invalid_map_this_expr); 14948 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14949 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14950 } 14951 } 14952 RelevantExpr = TE; 14953 } 14954 14955 // Record the component - we don't have any declaration associated. 14956 CurComponents.emplace_back(CurE, nullptr); 14957 } else { 14958 if (!NoDiagnose) { 14959 // If nothing else worked, this is not a valid map clause expression. 14960 SemaRef.Diag( 14961 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14962 << ERange; 14963 } 14964 return nullptr; 14965 } 14966 } 14967 14968 return RelevantExpr; 14969 } 14970 14971 // Return true if expression E associated with value VD has conflicts with other 14972 // map information. 14973 static bool checkMapConflicts( 14974 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14975 bool CurrentRegionOnly, 14976 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14977 OpenMPClauseKind CKind) { 14978 assert(VD && E); 14979 SourceLocation ELoc = E->getExprLoc(); 14980 SourceRange ERange = E->getSourceRange(); 14981 14982 // In order to easily check the conflicts we need to match each component of 14983 // the expression under test with the components of the expressions that are 14984 // already in the stack. 14985 14986 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14987 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14988 "Map clause expression with unexpected base!"); 14989 14990 // Variables to help detecting enclosing problems in data environment nests. 14991 bool IsEnclosedByDataEnvironmentExpr = false; 14992 const Expr *EnclosingExpr = nullptr; 14993 14994 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14995 VD, CurrentRegionOnly, 14996 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14997 ERange, CKind, &EnclosingExpr, 14998 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14999 StackComponents, 15000 OpenMPClauseKind) { 15001 assert(!StackComponents.empty() && 15002 "Map clause expression with no components!"); 15003 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15004 "Map clause expression with unexpected base!"); 15005 (void)VD; 15006 15007 // The whole expression in the stack. 15008 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15009 15010 // Expressions must start from the same base. Here we detect at which 15011 // point both expressions diverge from each other and see if we can 15012 // detect if the memory referred to both expressions is contiguous and 15013 // do not overlap. 15014 auto CI = CurComponents.rbegin(); 15015 auto CE = CurComponents.rend(); 15016 auto SI = StackComponents.rbegin(); 15017 auto SE = StackComponents.rend(); 15018 for (; CI != CE && SI != SE; ++CI, ++SI) { 15019 15020 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15021 // At most one list item can be an array item derived from a given 15022 // variable in map clauses of the same construct. 15023 if (CurrentRegionOnly && 15024 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15025 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15026 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15027 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15028 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15029 diag::err_omp_multiple_array_items_in_map_clause) 15030 << CI->getAssociatedExpression()->getSourceRange(); 15031 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15032 diag::note_used_here) 15033 << SI->getAssociatedExpression()->getSourceRange(); 15034 return true; 15035 } 15036 15037 // Do both expressions have the same kind? 15038 if (CI->getAssociatedExpression()->getStmtClass() != 15039 SI->getAssociatedExpression()->getStmtClass()) 15040 break; 15041 15042 // Are we dealing with different variables/fields? 15043 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15044 break; 15045 } 15046 // Check if the extra components of the expressions in the enclosing 15047 // data environment are redundant for the current base declaration. 15048 // If they are, the maps completely overlap, which is legal. 15049 for (; SI != SE; ++SI) { 15050 QualType Type; 15051 if (const auto *ASE = 15052 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15053 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15054 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15055 SI->getAssociatedExpression())) { 15056 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15057 Type = 15058 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15059 } 15060 if (Type.isNull() || Type->isAnyPointerType() || 15061 checkArrayExpressionDoesNotReferToWholeSize( 15062 SemaRef, SI->getAssociatedExpression(), Type)) 15063 break; 15064 } 15065 15066 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15067 // List items of map clauses in the same construct must not share 15068 // original storage. 15069 // 15070 // If the expressions are exactly the same or one is a subset of the 15071 // other, it means they are sharing storage. 15072 if (CI == CE && SI == SE) { 15073 if (CurrentRegionOnly) { 15074 if (CKind == OMPC_map) { 15075 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15076 } else { 15077 assert(CKind == OMPC_to || CKind == OMPC_from); 15078 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15079 << ERange; 15080 } 15081 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15082 << RE->getSourceRange(); 15083 return true; 15084 } 15085 // If we find the same expression in the enclosing data environment, 15086 // that is legal. 15087 IsEnclosedByDataEnvironmentExpr = true; 15088 return false; 15089 } 15090 15091 QualType DerivedType = 15092 std::prev(CI)->getAssociatedDeclaration()->getType(); 15093 SourceLocation DerivedLoc = 15094 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15095 15096 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15097 // If the type of a list item is a reference to a type T then the type 15098 // will be considered to be T for all purposes of this clause. 15099 DerivedType = DerivedType.getNonReferenceType(); 15100 15101 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15102 // A variable for which the type is pointer and an array section 15103 // derived from that variable must not appear as list items of map 15104 // clauses of the same construct. 15105 // 15106 // Also, cover one of the cases in: 15107 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15108 // If any part of the original storage of a list item has corresponding 15109 // storage in the device data environment, all of the original storage 15110 // must have corresponding storage in the device data environment. 15111 // 15112 if (DerivedType->isAnyPointerType()) { 15113 if (CI == CE || SI == SE) { 15114 SemaRef.Diag( 15115 DerivedLoc, 15116 diag::err_omp_pointer_mapped_along_with_derived_section) 15117 << DerivedLoc; 15118 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15119 << RE->getSourceRange(); 15120 return true; 15121 } 15122 if (CI->getAssociatedExpression()->getStmtClass() != 15123 SI->getAssociatedExpression()->getStmtClass() || 15124 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15125 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15126 assert(CI != CE && SI != SE); 15127 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15128 << DerivedLoc; 15129 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15130 << RE->getSourceRange(); 15131 return true; 15132 } 15133 } 15134 15135 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15136 // List items of map clauses in the same construct must not share 15137 // original storage. 15138 // 15139 // An expression is a subset of the other. 15140 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15141 if (CKind == OMPC_map) { 15142 if (CI != CE || SI != SE) { 15143 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15144 // a pointer. 15145 auto Begin = 15146 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15147 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15148 auto It = Begin; 15149 while (It != End && !It->getAssociatedDeclaration()) 15150 std::advance(It, 1); 15151 assert(It != End && 15152 "Expected at least one component with the declaration."); 15153 if (It != Begin && It->getAssociatedDeclaration() 15154 ->getType() 15155 .getCanonicalType() 15156 ->isAnyPointerType()) { 15157 IsEnclosedByDataEnvironmentExpr = false; 15158 EnclosingExpr = nullptr; 15159 return false; 15160 } 15161 } 15162 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15163 } else { 15164 assert(CKind == OMPC_to || CKind == OMPC_from); 15165 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15166 << ERange; 15167 } 15168 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15169 << RE->getSourceRange(); 15170 return true; 15171 } 15172 15173 // The current expression uses the same base as other expression in the 15174 // data environment but does not contain it completely. 15175 if (!CurrentRegionOnly && SI != SE) 15176 EnclosingExpr = RE; 15177 15178 // The current expression is a subset of the expression in the data 15179 // environment. 15180 IsEnclosedByDataEnvironmentExpr |= 15181 (!CurrentRegionOnly && CI != CE && SI == SE); 15182 15183 return false; 15184 }); 15185 15186 if (CurrentRegionOnly) 15187 return FoundError; 15188 15189 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15190 // If any part of the original storage of a list item has corresponding 15191 // storage in the device data environment, all of the original storage must 15192 // have corresponding storage in the device data environment. 15193 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15194 // If a list item is an element of a structure, and a different element of 15195 // the structure has a corresponding list item in the device data environment 15196 // prior to a task encountering the construct associated with the map clause, 15197 // then the list item must also have a corresponding list item in the device 15198 // data environment prior to the task encountering the construct. 15199 // 15200 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15201 SemaRef.Diag(ELoc, 15202 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15203 << ERange; 15204 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15205 << EnclosingExpr->getSourceRange(); 15206 return true; 15207 } 15208 15209 return FoundError; 15210 } 15211 15212 // Look up the user-defined mapper given the mapper name and mapped type, and 15213 // build a reference to it. 15214 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15215 CXXScopeSpec &MapperIdScopeSpec, 15216 const DeclarationNameInfo &MapperId, 15217 QualType Type, 15218 Expr *UnresolvedMapper) { 15219 if (MapperIdScopeSpec.isInvalid()) 15220 return ExprError(); 15221 // Get the actual type for the array type. 15222 if (Type->isArrayType()) { 15223 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15224 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15225 } 15226 // Find all user-defined mappers with the given MapperId. 15227 SmallVector<UnresolvedSet<8>, 4> Lookups; 15228 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15229 Lookup.suppressDiagnostics(); 15230 if (S) { 15231 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15232 NamedDecl *D = Lookup.getRepresentativeDecl(); 15233 while (S && !S->isDeclScope(D)) 15234 S = S->getParent(); 15235 if (S) 15236 S = S->getParent(); 15237 Lookups.emplace_back(); 15238 Lookups.back().append(Lookup.begin(), Lookup.end()); 15239 Lookup.clear(); 15240 } 15241 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15242 // Extract the user-defined mappers with the given MapperId. 15243 Lookups.push_back(UnresolvedSet<8>()); 15244 for (NamedDecl *D : ULE->decls()) { 15245 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15246 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15247 Lookups.back().addDecl(DMD); 15248 } 15249 } 15250 // Defer the lookup for dependent types. The results will be passed through 15251 // UnresolvedMapper on instantiation. 15252 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15253 Type->isInstantiationDependentType() || 15254 Type->containsUnexpandedParameterPack() || 15255 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15256 return !D->isInvalidDecl() && 15257 (D->getType()->isDependentType() || 15258 D->getType()->isInstantiationDependentType() || 15259 D->getType()->containsUnexpandedParameterPack()); 15260 })) { 15261 UnresolvedSet<8> URS; 15262 for (const UnresolvedSet<8> &Set : Lookups) { 15263 if (Set.empty()) 15264 continue; 15265 URS.append(Set.begin(), Set.end()); 15266 } 15267 return UnresolvedLookupExpr::Create( 15268 SemaRef.Context, /*NamingClass=*/nullptr, 15269 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15270 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15271 } 15272 SourceLocation Loc = MapperId.getLoc(); 15273 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15274 // The type must be of struct, union or class type in C and C++ 15275 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15276 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15277 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15278 return ExprError(); 15279 } 15280 // Perform argument dependent lookup. 15281 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15282 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15283 // Return the first user-defined mapper with the desired type. 15284 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15285 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15286 if (!D->isInvalidDecl() && 15287 SemaRef.Context.hasSameType(D->getType(), Type)) 15288 return D; 15289 return nullptr; 15290 })) 15291 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15292 // Find the first user-defined mapper with a type derived from the desired 15293 // type. 15294 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15295 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15296 if (!D->isInvalidDecl() && 15297 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15298 !Type.isMoreQualifiedThan(D->getType())) 15299 return D; 15300 return nullptr; 15301 })) { 15302 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15303 /*DetectVirtual=*/false); 15304 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15305 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15306 VD->getType().getUnqualifiedType()))) { 15307 if (SemaRef.CheckBaseClassAccess( 15308 Loc, VD->getType(), Type, Paths.front(), 15309 /*DiagID=*/0) != Sema::AR_inaccessible) { 15310 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15311 } 15312 } 15313 } 15314 } 15315 // Report error if a mapper is specified, but cannot be found. 15316 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15317 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15318 << Type << MapperId.getName(); 15319 return ExprError(); 15320 } 15321 return ExprEmpty(); 15322 } 15323 15324 namespace { 15325 // Utility struct that gathers all the related lists associated with a mappable 15326 // expression. 15327 struct MappableVarListInfo { 15328 // The list of expressions. 15329 ArrayRef<Expr *> VarList; 15330 // The list of processed expressions. 15331 SmallVector<Expr *, 16> ProcessedVarList; 15332 // The mappble components for each expression. 15333 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15334 // The base declaration of the variable. 15335 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15336 // The reference to the user-defined mapper associated with every expression. 15337 SmallVector<Expr *, 16> UDMapperList; 15338 15339 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15340 // We have a list of components and base declarations for each entry in the 15341 // variable list. 15342 VarComponents.reserve(VarList.size()); 15343 VarBaseDeclarations.reserve(VarList.size()); 15344 } 15345 }; 15346 } 15347 15348 // Check the validity of the provided variable list for the provided clause kind 15349 // \a CKind. In the check process the valid expressions, mappable expression 15350 // components, variables, and user-defined mappers are extracted and used to 15351 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15352 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15353 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15354 static void checkMappableExpressionList( 15355 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15356 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15357 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15358 ArrayRef<Expr *> UnresolvedMappers, 15359 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15360 bool IsMapTypeImplicit = false) { 15361 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15362 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15363 "Unexpected clause kind with mappable expressions!"); 15364 15365 // If the identifier of user-defined mapper is not specified, it is "default". 15366 // We do not change the actual name in this clause to distinguish whether a 15367 // mapper is specified explicitly, i.e., it is not explicitly specified when 15368 // MapperId.getName() is empty. 15369 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15370 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15371 MapperId.setName(DeclNames.getIdentifier( 15372 &SemaRef.getASTContext().Idents.get("default"))); 15373 } 15374 15375 // Iterators to find the current unresolved mapper expression. 15376 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15377 bool UpdateUMIt = false; 15378 Expr *UnresolvedMapper = nullptr; 15379 15380 // Keep track of the mappable components and base declarations in this clause. 15381 // Each entry in the list is going to have a list of components associated. We 15382 // record each set of the components so that we can build the clause later on. 15383 // In the end we should have the same amount of declarations and component 15384 // lists. 15385 15386 for (Expr *RE : MVLI.VarList) { 15387 assert(RE && "Null expr in omp to/from/map clause"); 15388 SourceLocation ELoc = RE->getExprLoc(); 15389 15390 // Find the current unresolved mapper expression. 15391 if (UpdateUMIt && UMIt != UMEnd) { 15392 UMIt++; 15393 assert( 15394 UMIt != UMEnd && 15395 "Expect the size of UnresolvedMappers to match with that of VarList"); 15396 } 15397 UpdateUMIt = true; 15398 if (UMIt != UMEnd) 15399 UnresolvedMapper = *UMIt; 15400 15401 const Expr *VE = RE->IgnoreParenLValueCasts(); 15402 15403 if (VE->isValueDependent() || VE->isTypeDependent() || 15404 VE->isInstantiationDependent() || 15405 VE->containsUnexpandedParameterPack()) { 15406 // Try to find the associated user-defined mapper. 15407 ExprResult ER = buildUserDefinedMapperRef( 15408 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15409 VE->getType().getCanonicalType(), UnresolvedMapper); 15410 if (ER.isInvalid()) 15411 continue; 15412 MVLI.UDMapperList.push_back(ER.get()); 15413 // We can only analyze this information once the missing information is 15414 // resolved. 15415 MVLI.ProcessedVarList.push_back(RE); 15416 continue; 15417 } 15418 15419 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15420 15421 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15422 SemaRef.Diag(ELoc, 15423 diag::err_omp_expected_named_var_member_or_array_expression) 15424 << RE->getSourceRange(); 15425 continue; 15426 } 15427 15428 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15429 ValueDecl *CurDeclaration = nullptr; 15430 15431 // Obtain the array or member expression bases if required. Also, fill the 15432 // components array with all the components identified in the process. 15433 const Expr *BE = checkMapClauseExpressionBase( 15434 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15435 if (!BE) 15436 continue; 15437 15438 assert(!CurComponents.empty() && 15439 "Invalid mappable expression information."); 15440 15441 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15442 // Add store "this" pointer to class in DSAStackTy for future checking 15443 DSAS->addMappedClassesQualTypes(TE->getType()); 15444 // Try to find the associated user-defined mapper. 15445 ExprResult ER = buildUserDefinedMapperRef( 15446 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15447 VE->getType().getCanonicalType(), UnresolvedMapper); 15448 if (ER.isInvalid()) 15449 continue; 15450 MVLI.UDMapperList.push_back(ER.get()); 15451 // Skip restriction checking for variable or field declarations 15452 MVLI.ProcessedVarList.push_back(RE); 15453 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15454 MVLI.VarComponents.back().append(CurComponents.begin(), 15455 CurComponents.end()); 15456 MVLI.VarBaseDeclarations.push_back(nullptr); 15457 continue; 15458 } 15459 15460 // For the following checks, we rely on the base declaration which is 15461 // expected to be associated with the last component. The declaration is 15462 // expected to be a variable or a field (if 'this' is being mapped). 15463 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15464 assert(CurDeclaration && "Null decl on map clause."); 15465 assert( 15466 CurDeclaration->isCanonicalDecl() && 15467 "Expecting components to have associated only canonical declarations."); 15468 15469 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15470 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15471 15472 assert((VD || FD) && "Only variables or fields are expected here!"); 15473 (void)FD; 15474 15475 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15476 // threadprivate variables cannot appear in a map clause. 15477 // OpenMP 4.5 [2.10.5, target update Construct] 15478 // threadprivate variables cannot appear in a from clause. 15479 if (VD && DSAS->isThreadPrivate(VD)) { 15480 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15481 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15482 << getOpenMPClauseName(CKind); 15483 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15484 continue; 15485 } 15486 15487 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15488 // A list item cannot appear in both a map clause and a data-sharing 15489 // attribute clause on the same construct. 15490 15491 // Check conflicts with other map clause expressions. We check the conflicts 15492 // with the current construct separately from the enclosing data 15493 // environment, because the restrictions are different. We only have to 15494 // check conflicts across regions for the map clauses. 15495 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15496 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15497 break; 15498 if (CKind == OMPC_map && 15499 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15500 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15501 break; 15502 15503 // OpenMP 4.5 [2.10.5, target update Construct] 15504 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15505 // If the type of a list item is a reference to a type T then the type will 15506 // be considered to be T for all purposes of this clause. 15507 auto I = llvm::find_if( 15508 CurComponents, 15509 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15510 return MC.getAssociatedDeclaration(); 15511 }); 15512 assert(I != CurComponents.end() && "Null decl on map clause."); 15513 QualType Type = 15514 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15515 15516 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15517 // A list item in a to or from clause must have a mappable type. 15518 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15519 // A list item must have a mappable type. 15520 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15521 DSAS, Type)) 15522 continue; 15523 15524 if (CKind == OMPC_map) { 15525 // target enter data 15526 // OpenMP [2.10.2, Restrictions, p. 99] 15527 // A map-type must be specified in all map clauses and must be either 15528 // to or alloc. 15529 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15530 if (DKind == OMPD_target_enter_data && 15531 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15532 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15533 << (IsMapTypeImplicit ? 1 : 0) 15534 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15535 << getOpenMPDirectiveName(DKind); 15536 continue; 15537 } 15538 15539 // target exit_data 15540 // OpenMP [2.10.3, Restrictions, p. 102] 15541 // A map-type must be specified in all map clauses and must be either 15542 // from, release, or delete. 15543 if (DKind == OMPD_target_exit_data && 15544 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15545 MapType == OMPC_MAP_delete)) { 15546 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15547 << (IsMapTypeImplicit ? 1 : 0) 15548 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15549 << getOpenMPDirectiveName(DKind); 15550 continue; 15551 } 15552 15553 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15554 // A list item cannot appear in both a map clause and a data-sharing 15555 // attribute clause on the same construct 15556 // 15557 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15558 // A list item cannot appear in both a map clause and a data-sharing 15559 // attribute clause on the same construct unless the construct is a 15560 // combined construct. 15561 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15562 isOpenMPTargetExecutionDirective(DKind)) || 15563 DKind == OMPD_target)) { 15564 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15565 if (isOpenMPPrivate(DVar.CKind)) { 15566 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15567 << getOpenMPClauseName(DVar.CKind) 15568 << getOpenMPClauseName(OMPC_map) 15569 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15570 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15571 continue; 15572 } 15573 } 15574 } 15575 15576 // Try to find the associated user-defined mapper. 15577 ExprResult ER = buildUserDefinedMapperRef( 15578 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15579 Type.getCanonicalType(), UnresolvedMapper); 15580 if (ER.isInvalid()) 15581 continue; 15582 MVLI.UDMapperList.push_back(ER.get()); 15583 15584 // Save the current expression. 15585 MVLI.ProcessedVarList.push_back(RE); 15586 15587 // Store the components in the stack so that they can be used to check 15588 // against other clauses later on. 15589 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15590 /*WhereFoundClauseKind=*/OMPC_map); 15591 15592 // Save the components and declaration to create the clause. For purposes of 15593 // the clause creation, any component list that has has base 'this' uses 15594 // null as base declaration. 15595 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15596 MVLI.VarComponents.back().append(CurComponents.begin(), 15597 CurComponents.end()); 15598 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15599 : CurDeclaration); 15600 } 15601 } 15602 15603 OMPClause *Sema::ActOnOpenMPMapClause( 15604 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15605 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15606 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15607 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15608 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15609 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15610 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15611 OMPC_MAP_MODIFIER_unknown, 15612 OMPC_MAP_MODIFIER_unknown}; 15613 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15614 15615 // Process map-type-modifiers, flag errors for duplicate modifiers. 15616 unsigned Count = 0; 15617 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15618 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15619 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15620 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15621 continue; 15622 } 15623 assert(Count < OMPMapClause::NumberOfModifiers && 15624 "Modifiers exceed the allowed number of map type modifiers"); 15625 Modifiers[Count] = MapTypeModifiers[I]; 15626 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15627 ++Count; 15628 } 15629 15630 MappableVarListInfo MVLI(VarList); 15631 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15632 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15633 MapType, IsMapTypeImplicit); 15634 15635 // We need to produce a map clause even if we don't have variables so that 15636 // other diagnostics related with non-existing map clauses are accurate. 15637 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15638 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15639 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15640 MapperIdScopeSpec.getWithLocInContext(Context), 15641 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15642 } 15643 15644 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15645 TypeResult ParsedType) { 15646 assert(ParsedType.isUsable()); 15647 15648 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15649 if (ReductionType.isNull()) 15650 return QualType(); 15651 15652 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15653 // A type name in a declare reduction directive cannot be a function type, an 15654 // array type, a reference type, or a type qualified with const, volatile or 15655 // restrict. 15656 if (ReductionType.hasQualifiers()) { 15657 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15658 return QualType(); 15659 } 15660 15661 if (ReductionType->isFunctionType()) { 15662 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15663 return QualType(); 15664 } 15665 if (ReductionType->isReferenceType()) { 15666 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15667 return QualType(); 15668 } 15669 if (ReductionType->isArrayType()) { 15670 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15671 return QualType(); 15672 } 15673 return ReductionType; 15674 } 15675 15676 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15677 Scope *S, DeclContext *DC, DeclarationName Name, 15678 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15679 AccessSpecifier AS, Decl *PrevDeclInScope) { 15680 SmallVector<Decl *, 8> Decls; 15681 Decls.reserve(ReductionTypes.size()); 15682 15683 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15684 forRedeclarationInCurContext()); 15685 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15686 // A reduction-identifier may not be re-declared in the current scope for the 15687 // same type or for a type that is compatible according to the base language 15688 // rules. 15689 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15690 OMPDeclareReductionDecl *PrevDRD = nullptr; 15691 bool InCompoundScope = true; 15692 if (S != nullptr) { 15693 // Find previous declaration with the same name not referenced in other 15694 // declarations. 15695 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15696 InCompoundScope = 15697 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15698 LookupName(Lookup, S); 15699 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15700 /*AllowInlineNamespace=*/false); 15701 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15702 LookupResult::Filter Filter = Lookup.makeFilter(); 15703 while (Filter.hasNext()) { 15704 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15705 if (InCompoundScope) { 15706 auto I = UsedAsPrevious.find(PrevDecl); 15707 if (I == UsedAsPrevious.end()) 15708 UsedAsPrevious[PrevDecl] = false; 15709 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15710 UsedAsPrevious[D] = true; 15711 } 15712 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15713 PrevDecl->getLocation(); 15714 } 15715 Filter.done(); 15716 if (InCompoundScope) { 15717 for (const auto &PrevData : UsedAsPrevious) { 15718 if (!PrevData.second) { 15719 PrevDRD = PrevData.first; 15720 break; 15721 } 15722 } 15723 } 15724 } else if (PrevDeclInScope != nullptr) { 15725 auto *PrevDRDInScope = PrevDRD = 15726 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15727 do { 15728 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15729 PrevDRDInScope->getLocation(); 15730 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15731 } while (PrevDRDInScope != nullptr); 15732 } 15733 for (const auto &TyData : ReductionTypes) { 15734 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15735 bool Invalid = false; 15736 if (I != PreviousRedeclTypes.end()) { 15737 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15738 << TyData.first; 15739 Diag(I->second, diag::note_previous_definition); 15740 Invalid = true; 15741 } 15742 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15743 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15744 Name, TyData.first, PrevDRD); 15745 DC->addDecl(DRD); 15746 DRD->setAccess(AS); 15747 Decls.push_back(DRD); 15748 if (Invalid) 15749 DRD->setInvalidDecl(); 15750 else 15751 PrevDRD = DRD; 15752 } 15753 15754 return DeclGroupPtrTy::make( 15755 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15756 } 15757 15758 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15759 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15760 15761 // Enter new function scope. 15762 PushFunctionScope(); 15763 setFunctionHasBranchProtectedScope(); 15764 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15765 15766 if (S != nullptr) 15767 PushDeclContext(S, DRD); 15768 else 15769 CurContext = DRD; 15770 15771 PushExpressionEvaluationContext( 15772 ExpressionEvaluationContext::PotentiallyEvaluated); 15773 15774 QualType ReductionType = DRD->getType(); 15775 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15776 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15777 // uses semantics of argument handles by value, but it should be passed by 15778 // reference. C lang does not support references, so pass all parameters as 15779 // pointers. 15780 // Create 'T omp_in;' variable. 15781 VarDecl *OmpInParm = 15782 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15783 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15784 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15785 // uses semantics of argument handles by value, but it should be passed by 15786 // reference. C lang does not support references, so pass all parameters as 15787 // pointers. 15788 // Create 'T omp_out;' variable. 15789 VarDecl *OmpOutParm = 15790 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15791 if (S != nullptr) { 15792 PushOnScopeChains(OmpInParm, S); 15793 PushOnScopeChains(OmpOutParm, S); 15794 } else { 15795 DRD->addDecl(OmpInParm); 15796 DRD->addDecl(OmpOutParm); 15797 } 15798 Expr *InE = 15799 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15800 Expr *OutE = 15801 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15802 DRD->setCombinerData(InE, OutE); 15803 } 15804 15805 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15806 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15807 DiscardCleanupsInEvaluationContext(); 15808 PopExpressionEvaluationContext(); 15809 15810 PopDeclContext(); 15811 PopFunctionScopeInfo(); 15812 15813 if (Combiner != nullptr) 15814 DRD->setCombiner(Combiner); 15815 else 15816 DRD->setInvalidDecl(); 15817 } 15818 15819 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15820 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15821 15822 // Enter new function scope. 15823 PushFunctionScope(); 15824 setFunctionHasBranchProtectedScope(); 15825 15826 if (S != nullptr) 15827 PushDeclContext(S, DRD); 15828 else 15829 CurContext = DRD; 15830 15831 PushExpressionEvaluationContext( 15832 ExpressionEvaluationContext::PotentiallyEvaluated); 15833 15834 QualType ReductionType = DRD->getType(); 15835 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15836 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15837 // uses semantics of argument handles by value, but it should be passed by 15838 // reference. C lang does not support references, so pass all parameters as 15839 // pointers. 15840 // Create 'T omp_priv;' variable. 15841 VarDecl *OmpPrivParm = 15842 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15843 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15844 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15845 // uses semantics of argument handles by value, but it should be passed by 15846 // reference. C lang does not support references, so pass all parameters as 15847 // pointers. 15848 // Create 'T omp_orig;' variable. 15849 VarDecl *OmpOrigParm = 15850 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15851 if (S != nullptr) { 15852 PushOnScopeChains(OmpPrivParm, S); 15853 PushOnScopeChains(OmpOrigParm, S); 15854 } else { 15855 DRD->addDecl(OmpPrivParm); 15856 DRD->addDecl(OmpOrigParm); 15857 } 15858 Expr *OrigE = 15859 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15860 Expr *PrivE = 15861 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15862 DRD->setInitializerData(OrigE, PrivE); 15863 return OmpPrivParm; 15864 } 15865 15866 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15867 VarDecl *OmpPrivParm) { 15868 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15869 DiscardCleanupsInEvaluationContext(); 15870 PopExpressionEvaluationContext(); 15871 15872 PopDeclContext(); 15873 PopFunctionScopeInfo(); 15874 15875 if (Initializer != nullptr) { 15876 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15877 } else if (OmpPrivParm->hasInit()) { 15878 DRD->setInitializer(OmpPrivParm->getInit(), 15879 OmpPrivParm->isDirectInit() 15880 ? OMPDeclareReductionDecl::DirectInit 15881 : OMPDeclareReductionDecl::CopyInit); 15882 } else { 15883 DRD->setInvalidDecl(); 15884 } 15885 } 15886 15887 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15888 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15889 for (Decl *D : DeclReductions.get()) { 15890 if (IsValid) { 15891 if (S) 15892 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15893 /*AddToContext=*/false); 15894 } else { 15895 D->setInvalidDecl(); 15896 } 15897 } 15898 return DeclReductions; 15899 } 15900 15901 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15902 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15903 QualType T = TInfo->getType(); 15904 if (D.isInvalidType()) 15905 return true; 15906 15907 if (getLangOpts().CPlusPlus) { 15908 // Check that there are no default arguments (C++ only). 15909 CheckExtraCXXDefaultArguments(D); 15910 } 15911 15912 return CreateParsedType(T, TInfo); 15913 } 15914 15915 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15916 TypeResult ParsedType) { 15917 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15918 15919 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15920 assert(!MapperType.isNull() && "Expect valid mapper type"); 15921 15922 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15923 // The type must be of struct, union or class type in C and C++ 15924 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15925 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15926 return QualType(); 15927 } 15928 return MapperType; 15929 } 15930 15931 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15932 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15933 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15934 Decl *PrevDeclInScope) { 15935 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15936 forRedeclarationInCurContext()); 15937 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15938 // A mapper-identifier may not be redeclared in the current scope for the 15939 // same type or for a type that is compatible according to the base language 15940 // rules. 15941 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15942 OMPDeclareMapperDecl *PrevDMD = nullptr; 15943 bool InCompoundScope = true; 15944 if (S != nullptr) { 15945 // Find previous declaration with the same name not referenced in other 15946 // declarations. 15947 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15948 InCompoundScope = 15949 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15950 LookupName(Lookup, S); 15951 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15952 /*AllowInlineNamespace=*/false); 15953 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15954 LookupResult::Filter Filter = Lookup.makeFilter(); 15955 while (Filter.hasNext()) { 15956 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15957 if (InCompoundScope) { 15958 auto I = UsedAsPrevious.find(PrevDecl); 15959 if (I == UsedAsPrevious.end()) 15960 UsedAsPrevious[PrevDecl] = false; 15961 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15962 UsedAsPrevious[D] = true; 15963 } 15964 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15965 PrevDecl->getLocation(); 15966 } 15967 Filter.done(); 15968 if (InCompoundScope) { 15969 for (const auto &PrevData : UsedAsPrevious) { 15970 if (!PrevData.second) { 15971 PrevDMD = PrevData.first; 15972 break; 15973 } 15974 } 15975 } 15976 } else if (PrevDeclInScope) { 15977 auto *PrevDMDInScope = PrevDMD = 15978 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15979 do { 15980 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15981 PrevDMDInScope->getLocation(); 15982 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15983 } while (PrevDMDInScope != nullptr); 15984 } 15985 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15986 bool Invalid = false; 15987 if (I != PreviousRedeclTypes.end()) { 15988 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15989 << MapperType << Name; 15990 Diag(I->second, diag::note_previous_definition); 15991 Invalid = true; 15992 } 15993 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15994 MapperType, VN, PrevDMD); 15995 DC->addDecl(DMD); 15996 DMD->setAccess(AS); 15997 if (Invalid) 15998 DMD->setInvalidDecl(); 15999 16000 // Enter new function scope. 16001 PushFunctionScope(); 16002 setFunctionHasBranchProtectedScope(); 16003 16004 CurContext = DMD; 16005 16006 return DMD; 16007 } 16008 16009 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16010 Scope *S, 16011 QualType MapperType, 16012 SourceLocation StartLoc, 16013 DeclarationName VN) { 16014 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16015 if (S) 16016 PushOnScopeChains(VD, S); 16017 else 16018 DMD->addDecl(VD); 16019 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16020 DMD->setMapperVarRef(MapperVarRefExpr); 16021 } 16022 16023 Sema::DeclGroupPtrTy 16024 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16025 ArrayRef<OMPClause *> ClauseList) { 16026 PopDeclContext(); 16027 PopFunctionScopeInfo(); 16028 16029 if (D) { 16030 if (S) 16031 PushOnScopeChains(D, S, /*AddToContext=*/false); 16032 D->CreateClauses(Context, ClauseList); 16033 } 16034 16035 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16036 } 16037 16038 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16039 SourceLocation StartLoc, 16040 SourceLocation LParenLoc, 16041 SourceLocation EndLoc) { 16042 Expr *ValExpr = NumTeams; 16043 Stmt *HelperValStmt = nullptr; 16044 16045 // OpenMP [teams Constrcut, Restrictions] 16046 // The num_teams expression must evaluate to a positive integer value. 16047 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16048 /*StrictlyPositive=*/true)) 16049 return nullptr; 16050 16051 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16052 OpenMPDirectiveKind CaptureRegion = 16053 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 16054 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16055 ValExpr = MakeFullExpr(ValExpr).get(); 16056 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16057 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16058 HelperValStmt = buildPreInits(Context, Captures); 16059 } 16060 16061 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16062 StartLoc, LParenLoc, EndLoc); 16063 } 16064 16065 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16066 SourceLocation StartLoc, 16067 SourceLocation LParenLoc, 16068 SourceLocation EndLoc) { 16069 Expr *ValExpr = ThreadLimit; 16070 Stmt *HelperValStmt = nullptr; 16071 16072 // OpenMP [teams Constrcut, Restrictions] 16073 // The thread_limit expression must evaluate to a positive integer value. 16074 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16075 /*StrictlyPositive=*/true)) 16076 return nullptr; 16077 16078 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16079 OpenMPDirectiveKind CaptureRegion = 16080 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 16081 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16082 ValExpr = MakeFullExpr(ValExpr).get(); 16083 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16084 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16085 HelperValStmt = buildPreInits(Context, Captures); 16086 } 16087 16088 return new (Context) OMPThreadLimitClause( 16089 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16090 } 16091 16092 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16093 SourceLocation StartLoc, 16094 SourceLocation LParenLoc, 16095 SourceLocation EndLoc) { 16096 Expr *ValExpr = Priority; 16097 Stmt *HelperValStmt = nullptr; 16098 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16099 16100 // OpenMP [2.9.1, task Constrcut] 16101 // The priority-value is a non-negative numerical scalar expression. 16102 if (!isNonNegativeIntegerValue( 16103 ValExpr, *this, OMPC_priority, 16104 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16105 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16106 return nullptr; 16107 16108 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16109 StartLoc, LParenLoc, EndLoc); 16110 } 16111 16112 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16113 SourceLocation StartLoc, 16114 SourceLocation LParenLoc, 16115 SourceLocation EndLoc) { 16116 Expr *ValExpr = Grainsize; 16117 Stmt *HelperValStmt = nullptr; 16118 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16119 16120 // OpenMP [2.9.2, taskloop Constrcut] 16121 // The parameter of the grainsize clause must be a positive integer 16122 // expression. 16123 if (!isNonNegativeIntegerValue( 16124 ValExpr, *this, OMPC_grainsize, 16125 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16126 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16127 return nullptr; 16128 16129 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16130 StartLoc, LParenLoc, EndLoc); 16131 } 16132 16133 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16134 SourceLocation StartLoc, 16135 SourceLocation LParenLoc, 16136 SourceLocation EndLoc) { 16137 Expr *ValExpr = NumTasks; 16138 Stmt *HelperValStmt = nullptr; 16139 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16140 16141 // OpenMP [2.9.2, taskloop Constrcut] 16142 // The parameter of the num_tasks clause must be a positive integer 16143 // expression. 16144 if (!isNonNegativeIntegerValue( 16145 ValExpr, *this, OMPC_num_tasks, 16146 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16147 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16148 return nullptr; 16149 16150 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16151 StartLoc, LParenLoc, EndLoc); 16152 } 16153 16154 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16155 SourceLocation LParenLoc, 16156 SourceLocation EndLoc) { 16157 // OpenMP [2.13.2, critical construct, Description] 16158 // ... where hint-expression is an integer constant expression that evaluates 16159 // to a valid lock hint. 16160 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16161 if (HintExpr.isInvalid()) 16162 return nullptr; 16163 return new (Context) 16164 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16165 } 16166 16167 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16168 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16169 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16170 SourceLocation EndLoc) { 16171 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16172 std::string Values; 16173 Values += "'"; 16174 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16175 Values += "'"; 16176 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16177 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16178 return nullptr; 16179 } 16180 Expr *ValExpr = ChunkSize; 16181 Stmt *HelperValStmt = nullptr; 16182 if (ChunkSize) { 16183 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16184 !ChunkSize->isInstantiationDependent() && 16185 !ChunkSize->containsUnexpandedParameterPack()) { 16186 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16187 ExprResult Val = 16188 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16189 if (Val.isInvalid()) 16190 return nullptr; 16191 16192 ValExpr = Val.get(); 16193 16194 // OpenMP [2.7.1, Restrictions] 16195 // chunk_size must be a loop invariant integer expression with a positive 16196 // value. 16197 llvm::APSInt Result; 16198 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16199 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16200 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16201 << "dist_schedule" << ChunkSize->getSourceRange(); 16202 return nullptr; 16203 } 16204 } else if (getOpenMPCaptureRegionForClause( 16205 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 16206 OMPD_unknown && 16207 !CurContext->isDependentContext()) { 16208 ValExpr = MakeFullExpr(ValExpr).get(); 16209 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16210 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16211 HelperValStmt = buildPreInits(Context, Captures); 16212 } 16213 } 16214 } 16215 16216 return new (Context) 16217 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16218 Kind, ValExpr, HelperValStmt); 16219 } 16220 16221 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16222 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16223 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16224 SourceLocation KindLoc, SourceLocation EndLoc) { 16225 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 16226 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 16227 std::string Value; 16228 SourceLocation Loc; 16229 Value += "'"; 16230 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16231 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16232 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16233 Loc = MLoc; 16234 } else { 16235 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16236 OMPC_DEFAULTMAP_scalar); 16237 Loc = KindLoc; 16238 } 16239 Value += "'"; 16240 Diag(Loc, diag::err_omp_unexpected_clause_value) 16241 << Value << getOpenMPClauseName(OMPC_defaultmap); 16242 return nullptr; 16243 } 16244 DSAStack->setDefaultDMAToFromScalar(StartLoc); 16245 16246 return new (Context) 16247 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16248 } 16249 16250 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16251 DeclContext *CurLexicalContext = getCurLexicalContext(); 16252 if (!CurLexicalContext->isFileContext() && 16253 !CurLexicalContext->isExternCContext() && 16254 !CurLexicalContext->isExternCXXContext() && 16255 !isa<CXXRecordDecl>(CurLexicalContext) && 16256 !isa<ClassTemplateDecl>(CurLexicalContext) && 16257 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16258 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16259 Diag(Loc, diag::err_omp_region_not_file_context); 16260 return false; 16261 } 16262 ++DeclareTargetNestingLevel; 16263 return true; 16264 } 16265 16266 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16267 assert(DeclareTargetNestingLevel > 0 && 16268 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16269 --DeclareTargetNestingLevel; 16270 } 16271 16272 NamedDecl * 16273 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16274 const DeclarationNameInfo &Id, 16275 NamedDeclSetType &SameDirectiveDecls) { 16276 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16277 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16278 16279 if (Lookup.isAmbiguous()) 16280 return nullptr; 16281 Lookup.suppressDiagnostics(); 16282 16283 if (!Lookup.isSingleResult()) { 16284 VarOrFuncDeclFilterCCC CCC(*this); 16285 if (TypoCorrection Corrected = 16286 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16287 CTK_ErrorRecovery)) { 16288 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16289 << Id.getName()); 16290 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16291 return nullptr; 16292 } 16293 16294 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16295 return nullptr; 16296 } 16297 16298 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16299 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16300 !isa<FunctionTemplateDecl>(ND)) { 16301 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16302 return nullptr; 16303 } 16304 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16305 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16306 return ND; 16307 } 16308 16309 void Sema::ActOnOpenMPDeclareTargetName( 16310 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16311 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16312 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16313 isa<FunctionTemplateDecl>(ND)) && 16314 "Expected variable, function or function template."); 16315 16316 // Diagnose marking after use as it may lead to incorrect diagnosis and 16317 // codegen. 16318 if (LangOpts.OpenMP >= 50 && 16319 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16320 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16321 16322 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16323 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16324 if (DevTy.hasValue() && *DevTy != DT) { 16325 Diag(Loc, diag::err_omp_device_type_mismatch) 16326 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16327 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16328 return; 16329 } 16330 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16331 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16332 if (!Res) { 16333 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16334 SourceRange(Loc, Loc)); 16335 ND->addAttr(A); 16336 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16337 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16338 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16339 } else if (*Res != MT) { 16340 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16341 } 16342 } 16343 16344 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16345 Sema &SemaRef, Decl *D) { 16346 if (!D || !isa<VarDecl>(D)) 16347 return; 16348 auto *VD = cast<VarDecl>(D); 16349 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16350 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16351 if (SemaRef.LangOpts.OpenMP >= 50 && 16352 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16353 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16354 VD->hasGlobalStorage()) { 16355 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16356 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16357 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16358 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16359 // If a lambda declaration and definition appears between a 16360 // declare target directive and the matching end declare target 16361 // directive, all variables that are captured by the lambda 16362 // expression must also appear in a to clause. 16363 SemaRef.Diag(VD->getLocation(), 16364 diag::err_omp_lambda_capture_in_declare_target_not_to); 16365 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16366 << VD << 0 << SR; 16367 return; 16368 } 16369 } 16370 if (MapTy.hasValue()) 16371 return; 16372 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16373 SemaRef.Diag(SL, diag::note_used_here) << SR; 16374 } 16375 16376 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16377 Sema &SemaRef, DSAStackTy *Stack, 16378 ValueDecl *VD) { 16379 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16380 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16381 /*FullCheck=*/false); 16382 } 16383 16384 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16385 SourceLocation IdLoc) { 16386 if (!D || D->isInvalidDecl()) 16387 return; 16388 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16389 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16390 if (auto *VD = dyn_cast<VarDecl>(D)) { 16391 // Only global variables can be marked as declare target. 16392 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16393 !VD->isStaticDataMember()) 16394 return; 16395 // 2.10.6: threadprivate variable cannot appear in a declare target 16396 // directive. 16397 if (DSAStack->isThreadPrivate(VD)) { 16398 Diag(SL, diag::err_omp_threadprivate_in_target); 16399 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16400 return; 16401 } 16402 } 16403 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16404 D = FTD->getTemplatedDecl(); 16405 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16406 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16407 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16408 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16409 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16410 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16411 return; 16412 } 16413 // Mark the function as must be emitted for the device. 16414 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16415 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16416 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16417 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16418 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16419 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16420 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16421 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16422 } 16423 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16424 // Problem if any with var declared with incomplete type will be reported 16425 // as normal, so no need to check it here. 16426 if ((E || !VD->getType()->isIncompleteType()) && 16427 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16428 return; 16429 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16430 // Checking declaration inside declare target region. 16431 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16432 isa<FunctionTemplateDecl>(D)) { 16433 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16434 Context, OMPDeclareTargetDeclAttr::MT_To, 16435 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16436 D->addAttr(A); 16437 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16438 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16439 } 16440 return; 16441 } 16442 } 16443 if (!E) 16444 return; 16445 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16446 } 16447 16448 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16449 CXXScopeSpec &MapperIdScopeSpec, 16450 DeclarationNameInfo &MapperId, 16451 const OMPVarListLocTy &Locs, 16452 ArrayRef<Expr *> UnresolvedMappers) { 16453 MappableVarListInfo MVLI(VarList); 16454 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16455 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16456 if (MVLI.ProcessedVarList.empty()) 16457 return nullptr; 16458 16459 return OMPToClause::Create( 16460 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16461 MVLI.VarComponents, MVLI.UDMapperList, 16462 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16463 } 16464 16465 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16466 CXXScopeSpec &MapperIdScopeSpec, 16467 DeclarationNameInfo &MapperId, 16468 const OMPVarListLocTy &Locs, 16469 ArrayRef<Expr *> UnresolvedMappers) { 16470 MappableVarListInfo MVLI(VarList); 16471 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16472 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16473 if (MVLI.ProcessedVarList.empty()) 16474 return nullptr; 16475 16476 return OMPFromClause::Create( 16477 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16478 MVLI.VarComponents, MVLI.UDMapperList, 16479 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16480 } 16481 16482 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16483 const OMPVarListLocTy &Locs) { 16484 MappableVarListInfo MVLI(VarList); 16485 SmallVector<Expr *, 8> PrivateCopies; 16486 SmallVector<Expr *, 8> Inits; 16487 16488 for (Expr *RefExpr : VarList) { 16489 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16490 SourceLocation ELoc; 16491 SourceRange ERange; 16492 Expr *SimpleRefExpr = RefExpr; 16493 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16494 if (Res.second) { 16495 // It will be analyzed later. 16496 MVLI.ProcessedVarList.push_back(RefExpr); 16497 PrivateCopies.push_back(nullptr); 16498 Inits.push_back(nullptr); 16499 } 16500 ValueDecl *D = Res.first; 16501 if (!D) 16502 continue; 16503 16504 QualType Type = D->getType(); 16505 Type = Type.getNonReferenceType().getUnqualifiedType(); 16506 16507 auto *VD = dyn_cast<VarDecl>(D); 16508 16509 // Item should be a pointer or reference to pointer. 16510 if (!Type->isPointerType()) { 16511 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16512 << 0 << RefExpr->getSourceRange(); 16513 continue; 16514 } 16515 16516 // Build the private variable and the expression that refers to it. 16517 auto VDPrivate = 16518 buildVarDecl(*this, ELoc, Type, D->getName(), 16519 D->hasAttrs() ? &D->getAttrs() : nullptr, 16520 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16521 if (VDPrivate->isInvalidDecl()) 16522 continue; 16523 16524 CurContext->addDecl(VDPrivate); 16525 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16526 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16527 16528 // Add temporary variable to initialize the private copy of the pointer. 16529 VarDecl *VDInit = 16530 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16531 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16532 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16533 AddInitializerToDecl(VDPrivate, 16534 DefaultLvalueConversion(VDInitRefExpr).get(), 16535 /*DirectInit=*/false); 16536 16537 // If required, build a capture to implement the privatization initialized 16538 // with the current list item value. 16539 DeclRefExpr *Ref = nullptr; 16540 if (!VD) 16541 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16542 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16543 PrivateCopies.push_back(VDPrivateRefExpr); 16544 Inits.push_back(VDInitRefExpr); 16545 16546 // We need to add a data sharing attribute for this variable to make sure it 16547 // is correctly captured. A variable that shows up in a use_device_ptr has 16548 // similar properties of a first private variable. 16549 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16550 16551 // Create a mappable component for the list item. List items in this clause 16552 // only need a component. 16553 MVLI.VarBaseDeclarations.push_back(D); 16554 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16555 MVLI.VarComponents.back().push_back( 16556 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16557 } 16558 16559 if (MVLI.ProcessedVarList.empty()) 16560 return nullptr; 16561 16562 return OMPUseDevicePtrClause::Create( 16563 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16564 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16565 } 16566 16567 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16568 const OMPVarListLocTy &Locs) { 16569 MappableVarListInfo MVLI(VarList); 16570 for (Expr *RefExpr : VarList) { 16571 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16572 SourceLocation ELoc; 16573 SourceRange ERange; 16574 Expr *SimpleRefExpr = RefExpr; 16575 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16576 if (Res.second) { 16577 // It will be analyzed later. 16578 MVLI.ProcessedVarList.push_back(RefExpr); 16579 } 16580 ValueDecl *D = Res.first; 16581 if (!D) 16582 continue; 16583 16584 QualType Type = D->getType(); 16585 // item should be a pointer or array or reference to pointer or array 16586 if (!Type.getNonReferenceType()->isPointerType() && 16587 !Type.getNonReferenceType()->isArrayType()) { 16588 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16589 << 0 << RefExpr->getSourceRange(); 16590 continue; 16591 } 16592 16593 // Check if the declaration in the clause does not show up in any data 16594 // sharing attribute. 16595 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16596 if (isOpenMPPrivate(DVar.CKind)) { 16597 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16598 << getOpenMPClauseName(DVar.CKind) 16599 << getOpenMPClauseName(OMPC_is_device_ptr) 16600 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16601 reportOriginalDsa(*this, DSAStack, D, DVar); 16602 continue; 16603 } 16604 16605 const Expr *ConflictExpr; 16606 if (DSAStack->checkMappableExprComponentListsForDecl( 16607 D, /*CurrentRegionOnly=*/true, 16608 [&ConflictExpr]( 16609 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16610 OpenMPClauseKind) -> bool { 16611 ConflictExpr = R.front().getAssociatedExpression(); 16612 return true; 16613 })) { 16614 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16615 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16616 << ConflictExpr->getSourceRange(); 16617 continue; 16618 } 16619 16620 // Store the components in the stack so that they can be used to check 16621 // against other clauses later on. 16622 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16623 DSAStack->addMappableExpressionComponents( 16624 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16625 16626 // Record the expression we've just processed. 16627 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16628 16629 // Create a mappable component for the list item. List items in this clause 16630 // only need a component. We use a null declaration to signal fields in 16631 // 'this'. 16632 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16633 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16634 "Unexpected device pointer expression!"); 16635 MVLI.VarBaseDeclarations.push_back( 16636 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16637 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16638 MVLI.VarComponents.back().push_back(MC); 16639 } 16640 16641 if (MVLI.ProcessedVarList.empty()) 16642 return nullptr; 16643 16644 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16645 MVLI.VarBaseDeclarations, 16646 MVLI.VarComponents); 16647 } 16648 16649 OMPClause *Sema::ActOnOpenMPAllocateClause( 16650 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16651 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16652 if (Allocator) { 16653 // OpenMP [2.11.4 allocate Clause, Description] 16654 // allocator is an expression of omp_allocator_handle_t type. 16655 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16656 return nullptr; 16657 16658 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16659 if (AllocatorRes.isInvalid()) 16660 return nullptr; 16661 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16662 DSAStack->getOMPAllocatorHandleT(), 16663 Sema::AA_Initializing, 16664 /*AllowExplicit=*/true); 16665 if (AllocatorRes.isInvalid()) 16666 return nullptr; 16667 Allocator = AllocatorRes.get(); 16668 } else { 16669 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16670 // allocate clauses that appear on a target construct or on constructs in a 16671 // target region must specify an allocator expression unless a requires 16672 // directive with the dynamic_allocators clause is present in the same 16673 // compilation unit. 16674 if (LangOpts.OpenMPIsDevice && 16675 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16676 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16677 } 16678 // Analyze and build list of variables. 16679 SmallVector<Expr *, 8> Vars; 16680 for (Expr *RefExpr : VarList) { 16681 assert(RefExpr && "NULL expr in OpenMP private clause."); 16682 SourceLocation ELoc; 16683 SourceRange ERange; 16684 Expr *SimpleRefExpr = RefExpr; 16685 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16686 if (Res.second) { 16687 // It will be analyzed later. 16688 Vars.push_back(RefExpr); 16689 } 16690 ValueDecl *D = Res.first; 16691 if (!D) 16692 continue; 16693 16694 auto *VD = dyn_cast<VarDecl>(D); 16695 DeclRefExpr *Ref = nullptr; 16696 if (!VD && !CurContext->isDependentContext()) 16697 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16698 Vars.push_back((VD || CurContext->isDependentContext()) 16699 ? RefExpr->IgnoreParens() 16700 : Ref); 16701 } 16702 16703 if (Vars.empty()) 16704 return nullptr; 16705 16706 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16707 ColonLoc, EndLoc, Vars); 16708 } 16709