1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 bool HasMutipleLoops = false; 143 const Decl *PossiblyLoopCounter = nullptr; 144 bool NowaitRegion = false; 145 bool CancelRegion = false; 146 bool LoopStart = false; 147 bool BodyComplete = false; 148 SourceLocation InnerTeamsRegionLoc; 149 /// Reference to the taskgroup task_reduction reference expression. 150 Expr *TaskgroupReductionRef = nullptr; 151 llvm::DenseSet<QualType> MappedClassesQualTypes; 152 /// List of globals marked as declare target link in this target region 153 /// (isOpenMPTargetExecutionDirective(Directive) == true). 154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 156 Scope *CurScope, SourceLocation Loc) 157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 158 ConstructLoc(Loc) {} 159 SharingMapTy() = default; 160 }; 161 162 using StackTy = SmallVector<SharingMapTy, 4>; 163 164 /// Stack of used declaration and their data-sharing attributes. 165 DeclSAMapTy Threadprivates; 166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 168 /// true, if check for DSA must be from parent directive, false, if 169 /// from current directive. 170 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 171 Sema &SemaRef; 172 bool ForceCapturing = false; 173 /// true if all the variables in the target executable directives must be 174 /// captured by reference. 175 bool ForceCaptureByReferenceInTargetExecutable = false; 176 CriticalsWithHintsTy Criticals; 177 unsigned IgnoredStackElements = 0; 178 179 /// Iterators over the stack iterate in order from innermost to outermost 180 /// directive. 181 using const_iterator = StackTy::const_reverse_iterator; 182 const_iterator begin() const { 183 return Stack.empty() ? const_iterator() 184 : Stack.back().first.rbegin() + IgnoredStackElements; 185 } 186 const_iterator end() const { 187 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 188 } 189 using iterator = StackTy::reverse_iterator; 190 iterator begin() { 191 return Stack.empty() ? iterator() 192 : Stack.back().first.rbegin() + IgnoredStackElements; 193 } 194 iterator end() { 195 return Stack.empty() ? iterator() : Stack.back().first.rend(); 196 } 197 198 // Convenience operations to get at the elements of the stack. 199 200 bool isStackEmpty() const { 201 return Stack.empty() || 202 Stack.back().second != CurrentNonCapturingFunctionScope || 203 Stack.back().first.size() <= IgnoredStackElements; 204 } 205 size_t getStackSize() const { 206 return isStackEmpty() ? 0 207 : Stack.back().first.size() - IgnoredStackElements; 208 } 209 210 SharingMapTy *getTopOfStackOrNull() { 211 size_t Size = getStackSize(); 212 if (Size == 0) 213 return nullptr; 214 return &Stack.back().first[Size - 1]; 215 } 216 const SharingMapTy *getTopOfStackOrNull() const { 217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 218 } 219 SharingMapTy &getTopOfStack() { 220 assert(!isStackEmpty() && "no current directive"); 221 return *getTopOfStackOrNull(); 222 } 223 const SharingMapTy &getTopOfStack() const { 224 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 225 } 226 227 SharingMapTy *getSecondOnStackOrNull() { 228 size_t Size = getStackSize(); 229 if (Size <= 1) 230 return nullptr; 231 return &Stack.back().first[Size - 2]; 232 } 233 const SharingMapTy *getSecondOnStackOrNull() const { 234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 235 } 236 237 /// Get the stack element at a certain level (previously returned by 238 /// \c getNestingLevel). 239 /// 240 /// Note that nesting levels count from outermost to innermost, and this is 241 /// the reverse of our iteration order where new inner levels are pushed at 242 /// the front of the stack. 243 SharingMapTy &getStackElemAtLevel(unsigned Level) { 244 assert(Level < getStackSize() && "no such stack element"); 245 return Stack.back().first[Level]; 246 } 247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 249 } 250 251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 252 253 /// Checks if the variable is a local for OpenMP region. 254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 255 256 /// Vector of previously declared requires directives 257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 258 /// omp_allocator_handle_t type. 259 QualType OMPAllocatorHandleT; 260 /// Expression for the predefined allocators. 261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 262 nullptr}; 263 /// Vector of previously encountered target directives 264 SmallVector<SourceLocation, 2> TargetLocations; 265 266 public: 267 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 268 269 /// Sets omp_allocator_handle_t type. 270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 271 /// Gets omp_allocator_handle_t type. 272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 273 /// Sets the given default allocator. 274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 275 Expr *Allocator) { 276 OMPPredefinedAllocators[AllocatorKind] = Allocator; 277 } 278 /// Returns the specified default allocator. 279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 280 return OMPPredefinedAllocators[AllocatorKind]; 281 } 282 283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 284 OpenMPClauseKind getClauseParsingMode() const { 285 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 286 return ClauseKindMode; 287 } 288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 289 290 bool isBodyComplete() const { 291 const SharingMapTy *Top = getTopOfStackOrNull(); 292 return Top && Top->BodyComplete; 293 } 294 void setBodyComplete() { 295 getTopOfStack().BodyComplete = true; 296 } 297 298 bool isForceVarCapturing() const { return ForceCapturing; } 299 void setForceVarCapturing(bool V) { ForceCapturing = V; } 300 301 void setForceCaptureByReferenceInTargetExecutable(bool V) { 302 ForceCaptureByReferenceInTargetExecutable = V; 303 } 304 bool isForceCaptureByReferenceInTargetExecutable() const { 305 return ForceCaptureByReferenceInTargetExecutable; 306 } 307 308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 309 Scope *CurScope, SourceLocation Loc) { 310 assert(!IgnoredStackElements && 311 "cannot change stack while ignoring elements"); 312 if (Stack.empty() || 313 Stack.back().second != CurrentNonCapturingFunctionScope) 314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 316 Stack.back().first.back().DefaultAttrLoc = Loc; 317 } 318 319 void pop() { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 assert(!Stack.back().first.empty() && 323 "Data-sharing attributes stack is empty!"); 324 Stack.back().first.pop_back(); 325 } 326 327 /// RAII object to temporarily leave the scope of a directive when we want to 328 /// logically operate in its parent. 329 class ParentDirectiveScope { 330 DSAStackTy &Self; 331 bool Active; 332 public: 333 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 334 : Self(Self), Active(false) { 335 if (Activate) 336 enable(); 337 } 338 ~ParentDirectiveScope() { disable(); } 339 void disable() { 340 if (Active) { 341 --Self.IgnoredStackElements; 342 Active = false; 343 } 344 } 345 void enable() { 346 if (!Active) { 347 ++Self.IgnoredStackElements; 348 Active = true; 349 } 350 } 351 }; 352 353 /// Marks that we're started loop parsing. 354 void loopInit() { 355 assert(isOpenMPLoopDirective(getCurrentDirective()) && 356 "Expected loop-based directive."); 357 getTopOfStack().LoopStart = true; 358 } 359 /// Start capturing of the variables in the loop context. 360 void loopStart() { 361 assert(isOpenMPLoopDirective(getCurrentDirective()) && 362 "Expected loop-based directive."); 363 getTopOfStack().LoopStart = false; 364 } 365 /// true, if variables are captured, false otherwise. 366 bool isLoopStarted() const { 367 assert(isOpenMPLoopDirective(getCurrentDirective()) && 368 "Expected loop-based directive."); 369 return !getTopOfStack().LoopStart; 370 } 371 /// Marks (or clears) declaration as possibly loop counter. 372 void resetPossibleLoopCounter(const Decl *D = nullptr) { 373 getTopOfStack().PossiblyLoopCounter = 374 D ? D->getCanonicalDecl() : D; 375 } 376 /// Gets the possible loop counter decl. 377 const Decl *getPossiblyLoopCunter() const { 378 return getTopOfStack().PossiblyLoopCounter; 379 } 380 /// Start new OpenMP region stack in new non-capturing function. 381 void pushFunction() { 382 assert(!IgnoredStackElements && 383 "cannot change stack while ignoring elements"); 384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 385 assert(!isa<CapturingScopeInfo>(CurFnScope)); 386 CurrentNonCapturingFunctionScope = CurFnScope; 387 } 388 /// Pop region stack for non-capturing function. 389 void popFunction(const FunctionScopeInfo *OldFSI) { 390 assert(!IgnoredStackElements && 391 "cannot change stack while ignoring elements"); 392 if (!Stack.empty() && Stack.back().second == OldFSI) { 393 assert(Stack.back().first.empty()); 394 Stack.pop_back(); 395 } 396 CurrentNonCapturingFunctionScope = nullptr; 397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 398 if (!isa<CapturingScopeInfo>(FSI)) { 399 CurrentNonCapturingFunctionScope = FSI; 400 break; 401 } 402 } 403 } 404 405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 407 } 408 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 409 getCriticalWithHint(const DeclarationNameInfo &Name) const { 410 auto I = Criticals.find(Name.getAsString()); 411 if (I != Criticals.end()) 412 return I->second; 413 return std::make_pair(nullptr, llvm::APSInt()); 414 } 415 /// If 'aligned' declaration for given variable \a D was not seen yet, 416 /// add it and return NULL; otherwise return previous occurrence's expression 417 /// for diagnostics. 418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 419 420 /// Register specified variable as loop control variable. 421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 422 /// Check if the specified variable is a loop control variable for 423 /// current region. 424 /// \return The index of the loop control variable in the list of associated 425 /// for-loops (from outer to inner). 426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 427 /// Check if the specified variable is a loop control variable for 428 /// parent region. 429 /// \return The index of the loop control variable in the list of associated 430 /// for-loops (from outer to inner). 431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 432 /// Get the loop control variable for the I-th loop (or nullptr) in 433 /// parent directive. 434 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 435 436 /// Adds explicit data sharing attribute to the specified declaration. 437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 438 DeclRefExpr *PrivateCopy = nullptr); 439 440 /// Adds additional information for the reduction items with the reduction id 441 /// represented as an operator. 442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 443 BinaryOperatorKind BOK); 444 /// Adds additional information for the reduction items with the reduction id 445 /// represented as reduction identifier. 446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 447 const Expr *ReductionRef); 448 /// Returns the location and reduction operation from the innermost parent 449 /// region for the given \p D. 450 const DSAVarData 451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 452 BinaryOperatorKind &BOK, 453 Expr *&TaskgroupDescriptor) const; 454 /// Returns the location and reduction operation from the innermost parent 455 /// region for the given \p D. 456 const DSAVarData 457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 458 const Expr *&ReductionRef, 459 Expr *&TaskgroupDescriptor) const; 460 /// Return reduction reference expression for the current taskgroup. 461 Expr *getTaskgroupReductionRef() const { 462 assert(getTopOfStack().Directive == OMPD_taskgroup && 463 "taskgroup reference expression requested for non taskgroup " 464 "directive."); 465 return getTopOfStack().TaskgroupReductionRef; 466 } 467 /// Checks if the given \p VD declaration is actually a taskgroup reduction 468 /// descriptor variable at the \p Level of OpenMP regions. 469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 470 return getStackElemAtLevel(Level).TaskgroupReductionRef && 471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 472 ->getDecl() == VD; 473 } 474 475 /// Returns data sharing attributes from top of the stack for the 476 /// specified declaration. 477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 478 /// Returns data-sharing attributes for the specified declaration. 479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 480 /// Checks if the specified variables has data-sharing attributes which 481 /// match specified \a CPred predicate in any directive which matches \a DPred 482 /// predicate. 483 const DSAVarData 484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 486 bool FromParent) const; 487 /// Checks if the specified variables has data-sharing attributes which 488 /// match specified \a CPred predicate in any innermost directive which 489 /// matches \a DPred predicate. 490 const DSAVarData 491 hasInnermostDSA(ValueDecl *D, 492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 494 bool FromParent) const; 495 /// Checks if the specified variables has explicit data-sharing 496 /// attributes which match specified \a CPred predicate at the specified 497 /// OpenMP region. 498 bool hasExplicitDSA(const ValueDecl *D, 499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 500 unsigned Level, bool NotLastprivate = false) const; 501 502 /// Returns true if the directive at level \Level matches in the 503 /// specified \a DPred predicate. 504 bool hasExplicitDirective( 505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 506 unsigned Level) const; 507 508 /// Finds a directive which matches specified \a DPred predicate. 509 bool hasDirective( 510 const llvm::function_ref<bool( 511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 512 DPred, 513 bool FromParent) const; 514 515 /// Returns currently analyzed directive. 516 OpenMPDirectiveKind getCurrentDirective() const { 517 const SharingMapTy *Top = getTopOfStackOrNull(); 518 return Top ? Top->Directive : OMPD_unknown; 519 } 520 /// Returns directive kind at specified level. 521 OpenMPDirectiveKind getDirective(unsigned Level) const { 522 assert(!isStackEmpty() && "No directive at specified level."); 523 return getStackElemAtLevel(Level).Directive; 524 } 525 /// Returns the capture region at the specified level. 526 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 527 unsigned OpenMPCaptureLevel) const { 528 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 529 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 530 return CaptureRegions[OpenMPCaptureLevel]; 531 } 532 /// Returns parent directive. 533 OpenMPDirectiveKind getParentDirective() const { 534 const SharingMapTy *Parent = getSecondOnStackOrNull(); 535 return Parent ? Parent->Directive : OMPD_unknown; 536 } 537 538 /// Add requires decl to internal vector 539 void addRequiresDecl(OMPRequiresDecl *RD) { 540 RequiresDecls.push_back(RD); 541 } 542 543 /// Checks if the defined 'requires' directive has specified type of clause. 544 template <typename ClauseType> 545 bool hasRequiresDeclWithClause() { 546 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 547 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 548 return isa<ClauseType>(C); 549 }); 550 }); 551 } 552 553 /// Checks for a duplicate clause amongst previously declared requires 554 /// directives 555 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 556 bool IsDuplicate = false; 557 for (OMPClause *CNew : ClauseList) { 558 for (const OMPRequiresDecl *D : RequiresDecls) { 559 for (const OMPClause *CPrev : D->clauselists()) { 560 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 561 SemaRef.Diag(CNew->getBeginLoc(), 562 diag::err_omp_requires_clause_redeclaration) 563 << getOpenMPClauseName(CNew->getClauseKind()); 564 SemaRef.Diag(CPrev->getBeginLoc(), 565 diag::note_omp_requires_previous_clause) 566 << getOpenMPClauseName(CPrev->getClauseKind()); 567 IsDuplicate = true; 568 } 569 } 570 } 571 } 572 return IsDuplicate; 573 } 574 575 /// Add location of previously encountered target to internal vector 576 void addTargetDirLocation(SourceLocation LocStart) { 577 TargetLocations.push_back(LocStart); 578 } 579 580 // Return previously encountered target region locations. 581 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 582 return TargetLocations; 583 } 584 585 /// Set default data sharing attribute to none. 586 void setDefaultDSANone(SourceLocation Loc) { 587 getTopOfStack().DefaultAttr = DSA_none; 588 getTopOfStack().DefaultAttrLoc = Loc; 589 } 590 /// Set default data sharing attribute to shared. 591 void setDefaultDSAShared(SourceLocation Loc) { 592 getTopOfStack().DefaultAttr = DSA_shared; 593 getTopOfStack().DefaultAttrLoc = Loc; 594 } 595 /// Set default data mapping attribute to 'tofrom:scalar'. 596 void setDefaultDMAToFromScalar(SourceLocation Loc) { 597 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 598 getTopOfStack().DefaultMapAttrLoc = Loc; 599 } 600 601 DefaultDataSharingAttributes getDefaultDSA() const { 602 return isStackEmpty() ? DSA_unspecified 603 : getTopOfStack().DefaultAttr; 604 } 605 SourceLocation getDefaultDSALocation() const { 606 return isStackEmpty() ? SourceLocation() 607 : getTopOfStack().DefaultAttrLoc; 608 } 609 DefaultMapAttributes getDefaultDMA() const { 610 return isStackEmpty() ? DMA_unspecified 611 : getTopOfStack().DefaultMapAttr; 612 } 613 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 614 return getStackElemAtLevel(Level).DefaultMapAttr; 615 } 616 SourceLocation getDefaultDMALocation() const { 617 return isStackEmpty() ? SourceLocation() 618 : getTopOfStack().DefaultMapAttrLoc; 619 } 620 621 /// Checks if the specified variable is a threadprivate. 622 bool isThreadPrivate(VarDecl *D) { 623 const DSAVarData DVar = getTopDSA(D, false); 624 return isOpenMPThreadPrivate(DVar.CKind); 625 } 626 627 /// Marks current region as ordered (it has an 'ordered' clause). 628 void setOrderedRegion(bool IsOrdered, const Expr *Param, 629 OMPOrderedClause *Clause) { 630 if (IsOrdered) 631 getTopOfStack().OrderedRegion.emplace(Param, Clause); 632 else 633 getTopOfStack().OrderedRegion.reset(); 634 } 635 /// Returns true, if region is ordered (has associated 'ordered' clause), 636 /// false - otherwise. 637 bool isOrderedRegion() const { 638 if (const SharingMapTy *Top = getTopOfStackOrNull()) 639 return Top->OrderedRegion.hasValue(); 640 return false; 641 } 642 /// Returns optional parameter for the ordered region. 643 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 644 if (const SharingMapTy *Top = getTopOfStackOrNull()) 645 if (Top->OrderedRegion.hasValue()) 646 return Top->OrderedRegion.getValue(); 647 return std::make_pair(nullptr, nullptr); 648 } 649 /// Returns true, if parent region is ordered (has associated 650 /// 'ordered' clause), false - otherwise. 651 bool isParentOrderedRegion() const { 652 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 653 return Parent->OrderedRegion.hasValue(); 654 return false; 655 } 656 /// Returns optional parameter for the ordered region. 657 std::pair<const Expr *, OMPOrderedClause *> 658 getParentOrderedRegionParam() const { 659 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 660 if (Parent->OrderedRegion.hasValue()) 661 return Parent->OrderedRegion.getValue(); 662 return std::make_pair(nullptr, nullptr); 663 } 664 /// Marks current region as nowait (it has a 'nowait' clause). 665 void setNowaitRegion(bool IsNowait = true) { 666 getTopOfStack().NowaitRegion = IsNowait; 667 } 668 /// Returns true, if parent region is nowait (has associated 669 /// 'nowait' clause), false - otherwise. 670 bool isParentNowaitRegion() const { 671 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 672 return Parent->NowaitRegion; 673 return false; 674 } 675 /// Marks parent region as cancel region. 676 void setParentCancelRegion(bool Cancel = true) { 677 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 678 Parent->CancelRegion |= Cancel; 679 } 680 /// Return true if current region has inner cancel construct. 681 bool isCancelRegion() const { 682 const SharingMapTy *Top = getTopOfStackOrNull(); 683 return Top ? Top->CancelRegion : false; 684 } 685 686 /// Set collapse value for the region. 687 void setAssociatedLoops(unsigned Val) { 688 getTopOfStack().AssociatedLoops = Val; 689 if (Val > 1) 690 getTopOfStack().HasMutipleLoops = true; 691 } 692 /// Return collapse value for region. 693 unsigned getAssociatedLoops() const { 694 const SharingMapTy *Top = getTopOfStackOrNull(); 695 return Top ? Top->AssociatedLoops : 0; 696 } 697 /// Returns true if the construct is associated with multiple loops. 698 bool hasMutipleLoops() const { 699 const SharingMapTy *Top = getTopOfStackOrNull(); 700 return Top ? Top->HasMutipleLoops : false; 701 } 702 703 /// Marks current target region as one with closely nested teams 704 /// region. 705 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 706 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 707 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 708 } 709 /// Returns true, if current region has closely nested teams region. 710 bool hasInnerTeamsRegion() const { 711 return getInnerTeamsRegionLoc().isValid(); 712 } 713 /// Returns location of the nested teams region (if any). 714 SourceLocation getInnerTeamsRegionLoc() const { 715 const SharingMapTy *Top = getTopOfStackOrNull(); 716 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 717 } 718 719 Scope *getCurScope() const { 720 const SharingMapTy *Top = getTopOfStackOrNull(); 721 return Top ? Top->CurScope : nullptr; 722 } 723 SourceLocation getConstructLoc() const { 724 const SharingMapTy *Top = getTopOfStackOrNull(); 725 return Top ? Top->ConstructLoc : SourceLocation(); 726 } 727 728 /// Do the check specified in \a Check to all component lists and return true 729 /// if any issue is found. 730 bool checkMappableExprComponentListsForDecl( 731 const ValueDecl *VD, bool CurrentRegionOnly, 732 const llvm::function_ref< 733 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 734 OpenMPClauseKind)> 735 Check) const { 736 if (isStackEmpty()) 737 return false; 738 auto SI = begin(); 739 auto SE = end(); 740 741 if (SI == SE) 742 return false; 743 744 if (CurrentRegionOnly) 745 SE = std::next(SI); 746 else 747 std::advance(SI, 1); 748 749 for (; SI != SE; ++SI) { 750 auto MI = SI->MappedExprComponents.find(VD); 751 if (MI != SI->MappedExprComponents.end()) 752 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 753 MI->second.Components) 754 if (Check(L, MI->second.Kind)) 755 return true; 756 } 757 return false; 758 } 759 760 /// Do the check specified in \a Check to all component lists at a given level 761 /// and return true if any issue is found. 762 bool checkMappableExprComponentListsForDeclAtLevel( 763 const ValueDecl *VD, unsigned Level, 764 const llvm::function_ref< 765 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 766 OpenMPClauseKind)> 767 Check) const { 768 if (getStackSize() <= Level) 769 return false; 770 771 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 772 auto MI = StackElem.MappedExprComponents.find(VD); 773 if (MI != StackElem.MappedExprComponents.end()) 774 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 775 MI->second.Components) 776 if (Check(L, MI->second.Kind)) 777 return true; 778 return false; 779 } 780 781 /// Create a new mappable expression component list associated with a given 782 /// declaration and initialize it with the provided list of components. 783 void addMappableExpressionComponents( 784 const ValueDecl *VD, 785 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 786 OpenMPClauseKind WhereFoundClauseKind) { 787 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 788 // Create new entry and append the new components there. 789 MEC.Components.resize(MEC.Components.size() + 1); 790 MEC.Components.back().append(Components.begin(), Components.end()); 791 MEC.Kind = WhereFoundClauseKind; 792 } 793 794 unsigned getNestingLevel() const { 795 assert(!isStackEmpty()); 796 return getStackSize() - 1; 797 } 798 void addDoacrossDependClause(OMPDependClause *C, 799 const OperatorOffsetTy &OpsOffs) { 800 SharingMapTy *Parent = getSecondOnStackOrNull(); 801 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 802 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 803 } 804 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 805 getDoacrossDependClauses() const { 806 const SharingMapTy &StackElem = getTopOfStack(); 807 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 808 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 809 return llvm::make_range(Ref.begin(), Ref.end()); 810 } 811 return llvm::make_range(StackElem.DoacrossDepends.end(), 812 StackElem.DoacrossDepends.end()); 813 } 814 815 // Store types of classes which have been explicitly mapped 816 void addMappedClassesQualTypes(QualType QT) { 817 SharingMapTy &StackElem = getTopOfStack(); 818 StackElem.MappedClassesQualTypes.insert(QT); 819 } 820 821 // Return set of mapped classes types 822 bool isClassPreviouslyMapped(QualType QT) const { 823 const SharingMapTy &StackElem = getTopOfStack(); 824 return StackElem.MappedClassesQualTypes.count(QT) != 0; 825 } 826 827 /// Adds global declare target to the parent target region. 828 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 829 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 830 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 831 "Expected declare target link global."); 832 for (auto &Elem : *this) { 833 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 834 Elem.DeclareTargetLinkVarDecls.push_back(E); 835 return; 836 } 837 } 838 } 839 840 /// Returns the list of globals with declare target link if current directive 841 /// is target. 842 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 843 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 844 "Expected target executable directive."); 845 return getTopOfStack().DeclareTargetLinkVarDecls; 846 } 847 }; 848 849 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 850 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 851 } 852 853 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 854 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 855 DKind == OMPD_unknown; 856 } 857 858 } // namespace 859 860 static const Expr *getExprAsWritten(const Expr *E) { 861 if (const auto *FE = dyn_cast<FullExpr>(E)) 862 E = FE->getSubExpr(); 863 864 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 865 E = MTE->GetTemporaryExpr(); 866 867 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 868 E = Binder->getSubExpr(); 869 870 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 871 E = ICE->getSubExprAsWritten(); 872 return E->IgnoreParens(); 873 } 874 875 static Expr *getExprAsWritten(Expr *E) { 876 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 877 } 878 879 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 880 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 881 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 882 D = ME->getMemberDecl(); 883 const auto *VD = dyn_cast<VarDecl>(D); 884 const auto *FD = dyn_cast<FieldDecl>(D); 885 if (VD != nullptr) { 886 VD = VD->getCanonicalDecl(); 887 D = VD; 888 } else { 889 assert(FD); 890 FD = FD->getCanonicalDecl(); 891 D = FD; 892 } 893 return D; 894 } 895 896 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 897 return const_cast<ValueDecl *>( 898 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 899 } 900 901 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 902 ValueDecl *D) const { 903 D = getCanonicalDecl(D); 904 auto *VD = dyn_cast<VarDecl>(D); 905 const auto *FD = dyn_cast<FieldDecl>(D); 906 DSAVarData DVar; 907 if (Iter == end()) { 908 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 909 // in a region but not in construct] 910 // File-scope or namespace-scope variables referenced in called routines 911 // in the region are shared unless they appear in a threadprivate 912 // directive. 913 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 914 DVar.CKind = OMPC_shared; 915 916 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 917 // in a region but not in construct] 918 // Variables with static storage duration that are declared in called 919 // routines in the region are shared. 920 if (VD && VD->hasGlobalStorage()) 921 DVar.CKind = OMPC_shared; 922 923 // Non-static data members are shared by default. 924 if (FD) 925 DVar.CKind = OMPC_shared; 926 927 return DVar; 928 } 929 930 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 931 // in a Construct, C/C++, predetermined, p.1] 932 // Variables with automatic storage duration that are declared in a scope 933 // inside the construct are private. 934 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 935 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 936 DVar.CKind = OMPC_private; 937 return DVar; 938 } 939 940 DVar.DKind = Iter->Directive; 941 // Explicitly specified attributes and local variables with predetermined 942 // attributes. 943 if (Iter->SharingMap.count(D)) { 944 const DSAInfo &Data = Iter->SharingMap.lookup(D); 945 DVar.RefExpr = Data.RefExpr.getPointer(); 946 DVar.PrivateCopy = Data.PrivateCopy; 947 DVar.CKind = Data.Attributes; 948 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 949 return DVar; 950 } 951 952 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 953 // in a Construct, C/C++, implicitly determined, p.1] 954 // In a parallel or task construct, the data-sharing attributes of these 955 // variables are determined by the default clause, if present. 956 switch (Iter->DefaultAttr) { 957 case DSA_shared: 958 DVar.CKind = OMPC_shared; 959 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 960 return DVar; 961 case DSA_none: 962 return DVar; 963 case DSA_unspecified: 964 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 965 // in a Construct, implicitly determined, p.2] 966 // In a parallel construct, if no default clause is present, these 967 // variables are shared. 968 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 969 if (isOpenMPParallelDirective(DVar.DKind) || 970 isOpenMPTeamsDirective(DVar.DKind)) { 971 DVar.CKind = OMPC_shared; 972 return DVar; 973 } 974 975 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 976 // in a Construct, implicitly determined, p.4] 977 // In a task construct, if no default clause is present, a variable that in 978 // the enclosing context is determined to be shared by all implicit tasks 979 // bound to the current team is shared. 980 if (isOpenMPTaskingDirective(DVar.DKind)) { 981 DSAVarData DVarTemp; 982 const_iterator I = Iter, E = end(); 983 do { 984 ++I; 985 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 986 // Referenced in a Construct, implicitly determined, p.6] 987 // In a task construct, if no default clause is present, a variable 988 // whose data-sharing attribute is not determined by the rules above is 989 // firstprivate. 990 DVarTemp = getDSA(I, D); 991 if (DVarTemp.CKind != OMPC_shared) { 992 DVar.RefExpr = nullptr; 993 DVar.CKind = OMPC_firstprivate; 994 return DVar; 995 } 996 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 997 DVar.CKind = 998 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 999 return DVar; 1000 } 1001 } 1002 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1003 // in a Construct, implicitly determined, p.3] 1004 // For constructs other than task, if no default clause is present, these 1005 // variables inherit their data-sharing attributes from the enclosing 1006 // context. 1007 return getDSA(++Iter, D); 1008 } 1009 1010 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1011 const Expr *NewDE) { 1012 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1013 D = getCanonicalDecl(D); 1014 SharingMapTy &StackElem = getTopOfStack(); 1015 auto It = StackElem.AlignedMap.find(D); 1016 if (It == StackElem.AlignedMap.end()) { 1017 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1018 StackElem.AlignedMap[D] = NewDE; 1019 return nullptr; 1020 } 1021 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1022 return It->second; 1023 } 1024 1025 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1026 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1027 D = getCanonicalDecl(D); 1028 SharingMapTy &StackElem = getTopOfStack(); 1029 StackElem.LCVMap.try_emplace( 1030 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1031 } 1032 1033 const DSAStackTy::LCDeclInfo 1034 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1035 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1036 D = getCanonicalDecl(D); 1037 const SharingMapTy &StackElem = getTopOfStack(); 1038 auto It = StackElem.LCVMap.find(D); 1039 if (It != StackElem.LCVMap.end()) 1040 return It->second; 1041 return {0, nullptr}; 1042 } 1043 1044 const DSAStackTy::LCDeclInfo 1045 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1046 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1047 assert(Parent && "Data-sharing attributes stack is empty"); 1048 D = getCanonicalDecl(D); 1049 auto It = Parent->LCVMap.find(D); 1050 if (It != Parent->LCVMap.end()) 1051 return It->second; 1052 return {0, nullptr}; 1053 } 1054 1055 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1056 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1057 assert(Parent && "Data-sharing attributes stack is empty"); 1058 if (Parent->LCVMap.size() < I) 1059 return nullptr; 1060 for (const auto &Pair : Parent->LCVMap) 1061 if (Pair.second.first == I) 1062 return Pair.first; 1063 return nullptr; 1064 } 1065 1066 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1067 DeclRefExpr *PrivateCopy) { 1068 D = getCanonicalDecl(D); 1069 if (A == OMPC_threadprivate) { 1070 DSAInfo &Data = Threadprivates[D]; 1071 Data.Attributes = A; 1072 Data.RefExpr.setPointer(E); 1073 Data.PrivateCopy = nullptr; 1074 } else { 1075 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1076 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1077 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1078 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1079 (isLoopControlVariable(D).first && A == OMPC_private)); 1080 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1081 Data.RefExpr.setInt(/*IntVal=*/true); 1082 return; 1083 } 1084 const bool IsLastprivate = 1085 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1086 Data.Attributes = A; 1087 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1088 Data.PrivateCopy = PrivateCopy; 1089 if (PrivateCopy) { 1090 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1091 Data.Attributes = A; 1092 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1093 Data.PrivateCopy = nullptr; 1094 } 1095 } 1096 } 1097 1098 /// Build a variable declaration for OpenMP loop iteration variable. 1099 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1100 StringRef Name, const AttrVec *Attrs = nullptr, 1101 DeclRefExpr *OrigRef = nullptr) { 1102 DeclContext *DC = SemaRef.CurContext; 1103 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1104 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1105 auto *Decl = 1106 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1107 if (Attrs) { 1108 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1109 I != E; ++I) 1110 Decl->addAttr(*I); 1111 } 1112 Decl->setImplicit(); 1113 if (OrigRef) { 1114 Decl->addAttr( 1115 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1116 } 1117 return Decl; 1118 } 1119 1120 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1121 SourceLocation Loc, 1122 bool RefersToCapture = false) { 1123 D->setReferenced(); 1124 D->markUsed(S.Context); 1125 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1126 SourceLocation(), D, RefersToCapture, Loc, Ty, 1127 VK_LValue); 1128 } 1129 1130 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1131 BinaryOperatorKind BOK) { 1132 D = getCanonicalDecl(D); 1133 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1134 assert( 1135 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1136 "Additional reduction info may be specified only for reduction items."); 1137 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1138 assert(ReductionData.ReductionRange.isInvalid() && 1139 getTopOfStack().Directive == OMPD_taskgroup && 1140 "Additional reduction info may be specified only once for reduction " 1141 "items."); 1142 ReductionData.set(BOK, SR); 1143 Expr *&TaskgroupReductionRef = 1144 getTopOfStack().TaskgroupReductionRef; 1145 if (!TaskgroupReductionRef) { 1146 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1147 SemaRef.Context.VoidPtrTy, ".task_red."); 1148 TaskgroupReductionRef = 1149 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1150 } 1151 } 1152 1153 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1154 const Expr *ReductionRef) { 1155 D = getCanonicalDecl(D); 1156 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1157 assert( 1158 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1159 "Additional reduction info may be specified only for reduction items."); 1160 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1161 assert(ReductionData.ReductionRange.isInvalid() && 1162 getTopOfStack().Directive == OMPD_taskgroup && 1163 "Additional reduction info may be specified only once for reduction " 1164 "items."); 1165 ReductionData.set(ReductionRef, SR); 1166 Expr *&TaskgroupReductionRef = 1167 getTopOfStack().TaskgroupReductionRef; 1168 if (!TaskgroupReductionRef) { 1169 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1170 SemaRef.Context.VoidPtrTy, ".task_red."); 1171 TaskgroupReductionRef = 1172 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1173 } 1174 } 1175 1176 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1177 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1178 Expr *&TaskgroupDescriptor) const { 1179 D = getCanonicalDecl(D); 1180 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1181 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1182 const DSAInfo &Data = I->SharingMap.lookup(D); 1183 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1184 continue; 1185 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1186 if (!ReductionData.ReductionOp || 1187 ReductionData.ReductionOp.is<const Expr *>()) 1188 return DSAVarData(); 1189 SR = ReductionData.ReductionRange; 1190 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1191 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1192 "expression for the descriptor is not " 1193 "set."); 1194 TaskgroupDescriptor = I->TaskgroupReductionRef; 1195 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1196 Data.PrivateCopy, I->DefaultAttrLoc); 1197 } 1198 return DSAVarData(); 1199 } 1200 1201 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1202 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1203 Expr *&TaskgroupDescriptor) const { 1204 D = getCanonicalDecl(D); 1205 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1206 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1207 const DSAInfo &Data = I->SharingMap.lookup(D); 1208 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1209 continue; 1210 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1211 if (!ReductionData.ReductionOp || 1212 !ReductionData.ReductionOp.is<const Expr *>()) 1213 return DSAVarData(); 1214 SR = ReductionData.ReductionRange; 1215 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1216 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1217 "expression for the descriptor is not " 1218 "set."); 1219 TaskgroupDescriptor = I->TaskgroupReductionRef; 1220 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1221 Data.PrivateCopy, I->DefaultAttrLoc); 1222 } 1223 return DSAVarData(); 1224 } 1225 1226 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1227 D = D->getCanonicalDecl(); 1228 for (const_iterator E = end(); I != E; ++I) { 1229 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1230 isOpenMPTargetExecutionDirective(I->Directive)) { 1231 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1232 Scope *CurScope = getCurScope(); 1233 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1234 CurScope = CurScope->getParent(); 1235 return CurScope != TopScope; 1236 } 1237 } 1238 return false; 1239 } 1240 1241 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1242 bool AcceptIfMutable = true, 1243 bool *IsClassType = nullptr) { 1244 ASTContext &Context = SemaRef.getASTContext(); 1245 Type = Type.getNonReferenceType().getCanonicalType(); 1246 bool IsConstant = Type.isConstant(Context); 1247 Type = Context.getBaseElementType(Type); 1248 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1249 ? Type->getAsCXXRecordDecl() 1250 : nullptr; 1251 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1252 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1253 RD = CTD->getTemplatedDecl(); 1254 if (IsClassType) 1255 *IsClassType = RD; 1256 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1257 RD->hasDefinition() && RD->hasMutableFields()); 1258 } 1259 1260 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1261 QualType Type, OpenMPClauseKind CKind, 1262 SourceLocation ELoc, 1263 bool AcceptIfMutable = true, 1264 bool ListItemNotVar = false) { 1265 ASTContext &Context = SemaRef.getASTContext(); 1266 bool IsClassType; 1267 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1268 unsigned Diag = ListItemNotVar 1269 ? diag::err_omp_const_list_item 1270 : IsClassType ? diag::err_omp_const_not_mutable_variable 1271 : diag::err_omp_const_variable; 1272 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1273 if (!ListItemNotVar && D) { 1274 const VarDecl *VD = dyn_cast<VarDecl>(D); 1275 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1276 VarDecl::DeclarationOnly; 1277 SemaRef.Diag(D->getLocation(), 1278 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1279 << D; 1280 } 1281 return true; 1282 } 1283 return false; 1284 } 1285 1286 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1287 bool FromParent) { 1288 D = getCanonicalDecl(D); 1289 DSAVarData DVar; 1290 1291 auto *VD = dyn_cast<VarDecl>(D); 1292 auto TI = Threadprivates.find(D); 1293 if (TI != Threadprivates.end()) { 1294 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1295 DVar.CKind = OMPC_threadprivate; 1296 return DVar; 1297 } 1298 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1299 DVar.RefExpr = buildDeclRefExpr( 1300 SemaRef, VD, D->getType().getNonReferenceType(), 1301 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1302 DVar.CKind = OMPC_threadprivate; 1303 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1304 return DVar; 1305 } 1306 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1307 // in a Construct, C/C++, predetermined, p.1] 1308 // Variables appearing in threadprivate directives are threadprivate. 1309 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1310 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1311 SemaRef.getLangOpts().OpenMPUseTLS && 1312 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1313 (VD && VD->getStorageClass() == SC_Register && 1314 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1315 DVar.RefExpr = buildDeclRefExpr( 1316 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1317 DVar.CKind = OMPC_threadprivate; 1318 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1319 return DVar; 1320 } 1321 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1322 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1323 !isLoopControlVariable(D).first) { 1324 const_iterator IterTarget = 1325 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1326 return isOpenMPTargetExecutionDirective(Data.Directive); 1327 }); 1328 if (IterTarget != end()) { 1329 const_iterator ParentIterTarget = IterTarget + 1; 1330 for (const_iterator Iter = begin(); 1331 Iter != ParentIterTarget; ++Iter) { 1332 if (isOpenMPLocal(VD, Iter)) { 1333 DVar.RefExpr = 1334 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1335 D->getLocation()); 1336 DVar.CKind = OMPC_threadprivate; 1337 return DVar; 1338 } 1339 } 1340 if (!isClauseParsingMode() || IterTarget != begin()) { 1341 auto DSAIter = IterTarget->SharingMap.find(D); 1342 if (DSAIter != IterTarget->SharingMap.end() && 1343 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1344 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1345 DVar.CKind = OMPC_threadprivate; 1346 return DVar; 1347 } 1348 const_iterator End = end(); 1349 if (!SemaRef.isOpenMPCapturedByRef( 1350 D, std::distance(ParentIterTarget, End), 1351 /*OpenMPCaptureLevel=*/0)) { 1352 DVar.RefExpr = 1353 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1354 IterTarget->ConstructLoc); 1355 DVar.CKind = OMPC_threadprivate; 1356 return DVar; 1357 } 1358 } 1359 } 1360 } 1361 1362 if (isStackEmpty()) 1363 // Not in OpenMP execution region and top scope was already checked. 1364 return DVar; 1365 1366 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1367 // in a Construct, C/C++, predetermined, p.4] 1368 // Static data members are shared. 1369 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1370 // in a Construct, C/C++, predetermined, p.7] 1371 // Variables with static storage duration that are declared in a scope 1372 // inside the construct are shared. 1373 if (VD && VD->isStaticDataMember()) { 1374 // Check for explicitly specified attributes. 1375 const_iterator I = begin(); 1376 const_iterator EndI = end(); 1377 if (FromParent && I != EndI) 1378 ++I; 1379 auto It = I->SharingMap.find(D); 1380 if (It != I->SharingMap.end()) { 1381 const DSAInfo &Data = It->getSecond(); 1382 DVar.RefExpr = Data.RefExpr.getPointer(); 1383 DVar.PrivateCopy = Data.PrivateCopy; 1384 DVar.CKind = Data.Attributes; 1385 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1386 DVar.DKind = I->Directive; 1387 return DVar; 1388 } 1389 1390 DVar.CKind = OMPC_shared; 1391 return DVar; 1392 } 1393 1394 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1395 // The predetermined shared attribute for const-qualified types having no 1396 // mutable members was removed after OpenMP 3.1. 1397 if (SemaRef.LangOpts.OpenMP <= 31) { 1398 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1399 // in a Construct, C/C++, predetermined, p.6] 1400 // Variables with const qualified type having no mutable member are 1401 // shared. 1402 if (isConstNotMutableType(SemaRef, D->getType())) { 1403 // Variables with const-qualified type having no mutable member may be 1404 // listed in a firstprivate clause, even if they are static data members. 1405 DSAVarData DVarTemp = hasInnermostDSA( 1406 D, 1407 [](OpenMPClauseKind C) { 1408 return C == OMPC_firstprivate || C == OMPC_shared; 1409 }, 1410 MatchesAlways, FromParent); 1411 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1412 return DVarTemp; 1413 1414 DVar.CKind = OMPC_shared; 1415 return DVar; 1416 } 1417 } 1418 1419 // Explicitly specified attributes and local variables with predetermined 1420 // attributes. 1421 const_iterator I = begin(); 1422 const_iterator EndI = end(); 1423 if (FromParent && I != EndI) 1424 ++I; 1425 auto It = I->SharingMap.find(D); 1426 if (It != I->SharingMap.end()) { 1427 const DSAInfo &Data = It->getSecond(); 1428 DVar.RefExpr = Data.RefExpr.getPointer(); 1429 DVar.PrivateCopy = Data.PrivateCopy; 1430 DVar.CKind = Data.Attributes; 1431 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1432 DVar.DKind = I->Directive; 1433 } 1434 1435 return DVar; 1436 } 1437 1438 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1439 bool FromParent) const { 1440 if (isStackEmpty()) { 1441 const_iterator I; 1442 return getDSA(I, D); 1443 } 1444 D = getCanonicalDecl(D); 1445 const_iterator StartI = begin(); 1446 const_iterator EndI = end(); 1447 if (FromParent && StartI != EndI) 1448 ++StartI; 1449 return getDSA(StartI, D); 1450 } 1451 1452 const DSAStackTy::DSAVarData 1453 DSAStackTy::hasDSA(ValueDecl *D, 1454 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1455 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1456 bool FromParent) const { 1457 if (isStackEmpty()) 1458 return {}; 1459 D = getCanonicalDecl(D); 1460 const_iterator I = begin(); 1461 const_iterator EndI = end(); 1462 if (FromParent && I != EndI) 1463 ++I; 1464 for (; I != EndI; ++I) { 1465 if (!DPred(I->Directive) && 1466 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1467 continue; 1468 const_iterator NewI = I; 1469 DSAVarData DVar = getDSA(NewI, D); 1470 if (I == NewI && CPred(DVar.CKind)) 1471 return DVar; 1472 } 1473 return {}; 1474 } 1475 1476 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1477 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1478 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1479 bool FromParent) const { 1480 if (isStackEmpty()) 1481 return {}; 1482 D = getCanonicalDecl(D); 1483 const_iterator StartI = begin(); 1484 const_iterator EndI = end(); 1485 if (FromParent && StartI != EndI) 1486 ++StartI; 1487 if (StartI == EndI || !DPred(StartI->Directive)) 1488 return {}; 1489 const_iterator NewI = StartI; 1490 DSAVarData DVar = getDSA(NewI, D); 1491 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1492 } 1493 1494 bool DSAStackTy::hasExplicitDSA( 1495 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1496 unsigned Level, bool NotLastprivate) const { 1497 if (getStackSize() <= Level) 1498 return false; 1499 D = getCanonicalDecl(D); 1500 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1501 auto I = StackElem.SharingMap.find(D); 1502 if (I != StackElem.SharingMap.end() && 1503 I->getSecond().RefExpr.getPointer() && 1504 CPred(I->getSecond().Attributes) && 1505 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1506 return true; 1507 // Check predetermined rules for the loop control variables. 1508 auto LI = StackElem.LCVMap.find(D); 1509 if (LI != StackElem.LCVMap.end()) 1510 return CPred(OMPC_private); 1511 return false; 1512 } 1513 1514 bool DSAStackTy::hasExplicitDirective( 1515 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1516 unsigned Level) const { 1517 if (getStackSize() <= Level) 1518 return false; 1519 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1520 return DPred(StackElem.Directive); 1521 } 1522 1523 bool DSAStackTy::hasDirective( 1524 const llvm::function_ref<bool(OpenMPDirectiveKind, 1525 const DeclarationNameInfo &, SourceLocation)> 1526 DPred, 1527 bool FromParent) const { 1528 // We look only in the enclosing region. 1529 size_t Skip = FromParent ? 2 : 1; 1530 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1531 I != E; ++I) { 1532 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1533 return true; 1534 } 1535 return false; 1536 } 1537 1538 void Sema::InitDataSharingAttributesStack() { 1539 VarDataSharingAttributesStack = new DSAStackTy(*this); 1540 } 1541 1542 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1543 1544 void Sema::pushOpenMPFunctionRegion() { 1545 DSAStack->pushFunction(); 1546 } 1547 1548 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1549 DSAStack->popFunction(OldFSI); 1550 } 1551 1552 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1553 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1554 "Expected OpenMP device compilation."); 1555 return !S.isInOpenMPTargetExecutionDirective() && 1556 !S.isInOpenMPDeclareTargetContext(); 1557 } 1558 1559 namespace { 1560 /// Status of the function emission on the host/device. 1561 enum class FunctionEmissionStatus { 1562 Emitted, 1563 Discarded, 1564 Unknown, 1565 }; 1566 } // anonymous namespace 1567 1568 /// Do we know that we will eventually codegen the given function? 1569 static FunctionEmissionStatus isKnownDeviceEmitted(Sema &S, FunctionDecl *FD) { 1570 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1571 "Expected OpenMP device compilation."); 1572 // Templates are emitted when they're instantiated. 1573 if (FD->isDependentContext()) 1574 return FunctionEmissionStatus::Discarded; 1575 1576 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 1577 OMPDeclareTargetDeclAttr::getDeviceType(FD->getCanonicalDecl()); 1578 if (DevTy.hasValue()) 1579 return (*DevTy == OMPDeclareTargetDeclAttr::DT_Host) 1580 ? FunctionEmissionStatus::Discarded 1581 : FunctionEmissionStatus::Emitted; 1582 1583 // Otherwise, the function is known-emitted if it's in our set of 1584 // known-emitted functions. 1585 return (S.DeviceKnownEmittedFns.count(FD) > 0) 1586 ? FunctionEmissionStatus::Emitted 1587 : FunctionEmissionStatus::Unknown; 1588 } 1589 1590 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1591 unsigned DiagID) { 1592 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1593 "Expected OpenMP device compilation."); 1594 FunctionEmissionStatus FES = 1595 isKnownDeviceEmitted(*this, getCurFunctionDecl()); 1596 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1597 switch (FES) { 1598 case FunctionEmissionStatus::Emitted: 1599 Kind = DeviceDiagBuilder::K_Immediate; 1600 break; 1601 case FunctionEmissionStatus::Unknown: 1602 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1603 : DeviceDiagBuilder::K_Immediate; 1604 break; 1605 case FunctionEmissionStatus::Discarded: 1606 Kind = DeviceDiagBuilder::K_Nop; 1607 break; 1608 } 1609 1610 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1611 } 1612 1613 /// Do we know that we will eventually codegen the given function? 1614 static FunctionEmissionStatus isKnownHostEmitted(Sema &S, FunctionDecl *FD) { 1615 assert(S.LangOpts.OpenMP && !S.LangOpts.OpenMPIsDevice && 1616 "Expected OpenMP host compilation."); 1617 // In OpenMP 4.5 all the functions are host functions. 1618 if (S.LangOpts.OpenMP <= 45) 1619 return FunctionEmissionStatus::Emitted; 1620 1621 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 1622 OMPDeclareTargetDeclAttr::getDeviceType(FD->getCanonicalDecl()); 1623 if (DevTy.hasValue()) 1624 return (*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 1625 ? FunctionEmissionStatus::Discarded 1626 : FunctionEmissionStatus::Emitted; 1627 1628 // Otherwise, the function is known-emitted if it's in our set of 1629 // known-emitted functions. 1630 return (S.DeviceKnownEmittedFns.count(FD) > 0) 1631 ? FunctionEmissionStatus::Emitted 1632 : FunctionEmissionStatus::Unknown; 1633 } 1634 1635 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1636 unsigned DiagID) { 1637 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1638 "Expected OpenMP host compilation."); 1639 FunctionEmissionStatus FES = 1640 isKnownHostEmitted(*this, getCurFunctionDecl()); 1641 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1642 switch (FES) { 1643 case FunctionEmissionStatus::Emitted: 1644 Kind = DeviceDiagBuilder::K_Immediate; 1645 break; 1646 case FunctionEmissionStatus::Unknown: 1647 Kind = DeviceDiagBuilder::K_Deferred; 1648 break; 1649 case FunctionEmissionStatus::Discarded: 1650 Kind = DeviceDiagBuilder::K_Nop; 1651 break; 1652 } 1653 1654 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1655 } 1656 1657 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1658 bool CheckForDelayedContext) { 1659 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1660 "Expected OpenMP device compilation."); 1661 assert(Callee && "Callee may not be null."); 1662 Callee = Callee->getMostRecentDecl(); 1663 FunctionDecl *Caller = getCurFunctionDecl(); 1664 1665 // host only function are not available on the device. 1666 if (Caller && 1667 (isKnownDeviceEmitted(*this, Caller) == FunctionEmissionStatus::Emitted || 1668 (!isOpenMPDeviceDelayedContext(*this) && 1669 isKnownDeviceEmitted(*this, Caller) == 1670 FunctionEmissionStatus::Unknown)) && 1671 isKnownDeviceEmitted(*this, Callee) == 1672 FunctionEmissionStatus::Discarded) { 1673 StringRef HostDevTy = 1674 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 1675 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1676 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1677 diag::note_omp_marked_device_type_here) 1678 << HostDevTy; 1679 return; 1680 } 1681 // If the caller is known-emitted, mark the callee as known-emitted. 1682 // Otherwise, mark the call in our call graph so we can traverse it later. 1683 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1684 (!Caller && !CheckForDelayedContext) || 1685 (Caller && 1686 isKnownDeviceEmitted(*this, Caller) == FunctionEmissionStatus::Emitted)) 1687 markKnownEmitted(*this, Caller, Callee, Loc, 1688 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1689 return CheckForDelayedContext && 1690 isKnownDeviceEmitted(S, FD) == 1691 FunctionEmissionStatus::Emitted; 1692 }); 1693 else if (Caller) 1694 DeviceCallGraph[Caller].insert({Callee, Loc}); 1695 } 1696 1697 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1698 bool CheckCaller) { 1699 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1700 "Expected OpenMP host compilation."); 1701 assert(Callee && "Callee may not be null."); 1702 Callee = Callee->getMostRecentDecl(); 1703 FunctionDecl *Caller = getCurFunctionDecl(); 1704 1705 // device only function are not available on the host. 1706 if (Caller && 1707 isKnownHostEmitted(*this, Caller) == FunctionEmissionStatus::Emitted && 1708 isKnownHostEmitted(*this, Callee) == FunctionEmissionStatus::Discarded) { 1709 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1710 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1711 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1712 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1713 diag::note_omp_marked_device_type_here) 1714 << NoHostDevTy; 1715 return; 1716 } 1717 // If the caller is known-emitted, mark the callee as known-emitted. 1718 // Otherwise, mark the call in our call graph so we can traverse it later. 1719 if ((!CheckCaller && !Caller) || 1720 (Caller && 1721 isKnownHostEmitted(*this, Caller) == FunctionEmissionStatus::Emitted)) 1722 markKnownEmitted( 1723 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1724 return CheckCaller && 1725 isKnownHostEmitted(S, FD) == FunctionEmissionStatus::Emitted; 1726 }); 1727 else if (Caller) 1728 DeviceCallGraph[Caller].insert({Callee, Loc}); 1729 } 1730 1731 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1732 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1733 "OpenMP device compilation mode is expected."); 1734 QualType Ty = E->getType(); 1735 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1736 ((Ty->isFloat128Type() || 1737 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1738 !Context.getTargetInfo().hasFloat128Type()) || 1739 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1740 !Context.getTargetInfo().hasInt128Type())) 1741 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1742 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1743 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1744 } 1745 1746 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1747 unsigned OpenMPCaptureLevel) const { 1748 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1749 1750 ASTContext &Ctx = getASTContext(); 1751 bool IsByRef = true; 1752 1753 // Find the directive that is associated with the provided scope. 1754 D = cast<ValueDecl>(D->getCanonicalDecl()); 1755 QualType Ty = D->getType(); 1756 1757 bool IsVariableUsedInMapClause = false; 1758 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1759 // This table summarizes how a given variable should be passed to the device 1760 // given its type and the clauses where it appears. This table is based on 1761 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1762 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1763 // 1764 // ========================================================================= 1765 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1766 // | |(tofrom:scalar)| | pvt | | | | 1767 // ========================================================================= 1768 // | scl | | | | - | | bycopy| 1769 // | scl | | - | x | - | - | bycopy| 1770 // | scl | | x | - | - | - | null | 1771 // | scl | x | | | - | | byref | 1772 // | scl | x | - | x | - | - | bycopy| 1773 // | scl | x | x | - | - | - | null | 1774 // | scl | | - | - | - | x | byref | 1775 // | scl | x | - | - | - | x | byref | 1776 // 1777 // | agg | n.a. | | | - | | byref | 1778 // | agg | n.a. | - | x | - | - | byref | 1779 // | agg | n.a. | x | - | - | - | null | 1780 // | agg | n.a. | - | - | - | x | byref | 1781 // | agg | n.a. | - | - | - | x[] | byref | 1782 // 1783 // | ptr | n.a. | | | - | | bycopy| 1784 // | ptr | n.a. | - | x | - | - | bycopy| 1785 // | ptr | n.a. | x | - | - | - | null | 1786 // | ptr | n.a. | - | - | - | x | byref | 1787 // | ptr | n.a. | - | - | - | x[] | bycopy| 1788 // | ptr | n.a. | - | - | x | | bycopy| 1789 // | ptr | n.a. | - | - | x | x | bycopy| 1790 // | ptr | n.a. | - | - | x | x[] | bycopy| 1791 // ========================================================================= 1792 // Legend: 1793 // scl - scalar 1794 // ptr - pointer 1795 // agg - aggregate 1796 // x - applies 1797 // - - invalid in this combination 1798 // [] - mapped with an array section 1799 // byref - should be mapped by reference 1800 // byval - should be mapped by value 1801 // null - initialize a local variable to null on the device 1802 // 1803 // Observations: 1804 // - All scalar declarations that show up in a map clause have to be passed 1805 // by reference, because they may have been mapped in the enclosing data 1806 // environment. 1807 // - If the scalar value does not fit the size of uintptr, it has to be 1808 // passed by reference, regardless the result in the table above. 1809 // - For pointers mapped by value that have either an implicit map or an 1810 // array section, the runtime library may pass the NULL value to the 1811 // device instead of the value passed to it by the compiler. 1812 1813 if (Ty->isReferenceType()) 1814 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1815 1816 // Locate map clauses and see if the variable being captured is referred to 1817 // in any of those clauses. Here we only care about variables, not fields, 1818 // because fields are part of aggregates. 1819 bool IsVariableAssociatedWithSection = false; 1820 1821 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1822 D, Level, 1823 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1824 OMPClauseMappableExprCommon::MappableExprComponentListRef 1825 MapExprComponents, 1826 OpenMPClauseKind WhereFoundClauseKind) { 1827 // Only the map clause information influences how a variable is 1828 // captured. E.g. is_device_ptr does not require changing the default 1829 // behavior. 1830 if (WhereFoundClauseKind != OMPC_map) 1831 return false; 1832 1833 auto EI = MapExprComponents.rbegin(); 1834 auto EE = MapExprComponents.rend(); 1835 1836 assert(EI != EE && "Invalid map expression!"); 1837 1838 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1839 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1840 1841 ++EI; 1842 if (EI == EE) 1843 return false; 1844 1845 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1846 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1847 isa<MemberExpr>(EI->getAssociatedExpression())) { 1848 IsVariableAssociatedWithSection = true; 1849 // There is nothing more we need to know about this variable. 1850 return true; 1851 } 1852 1853 // Keep looking for more map info. 1854 return false; 1855 }); 1856 1857 if (IsVariableUsedInMapClause) { 1858 // If variable is identified in a map clause it is always captured by 1859 // reference except if it is a pointer that is dereferenced somehow. 1860 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1861 } else { 1862 // By default, all the data that has a scalar type is mapped by copy 1863 // (except for reduction variables). 1864 IsByRef = 1865 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1866 !Ty->isAnyPointerType()) || 1867 !Ty->isScalarType() || 1868 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1869 DSAStack->hasExplicitDSA( 1870 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1871 } 1872 } 1873 1874 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1875 IsByRef = 1876 ((IsVariableUsedInMapClause && 1877 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1878 OMPD_target) || 1879 !DSAStack->hasExplicitDSA( 1880 D, 1881 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1882 Level, /*NotLastprivate=*/true)) && 1883 // If the variable is artificial and must be captured by value - try to 1884 // capture by value. 1885 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1886 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1887 } 1888 1889 // When passing data by copy, we need to make sure it fits the uintptr size 1890 // and alignment, because the runtime library only deals with uintptr types. 1891 // If it does not fit the uintptr size, we need to pass the data by reference 1892 // instead. 1893 if (!IsByRef && 1894 (Ctx.getTypeSizeInChars(Ty) > 1895 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1896 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1897 IsByRef = true; 1898 } 1899 1900 return IsByRef; 1901 } 1902 1903 unsigned Sema::getOpenMPNestingLevel() const { 1904 assert(getLangOpts().OpenMP); 1905 return DSAStack->getNestingLevel(); 1906 } 1907 1908 bool Sema::isInOpenMPTargetExecutionDirective() const { 1909 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1910 !DSAStack->isClauseParsingMode()) || 1911 DSAStack->hasDirective( 1912 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1913 SourceLocation) -> bool { 1914 return isOpenMPTargetExecutionDirective(K); 1915 }, 1916 false); 1917 } 1918 1919 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1920 unsigned StopAt) { 1921 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1922 D = getCanonicalDecl(D); 1923 1924 // If we want to determine whether the variable should be captured from the 1925 // perspective of the current capturing scope, and we've already left all the 1926 // capturing scopes of the top directive on the stack, check from the 1927 // perspective of its parent directive (if any) instead. 1928 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1929 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1930 1931 // If we are attempting to capture a global variable in a directive with 1932 // 'target' we return true so that this global is also mapped to the device. 1933 // 1934 auto *VD = dyn_cast<VarDecl>(D); 1935 if (VD && !VD->hasLocalStorage() && 1936 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1937 if (isInOpenMPDeclareTargetContext()) { 1938 // Try to mark variable as declare target if it is used in capturing 1939 // regions. 1940 if (LangOpts.OpenMP <= 45 && 1941 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1942 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1943 return nullptr; 1944 } else if (isInOpenMPTargetExecutionDirective()) { 1945 // If the declaration is enclosed in a 'declare target' directive, 1946 // then it should not be captured. 1947 // 1948 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1949 return nullptr; 1950 return VD; 1951 } 1952 } 1953 1954 if (CheckScopeInfo) { 1955 bool OpenMPFound = false; 1956 for (unsigned I = StopAt + 1; I > 0; --I) { 1957 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1958 if(!isa<CapturingScopeInfo>(FSI)) 1959 return nullptr; 1960 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1961 if (RSI->CapRegionKind == CR_OpenMP) { 1962 OpenMPFound = true; 1963 break; 1964 } 1965 } 1966 if (!OpenMPFound) 1967 return nullptr; 1968 } 1969 1970 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1971 (!DSAStack->isClauseParsingMode() || 1972 DSAStack->getParentDirective() != OMPD_unknown)) { 1973 auto &&Info = DSAStack->isLoopControlVariable(D); 1974 if (Info.first || 1975 (VD && VD->hasLocalStorage() && 1976 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1977 (VD && DSAStack->isForceVarCapturing())) 1978 return VD ? VD : Info.second; 1979 DSAStackTy::DSAVarData DVarPrivate = 1980 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1981 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1982 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1983 // Threadprivate variables must not be captured. 1984 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1985 return nullptr; 1986 // The variable is not private or it is the variable in the directive with 1987 // default(none) clause and not used in any clause. 1988 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1989 [](OpenMPDirectiveKind) { return true; }, 1990 DSAStack->isClauseParsingMode()); 1991 if (DVarPrivate.CKind != OMPC_unknown || 1992 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1993 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1994 } 1995 return nullptr; 1996 } 1997 1998 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1999 unsigned Level) const { 2000 SmallVector<OpenMPDirectiveKind, 4> Regions; 2001 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2002 FunctionScopesIndex -= Regions.size(); 2003 } 2004 2005 void Sema::startOpenMPLoop() { 2006 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2007 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2008 DSAStack->loopInit(); 2009 } 2010 2011 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2012 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2013 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2014 if (DSAStack->getAssociatedLoops() > 0 && 2015 !DSAStack->isLoopStarted()) { 2016 DSAStack->resetPossibleLoopCounter(D); 2017 DSAStack->loopStart(); 2018 return true; 2019 } 2020 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2021 DSAStack->isLoopControlVariable(D).first) && 2022 !DSAStack->hasExplicitDSA( 2023 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2024 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2025 return true; 2026 } 2027 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2028 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2029 DSAStack->isForceVarCapturing() && 2030 !DSAStack->hasExplicitDSA( 2031 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2032 return true; 2033 } 2034 return DSAStack->hasExplicitDSA( 2035 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2036 (DSAStack->isClauseParsingMode() && 2037 DSAStack->getClauseParsingMode() == OMPC_private) || 2038 // Consider taskgroup reduction descriptor variable a private to avoid 2039 // possible capture in the region. 2040 (DSAStack->hasExplicitDirective( 2041 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2042 Level) && 2043 DSAStack->isTaskgroupReductionRef(D, Level)); 2044 } 2045 2046 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2047 unsigned Level) { 2048 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2049 D = getCanonicalDecl(D); 2050 OpenMPClauseKind OMPC = OMPC_unknown; 2051 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2052 const unsigned NewLevel = I - 1; 2053 if (DSAStack->hasExplicitDSA(D, 2054 [&OMPC](const OpenMPClauseKind K) { 2055 if (isOpenMPPrivate(K)) { 2056 OMPC = K; 2057 return true; 2058 } 2059 return false; 2060 }, 2061 NewLevel)) 2062 break; 2063 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2064 D, NewLevel, 2065 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2066 OpenMPClauseKind) { return true; })) { 2067 OMPC = OMPC_map; 2068 break; 2069 } 2070 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2071 NewLevel)) { 2072 OMPC = OMPC_map; 2073 if (D->getType()->isScalarType() && 2074 DSAStack->getDefaultDMAAtLevel(NewLevel) != 2075 DefaultMapAttributes::DMA_tofrom_scalar) 2076 OMPC = OMPC_firstprivate; 2077 break; 2078 } 2079 } 2080 if (OMPC != OMPC_unknown) 2081 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2082 } 2083 2084 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2085 unsigned Level) const { 2086 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2087 // Return true if the current level is no longer enclosed in a target region. 2088 2089 const auto *VD = dyn_cast<VarDecl>(D); 2090 return VD && !VD->hasLocalStorage() && 2091 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2092 Level); 2093 } 2094 2095 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2096 2097 void Sema::finalizeOpenMPDelayedAnalysis() { 2098 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2099 // Diagnose implicit declare target functions and their callees. 2100 for (const auto &CallerCallees : DeviceCallGraph) { 2101 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2102 OMPDeclareTargetDeclAttr::getDeviceType( 2103 CallerCallees.getFirst()->getMostRecentDecl()); 2104 // Ignore host functions during device analyzis. 2105 if (LangOpts.OpenMPIsDevice && DevTy && 2106 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2107 continue; 2108 // Ignore nohost functions during host analyzis. 2109 if (!LangOpts.OpenMPIsDevice && DevTy && 2110 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2111 continue; 2112 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2113 &Callee : CallerCallees.getSecond()) { 2114 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2115 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2116 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2117 if (LangOpts.OpenMPIsDevice && DevTy && 2118 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2119 // Diagnose host function called during device codegen. 2120 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2121 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2122 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2123 << HostDevTy << 0; 2124 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2125 diag::note_omp_marked_device_type_here) 2126 << HostDevTy; 2127 continue; 2128 } 2129 if (!LangOpts.OpenMPIsDevice && DevTy && 2130 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2131 // Diagnose nohost function called during host codegen. 2132 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2133 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2134 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2135 << NoHostDevTy << 1; 2136 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2137 diag::note_omp_marked_device_type_here) 2138 << NoHostDevTy; 2139 continue; 2140 } 2141 } 2142 } 2143 } 2144 2145 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2146 const DeclarationNameInfo &DirName, 2147 Scope *CurScope, SourceLocation Loc) { 2148 DSAStack->push(DKind, DirName, CurScope, Loc); 2149 PushExpressionEvaluationContext( 2150 ExpressionEvaluationContext::PotentiallyEvaluated); 2151 } 2152 2153 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2154 DSAStack->setClauseParsingMode(K); 2155 } 2156 2157 void Sema::EndOpenMPClause() { 2158 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2159 } 2160 2161 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2162 ArrayRef<OMPClause *> Clauses); 2163 2164 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2165 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2166 // A variable of class type (or array thereof) that appears in a lastprivate 2167 // clause requires an accessible, unambiguous default constructor for the 2168 // class type, unless the list item is also specified in a firstprivate 2169 // clause. 2170 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2171 for (OMPClause *C : D->clauses()) { 2172 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2173 SmallVector<Expr *, 8> PrivateCopies; 2174 for (Expr *DE : Clause->varlists()) { 2175 if (DE->isValueDependent() || DE->isTypeDependent()) { 2176 PrivateCopies.push_back(nullptr); 2177 continue; 2178 } 2179 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2180 auto *VD = cast<VarDecl>(DRE->getDecl()); 2181 QualType Type = VD->getType().getNonReferenceType(); 2182 const DSAStackTy::DSAVarData DVar = 2183 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2184 if (DVar.CKind == OMPC_lastprivate) { 2185 // Generate helper private variable and initialize it with the 2186 // default value. The address of the original variable is replaced 2187 // by the address of the new private variable in CodeGen. This new 2188 // variable is not added to IdResolver, so the code in the OpenMP 2189 // region uses original variable for proper diagnostics. 2190 VarDecl *VDPrivate = buildVarDecl( 2191 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2192 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2193 ActOnUninitializedDecl(VDPrivate); 2194 if (VDPrivate->isInvalidDecl()) { 2195 PrivateCopies.push_back(nullptr); 2196 continue; 2197 } 2198 PrivateCopies.push_back(buildDeclRefExpr( 2199 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2200 } else { 2201 // The variable is also a firstprivate, so initialization sequence 2202 // for private copy is generated already. 2203 PrivateCopies.push_back(nullptr); 2204 } 2205 } 2206 Clause->setPrivateCopies(PrivateCopies); 2207 } 2208 } 2209 // Check allocate clauses. 2210 if (!CurContext->isDependentContext()) 2211 checkAllocateClauses(*this, DSAStack, D->clauses()); 2212 } 2213 2214 DSAStack->pop(); 2215 DiscardCleanupsInEvaluationContext(); 2216 PopExpressionEvaluationContext(); 2217 } 2218 2219 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2220 Expr *NumIterations, Sema &SemaRef, 2221 Scope *S, DSAStackTy *Stack); 2222 2223 namespace { 2224 2225 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2226 private: 2227 Sema &SemaRef; 2228 2229 public: 2230 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2231 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2232 NamedDecl *ND = Candidate.getCorrectionDecl(); 2233 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2234 return VD->hasGlobalStorage() && 2235 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2236 SemaRef.getCurScope()); 2237 } 2238 return false; 2239 } 2240 2241 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2242 return std::make_unique<VarDeclFilterCCC>(*this); 2243 } 2244 2245 }; 2246 2247 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2248 private: 2249 Sema &SemaRef; 2250 2251 public: 2252 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2253 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2254 NamedDecl *ND = Candidate.getCorrectionDecl(); 2255 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2256 isa<FunctionDecl>(ND))) { 2257 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2258 SemaRef.getCurScope()); 2259 } 2260 return false; 2261 } 2262 2263 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2264 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2265 } 2266 }; 2267 2268 } // namespace 2269 2270 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2271 CXXScopeSpec &ScopeSpec, 2272 const DeclarationNameInfo &Id, 2273 OpenMPDirectiveKind Kind) { 2274 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2275 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2276 2277 if (Lookup.isAmbiguous()) 2278 return ExprError(); 2279 2280 VarDecl *VD; 2281 if (!Lookup.isSingleResult()) { 2282 VarDeclFilterCCC CCC(*this); 2283 if (TypoCorrection Corrected = 2284 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2285 CTK_ErrorRecovery)) { 2286 diagnoseTypo(Corrected, 2287 PDiag(Lookup.empty() 2288 ? diag::err_undeclared_var_use_suggest 2289 : diag::err_omp_expected_var_arg_suggest) 2290 << Id.getName()); 2291 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2292 } else { 2293 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2294 : diag::err_omp_expected_var_arg) 2295 << Id.getName(); 2296 return ExprError(); 2297 } 2298 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2299 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2300 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2301 return ExprError(); 2302 } 2303 Lookup.suppressDiagnostics(); 2304 2305 // OpenMP [2.9.2, Syntax, C/C++] 2306 // Variables must be file-scope, namespace-scope, or static block-scope. 2307 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2308 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2309 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2310 bool IsDecl = 2311 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2312 Diag(VD->getLocation(), 2313 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2314 << VD; 2315 return ExprError(); 2316 } 2317 2318 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2319 NamedDecl *ND = CanonicalVD; 2320 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2321 // A threadprivate directive for file-scope variables must appear outside 2322 // any definition or declaration. 2323 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2324 !getCurLexicalContext()->isTranslationUnit()) { 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.3] 2335 // A threadprivate directive for static class member variables must appear 2336 // in the class definition, in the same scope in which the member 2337 // variables are declared. 2338 if (CanonicalVD->isStaticDataMember() && 2339 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2340 Diag(Id.getLoc(), diag::err_omp_var_scope) 2341 << getOpenMPDirectiveName(Kind) << VD; 2342 bool IsDecl = 2343 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2344 Diag(VD->getLocation(), 2345 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2346 << VD; 2347 return ExprError(); 2348 } 2349 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2350 // A threadprivate directive for namespace-scope variables must appear 2351 // outside any definition or declaration other than the namespace 2352 // definition itself. 2353 if (CanonicalVD->getDeclContext()->isNamespace() && 2354 (!getCurLexicalContext()->isFileContext() || 2355 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2356 Diag(Id.getLoc(), diag::err_omp_var_scope) 2357 << getOpenMPDirectiveName(Kind) << VD; 2358 bool IsDecl = 2359 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2360 Diag(VD->getLocation(), 2361 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2362 << VD; 2363 return ExprError(); 2364 } 2365 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2366 // A threadprivate directive for static block-scope variables must appear 2367 // in the scope of the variable and not in a nested scope. 2368 if (CanonicalVD->isLocalVarDecl() && CurScope && 2369 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2370 Diag(Id.getLoc(), diag::err_omp_var_scope) 2371 << getOpenMPDirectiveName(Kind) << VD; 2372 bool IsDecl = 2373 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2374 Diag(VD->getLocation(), 2375 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2376 << VD; 2377 return ExprError(); 2378 } 2379 2380 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2381 // A threadprivate directive must lexically precede all references to any 2382 // of the variables in its list. 2383 if (Kind == OMPD_threadprivate && VD->isUsed() && 2384 !DSAStack->isThreadPrivate(VD)) { 2385 Diag(Id.getLoc(), diag::err_omp_var_used) 2386 << getOpenMPDirectiveName(Kind) << VD; 2387 return ExprError(); 2388 } 2389 2390 QualType ExprType = VD->getType().getNonReferenceType(); 2391 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2392 SourceLocation(), VD, 2393 /*RefersToEnclosingVariableOrCapture=*/false, 2394 Id.getLoc(), ExprType, VK_LValue); 2395 } 2396 2397 Sema::DeclGroupPtrTy 2398 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2399 ArrayRef<Expr *> VarList) { 2400 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2401 CurContext->addDecl(D); 2402 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2403 } 2404 return nullptr; 2405 } 2406 2407 namespace { 2408 class LocalVarRefChecker final 2409 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2410 Sema &SemaRef; 2411 2412 public: 2413 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2414 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2415 if (VD->hasLocalStorage()) { 2416 SemaRef.Diag(E->getBeginLoc(), 2417 diag::err_omp_local_var_in_threadprivate_init) 2418 << E->getSourceRange(); 2419 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2420 << VD << VD->getSourceRange(); 2421 return true; 2422 } 2423 } 2424 return false; 2425 } 2426 bool VisitStmt(const Stmt *S) { 2427 for (const Stmt *Child : S->children()) { 2428 if (Child && Visit(Child)) 2429 return true; 2430 } 2431 return false; 2432 } 2433 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2434 }; 2435 } // namespace 2436 2437 OMPThreadPrivateDecl * 2438 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2439 SmallVector<Expr *, 8> Vars; 2440 for (Expr *RefExpr : VarList) { 2441 auto *DE = cast<DeclRefExpr>(RefExpr); 2442 auto *VD = cast<VarDecl>(DE->getDecl()); 2443 SourceLocation ILoc = DE->getExprLoc(); 2444 2445 // Mark variable as used. 2446 VD->setReferenced(); 2447 VD->markUsed(Context); 2448 2449 QualType QType = VD->getType(); 2450 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2451 // It will be analyzed later. 2452 Vars.push_back(DE); 2453 continue; 2454 } 2455 2456 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2457 // A threadprivate variable must not have an incomplete type. 2458 if (RequireCompleteType(ILoc, VD->getType(), 2459 diag::err_omp_threadprivate_incomplete_type)) { 2460 continue; 2461 } 2462 2463 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2464 // A threadprivate variable must not have a reference type. 2465 if (VD->getType()->isReferenceType()) { 2466 Diag(ILoc, diag::err_omp_ref_type_arg) 2467 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2468 bool IsDecl = 2469 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2470 Diag(VD->getLocation(), 2471 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2472 << VD; 2473 continue; 2474 } 2475 2476 // Check if this is a TLS variable. If TLS is not being supported, produce 2477 // the corresponding diagnostic. 2478 if ((VD->getTLSKind() != VarDecl::TLS_None && 2479 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2480 getLangOpts().OpenMPUseTLS && 2481 getASTContext().getTargetInfo().isTLSSupported())) || 2482 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2483 !VD->isLocalVarDecl())) { 2484 Diag(ILoc, diag::err_omp_var_thread_local) 2485 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2486 bool IsDecl = 2487 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2488 Diag(VD->getLocation(), 2489 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2490 << VD; 2491 continue; 2492 } 2493 2494 // Check if initial value of threadprivate variable reference variable with 2495 // local storage (it is not supported by runtime). 2496 if (const Expr *Init = VD->getAnyInitializer()) { 2497 LocalVarRefChecker Checker(*this); 2498 if (Checker.Visit(Init)) 2499 continue; 2500 } 2501 2502 Vars.push_back(RefExpr); 2503 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2504 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2505 Context, SourceRange(Loc, Loc))); 2506 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2507 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2508 } 2509 OMPThreadPrivateDecl *D = nullptr; 2510 if (!Vars.empty()) { 2511 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2512 Vars); 2513 D->setAccess(AS_public); 2514 } 2515 return D; 2516 } 2517 2518 static OMPAllocateDeclAttr::AllocatorTypeTy 2519 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2520 if (!Allocator) 2521 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2522 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2523 Allocator->isInstantiationDependent() || 2524 Allocator->containsUnexpandedParameterPack()) 2525 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2526 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2527 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2528 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2529 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2530 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2531 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2532 llvm::FoldingSetNodeID AEId, DAEId; 2533 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2534 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2535 if (AEId == DAEId) { 2536 AllocatorKindRes = AllocatorKind; 2537 break; 2538 } 2539 } 2540 return AllocatorKindRes; 2541 } 2542 2543 static bool checkPreviousOMPAllocateAttribute( 2544 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2545 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2546 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2547 return false; 2548 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2549 Expr *PrevAllocator = A->getAllocator(); 2550 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2551 getAllocatorKind(S, Stack, PrevAllocator); 2552 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2553 if (AllocatorsMatch && 2554 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2555 Allocator && PrevAllocator) { 2556 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2557 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2558 llvm::FoldingSetNodeID AEId, PAEId; 2559 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2560 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2561 AllocatorsMatch = AEId == PAEId; 2562 } 2563 if (!AllocatorsMatch) { 2564 SmallString<256> AllocatorBuffer; 2565 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2566 if (Allocator) 2567 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2568 SmallString<256> PrevAllocatorBuffer; 2569 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2570 if (PrevAllocator) 2571 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2572 S.getPrintingPolicy()); 2573 2574 SourceLocation AllocatorLoc = 2575 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2576 SourceRange AllocatorRange = 2577 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2578 SourceLocation PrevAllocatorLoc = 2579 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2580 SourceRange PrevAllocatorRange = 2581 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2582 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2583 << (Allocator ? 1 : 0) << AllocatorStream.str() 2584 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2585 << AllocatorRange; 2586 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2587 << PrevAllocatorRange; 2588 return true; 2589 } 2590 return false; 2591 } 2592 2593 static void 2594 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2595 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2596 Expr *Allocator, SourceRange SR) { 2597 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2598 return; 2599 if (Allocator && 2600 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2601 Allocator->isInstantiationDependent() || 2602 Allocator->containsUnexpandedParameterPack())) 2603 return; 2604 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2605 Allocator, SR); 2606 VD->addAttr(A); 2607 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2608 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2609 } 2610 2611 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2612 SourceLocation Loc, ArrayRef<Expr *> VarList, 2613 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2614 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2615 Expr *Allocator = nullptr; 2616 if (Clauses.empty()) { 2617 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2618 // allocate directives that appear in a target region must specify an 2619 // allocator clause unless a requires directive with the dynamic_allocators 2620 // clause is present in the same compilation unit. 2621 if (LangOpts.OpenMPIsDevice && 2622 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2623 targetDiag(Loc, diag::err_expected_allocator_clause); 2624 } else { 2625 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2626 } 2627 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2628 getAllocatorKind(*this, DSAStack, Allocator); 2629 SmallVector<Expr *, 8> Vars; 2630 for (Expr *RefExpr : VarList) { 2631 auto *DE = cast<DeclRefExpr>(RefExpr); 2632 auto *VD = cast<VarDecl>(DE->getDecl()); 2633 2634 // Check if this is a TLS variable or global register. 2635 if (VD->getTLSKind() != VarDecl::TLS_None || 2636 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2637 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2638 !VD->isLocalVarDecl())) 2639 continue; 2640 2641 // If the used several times in the allocate directive, the same allocator 2642 // must be used. 2643 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2644 AllocatorKind, Allocator)) 2645 continue; 2646 2647 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2648 // If a list item has a static storage type, the allocator expression in the 2649 // allocator clause must be a constant expression that evaluates to one of 2650 // the predefined memory allocator values. 2651 if (Allocator && VD->hasGlobalStorage()) { 2652 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2653 Diag(Allocator->getExprLoc(), 2654 diag::err_omp_expected_predefined_allocator) 2655 << Allocator->getSourceRange(); 2656 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2657 VarDecl::DeclarationOnly; 2658 Diag(VD->getLocation(), 2659 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2660 << VD; 2661 continue; 2662 } 2663 } 2664 2665 Vars.push_back(RefExpr); 2666 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2667 DE->getSourceRange()); 2668 } 2669 if (Vars.empty()) 2670 return nullptr; 2671 if (!Owner) 2672 Owner = getCurLexicalContext(); 2673 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2674 D->setAccess(AS_public); 2675 Owner->addDecl(D); 2676 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2677 } 2678 2679 Sema::DeclGroupPtrTy 2680 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2681 ArrayRef<OMPClause *> ClauseList) { 2682 OMPRequiresDecl *D = nullptr; 2683 if (!CurContext->isFileContext()) { 2684 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2685 } else { 2686 D = CheckOMPRequiresDecl(Loc, ClauseList); 2687 if (D) { 2688 CurContext->addDecl(D); 2689 DSAStack->addRequiresDecl(D); 2690 } 2691 } 2692 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2693 } 2694 2695 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2696 ArrayRef<OMPClause *> ClauseList) { 2697 /// For target specific clauses, the requires directive cannot be 2698 /// specified after the handling of any of the target regions in the 2699 /// current compilation unit. 2700 ArrayRef<SourceLocation> TargetLocations = 2701 DSAStack->getEncounteredTargetLocs(); 2702 if (!TargetLocations.empty()) { 2703 for (const OMPClause *CNew : ClauseList) { 2704 // Check if any of the requires clauses affect target regions. 2705 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2706 isa<OMPUnifiedAddressClause>(CNew) || 2707 isa<OMPReverseOffloadClause>(CNew) || 2708 isa<OMPDynamicAllocatorsClause>(CNew)) { 2709 Diag(Loc, diag::err_omp_target_before_requires) 2710 << getOpenMPClauseName(CNew->getClauseKind()); 2711 for (SourceLocation TargetLoc : TargetLocations) { 2712 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2713 } 2714 } 2715 } 2716 } 2717 2718 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2719 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2720 ClauseList); 2721 return nullptr; 2722 } 2723 2724 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2725 const ValueDecl *D, 2726 const DSAStackTy::DSAVarData &DVar, 2727 bool IsLoopIterVar = false) { 2728 if (DVar.RefExpr) { 2729 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2730 << getOpenMPClauseName(DVar.CKind); 2731 return; 2732 } 2733 enum { 2734 PDSA_StaticMemberShared, 2735 PDSA_StaticLocalVarShared, 2736 PDSA_LoopIterVarPrivate, 2737 PDSA_LoopIterVarLinear, 2738 PDSA_LoopIterVarLastprivate, 2739 PDSA_ConstVarShared, 2740 PDSA_GlobalVarShared, 2741 PDSA_TaskVarFirstprivate, 2742 PDSA_LocalVarPrivate, 2743 PDSA_Implicit 2744 } Reason = PDSA_Implicit; 2745 bool ReportHint = false; 2746 auto ReportLoc = D->getLocation(); 2747 auto *VD = dyn_cast<VarDecl>(D); 2748 if (IsLoopIterVar) { 2749 if (DVar.CKind == OMPC_private) 2750 Reason = PDSA_LoopIterVarPrivate; 2751 else if (DVar.CKind == OMPC_lastprivate) 2752 Reason = PDSA_LoopIterVarLastprivate; 2753 else 2754 Reason = PDSA_LoopIterVarLinear; 2755 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2756 DVar.CKind == OMPC_firstprivate) { 2757 Reason = PDSA_TaskVarFirstprivate; 2758 ReportLoc = DVar.ImplicitDSALoc; 2759 } else if (VD && VD->isStaticLocal()) 2760 Reason = PDSA_StaticLocalVarShared; 2761 else if (VD && VD->isStaticDataMember()) 2762 Reason = PDSA_StaticMemberShared; 2763 else if (VD && VD->isFileVarDecl()) 2764 Reason = PDSA_GlobalVarShared; 2765 else if (D->getType().isConstant(SemaRef.getASTContext())) 2766 Reason = PDSA_ConstVarShared; 2767 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2768 ReportHint = true; 2769 Reason = PDSA_LocalVarPrivate; 2770 } 2771 if (Reason != PDSA_Implicit) { 2772 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2773 << Reason << ReportHint 2774 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2775 } else if (DVar.ImplicitDSALoc.isValid()) { 2776 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2777 << getOpenMPClauseName(DVar.CKind); 2778 } 2779 } 2780 2781 namespace { 2782 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2783 DSAStackTy *Stack; 2784 Sema &SemaRef; 2785 bool ErrorFound = false; 2786 CapturedStmt *CS = nullptr; 2787 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2788 llvm::SmallVector<Expr *, 4> ImplicitMap; 2789 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2790 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2791 2792 void VisitSubCaptures(OMPExecutableDirective *S) { 2793 // Check implicitly captured variables. 2794 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2795 return; 2796 visitSubCaptures(S->getInnermostCapturedStmt()); 2797 } 2798 2799 public: 2800 void VisitDeclRefExpr(DeclRefExpr *E) { 2801 if (E->isTypeDependent() || E->isValueDependent() || 2802 E->containsUnexpandedParameterPack() || 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 { 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 QualType KmpInt32Ty = 3262 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3263 .withConst(); 3264 QualType KmpUInt64Ty = 3265 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3266 .withConst(); 3267 QualType KmpInt64Ty = 3268 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3269 .withConst(); 3270 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3271 QualType KmpInt32PtrTy = 3272 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3273 QualType Args[] = {VoidPtrTy}; 3274 FunctionProtoType::ExtProtoInfo EPI; 3275 EPI.Variadic = true; 3276 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3277 Sema::CapturedParamNameType Params[] = { 3278 std::make_pair(".global_tid.", KmpInt32Ty), 3279 std::make_pair(".part_id.", KmpInt32PtrTy), 3280 std::make_pair(".privates.", VoidPtrTy), 3281 std::make_pair( 3282 ".copy_fn.", 3283 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3284 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3285 std::make_pair(".lb.", KmpUInt64Ty), 3286 std::make_pair(".ub.", KmpUInt64Ty), 3287 std::make_pair(".st.", KmpInt64Ty), 3288 std::make_pair(".liter.", KmpInt32Ty), 3289 std::make_pair(".reductions.", VoidPtrTy), 3290 std::make_pair(StringRef(), QualType()) // __context with shared vars 3291 }; 3292 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3293 Params); 3294 // Mark this captured region as inlined, because we don't use outlined 3295 // function directly. 3296 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3297 AlwaysInlineAttr::CreateImplicit( 3298 Context, {}, AttributeCommonInfo::AS_Keyword, 3299 AlwaysInlineAttr::Keyword_forceinline)); 3300 break; 3301 } 3302 case OMPD_distribute_parallel_for_simd: 3303 case OMPD_distribute_parallel_for: { 3304 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3305 QualType KmpInt32PtrTy = 3306 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3307 Sema::CapturedParamNameType Params[] = { 3308 std::make_pair(".global_tid.", KmpInt32PtrTy), 3309 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3310 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3311 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3312 std::make_pair(StringRef(), QualType()) // __context with shared vars 3313 }; 3314 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3315 Params); 3316 break; 3317 } 3318 case OMPD_target_teams_distribute_parallel_for: 3319 case OMPD_target_teams_distribute_parallel_for_simd: { 3320 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3321 QualType KmpInt32PtrTy = 3322 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3323 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3324 3325 QualType Args[] = {VoidPtrTy}; 3326 FunctionProtoType::ExtProtoInfo EPI; 3327 EPI.Variadic = true; 3328 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3329 Sema::CapturedParamNameType Params[] = { 3330 std::make_pair(".global_tid.", KmpInt32Ty), 3331 std::make_pair(".part_id.", KmpInt32PtrTy), 3332 std::make_pair(".privates.", VoidPtrTy), 3333 std::make_pair( 3334 ".copy_fn.", 3335 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3336 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3337 std::make_pair(StringRef(), QualType()) // __context with shared vars 3338 }; 3339 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3340 Params, /*OpenMPCaptureLevel=*/0); 3341 // Mark this captured region as inlined, because we don't use outlined 3342 // function directly. 3343 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3344 AlwaysInlineAttr::CreateImplicit( 3345 Context, {}, AttributeCommonInfo::AS_Keyword, 3346 AlwaysInlineAttr::Keyword_forceinline)); 3347 Sema::CapturedParamNameType ParamsTarget[] = { 3348 std::make_pair(StringRef(), QualType()) // __context with shared vars 3349 }; 3350 // Start a captured region for 'target' with no implicit parameters. 3351 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3352 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3353 3354 Sema::CapturedParamNameType ParamsTeams[] = { 3355 std::make_pair(".global_tid.", KmpInt32PtrTy), 3356 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3357 std::make_pair(StringRef(), QualType()) // __context with shared vars 3358 }; 3359 // Start a captured region for 'target' with no implicit parameters. 3360 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3361 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3362 3363 Sema::CapturedParamNameType ParamsParallel[] = { 3364 std::make_pair(".global_tid.", KmpInt32PtrTy), 3365 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3366 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3367 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3368 std::make_pair(StringRef(), QualType()) // __context with shared vars 3369 }; 3370 // Start a captured region for 'teams' or 'parallel'. Both regions have 3371 // the same implicit parameters. 3372 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3373 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3374 break; 3375 } 3376 3377 case OMPD_teams_distribute_parallel_for: 3378 case OMPD_teams_distribute_parallel_for_simd: { 3379 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3380 QualType KmpInt32PtrTy = 3381 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3382 3383 Sema::CapturedParamNameType ParamsTeams[] = { 3384 std::make_pair(".global_tid.", KmpInt32PtrTy), 3385 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3386 std::make_pair(StringRef(), QualType()) // __context with shared vars 3387 }; 3388 // Start a captured region for 'target' with no implicit parameters. 3389 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3390 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3391 3392 Sema::CapturedParamNameType ParamsParallel[] = { 3393 std::make_pair(".global_tid.", KmpInt32PtrTy), 3394 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3395 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3396 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3397 std::make_pair(StringRef(), QualType()) // __context with shared vars 3398 }; 3399 // Start a captured region for 'teams' or 'parallel'. Both regions have 3400 // the same implicit parameters. 3401 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3402 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3403 break; 3404 } 3405 case OMPD_target_update: 3406 case OMPD_target_enter_data: 3407 case OMPD_target_exit_data: { 3408 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3409 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3410 QualType KmpInt32PtrTy = 3411 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3412 QualType Args[] = {VoidPtrTy}; 3413 FunctionProtoType::ExtProtoInfo EPI; 3414 EPI.Variadic = true; 3415 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3416 Sema::CapturedParamNameType Params[] = { 3417 std::make_pair(".global_tid.", KmpInt32Ty), 3418 std::make_pair(".part_id.", KmpInt32PtrTy), 3419 std::make_pair(".privates.", VoidPtrTy), 3420 std::make_pair( 3421 ".copy_fn.", 3422 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3423 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3424 std::make_pair(StringRef(), QualType()) // __context with shared vars 3425 }; 3426 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3427 Params); 3428 // Mark this captured region as inlined, because we don't use outlined 3429 // function directly. 3430 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3431 AlwaysInlineAttr::CreateImplicit( 3432 Context, {}, AttributeCommonInfo::AS_Keyword, 3433 AlwaysInlineAttr::Keyword_forceinline)); 3434 break; 3435 } 3436 case OMPD_threadprivate: 3437 case OMPD_allocate: 3438 case OMPD_taskyield: 3439 case OMPD_barrier: 3440 case OMPD_taskwait: 3441 case OMPD_cancellation_point: 3442 case OMPD_cancel: 3443 case OMPD_flush: 3444 case OMPD_declare_reduction: 3445 case OMPD_declare_mapper: 3446 case OMPD_declare_simd: 3447 case OMPD_declare_target: 3448 case OMPD_end_declare_target: 3449 case OMPD_requires: 3450 case OMPD_declare_variant: 3451 llvm_unreachable("OpenMP Directive is not allowed"); 3452 case OMPD_unknown: 3453 llvm_unreachable("Unknown OpenMP directive"); 3454 } 3455 } 3456 3457 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3458 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3459 getOpenMPCaptureRegions(CaptureRegions, DKind); 3460 return CaptureRegions.size(); 3461 } 3462 3463 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3464 Expr *CaptureExpr, bool WithInit, 3465 bool AsExpression) { 3466 assert(CaptureExpr); 3467 ASTContext &C = S.getASTContext(); 3468 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3469 QualType Ty = Init->getType(); 3470 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3471 if (S.getLangOpts().CPlusPlus) { 3472 Ty = C.getLValueReferenceType(Ty); 3473 } else { 3474 Ty = C.getPointerType(Ty); 3475 ExprResult Res = 3476 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3477 if (!Res.isUsable()) 3478 return nullptr; 3479 Init = Res.get(); 3480 } 3481 WithInit = true; 3482 } 3483 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3484 CaptureExpr->getBeginLoc()); 3485 if (!WithInit) 3486 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3487 S.CurContext->addHiddenDecl(CED); 3488 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3489 return CED; 3490 } 3491 3492 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3493 bool WithInit) { 3494 OMPCapturedExprDecl *CD; 3495 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3496 CD = cast<OMPCapturedExprDecl>(VD); 3497 else 3498 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3499 /*AsExpression=*/false); 3500 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3501 CaptureExpr->getExprLoc()); 3502 } 3503 3504 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3505 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3506 if (!Ref) { 3507 OMPCapturedExprDecl *CD = buildCaptureDecl( 3508 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3509 /*WithInit=*/true, /*AsExpression=*/true); 3510 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3511 CaptureExpr->getExprLoc()); 3512 } 3513 ExprResult Res = Ref; 3514 if (!S.getLangOpts().CPlusPlus && 3515 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3516 Ref->getType()->isPointerType()) { 3517 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3518 if (!Res.isUsable()) 3519 return ExprError(); 3520 } 3521 return S.DefaultLvalueConversion(Res.get()); 3522 } 3523 3524 namespace { 3525 // OpenMP directives parsed in this section are represented as a 3526 // CapturedStatement with an associated statement. If a syntax error 3527 // is detected during the parsing of the associated statement, the 3528 // compiler must abort processing and close the CapturedStatement. 3529 // 3530 // Combined directives such as 'target parallel' have more than one 3531 // nested CapturedStatements. This RAII ensures that we unwind out 3532 // of all the nested CapturedStatements when an error is found. 3533 class CaptureRegionUnwinderRAII { 3534 private: 3535 Sema &S; 3536 bool &ErrorFound; 3537 OpenMPDirectiveKind DKind = OMPD_unknown; 3538 3539 public: 3540 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3541 OpenMPDirectiveKind DKind) 3542 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3543 ~CaptureRegionUnwinderRAII() { 3544 if (ErrorFound) { 3545 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3546 while (--ThisCaptureLevel >= 0) 3547 S.ActOnCapturedRegionError(); 3548 } 3549 } 3550 }; 3551 } // namespace 3552 3553 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3554 // Capture variables captured by reference in lambdas for target-based 3555 // directives. 3556 if (!CurContext->isDependentContext() && 3557 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3558 isOpenMPTargetDataManagementDirective( 3559 DSAStack->getCurrentDirective()))) { 3560 QualType Type = V->getType(); 3561 if (const auto *RD = Type.getCanonicalType() 3562 .getNonReferenceType() 3563 ->getAsCXXRecordDecl()) { 3564 bool SavedForceCaptureByReferenceInTargetExecutable = 3565 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3566 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3567 /*V=*/true); 3568 if (RD->isLambda()) { 3569 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3570 FieldDecl *ThisCapture; 3571 RD->getCaptureFields(Captures, ThisCapture); 3572 for (const LambdaCapture &LC : RD->captures()) { 3573 if (LC.getCaptureKind() == LCK_ByRef) { 3574 VarDecl *VD = LC.getCapturedVar(); 3575 DeclContext *VDC = VD->getDeclContext(); 3576 if (!VDC->Encloses(CurContext)) 3577 continue; 3578 MarkVariableReferenced(LC.getLocation(), VD); 3579 } else if (LC.getCaptureKind() == LCK_This) { 3580 QualType ThisTy = getCurrentThisType(); 3581 if (!ThisTy.isNull() && 3582 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3583 CheckCXXThisCapture(LC.getLocation()); 3584 } 3585 } 3586 } 3587 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3588 SavedForceCaptureByReferenceInTargetExecutable); 3589 } 3590 } 3591 } 3592 3593 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3594 ArrayRef<OMPClause *> Clauses) { 3595 bool ErrorFound = false; 3596 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3597 *this, ErrorFound, DSAStack->getCurrentDirective()); 3598 if (!S.isUsable()) { 3599 ErrorFound = true; 3600 return StmtError(); 3601 } 3602 3603 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3604 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3605 OMPOrderedClause *OC = nullptr; 3606 OMPScheduleClause *SC = nullptr; 3607 SmallVector<const OMPLinearClause *, 4> LCs; 3608 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3609 // This is required for proper codegen. 3610 for (OMPClause *Clause : Clauses) { 3611 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3612 Clause->getClauseKind() == OMPC_in_reduction) { 3613 // Capture taskgroup task_reduction descriptors inside the tasking regions 3614 // with the corresponding in_reduction items. 3615 auto *IRC = cast<OMPInReductionClause>(Clause); 3616 for (Expr *E : IRC->taskgroup_descriptors()) 3617 if (E) 3618 MarkDeclarationsReferencedInExpr(E); 3619 } 3620 if (isOpenMPPrivate(Clause->getClauseKind()) || 3621 Clause->getClauseKind() == OMPC_copyprivate || 3622 (getLangOpts().OpenMPUseTLS && 3623 getASTContext().getTargetInfo().isTLSSupported() && 3624 Clause->getClauseKind() == OMPC_copyin)) { 3625 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3626 // Mark all variables in private list clauses as used in inner region. 3627 for (Stmt *VarRef : Clause->children()) { 3628 if (auto *E = cast_or_null<Expr>(VarRef)) { 3629 MarkDeclarationsReferencedInExpr(E); 3630 } 3631 } 3632 DSAStack->setForceVarCapturing(/*V=*/false); 3633 } else if (CaptureRegions.size() > 1 || 3634 CaptureRegions.back() != OMPD_unknown) { 3635 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3636 PICs.push_back(C); 3637 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3638 if (Expr *E = C->getPostUpdateExpr()) 3639 MarkDeclarationsReferencedInExpr(E); 3640 } 3641 } 3642 if (Clause->getClauseKind() == OMPC_schedule) 3643 SC = cast<OMPScheduleClause>(Clause); 3644 else if (Clause->getClauseKind() == OMPC_ordered) 3645 OC = cast<OMPOrderedClause>(Clause); 3646 else if (Clause->getClauseKind() == OMPC_linear) 3647 LCs.push_back(cast<OMPLinearClause>(Clause)); 3648 } 3649 // OpenMP, 2.7.1 Loop Construct, Restrictions 3650 // The nonmonotonic modifier cannot be specified if an ordered clause is 3651 // specified. 3652 if (SC && 3653 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3654 SC->getSecondScheduleModifier() == 3655 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3656 OC) { 3657 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3658 ? SC->getFirstScheduleModifierLoc() 3659 : SC->getSecondScheduleModifierLoc(), 3660 diag::err_omp_schedule_nonmonotonic_ordered) 3661 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3662 ErrorFound = true; 3663 } 3664 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3665 for (const OMPLinearClause *C : LCs) { 3666 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3667 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3668 } 3669 ErrorFound = true; 3670 } 3671 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3672 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3673 OC->getNumForLoops()) { 3674 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3675 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3676 ErrorFound = true; 3677 } 3678 if (ErrorFound) { 3679 return StmtError(); 3680 } 3681 StmtResult SR = S; 3682 unsigned CompletedRegions = 0; 3683 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3684 // Mark all variables in private list clauses as used in inner region. 3685 // Required for proper codegen of combined directives. 3686 // TODO: add processing for other clauses. 3687 if (ThisCaptureRegion != OMPD_unknown) { 3688 for (const clang::OMPClauseWithPreInit *C : PICs) { 3689 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3690 // Find the particular capture region for the clause if the 3691 // directive is a combined one with multiple capture regions. 3692 // If the directive is not a combined one, the capture region 3693 // associated with the clause is OMPD_unknown and is generated 3694 // only once. 3695 if (CaptureRegion == ThisCaptureRegion || 3696 CaptureRegion == OMPD_unknown) { 3697 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3698 for (Decl *D : DS->decls()) 3699 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3700 } 3701 } 3702 } 3703 } 3704 if (++CompletedRegions == CaptureRegions.size()) 3705 DSAStack->setBodyComplete(); 3706 SR = ActOnCapturedRegionEnd(SR.get()); 3707 } 3708 return SR; 3709 } 3710 3711 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3712 OpenMPDirectiveKind CancelRegion, 3713 SourceLocation StartLoc) { 3714 // CancelRegion is only needed for cancel and cancellation_point. 3715 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3716 return false; 3717 3718 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3719 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3720 return false; 3721 3722 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3723 << getOpenMPDirectiveName(CancelRegion); 3724 return true; 3725 } 3726 3727 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3728 OpenMPDirectiveKind CurrentRegion, 3729 const DeclarationNameInfo &CurrentName, 3730 OpenMPDirectiveKind CancelRegion, 3731 SourceLocation StartLoc) { 3732 if (Stack->getCurScope()) { 3733 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3734 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3735 bool NestingProhibited = false; 3736 bool CloseNesting = true; 3737 bool OrphanSeen = false; 3738 enum { 3739 NoRecommend, 3740 ShouldBeInParallelRegion, 3741 ShouldBeInOrderedRegion, 3742 ShouldBeInTargetRegion, 3743 ShouldBeInTeamsRegion 3744 } Recommend = NoRecommend; 3745 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3746 // OpenMP [2.16, Nesting of Regions] 3747 // OpenMP constructs may not be nested inside a simd region. 3748 // OpenMP [2.8.1,simd Construct, Restrictions] 3749 // An ordered construct with the simd clause is the only OpenMP 3750 // construct that can appear in the simd region. 3751 // Allowing a SIMD construct nested in another SIMD construct is an 3752 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3753 // message. 3754 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3755 ? diag::err_omp_prohibited_region_simd 3756 : diag::warn_omp_nesting_simd); 3757 return CurrentRegion != OMPD_simd; 3758 } 3759 if (ParentRegion == OMPD_atomic) { 3760 // OpenMP [2.16, Nesting of Regions] 3761 // OpenMP constructs may not be nested inside an atomic region. 3762 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3763 return true; 3764 } 3765 if (CurrentRegion == OMPD_section) { 3766 // OpenMP [2.7.2, sections Construct, Restrictions] 3767 // Orphaned section directives are prohibited. That is, the section 3768 // directives must appear within the sections construct and must not be 3769 // encountered elsewhere in the sections region. 3770 if (ParentRegion != OMPD_sections && 3771 ParentRegion != OMPD_parallel_sections) { 3772 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3773 << (ParentRegion != OMPD_unknown) 3774 << getOpenMPDirectiveName(ParentRegion); 3775 return true; 3776 } 3777 return false; 3778 } 3779 // Allow some constructs (except teams and cancellation constructs) to be 3780 // orphaned (they could be used in functions, called from OpenMP regions 3781 // with the required preconditions). 3782 if (ParentRegion == OMPD_unknown && 3783 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3784 CurrentRegion != OMPD_cancellation_point && 3785 CurrentRegion != OMPD_cancel) 3786 return false; 3787 if (CurrentRegion == OMPD_cancellation_point || 3788 CurrentRegion == OMPD_cancel) { 3789 // OpenMP [2.16, Nesting of Regions] 3790 // A cancellation point construct for which construct-type-clause is 3791 // taskgroup must be nested inside a task construct. A cancellation 3792 // point construct for which construct-type-clause is not taskgroup must 3793 // be closely nested inside an OpenMP construct that matches the type 3794 // specified in construct-type-clause. 3795 // A cancel construct for which construct-type-clause is taskgroup must be 3796 // nested inside a task construct. A cancel construct for which 3797 // construct-type-clause is not taskgroup must be closely nested inside an 3798 // OpenMP construct that matches the type specified in 3799 // construct-type-clause. 3800 NestingProhibited = 3801 !((CancelRegion == OMPD_parallel && 3802 (ParentRegion == OMPD_parallel || 3803 ParentRegion == OMPD_target_parallel)) || 3804 (CancelRegion == OMPD_for && 3805 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3806 ParentRegion == OMPD_target_parallel_for || 3807 ParentRegion == OMPD_distribute_parallel_for || 3808 ParentRegion == OMPD_teams_distribute_parallel_for || 3809 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3810 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3811 (CancelRegion == OMPD_sections && 3812 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3813 ParentRegion == OMPD_parallel_sections))); 3814 OrphanSeen = ParentRegion == OMPD_unknown; 3815 } else if (CurrentRegion == OMPD_master) { 3816 // OpenMP [2.16, Nesting of Regions] 3817 // A master region may not be closely nested inside a worksharing, 3818 // atomic, or explicit task region. 3819 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3820 isOpenMPTaskingDirective(ParentRegion); 3821 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3822 // OpenMP [2.16, Nesting of Regions] 3823 // A critical region may not be nested (closely or otherwise) inside a 3824 // critical region with the same name. Note that this restriction is not 3825 // sufficient to prevent deadlock. 3826 SourceLocation PreviousCriticalLoc; 3827 bool DeadLock = Stack->hasDirective( 3828 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3829 const DeclarationNameInfo &DNI, 3830 SourceLocation Loc) { 3831 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3832 PreviousCriticalLoc = Loc; 3833 return true; 3834 } 3835 return false; 3836 }, 3837 false /* skip top directive */); 3838 if (DeadLock) { 3839 SemaRef.Diag(StartLoc, 3840 diag::err_omp_prohibited_region_critical_same_name) 3841 << CurrentName.getName(); 3842 if (PreviousCriticalLoc.isValid()) 3843 SemaRef.Diag(PreviousCriticalLoc, 3844 diag::note_omp_previous_critical_region); 3845 return true; 3846 } 3847 } else if (CurrentRegion == OMPD_barrier) { 3848 // OpenMP [2.16, Nesting of Regions] 3849 // A barrier region may not be closely nested inside a worksharing, 3850 // explicit task, critical, ordered, atomic, or master region. 3851 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3852 isOpenMPTaskingDirective(ParentRegion) || 3853 ParentRegion == OMPD_master || 3854 ParentRegion == OMPD_critical || 3855 ParentRegion == OMPD_ordered; 3856 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3857 !isOpenMPParallelDirective(CurrentRegion) && 3858 !isOpenMPTeamsDirective(CurrentRegion)) { 3859 // OpenMP [2.16, Nesting of Regions] 3860 // A worksharing region may not be closely nested inside a worksharing, 3861 // explicit task, critical, ordered, atomic, or master region. 3862 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3863 isOpenMPTaskingDirective(ParentRegion) || 3864 ParentRegion == OMPD_master || 3865 ParentRegion == OMPD_critical || 3866 ParentRegion == OMPD_ordered; 3867 Recommend = ShouldBeInParallelRegion; 3868 } else if (CurrentRegion == OMPD_ordered) { 3869 // OpenMP [2.16, Nesting of Regions] 3870 // An ordered region may not be closely nested inside a critical, 3871 // atomic, or explicit task region. 3872 // An ordered region must be closely nested inside a loop region (or 3873 // parallel loop region) with an ordered clause. 3874 // OpenMP [2.8.1,simd Construct, Restrictions] 3875 // An ordered construct with the simd clause is the only OpenMP construct 3876 // that can appear in the simd region. 3877 NestingProhibited = ParentRegion == OMPD_critical || 3878 isOpenMPTaskingDirective(ParentRegion) || 3879 !(isOpenMPSimdDirective(ParentRegion) || 3880 Stack->isParentOrderedRegion()); 3881 Recommend = ShouldBeInOrderedRegion; 3882 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3883 // OpenMP [2.16, Nesting of Regions] 3884 // If specified, a teams construct must be contained within a target 3885 // construct. 3886 NestingProhibited = 3887 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 3888 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 3889 ParentRegion != OMPD_target); 3890 OrphanSeen = ParentRegion == OMPD_unknown; 3891 Recommend = ShouldBeInTargetRegion; 3892 } 3893 if (!NestingProhibited && 3894 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3895 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3896 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3897 // OpenMP [2.16, Nesting of Regions] 3898 // distribute, parallel, parallel sections, parallel workshare, and the 3899 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3900 // constructs that can be closely nested in the teams region. 3901 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3902 !isOpenMPDistributeDirective(CurrentRegion); 3903 Recommend = ShouldBeInParallelRegion; 3904 } 3905 if (!NestingProhibited && 3906 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3907 // OpenMP 4.5 [2.17 Nesting of Regions] 3908 // The region associated with the distribute construct must be strictly 3909 // nested inside a teams region 3910 NestingProhibited = 3911 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3912 Recommend = ShouldBeInTeamsRegion; 3913 } 3914 if (!NestingProhibited && 3915 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3916 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3917 // OpenMP 4.5 [2.17 Nesting of Regions] 3918 // If a target, target update, target data, target enter data, or 3919 // target exit data construct is encountered during execution of a 3920 // target region, the behavior is unspecified. 3921 NestingProhibited = Stack->hasDirective( 3922 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3923 SourceLocation) { 3924 if (isOpenMPTargetExecutionDirective(K)) { 3925 OffendingRegion = K; 3926 return true; 3927 } 3928 return false; 3929 }, 3930 false /* don't skip top directive */); 3931 CloseNesting = false; 3932 } 3933 if (NestingProhibited) { 3934 if (OrphanSeen) { 3935 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3936 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3937 } else { 3938 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3939 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3940 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3941 } 3942 return true; 3943 } 3944 } 3945 return false; 3946 } 3947 3948 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3949 ArrayRef<OMPClause *> Clauses, 3950 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3951 bool ErrorFound = false; 3952 unsigned NamedModifiersNumber = 0; 3953 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3954 OMPD_unknown + 1); 3955 SmallVector<SourceLocation, 4> NameModifierLoc; 3956 for (const OMPClause *C : Clauses) { 3957 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3958 // At most one if clause without a directive-name-modifier can appear on 3959 // the directive. 3960 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3961 if (FoundNameModifiers[CurNM]) { 3962 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3963 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3964 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3965 ErrorFound = true; 3966 } else if (CurNM != OMPD_unknown) { 3967 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3968 ++NamedModifiersNumber; 3969 } 3970 FoundNameModifiers[CurNM] = IC; 3971 if (CurNM == OMPD_unknown) 3972 continue; 3973 // Check if the specified name modifier is allowed for the current 3974 // directive. 3975 // At most one if clause with the particular directive-name-modifier can 3976 // appear on the directive. 3977 bool MatchFound = false; 3978 for (auto NM : AllowedNameModifiers) { 3979 if (CurNM == NM) { 3980 MatchFound = true; 3981 break; 3982 } 3983 } 3984 if (!MatchFound) { 3985 S.Diag(IC->getNameModifierLoc(), 3986 diag::err_omp_wrong_if_directive_name_modifier) 3987 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3988 ErrorFound = true; 3989 } 3990 } 3991 } 3992 // If any if clause on the directive includes a directive-name-modifier then 3993 // all if clauses on the directive must include a directive-name-modifier. 3994 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3995 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3996 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3997 diag::err_omp_no_more_if_clause); 3998 } else { 3999 std::string Values; 4000 std::string Sep(", "); 4001 unsigned AllowedCnt = 0; 4002 unsigned TotalAllowedNum = 4003 AllowedNameModifiers.size() - NamedModifiersNumber; 4004 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4005 ++Cnt) { 4006 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4007 if (!FoundNameModifiers[NM]) { 4008 Values += "'"; 4009 Values += getOpenMPDirectiveName(NM); 4010 Values += "'"; 4011 if (AllowedCnt + 2 == TotalAllowedNum) 4012 Values += " or "; 4013 else if (AllowedCnt + 1 != TotalAllowedNum) 4014 Values += Sep; 4015 ++AllowedCnt; 4016 } 4017 } 4018 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4019 diag::err_omp_unnamed_if_clause) 4020 << (TotalAllowedNum > 1) << Values; 4021 } 4022 for (SourceLocation Loc : NameModifierLoc) { 4023 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4024 } 4025 ErrorFound = true; 4026 } 4027 return ErrorFound; 4028 } 4029 4030 static std::pair<ValueDecl *, bool> 4031 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4032 SourceRange &ERange, bool AllowArraySection = false) { 4033 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4034 RefExpr->containsUnexpandedParameterPack()) 4035 return std::make_pair(nullptr, true); 4036 4037 // OpenMP [3.1, C/C++] 4038 // A list item is a variable name. 4039 // OpenMP [2.9.3.3, Restrictions, p.1] 4040 // A variable that is part of another variable (as an array or 4041 // structure element) cannot appear in a private clause. 4042 RefExpr = RefExpr->IgnoreParens(); 4043 enum { 4044 NoArrayExpr = -1, 4045 ArraySubscript = 0, 4046 OMPArraySection = 1 4047 } IsArrayExpr = NoArrayExpr; 4048 if (AllowArraySection) { 4049 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4050 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4051 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4052 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4053 RefExpr = Base; 4054 IsArrayExpr = ArraySubscript; 4055 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4056 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4057 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4058 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4059 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4060 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4061 RefExpr = Base; 4062 IsArrayExpr = OMPArraySection; 4063 } 4064 } 4065 ELoc = RefExpr->getExprLoc(); 4066 ERange = RefExpr->getSourceRange(); 4067 RefExpr = RefExpr->IgnoreParenImpCasts(); 4068 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4069 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4070 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4071 (S.getCurrentThisType().isNull() || !ME || 4072 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4073 !isa<FieldDecl>(ME->getMemberDecl()))) { 4074 if (IsArrayExpr != NoArrayExpr) { 4075 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4076 << ERange; 4077 } else { 4078 S.Diag(ELoc, 4079 AllowArraySection 4080 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4081 : diag::err_omp_expected_var_name_member_expr) 4082 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4083 } 4084 return std::make_pair(nullptr, false); 4085 } 4086 return std::make_pair( 4087 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4088 } 4089 4090 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4091 ArrayRef<OMPClause *> Clauses) { 4092 assert(!S.CurContext->isDependentContext() && 4093 "Expected non-dependent context."); 4094 auto AllocateRange = 4095 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4096 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4097 DeclToCopy; 4098 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4099 return isOpenMPPrivate(C->getClauseKind()); 4100 }); 4101 for (OMPClause *Cl : PrivateRange) { 4102 MutableArrayRef<Expr *>::iterator I, It, Et; 4103 if (Cl->getClauseKind() == OMPC_private) { 4104 auto *PC = cast<OMPPrivateClause>(Cl); 4105 I = PC->private_copies().begin(); 4106 It = PC->varlist_begin(); 4107 Et = PC->varlist_end(); 4108 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4109 auto *PC = cast<OMPFirstprivateClause>(Cl); 4110 I = PC->private_copies().begin(); 4111 It = PC->varlist_begin(); 4112 Et = PC->varlist_end(); 4113 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4114 auto *PC = cast<OMPLastprivateClause>(Cl); 4115 I = PC->private_copies().begin(); 4116 It = PC->varlist_begin(); 4117 Et = PC->varlist_end(); 4118 } else if (Cl->getClauseKind() == OMPC_linear) { 4119 auto *PC = cast<OMPLinearClause>(Cl); 4120 I = PC->privates().begin(); 4121 It = PC->varlist_begin(); 4122 Et = PC->varlist_end(); 4123 } else if (Cl->getClauseKind() == OMPC_reduction) { 4124 auto *PC = cast<OMPReductionClause>(Cl); 4125 I = PC->privates().begin(); 4126 It = PC->varlist_begin(); 4127 Et = PC->varlist_end(); 4128 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4129 auto *PC = cast<OMPTaskReductionClause>(Cl); 4130 I = PC->privates().begin(); 4131 It = PC->varlist_begin(); 4132 Et = PC->varlist_end(); 4133 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4134 auto *PC = cast<OMPInReductionClause>(Cl); 4135 I = PC->privates().begin(); 4136 It = PC->varlist_begin(); 4137 Et = PC->varlist_end(); 4138 } else { 4139 llvm_unreachable("Expected private clause."); 4140 } 4141 for (Expr *E : llvm::make_range(It, Et)) { 4142 if (!*I) { 4143 ++I; 4144 continue; 4145 } 4146 SourceLocation ELoc; 4147 SourceRange ERange; 4148 Expr *SimpleRefExpr = E; 4149 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4150 /*AllowArraySection=*/true); 4151 DeclToCopy.try_emplace(Res.first, 4152 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4153 ++I; 4154 } 4155 } 4156 for (OMPClause *C : AllocateRange) { 4157 auto *AC = cast<OMPAllocateClause>(C); 4158 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4159 getAllocatorKind(S, Stack, AC->getAllocator()); 4160 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4161 // For task, taskloop or target directives, allocation requests to memory 4162 // allocators with the trait access set to thread result in unspecified 4163 // behavior. 4164 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4165 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4166 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4167 S.Diag(AC->getAllocator()->getExprLoc(), 4168 diag::warn_omp_allocate_thread_on_task_target_directive) 4169 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4170 } 4171 for (Expr *E : AC->varlists()) { 4172 SourceLocation ELoc; 4173 SourceRange ERange; 4174 Expr *SimpleRefExpr = E; 4175 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4176 ValueDecl *VD = Res.first; 4177 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4178 if (!isOpenMPPrivate(Data.CKind)) { 4179 S.Diag(E->getExprLoc(), 4180 diag::err_omp_expected_private_copy_for_allocate); 4181 continue; 4182 } 4183 VarDecl *PrivateVD = DeclToCopy[VD]; 4184 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4185 AllocatorKind, AC->getAllocator())) 4186 continue; 4187 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4188 E->getSourceRange()); 4189 } 4190 } 4191 } 4192 4193 StmtResult Sema::ActOnOpenMPExecutableDirective( 4194 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4195 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4196 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4197 StmtResult Res = StmtError(); 4198 // First check CancelRegion which is then used in checkNestingOfRegions. 4199 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4200 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4201 StartLoc)) 4202 return StmtError(); 4203 4204 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4205 VarsWithInheritedDSAType VarsWithInheritedDSA; 4206 bool ErrorFound = false; 4207 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4208 if (AStmt && !CurContext->isDependentContext()) { 4209 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4210 4211 // Check default data sharing attributes for referenced variables. 4212 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4213 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4214 Stmt *S = AStmt; 4215 while (--ThisCaptureLevel >= 0) 4216 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4217 DSAChecker.Visit(S); 4218 if (!isOpenMPTargetDataManagementDirective(Kind) && 4219 !isOpenMPTaskingDirective(Kind)) { 4220 // Visit subcaptures to generate implicit clauses for captured vars. 4221 auto *CS = cast<CapturedStmt>(AStmt); 4222 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4223 getOpenMPCaptureRegions(CaptureRegions, Kind); 4224 // Ignore outer tasking regions for target directives. 4225 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4226 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4227 DSAChecker.visitSubCaptures(CS); 4228 } 4229 if (DSAChecker.isErrorFound()) 4230 return StmtError(); 4231 // Generate list of implicitly defined firstprivate variables. 4232 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4233 4234 SmallVector<Expr *, 4> ImplicitFirstprivates( 4235 DSAChecker.getImplicitFirstprivate().begin(), 4236 DSAChecker.getImplicitFirstprivate().end()); 4237 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4238 DSAChecker.getImplicitMap().end()); 4239 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4240 for (OMPClause *C : Clauses) { 4241 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4242 for (Expr *E : IRC->taskgroup_descriptors()) 4243 if (E) 4244 ImplicitFirstprivates.emplace_back(E); 4245 } 4246 } 4247 if (!ImplicitFirstprivates.empty()) { 4248 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4249 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4250 SourceLocation())) { 4251 ClausesWithImplicit.push_back(Implicit); 4252 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4253 ImplicitFirstprivates.size(); 4254 } else { 4255 ErrorFound = true; 4256 } 4257 } 4258 if (!ImplicitMaps.empty()) { 4259 CXXScopeSpec MapperIdScopeSpec; 4260 DeclarationNameInfo MapperId; 4261 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4262 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4263 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4264 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4265 ClausesWithImplicit.emplace_back(Implicit); 4266 ErrorFound |= 4267 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4268 } else { 4269 ErrorFound = true; 4270 } 4271 } 4272 } 4273 4274 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4275 switch (Kind) { 4276 case OMPD_parallel: 4277 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4278 EndLoc); 4279 AllowedNameModifiers.push_back(OMPD_parallel); 4280 break; 4281 case OMPD_simd: 4282 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4283 VarsWithInheritedDSA); 4284 break; 4285 case OMPD_for: 4286 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4287 VarsWithInheritedDSA); 4288 break; 4289 case OMPD_for_simd: 4290 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4291 EndLoc, VarsWithInheritedDSA); 4292 break; 4293 case OMPD_sections: 4294 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4295 EndLoc); 4296 break; 4297 case OMPD_section: 4298 assert(ClausesWithImplicit.empty() && 4299 "No clauses are allowed for 'omp section' directive"); 4300 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4301 break; 4302 case OMPD_single: 4303 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4304 EndLoc); 4305 break; 4306 case OMPD_master: 4307 assert(ClausesWithImplicit.empty() && 4308 "No clauses are allowed for 'omp master' directive"); 4309 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4310 break; 4311 case OMPD_critical: 4312 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4313 StartLoc, EndLoc); 4314 break; 4315 case OMPD_parallel_for: 4316 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4317 EndLoc, VarsWithInheritedDSA); 4318 AllowedNameModifiers.push_back(OMPD_parallel); 4319 break; 4320 case OMPD_parallel_for_simd: 4321 Res = ActOnOpenMPParallelForSimdDirective( 4322 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4323 AllowedNameModifiers.push_back(OMPD_parallel); 4324 break; 4325 case OMPD_parallel_sections: 4326 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4327 StartLoc, EndLoc); 4328 AllowedNameModifiers.push_back(OMPD_parallel); 4329 break; 4330 case OMPD_task: 4331 Res = 4332 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4333 AllowedNameModifiers.push_back(OMPD_task); 4334 break; 4335 case OMPD_taskyield: 4336 assert(ClausesWithImplicit.empty() && 4337 "No clauses are allowed for 'omp taskyield' directive"); 4338 assert(AStmt == nullptr && 4339 "No associated statement allowed for 'omp taskyield' directive"); 4340 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4341 break; 4342 case OMPD_barrier: 4343 assert(ClausesWithImplicit.empty() && 4344 "No clauses are allowed for 'omp barrier' directive"); 4345 assert(AStmt == nullptr && 4346 "No associated statement allowed for 'omp barrier' directive"); 4347 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4348 break; 4349 case OMPD_taskwait: 4350 assert(ClausesWithImplicit.empty() && 4351 "No clauses are allowed for 'omp taskwait' directive"); 4352 assert(AStmt == nullptr && 4353 "No associated statement allowed for 'omp taskwait' directive"); 4354 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4355 break; 4356 case OMPD_taskgroup: 4357 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4358 EndLoc); 4359 break; 4360 case OMPD_flush: 4361 assert(AStmt == nullptr && 4362 "No associated statement allowed for 'omp flush' directive"); 4363 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4364 break; 4365 case OMPD_ordered: 4366 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4367 EndLoc); 4368 break; 4369 case OMPD_atomic: 4370 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4371 EndLoc); 4372 break; 4373 case OMPD_teams: 4374 Res = 4375 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4376 break; 4377 case OMPD_target: 4378 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4379 EndLoc); 4380 AllowedNameModifiers.push_back(OMPD_target); 4381 break; 4382 case OMPD_target_parallel: 4383 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4384 StartLoc, EndLoc); 4385 AllowedNameModifiers.push_back(OMPD_target); 4386 AllowedNameModifiers.push_back(OMPD_parallel); 4387 break; 4388 case OMPD_target_parallel_for: 4389 Res = ActOnOpenMPTargetParallelForDirective( 4390 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4391 AllowedNameModifiers.push_back(OMPD_target); 4392 AllowedNameModifiers.push_back(OMPD_parallel); 4393 break; 4394 case OMPD_cancellation_point: 4395 assert(ClausesWithImplicit.empty() && 4396 "No clauses are allowed for 'omp cancellation point' directive"); 4397 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4398 "cancellation point' directive"); 4399 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4400 break; 4401 case OMPD_cancel: 4402 assert(AStmt == nullptr && 4403 "No associated statement allowed for 'omp cancel' directive"); 4404 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4405 CancelRegion); 4406 AllowedNameModifiers.push_back(OMPD_cancel); 4407 break; 4408 case OMPD_target_data: 4409 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4410 EndLoc); 4411 AllowedNameModifiers.push_back(OMPD_target_data); 4412 break; 4413 case OMPD_target_enter_data: 4414 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4415 EndLoc, AStmt); 4416 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4417 break; 4418 case OMPD_target_exit_data: 4419 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4420 EndLoc, AStmt); 4421 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4422 break; 4423 case OMPD_taskloop: 4424 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4425 EndLoc, VarsWithInheritedDSA); 4426 AllowedNameModifiers.push_back(OMPD_taskloop); 4427 break; 4428 case OMPD_taskloop_simd: 4429 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4430 EndLoc, VarsWithInheritedDSA); 4431 AllowedNameModifiers.push_back(OMPD_taskloop); 4432 break; 4433 case OMPD_distribute: 4434 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4435 EndLoc, VarsWithInheritedDSA); 4436 break; 4437 case OMPD_target_update: 4438 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4439 EndLoc, AStmt); 4440 AllowedNameModifiers.push_back(OMPD_target_update); 4441 break; 4442 case OMPD_distribute_parallel_for: 4443 Res = ActOnOpenMPDistributeParallelForDirective( 4444 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4445 AllowedNameModifiers.push_back(OMPD_parallel); 4446 break; 4447 case OMPD_distribute_parallel_for_simd: 4448 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4449 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4450 AllowedNameModifiers.push_back(OMPD_parallel); 4451 break; 4452 case OMPD_distribute_simd: 4453 Res = ActOnOpenMPDistributeSimdDirective( 4454 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4455 break; 4456 case OMPD_target_parallel_for_simd: 4457 Res = ActOnOpenMPTargetParallelForSimdDirective( 4458 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4459 AllowedNameModifiers.push_back(OMPD_target); 4460 AllowedNameModifiers.push_back(OMPD_parallel); 4461 break; 4462 case OMPD_target_simd: 4463 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4464 EndLoc, VarsWithInheritedDSA); 4465 AllowedNameModifiers.push_back(OMPD_target); 4466 break; 4467 case OMPD_teams_distribute: 4468 Res = ActOnOpenMPTeamsDistributeDirective( 4469 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4470 break; 4471 case OMPD_teams_distribute_simd: 4472 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4473 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4474 break; 4475 case OMPD_teams_distribute_parallel_for_simd: 4476 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4477 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4478 AllowedNameModifiers.push_back(OMPD_parallel); 4479 break; 4480 case OMPD_teams_distribute_parallel_for: 4481 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4482 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4483 AllowedNameModifiers.push_back(OMPD_parallel); 4484 break; 4485 case OMPD_target_teams: 4486 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4487 EndLoc); 4488 AllowedNameModifiers.push_back(OMPD_target); 4489 break; 4490 case OMPD_target_teams_distribute: 4491 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4492 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4493 AllowedNameModifiers.push_back(OMPD_target); 4494 break; 4495 case OMPD_target_teams_distribute_parallel_for: 4496 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4497 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4498 AllowedNameModifiers.push_back(OMPD_target); 4499 AllowedNameModifiers.push_back(OMPD_parallel); 4500 break; 4501 case OMPD_target_teams_distribute_parallel_for_simd: 4502 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4503 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4504 AllowedNameModifiers.push_back(OMPD_target); 4505 AllowedNameModifiers.push_back(OMPD_parallel); 4506 break; 4507 case OMPD_target_teams_distribute_simd: 4508 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4509 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4510 AllowedNameModifiers.push_back(OMPD_target); 4511 break; 4512 case OMPD_declare_target: 4513 case OMPD_end_declare_target: 4514 case OMPD_threadprivate: 4515 case OMPD_allocate: 4516 case OMPD_declare_reduction: 4517 case OMPD_declare_mapper: 4518 case OMPD_declare_simd: 4519 case OMPD_requires: 4520 case OMPD_declare_variant: 4521 llvm_unreachable("OpenMP Directive is not allowed"); 4522 case OMPD_unknown: 4523 llvm_unreachable("Unknown OpenMP directive"); 4524 } 4525 4526 ErrorFound = Res.isInvalid() || ErrorFound; 4527 4528 // Check variables in the clauses if default(none) was specified. 4529 if (DSAStack->getDefaultDSA() == DSA_none) { 4530 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4531 for (OMPClause *C : Clauses) { 4532 switch (C->getClauseKind()) { 4533 case OMPC_num_threads: 4534 case OMPC_dist_schedule: 4535 // Do not analyse if no parent teams directive. 4536 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4537 break; 4538 continue; 4539 case OMPC_if: 4540 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4541 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4542 break; 4543 continue; 4544 case OMPC_schedule: 4545 break; 4546 case OMPC_ordered: 4547 case OMPC_device: 4548 case OMPC_num_teams: 4549 case OMPC_thread_limit: 4550 case OMPC_priority: 4551 case OMPC_grainsize: 4552 case OMPC_num_tasks: 4553 case OMPC_hint: 4554 case OMPC_collapse: 4555 case OMPC_safelen: 4556 case OMPC_simdlen: 4557 case OMPC_final: 4558 case OMPC_default: 4559 case OMPC_proc_bind: 4560 case OMPC_private: 4561 case OMPC_firstprivate: 4562 case OMPC_lastprivate: 4563 case OMPC_shared: 4564 case OMPC_reduction: 4565 case OMPC_task_reduction: 4566 case OMPC_in_reduction: 4567 case OMPC_linear: 4568 case OMPC_aligned: 4569 case OMPC_copyin: 4570 case OMPC_copyprivate: 4571 case OMPC_nowait: 4572 case OMPC_untied: 4573 case OMPC_mergeable: 4574 case OMPC_allocate: 4575 case OMPC_read: 4576 case OMPC_write: 4577 case OMPC_update: 4578 case OMPC_capture: 4579 case OMPC_seq_cst: 4580 case OMPC_depend: 4581 case OMPC_threads: 4582 case OMPC_simd: 4583 case OMPC_map: 4584 case OMPC_nogroup: 4585 case OMPC_defaultmap: 4586 case OMPC_to: 4587 case OMPC_from: 4588 case OMPC_use_device_ptr: 4589 case OMPC_is_device_ptr: 4590 continue; 4591 case OMPC_allocator: 4592 case OMPC_flush: 4593 case OMPC_threadprivate: 4594 case OMPC_uniform: 4595 case OMPC_unknown: 4596 case OMPC_unified_address: 4597 case OMPC_unified_shared_memory: 4598 case OMPC_reverse_offload: 4599 case OMPC_dynamic_allocators: 4600 case OMPC_atomic_default_mem_order: 4601 case OMPC_device_type: 4602 case OMPC_match: 4603 llvm_unreachable("Unexpected clause"); 4604 } 4605 for (Stmt *CC : C->children()) { 4606 if (CC) 4607 DSAChecker.Visit(CC); 4608 } 4609 } 4610 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4611 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4612 } 4613 for (const auto &P : VarsWithInheritedDSA) { 4614 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4615 continue; 4616 ErrorFound = true; 4617 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4618 << P.first << P.second->getSourceRange(); 4619 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4620 } 4621 4622 if (!AllowedNameModifiers.empty()) 4623 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4624 ErrorFound; 4625 4626 if (ErrorFound) 4627 return StmtError(); 4628 4629 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4630 Res.getAs<OMPExecutableDirective>() 4631 ->getStructuredBlock() 4632 ->setIsOMPStructuredBlock(true); 4633 } 4634 4635 if (!CurContext->isDependentContext() && 4636 isOpenMPTargetExecutionDirective(Kind) && 4637 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4638 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4639 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4640 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4641 // Register target to DSA Stack. 4642 DSAStack->addTargetDirLocation(StartLoc); 4643 } 4644 4645 return Res; 4646 } 4647 4648 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4649 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4650 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4651 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4652 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4653 assert(Aligneds.size() == Alignments.size()); 4654 assert(Linears.size() == LinModifiers.size()); 4655 assert(Linears.size() == Steps.size()); 4656 if (!DG || DG.get().isNull()) 4657 return DeclGroupPtrTy(); 4658 4659 const int SimdId = 0; 4660 if (!DG.get().isSingleDecl()) { 4661 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4662 << SimdId; 4663 return DG; 4664 } 4665 Decl *ADecl = DG.get().getSingleDecl(); 4666 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4667 ADecl = FTD->getTemplatedDecl(); 4668 4669 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4670 if (!FD) { 4671 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4672 return DeclGroupPtrTy(); 4673 } 4674 4675 // OpenMP [2.8.2, declare simd construct, Description] 4676 // The parameter of the simdlen clause must be a constant positive integer 4677 // expression. 4678 ExprResult SL; 4679 if (Simdlen) 4680 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4681 // OpenMP [2.8.2, declare simd construct, Description] 4682 // The special this pointer can be used as if was one of the arguments to the 4683 // function in any of the linear, aligned, or uniform clauses. 4684 // The uniform clause declares one or more arguments to have an invariant 4685 // value for all concurrent invocations of the function in the execution of a 4686 // single SIMD loop. 4687 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4688 const Expr *UniformedLinearThis = nullptr; 4689 for (const Expr *E : Uniforms) { 4690 E = E->IgnoreParenImpCasts(); 4691 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4692 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4693 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4694 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4695 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4696 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4697 continue; 4698 } 4699 if (isa<CXXThisExpr>(E)) { 4700 UniformedLinearThis = E; 4701 continue; 4702 } 4703 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4704 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4705 } 4706 // OpenMP [2.8.2, declare simd construct, Description] 4707 // The aligned clause declares that the object to which each list item points 4708 // is aligned to the number of bytes expressed in the optional parameter of 4709 // the aligned clause. 4710 // The special this pointer can be used as if was one of the arguments to the 4711 // function in any of the linear, aligned, or uniform clauses. 4712 // The type of list items appearing in the aligned clause must be array, 4713 // pointer, reference to array, or reference to pointer. 4714 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4715 const Expr *AlignedThis = nullptr; 4716 for (const Expr *E : Aligneds) { 4717 E = E->IgnoreParenImpCasts(); 4718 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4719 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4720 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4721 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4722 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4723 ->getCanonicalDecl() == CanonPVD) { 4724 // OpenMP [2.8.1, simd construct, Restrictions] 4725 // A list-item cannot appear in more than one aligned clause. 4726 if (AlignedArgs.count(CanonPVD) > 0) { 4727 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4728 << 1 << E->getSourceRange(); 4729 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4730 diag::note_omp_explicit_dsa) 4731 << getOpenMPClauseName(OMPC_aligned); 4732 continue; 4733 } 4734 AlignedArgs[CanonPVD] = E; 4735 QualType QTy = PVD->getType() 4736 .getNonReferenceType() 4737 .getUnqualifiedType() 4738 .getCanonicalType(); 4739 const Type *Ty = QTy.getTypePtrOrNull(); 4740 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4741 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4742 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4743 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4744 } 4745 continue; 4746 } 4747 } 4748 if (isa<CXXThisExpr>(E)) { 4749 if (AlignedThis) { 4750 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4751 << 2 << E->getSourceRange(); 4752 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4753 << getOpenMPClauseName(OMPC_aligned); 4754 } 4755 AlignedThis = E; 4756 continue; 4757 } 4758 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4759 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4760 } 4761 // The optional parameter of the aligned clause, alignment, must be a constant 4762 // positive integer expression. If no optional parameter is specified, 4763 // implementation-defined default alignments for SIMD instructions on the 4764 // target platforms are assumed. 4765 SmallVector<const Expr *, 4> NewAligns; 4766 for (Expr *E : Alignments) { 4767 ExprResult Align; 4768 if (E) 4769 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4770 NewAligns.push_back(Align.get()); 4771 } 4772 // OpenMP [2.8.2, declare simd construct, Description] 4773 // The linear clause declares one or more list items to be private to a SIMD 4774 // lane and to have a linear relationship with respect to the iteration space 4775 // of a loop. 4776 // The special this pointer can be used as if was one of the arguments to the 4777 // function in any of the linear, aligned, or uniform clauses. 4778 // When a linear-step expression is specified in a linear clause it must be 4779 // either a constant integer expression or an integer-typed parameter that is 4780 // specified in a uniform clause on the directive. 4781 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4782 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4783 auto MI = LinModifiers.begin(); 4784 for (const Expr *E : Linears) { 4785 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4786 ++MI; 4787 E = E->IgnoreParenImpCasts(); 4788 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4789 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4790 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4791 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4792 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4793 ->getCanonicalDecl() == CanonPVD) { 4794 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4795 // A list-item cannot appear in more than one linear clause. 4796 if (LinearArgs.count(CanonPVD) > 0) { 4797 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4798 << getOpenMPClauseName(OMPC_linear) 4799 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4800 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4801 diag::note_omp_explicit_dsa) 4802 << getOpenMPClauseName(OMPC_linear); 4803 continue; 4804 } 4805 // Each argument can appear in at most one uniform or linear clause. 4806 if (UniformedArgs.count(CanonPVD) > 0) { 4807 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4808 << getOpenMPClauseName(OMPC_linear) 4809 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4810 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4811 diag::note_omp_explicit_dsa) 4812 << getOpenMPClauseName(OMPC_uniform); 4813 continue; 4814 } 4815 LinearArgs[CanonPVD] = E; 4816 if (E->isValueDependent() || E->isTypeDependent() || 4817 E->isInstantiationDependent() || 4818 E->containsUnexpandedParameterPack()) 4819 continue; 4820 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4821 PVD->getOriginalType()); 4822 continue; 4823 } 4824 } 4825 if (isa<CXXThisExpr>(E)) { 4826 if (UniformedLinearThis) { 4827 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4828 << getOpenMPClauseName(OMPC_linear) 4829 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4830 << E->getSourceRange(); 4831 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4832 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4833 : OMPC_linear); 4834 continue; 4835 } 4836 UniformedLinearThis = E; 4837 if (E->isValueDependent() || E->isTypeDependent() || 4838 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4839 continue; 4840 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4841 E->getType()); 4842 continue; 4843 } 4844 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4845 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4846 } 4847 Expr *Step = nullptr; 4848 Expr *NewStep = nullptr; 4849 SmallVector<Expr *, 4> NewSteps; 4850 for (Expr *E : Steps) { 4851 // Skip the same step expression, it was checked already. 4852 if (Step == E || !E) { 4853 NewSteps.push_back(E ? NewStep : nullptr); 4854 continue; 4855 } 4856 Step = E; 4857 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4858 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4859 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4860 if (UniformedArgs.count(CanonPVD) == 0) { 4861 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4862 << Step->getSourceRange(); 4863 } else if (E->isValueDependent() || E->isTypeDependent() || 4864 E->isInstantiationDependent() || 4865 E->containsUnexpandedParameterPack() || 4866 CanonPVD->getType()->hasIntegerRepresentation()) { 4867 NewSteps.push_back(Step); 4868 } else { 4869 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4870 << Step->getSourceRange(); 4871 } 4872 continue; 4873 } 4874 NewStep = Step; 4875 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4876 !Step->isInstantiationDependent() && 4877 !Step->containsUnexpandedParameterPack()) { 4878 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4879 .get(); 4880 if (NewStep) 4881 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4882 } 4883 NewSteps.push_back(NewStep); 4884 } 4885 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4886 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4887 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4888 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4889 const_cast<Expr **>(Linears.data()), Linears.size(), 4890 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4891 NewSteps.data(), NewSteps.size(), SR); 4892 ADecl->addAttr(NewAttr); 4893 return DG; 4894 } 4895 4896 Optional<std::pair<FunctionDecl *, Expr *>> 4897 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 4898 Expr *VariantRef, SourceRange SR) { 4899 if (!DG || DG.get().isNull()) 4900 return None; 4901 4902 const int VariantId = 1; 4903 // Must be applied only to single decl. 4904 if (!DG.get().isSingleDecl()) { 4905 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4906 << VariantId << SR; 4907 return None; 4908 } 4909 Decl *ADecl = DG.get().getSingleDecl(); 4910 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4911 ADecl = FTD->getTemplatedDecl(); 4912 4913 // Decl must be a function. 4914 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4915 if (!FD) { 4916 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 4917 << VariantId << SR; 4918 return None; 4919 } 4920 4921 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 4922 return FD->hasAttrs() && 4923 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 4924 FD->hasAttr<TargetAttr>()); 4925 }; 4926 // OpenMP is not compatible with CPU-specific attributes. 4927 if (HasMultiVersionAttributes(FD)) { 4928 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 4929 << SR; 4930 return None; 4931 } 4932 4933 // Allow #pragma omp declare variant only if the function is not used. 4934 if (FD->isUsed(false)) 4935 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 4936 << FD->getLocation(); 4937 4938 // Check if the function was emitted already. 4939 const FunctionDecl *Definition; 4940 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 4941 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 4942 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 4943 << FD->getLocation(); 4944 4945 // The VariantRef must point to function. 4946 if (!VariantRef) { 4947 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 4948 return None; 4949 } 4950 4951 // Do not check templates, wait until instantiation. 4952 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 4953 VariantRef->containsUnexpandedParameterPack() || 4954 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 4955 return std::make_pair(FD, VariantRef); 4956 4957 // Convert VariantRef expression to the type of the original function to 4958 // resolve possible conflicts. 4959 ExprResult VariantRefCast; 4960 if (LangOpts.CPlusPlus) { 4961 QualType FnPtrType; 4962 auto *Method = dyn_cast<CXXMethodDecl>(FD); 4963 if (Method && !Method->isStatic()) { 4964 const Type *ClassType = 4965 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 4966 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 4967 ExprResult ER; 4968 { 4969 // Build adrr_of unary op to correctly handle type checks for member 4970 // functions. 4971 Sema::TentativeAnalysisScope Trap(*this); 4972 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 4973 VariantRef); 4974 } 4975 if (!ER.isUsable()) { 4976 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 4977 << VariantId << VariantRef->getSourceRange(); 4978 return None; 4979 } 4980 VariantRef = ER.get(); 4981 } else { 4982 FnPtrType = Context.getPointerType(FD->getType()); 4983 } 4984 ImplicitConversionSequence ICS = 4985 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 4986 /*SuppressUserConversions=*/false, 4987 /*AllowExplicit=*/false, 4988 /*InOverloadResolution=*/false, 4989 /*CStyle=*/false, 4990 /*AllowObjCWritebackConversion=*/false); 4991 if (ICS.isFailure()) { 4992 Diag(VariantRef->getExprLoc(), 4993 diag::err_omp_declare_variant_incompat_types) 4994 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 4995 return None; 4996 } 4997 VariantRefCast = PerformImplicitConversion( 4998 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 4999 if (!VariantRefCast.isUsable()) 5000 return None; 5001 // Drop previously built artificial addr_of unary op for member functions. 5002 if (Method && !Method->isStatic()) { 5003 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5004 if (auto *UO = dyn_cast<UnaryOperator>( 5005 PossibleAddrOfVariantRef->IgnoreImplicit())) 5006 VariantRefCast = UO->getSubExpr(); 5007 } 5008 } else { 5009 VariantRefCast = VariantRef; 5010 } 5011 5012 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5013 if (!ER.isUsable() || 5014 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5015 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5016 << VariantId << VariantRef->getSourceRange(); 5017 return None; 5018 } 5019 5020 // The VariantRef must point to function. 5021 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5022 if (!DRE) { 5023 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5024 << VariantId << VariantRef->getSourceRange(); 5025 return None; 5026 } 5027 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5028 if (!NewFD) { 5029 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5030 << VariantId << VariantRef->getSourceRange(); 5031 return None; 5032 } 5033 5034 // Check if variant function is not marked with declare variant directive. 5035 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5036 Diag(VariantRef->getExprLoc(), 5037 diag::warn_omp_declare_variant_marked_as_declare_variant) 5038 << VariantRef->getSourceRange(); 5039 SourceRange SR = 5040 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5041 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5042 return None; 5043 } 5044 5045 enum DoesntSupport { 5046 VirtFuncs = 1, 5047 Constructors = 3, 5048 Destructors = 4, 5049 DeletedFuncs = 5, 5050 DefaultedFuncs = 6, 5051 ConstexprFuncs = 7, 5052 ConstevalFuncs = 8, 5053 }; 5054 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5055 if (CXXFD->isVirtual()) { 5056 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5057 << VirtFuncs; 5058 return None; 5059 } 5060 5061 if (isa<CXXConstructorDecl>(FD)) { 5062 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5063 << Constructors; 5064 return None; 5065 } 5066 5067 if (isa<CXXDestructorDecl>(FD)) { 5068 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5069 << Destructors; 5070 return None; 5071 } 5072 } 5073 5074 if (FD->isDeleted()) { 5075 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5076 << DeletedFuncs; 5077 return None; 5078 } 5079 5080 if (FD->isDefaulted()) { 5081 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5082 << DefaultedFuncs; 5083 return None; 5084 } 5085 5086 if (FD->isConstexpr()) { 5087 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5088 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5089 return None; 5090 } 5091 5092 // Check general compatibility. 5093 if (areMultiversionVariantFunctionsCompatible( 5094 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5095 PartialDiagnosticAt( 5096 SR.getBegin(), 5097 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5098 PartialDiagnosticAt( 5099 VariantRef->getExprLoc(), 5100 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5101 PartialDiagnosticAt(VariantRef->getExprLoc(), 5102 PDiag(diag::err_omp_declare_variant_diff) 5103 << FD->getLocation()), 5104 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false)) 5105 return None; 5106 return std::make_pair(FD, cast<Expr>(DRE)); 5107 } 5108 5109 void Sema::ActOnOpenMPDeclareVariantDirective( 5110 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5111 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { 5112 if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || 5113 Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) 5114 return; 5115 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5116 Context, VariantRef, Data.CtxSet, Data.Ctx, Data.ImplVendor, SR); 5117 FD->addAttr(NewAttr); 5118 } 5119 5120 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5121 FunctionDecl *Func, 5122 bool MightBeOdrUse) { 5123 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5124 5125 if (!Func->isDependentContext() && Func->hasAttrs()) { 5126 for (OMPDeclareVariantAttr *A : 5127 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5128 // TODO: add checks for active OpenMP context where possible. 5129 Expr *VariantRef = A->getVariantFuncRef(); 5130 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5131 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5132 if (!F->isDefined() && F->isTemplateInstantiation()) 5133 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5134 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5135 } 5136 } 5137 } 5138 5139 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5140 Stmt *AStmt, 5141 SourceLocation StartLoc, 5142 SourceLocation EndLoc) { 5143 if (!AStmt) 5144 return StmtError(); 5145 5146 auto *CS = cast<CapturedStmt>(AStmt); 5147 // 1.2.2 OpenMP Language Terminology 5148 // Structured block - An executable statement with a single entry at the 5149 // top and a single exit at the bottom. 5150 // The point of exit cannot be a branch out of the structured block. 5151 // longjmp() and throw() must not violate the entry/exit criteria. 5152 CS->getCapturedDecl()->setNothrow(); 5153 5154 setFunctionHasBranchProtectedScope(); 5155 5156 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5157 DSAStack->isCancelRegion()); 5158 } 5159 5160 namespace { 5161 /// Iteration space of a single for loop. 5162 struct LoopIterationSpace final { 5163 /// True if the condition operator is the strict compare operator (<, > or 5164 /// !=). 5165 bool IsStrictCompare = false; 5166 /// Condition of the loop. 5167 Expr *PreCond = nullptr; 5168 /// This expression calculates the number of iterations in the loop. 5169 /// It is always possible to calculate it before starting the loop. 5170 Expr *NumIterations = nullptr; 5171 /// The loop counter variable. 5172 Expr *CounterVar = nullptr; 5173 /// Private loop counter variable. 5174 Expr *PrivateCounterVar = nullptr; 5175 /// This is initializer for the initial value of #CounterVar. 5176 Expr *CounterInit = nullptr; 5177 /// This is step for the #CounterVar used to generate its update: 5178 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5179 Expr *CounterStep = nullptr; 5180 /// Should step be subtracted? 5181 bool Subtract = false; 5182 /// Source range of the loop init. 5183 SourceRange InitSrcRange; 5184 /// Source range of the loop condition. 5185 SourceRange CondSrcRange; 5186 /// Source range of the loop increment. 5187 SourceRange IncSrcRange; 5188 /// Minimum value that can have the loop control variable. Used to support 5189 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5190 /// since only such variables can be used in non-loop invariant expressions. 5191 Expr *MinValue = nullptr; 5192 /// Maximum value that can have the loop control variable. Used to support 5193 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5194 /// since only such variables can be used in non-loop invariant expressions. 5195 Expr *MaxValue = nullptr; 5196 /// true, if the lower bound depends on the outer loop control var. 5197 bool IsNonRectangularLB = false; 5198 /// true, if the upper bound depends on the outer loop control var. 5199 bool IsNonRectangularUB = false; 5200 /// Index of the loop this loop depends on and forms non-rectangular loop 5201 /// nest. 5202 unsigned LoopDependentIdx = 0; 5203 /// Final condition for the non-rectangular loop nest support. It is used to 5204 /// check that the number of iterations for this particular counter must be 5205 /// finished. 5206 Expr *FinalCondition = nullptr; 5207 }; 5208 5209 /// Helper class for checking canonical form of the OpenMP loops and 5210 /// extracting iteration space of each loop in the loop nest, that will be used 5211 /// for IR generation. 5212 class OpenMPIterationSpaceChecker { 5213 /// Reference to Sema. 5214 Sema &SemaRef; 5215 /// Data-sharing stack. 5216 DSAStackTy &Stack; 5217 /// A location for diagnostics (when there is no some better location). 5218 SourceLocation DefaultLoc; 5219 /// A location for diagnostics (when increment is not compatible). 5220 SourceLocation ConditionLoc; 5221 /// A source location for referring to loop init later. 5222 SourceRange InitSrcRange; 5223 /// A source location for referring to condition later. 5224 SourceRange ConditionSrcRange; 5225 /// A source location for referring to increment later. 5226 SourceRange IncrementSrcRange; 5227 /// Loop variable. 5228 ValueDecl *LCDecl = nullptr; 5229 /// Reference to loop variable. 5230 Expr *LCRef = nullptr; 5231 /// Lower bound (initializer for the var). 5232 Expr *LB = nullptr; 5233 /// Upper bound. 5234 Expr *UB = nullptr; 5235 /// Loop step (increment). 5236 Expr *Step = nullptr; 5237 /// This flag is true when condition is one of: 5238 /// Var < UB 5239 /// Var <= UB 5240 /// UB > Var 5241 /// UB >= Var 5242 /// This will have no value when the condition is != 5243 llvm::Optional<bool> TestIsLessOp; 5244 /// This flag is true when condition is strict ( < or > ). 5245 bool TestIsStrictOp = false; 5246 /// This flag is true when step is subtracted on each iteration. 5247 bool SubtractStep = false; 5248 /// The outer loop counter this loop depends on (if any). 5249 const ValueDecl *DepDecl = nullptr; 5250 /// Contains number of loop (starts from 1) on which loop counter init 5251 /// expression of this loop depends on. 5252 Optional<unsigned> InitDependOnLC; 5253 /// Contains number of loop (starts from 1) on which loop counter condition 5254 /// expression of this loop depends on. 5255 Optional<unsigned> CondDependOnLC; 5256 /// Checks if the provide statement depends on the loop counter. 5257 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5258 /// Original condition required for checking of the exit condition for 5259 /// non-rectangular loop. 5260 Expr *Condition = nullptr; 5261 5262 public: 5263 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5264 SourceLocation DefaultLoc) 5265 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5266 ConditionLoc(DefaultLoc) {} 5267 /// Check init-expr for canonical loop form and save loop counter 5268 /// variable - #Var and its initialization value - #LB. 5269 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5270 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5271 /// for less/greater and for strict/non-strict comparison. 5272 bool checkAndSetCond(Expr *S); 5273 /// Check incr-expr for canonical loop form and return true if it 5274 /// does not conform, otherwise save loop step (#Step). 5275 bool checkAndSetInc(Expr *S); 5276 /// Return the loop counter variable. 5277 ValueDecl *getLoopDecl() const { return LCDecl; } 5278 /// Return the reference expression to loop counter variable. 5279 Expr *getLoopDeclRefExpr() const { return LCRef; } 5280 /// Source range of the loop init. 5281 SourceRange getInitSrcRange() const { return InitSrcRange; } 5282 /// Source range of the loop condition. 5283 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5284 /// Source range of the loop increment. 5285 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5286 /// True if the step should be subtracted. 5287 bool shouldSubtractStep() const { return SubtractStep; } 5288 /// True, if the compare operator is strict (<, > or !=). 5289 bool isStrictTestOp() const { return TestIsStrictOp; } 5290 /// Build the expression to calculate the number of iterations. 5291 Expr *buildNumIterations( 5292 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5293 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5294 /// Build the precondition expression for the loops. 5295 Expr * 5296 buildPreCond(Scope *S, Expr *Cond, 5297 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5298 /// Build reference expression to the counter be used for codegen. 5299 DeclRefExpr * 5300 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5301 DSAStackTy &DSA) const; 5302 /// Build reference expression to the private counter be used for 5303 /// codegen. 5304 Expr *buildPrivateCounterVar() const; 5305 /// Build initialization of the counter be used for codegen. 5306 Expr *buildCounterInit() const; 5307 /// Build step of the counter be used for codegen. 5308 Expr *buildCounterStep() const; 5309 /// Build loop data with counter value for depend clauses in ordered 5310 /// directives. 5311 Expr * 5312 buildOrderedLoopData(Scope *S, Expr *Counter, 5313 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5314 SourceLocation Loc, Expr *Inc = nullptr, 5315 OverloadedOperatorKind OOK = OO_Amp); 5316 /// Builds the minimum value for the loop counter. 5317 std::pair<Expr *, Expr *> buildMinMaxValues( 5318 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5319 /// Builds final condition for the non-rectangular loops. 5320 Expr *buildFinalCondition(Scope *S) const; 5321 /// Return true if any expression is dependent. 5322 bool dependent() const; 5323 /// Returns true if the initializer forms non-rectangular loop. 5324 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5325 /// Returns true if the condition forms non-rectangular loop. 5326 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5327 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5328 unsigned getLoopDependentIdx() const { 5329 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5330 } 5331 5332 private: 5333 /// Check the right-hand side of an assignment in the increment 5334 /// expression. 5335 bool checkAndSetIncRHS(Expr *RHS); 5336 /// Helper to set loop counter variable and its initializer. 5337 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5338 bool EmitDiags); 5339 /// Helper to set upper bound. 5340 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5341 SourceRange SR, SourceLocation SL); 5342 /// Helper to set loop increment. 5343 bool setStep(Expr *NewStep, bool Subtract); 5344 }; 5345 5346 bool OpenMPIterationSpaceChecker::dependent() const { 5347 if (!LCDecl) { 5348 assert(!LB && !UB && !Step); 5349 return false; 5350 } 5351 return LCDecl->getType()->isDependentType() || 5352 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5353 (Step && Step->isValueDependent()); 5354 } 5355 5356 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5357 Expr *NewLCRefExpr, 5358 Expr *NewLB, bool EmitDiags) { 5359 // State consistency checking to ensure correct usage. 5360 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5361 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5362 if (!NewLCDecl || !NewLB) 5363 return true; 5364 LCDecl = getCanonicalDecl(NewLCDecl); 5365 LCRef = NewLCRefExpr; 5366 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5367 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5368 if ((Ctor->isCopyOrMoveConstructor() || 5369 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5370 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5371 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5372 LB = NewLB; 5373 if (EmitDiags) 5374 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5375 return false; 5376 } 5377 5378 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5379 llvm::Optional<bool> LessOp, 5380 bool StrictOp, SourceRange SR, 5381 SourceLocation SL) { 5382 // State consistency checking to ensure correct usage. 5383 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5384 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5385 if (!NewUB) 5386 return true; 5387 UB = NewUB; 5388 if (LessOp) 5389 TestIsLessOp = LessOp; 5390 TestIsStrictOp = StrictOp; 5391 ConditionSrcRange = SR; 5392 ConditionLoc = SL; 5393 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5394 return false; 5395 } 5396 5397 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5398 // State consistency checking to ensure correct usage. 5399 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5400 if (!NewStep) 5401 return true; 5402 if (!NewStep->isValueDependent()) { 5403 // Check that the step is integer expression. 5404 SourceLocation StepLoc = NewStep->getBeginLoc(); 5405 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5406 StepLoc, getExprAsWritten(NewStep)); 5407 if (Val.isInvalid()) 5408 return true; 5409 NewStep = Val.get(); 5410 5411 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5412 // If test-expr is of form var relational-op b and relational-op is < or 5413 // <= then incr-expr must cause var to increase on each iteration of the 5414 // loop. If test-expr is of form var relational-op b and relational-op is 5415 // > or >= then incr-expr must cause var to decrease on each iteration of 5416 // the loop. 5417 // If test-expr is of form b relational-op var and relational-op is < or 5418 // <= then incr-expr must cause var to decrease on each iteration of the 5419 // loop. If test-expr is of form b relational-op var and relational-op is 5420 // > or >= then incr-expr must cause var to increase on each iteration of 5421 // the loop. 5422 llvm::APSInt Result; 5423 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5424 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5425 bool IsConstNeg = 5426 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5427 bool IsConstPos = 5428 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5429 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5430 5431 // != with increment is treated as <; != with decrement is treated as > 5432 if (!TestIsLessOp.hasValue()) 5433 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5434 if (UB && (IsConstZero || 5435 (TestIsLessOp.getValue() ? 5436 (IsConstNeg || (IsUnsigned && Subtract)) : 5437 (IsConstPos || (IsUnsigned && !Subtract))))) { 5438 SemaRef.Diag(NewStep->getExprLoc(), 5439 diag::err_omp_loop_incr_not_compatible) 5440 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5441 SemaRef.Diag(ConditionLoc, 5442 diag::note_omp_loop_cond_requres_compatible_incr) 5443 << TestIsLessOp.getValue() << ConditionSrcRange; 5444 return true; 5445 } 5446 if (TestIsLessOp.getValue() == Subtract) { 5447 NewStep = 5448 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5449 .get(); 5450 Subtract = !Subtract; 5451 } 5452 } 5453 5454 Step = NewStep; 5455 SubtractStep = Subtract; 5456 return false; 5457 } 5458 5459 namespace { 5460 /// Checker for the non-rectangular loops. Checks if the initializer or 5461 /// condition expression references loop counter variable. 5462 class LoopCounterRefChecker final 5463 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5464 Sema &SemaRef; 5465 DSAStackTy &Stack; 5466 const ValueDecl *CurLCDecl = nullptr; 5467 const ValueDecl *DepDecl = nullptr; 5468 const ValueDecl *PrevDepDecl = nullptr; 5469 bool IsInitializer = true; 5470 unsigned BaseLoopId = 0; 5471 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5472 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5473 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5474 << (IsInitializer ? 0 : 1); 5475 return false; 5476 } 5477 const auto &&Data = Stack.isLoopControlVariable(VD); 5478 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5479 // The type of the loop iterator on which we depend may not have a random 5480 // access iterator type. 5481 if (Data.first && VD->getType()->isRecordType()) { 5482 SmallString<128> Name; 5483 llvm::raw_svector_ostream OS(Name); 5484 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5485 /*Qualified=*/true); 5486 SemaRef.Diag(E->getExprLoc(), 5487 diag::err_omp_wrong_dependency_iterator_type) 5488 << OS.str(); 5489 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5490 return false; 5491 } 5492 if (Data.first && 5493 (DepDecl || (PrevDepDecl && 5494 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5495 if (!DepDecl && PrevDepDecl) 5496 DepDecl = PrevDepDecl; 5497 SmallString<128> Name; 5498 llvm::raw_svector_ostream OS(Name); 5499 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5500 /*Qualified=*/true); 5501 SemaRef.Diag(E->getExprLoc(), 5502 diag::err_omp_invariant_or_linear_dependency) 5503 << OS.str(); 5504 return false; 5505 } 5506 if (Data.first) { 5507 DepDecl = VD; 5508 BaseLoopId = Data.first; 5509 } 5510 return Data.first; 5511 } 5512 5513 public: 5514 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5515 const ValueDecl *VD = E->getDecl(); 5516 if (isa<VarDecl>(VD)) 5517 return checkDecl(E, VD); 5518 return false; 5519 } 5520 bool VisitMemberExpr(const MemberExpr *E) { 5521 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5522 const ValueDecl *VD = E->getMemberDecl(); 5523 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5524 return checkDecl(E, VD); 5525 } 5526 return false; 5527 } 5528 bool VisitStmt(const Stmt *S) { 5529 bool Res = false; 5530 for (const Stmt *Child : S->children()) 5531 Res = (Child && Visit(Child)) || Res; 5532 return Res; 5533 } 5534 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5535 const ValueDecl *CurLCDecl, bool IsInitializer, 5536 const ValueDecl *PrevDepDecl = nullptr) 5537 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5538 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5539 unsigned getBaseLoopId() const { 5540 assert(CurLCDecl && "Expected loop dependency."); 5541 return BaseLoopId; 5542 } 5543 const ValueDecl *getDepDecl() const { 5544 assert(CurLCDecl && "Expected loop dependency."); 5545 return DepDecl; 5546 } 5547 }; 5548 } // namespace 5549 5550 Optional<unsigned> 5551 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5552 bool IsInitializer) { 5553 // Check for the non-rectangular loops. 5554 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5555 DepDecl); 5556 if (LoopStmtChecker.Visit(S)) { 5557 DepDecl = LoopStmtChecker.getDepDecl(); 5558 return LoopStmtChecker.getBaseLoopId(); 5559 } 5560 return llvm::None; 5561 } 5562 5563 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5564 // Check init-expr for canonical loop form and save loop counter 5565 // variable - #Var and its initialization value - #LB. 5566 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5567 // var = lb 5568 // integer-type var = lb 5569 // random-access-iterator-type var = lb 5570 // pointer-type var = lb 5571 // 5572 if (!S) { 5573 if (EmitDiags) { 5574 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5575 } 5576 return true; 5577 } 5578 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5579 if (!ExprTemp->cleanupsHaveSideEffects()) 5580 S = ExprTemp->getSubExpr(); 5581 5582 InitSrcRange = S->getSourceRange(); 5583 if (Expr *E = dyn_cast<Expr>(S)) 5584 S = E->IgnoreParens(); 5585 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5586 if (BO->getOpcode() == BO_Assign) { 5587 Expr *LHS = BO->getLHS()->IgnoreParens(); 5588 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5589 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5590 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5591 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5592 EmitDiags); 5593 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5594 } 5595 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5596 if (ME->isArrow() && 5597 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5598 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5599 EmitDiags); 5600 } 5601 } 5602 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5603 if (DS->isSingleDecl()) { 5604 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5605 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5606 // Accept non-canonical init form here but emit ext. warning. 5607 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5608 SemaRef.Diag(S->getBeginLoc(), 5609 diag::ext_omp_loop_not_canonical_init) 5610 << S->getSourceRange(); 5611 return setLCDeclAndLB( 5612 Var, 5613 buildDeclRefExpr(SemaRef, Var, 5614 Var->getType().getNonReferenceType(), 5615 DS->getBeginLoc()), 5616 Var->getInit(), EmitDiags); 5617 } 5618 } 5619 } 5620 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5621 if (CE->getOperator() == OO_Equal) { 5622 Expr *LHS = CE->getArg(0); 5623 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5624 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5625 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5626 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5627 EmitDiags); 5628 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5629 } 5630 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5631 if (ME->isArrow() && 5632 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5633 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5634 EmitDiags); 5635 } 5636 } 5637 } 5638 5639 if (dependent() || SemaRef.CurContext->isDependentContext()) 5640 return false; 5641 if (EmitDiags) { 5642 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5643 << S->getSourceRange(); 5644 } 5645 return true; 5646 } 5647 5648 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5649 /// variable (which may be the loop variable) if possible. 5650 static const ValueDecl *getInitLCDecl(const Expr *E) { 5651 if (!E) 5652 return nullptr; 5653 E = getExprAsWritten(E); 5654 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5655 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5656 if ((Ctor->isCopyOrMoveConstructor() || 5657 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5658 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5659 E = CE->getArg(0)->IgnoreParenImpCasts(); 5660 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5661 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5662 return getCanonicalDecl(VD); 5663 } 5664 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5665 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5666 return getCanonicalDecl(ME->getMemberDecl()); 5667 return nullptr; 5668 } 5669 5670 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5671 // Check test-expr for canonical form, save upper-bound UB, flags for 5672 // less/greater and for strict/non-strict comparison. 5673 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5674 // var relational-op b 5675 // b relational-op var 5676 // 5677 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5678 if (!S) { 5679 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5680 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5681 return true; 5682 } 5683 Condition = S; 5684 S = getExprAsWritten(S); 5685 SourceLocation CondLoc = S->getBeginLoc(); 5686 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5687 if (BO->isRelationalOp()) { 5688 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5689 return setUB(BO->getRHS(), 5690 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5691 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5692 BO->getSourceRange(), BO->getOperatorLoc()); 5693 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5694 return setUB(BO->getLHS(), 5695 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5696 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5697 BO->getSourceRange(), BO->getOperatorLoc()); 5698 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5699 return setUB( 5700 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5701 /*LessOp=*/llvm::None, 5702 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5703 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5704 if (CE->getNumArgs() == 2) { 5705 auto Op = CE->getOperator(); 5706 switch (Op) { 5707 case OO_Greater: 5708 case OO_GreaterEqual: 5709 case OO_Less: 5710 case OO_LessEqual: 5711 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5712 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5713 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5714 CE->getOperatorLoc()); 5715 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5716 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5717 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5718 CE->getOperatorLoc()); 5719 break; 5720 case OO_ExclaimEqual: 5721 if (IneqCondIsCanonical) 5722 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5723 : CE->getArg(0), 5724 /*LessOp=*/llvm::None, 5725 /*StrictOp=*/true, CE->getSourceRange(), 5726 CE->getOperatorLoc()); 5727 break; 5728 default: 5729 break; 5730 } 5731 } 5732 } 5733 if (dependent() || SemaRef.CurContext->isDependentContext()) 5734 return false; 5735 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5736 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5737 return true; 5738 } 5739 5740 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5741 // RHS of canonical loop form increment can be: 5742 // var + incr 5743 // incr + var 5744 // var - incr 5745 // 5746 RHS = RHS->IgnoreParenImpCasts(); 5747 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5748 if (BO->isAdditiveOp()) { 5749 bool IsAdd = BO->getOpcode() == BO_Add; 5750 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5751 return setStep(BO->getRHS(), !IsAdd); 5752 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5753 return setStep(BO->getLHS(), /*Subtract=*/false); 5754 } 5755 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5756 bool IsAdd = CE->getOperator() == OO_Plus; 5757 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5758 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5759 return setStep(CE->getArg(1), !IsAdd); 5760 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5761 return setStep(CE->getArg(0), /*Subtract=*/false); 5762 } 5763 } 5764 if (dependent() || SemaRef.CurContext->isDependentContext()) 5765 return false; 5766 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5767 << RHS->getSourceRange() << LCDecl; 5768 return true; 5769 } 5770 5771 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5772 // Check incr-expr for canonical loop form and return true if it 5773 // does not conform. 5774 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5775 // ++var 5776 // var++ 5777 // --var 5778 // var-- 5779 // var += incr 5780 // var -= incr 5781 // var = var + incr 5782 // var = incr + var 5783 // var = var - incr 5784 // 5785 if (!S) { 5786 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5787 return true; 5788 } 5789 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5790 if (!ExprTemp->cleanupsHaveSideEffects()) 5791 S = ExprTemp->getSubExpr(); 5792 5793 IncrementSrcRange = S->getSourceRange(); 5794 S = S->IgnoreParens(); 5795 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5796 if (UO->isIncrementDecrementOp() && 5797 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5798 return setStep(SemaRef 5799 .ActOnIntegerConstant(UO->getBeginLoc(), 5800 (UO->isDecrementOp() ? -1 : 1)) 5801 .get(), 5802 /*Subtract=*/false); 5803 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5804 switch (BO->getOpcode()) { 5805 case BO_AddAssign: 5806 case BO_SubAssign: 5807 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5808 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5809 break; 5810 case BO_Assign: 5811 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5812 return checkAndSetIncRHS(BO->getRHS()); 5813 break; 5814 default: 5815 break; 5816 } 5817 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5818 switch (CE->getOperator()) { 5819 case OO_PlusPlus: 5820 case OO_MinusMinus: 5821 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5822 return setStep(SemaRef 5823 .ActOnIntegerConstant( 5824 CE->getBeginLoc(), 5825 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5826 .get(), 5827 /*Subtract=*/false); 5828 break; 5829 case OO_PlusEqual: 5830 case OO_MinusEqual: 5831 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5832 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5833 break; 5834 case OO_Equal: 5835 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5836 return checkAndSetIncRHS(CE->getArg(1)); 5837 break; 5838 default: 5839 break; 5840 } 5841 } 5842 if (dependent() || SemaRef.CurContext->isDependentContext()) 5843 return false; 5844 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5845 << S->getSourceRange() << LCDecl; 5846 return true; 5847 } 5848 5849 static ExprResult 5850 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5851 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5852 if (SemaRef.CurContext->isDependentContext()) 5853 return ExprResult(Capture); 5854 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5855 return SemaRef.PerformImplicitConversion( 5856 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5857 /*AllowExplicit=*/true); 5858 auto I = Captures.find(Capture); 5859 if (I != Captures.end()) 5860 return buildCapture(SemaRef, Capture, I->second); 5861 DeclRefExpr *Ref = nullptr; 5862 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5863 Captures[Capture] = Ref; 5864 return Res; 5865 } 5866 5867 /// Build the expression to calculate the number of iterations. 5868 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5869 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5870 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5871 ExprResult Diff; 5872 QualType VarType = LCDecl->getType().getNonReferenceType(); 5873 if (VarType->isIntegerType() || VarType->isPointerType() || 5874 SemaRef.getLangOpts().CPlusPlus) { 5875 Expr *LBVal = LB; 5876 Expr *UBVal = UB; 5877 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5878 // max(LB(MinVal), LB(MaxVal)) 5879 if (InitDependOnLC) { 5880 const LoopIterationSpace &IS = 5881 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5882 InitDependOnLC.getValueOr( 5883 CondDependOnLC.getValueOr(0))]; 5884 if (!IS.MinValue || !IS.MaxValue) 5885 return nullptr; 5886 // OuterVar = Min 5887 ExprResult MinValue = 5888 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5889 if (!MinValue.isUsable()) 5890 return nullptr; 5891 5892 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5893 IS.CounterVar, MinValue.get()); 5894 if (!LBMinVal.isUsable()) 5895 return nullptr; 5896 // OuterVar = Min, LBVal 5897 LBMinVal = 5898 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5899 if (!LBMinVal.isUsable()) 5900 return nullptr; 5901 // (OuterVar = Min, LBVal) 5902 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5903 if (!LBMinVal.isUsable()) 5904 return nullptr; 5905 5906 // OuterVar = Max 5907 ExprResult MaxValue = 5908 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5909 if (!MaxValue.isUsable()) 5910 return nullptr; 5911 5912 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5913 IS.CounterVar, MaxValue.get()); 5914 if (!LBMaxVal.isUsable()) 5915 return nullptr; 5916 // OuterVar = Max, LBVal 5917 LBMaxVal = 5918 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5919 if (!LBMaxVal.isUsable()) 5920 return nullptr; 5921 // (OuterVar = Max, LBVal) 5922 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5923 if (!LBMaxVal.isUsable()) 5924 return nullptr; 5925 5926 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 5927 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 5928 if (!LBMin || !LBMax) 5929 return nullptr; 5930 // LB(MinVal) < LB(MaxVal) 5931 ExprResult MinLessMaxRes = 5932 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 5933 if (!MinLessMaxRes.isUsable()) 5934 return nullptr; 5935 Expr *MinLessMax = 5936 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 5937 if (!MinLessMax) 5938 return nullptr; 5939 if (TestIsLessOp.getValue()) { 5940 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 5941 // LB(MaxVal)) 5942 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5943 MinLessMax, LBMin, LBMax); 5944 if (!MinLB.isUsable()) 5945 return nullptr; 5946 LBVal = MinLB.get(); 5947 } else { 5948 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 5949 // LB(MaxVal)) 5950 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5951 MinLessMax, LBMax, LBMin); 5952 if (!MaxLB.isUsable()) 5953 return nullptr; 5954 LBVal = MaxLB.get(); 5955 } 5956 } 5957 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 5958 // min(UB(MinVal), UB(MaxVal)) 5959 if (CondDependOnLC) { 5960 const LoopIterationSpace &IS = 5961 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5962 InitDependOnLC.getValueOr( 5963 CondDependOnLC.getValueOr(0))]; 5964 if (!IS.MinValue || !IS.MaxValue) 5965 return nullptr; 5966 // OuterVar = Min 5967 ExprResult MinValue = 5968 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5969 if (!MinValue.isUsable()) 5970 return nullptr; 5971 5972 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5973 IS.CounterVar, MinValue.get()); 5974 if (!UBMinVal.isUsable()) 5975 return nullptr; 5976 // OuterVar = Min, UBVal 5977 UBMinVal = 5978 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 5979 if (!UBMinVal.isUsable()) 5980 return nullptr; 5981 // (OuterVar = Min, UBVal) 5982 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 5983 if (!UBMinVal.isUsable()) 5984 return nullptr; 5985 5986 // OuterVar = Max 5987 ExprResult MaxValue = 5988 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5989 if (!MaxValue.isUsable()) 5990 return nullptr; 5991 5992 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5993 IS.CounterVar, MaxValue.get()); 5994 if (!UBMaxVal.isUsable()) 5995 return nullptr; 5996 // OuterVar = Max, UBVal 5997 UBMaxVal = 5998 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 5999 if (!UBMaxVal.isUsable()) 6000 return nullptr; 6001 // (OuterVar = Max, UBVal) 6002 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6003 if (!UBMaxVal.isUsable()) 6004 return nullptr; 6005 6006 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6007 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6008 if (!UBMin || !UBMax) 6009 return nullptr; 6010 // UB(MinVal) > UB(MaxVal) 6011 ExprResult MinGreaterMaxRes = 6012 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6013 if (!MinGreaterMaxRes.isUsable()) 6014 return nullptr; 6015 Expr *MinGreaterMax = 6016 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6017 if (!MinGreaterMax) 6018 return nullptr; 6019 if (TestIsLessOp.getValue()) { 6020 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6021 // UB(MaxVal)) 6022 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6023 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6024 if (!MaxUB.isUsable()) 6025 return nullptr; 6026 UBVal = MaxUB.get(); 6027 } else { 6028 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6029 // UB(MaxVal)) 6030 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6031 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6032 if (!MinUB.isUsable()) 6033 return nullptr; 6034 UBVal = MinUB.get(); 6035 } 6036 } 6037 // Upper - Lower 6038 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6039 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6040 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6041 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6042 if (!Upper || !Lower) 6043 return nullptr; 6044 6045 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6046 6047 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6048 // BuildBinOp already emitted error, this one is to point user to upper 6049 // and lower bound, and to tell what is passed to 'operator-'. 6050 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6051 << Upper->getSourceRange() << Lower->getSourceRange(); 6052 return nullptr; 6053 } 6054 } 6055 6056 if (!Diff.isUsable()) 6057 return nullptr; 6058 6059 // Upper - Lower [- 1] 6060 if (TestIsStrictOp) 6061 Diff = SemaRef.BuildBinOp( 6062 S, DefaultLoc, BO_Sub, Diff.get(), 6063 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6064 if (!Diff.isUsable()) 6065 return nullptr; 6066 6067 // Upper - Lower [- 1] + Step 6068 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6069 if (!NewStep.isUsable()) 6070 return nullptr; 6071 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6072 if (!Diff.isUsable()) 6073 return nullptr; 6074 6075 // Parentheses (for dumping/debugging purposes only). 6076 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6077 if (!Diff.isUsable()) 6078 return nullptr; 6079 6080 // (Upper - Lower [- 1] + Step) / Step 6081 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6082 if (!Diff.isUsable()) 6083 return nullptr; 6084 6085 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6086 QualType Type = Diff.get()->getType(); 6087 ASTContext &C = SemaRef.Context; 6088 bool UseVarType = VarType->hasIntegerRepresentation() && 6089 C.getTypeSize(Type) > C.getTypeSize(VarType); 6090 if (!Type->isIntegerType() || UseVarType) { 6091 unsigned NewSize = 6092 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6093 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6094 : Type->hasSignedIntegerRepresentation(); 6095 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6096 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6097 Diff = SemaRef.PerformImplicitConversion( 6098 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6099 if (!Diff.isUsable()) 6100 return nullptr; 6101 } 6102 } 6103 if (LimitedType) { 6104 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6105 if (NewSize != C.getTypeSize(Type)) { 6106 if (NewSize < C.getTypeSize(Type)) { 6107 assert(NewSize == 64 && "incorrect loop var size"); 6108 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6109 << InitSrcRange << ConditionSrcRange; 6110 } 6111 QualType NewType = C.getIntTypeForBitwidth( 6112 NewSize, Type->hasSignedIntegerRepresentation() || 6113 C.getTypeSize(Type) < NewSize); 6114 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6115 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6116 Sema::AA_Converting, true); 6117 if (!Diff.isUsable()) 6118 return nullptr; 6119 } 6120 } 6121 } 6122 6123 return Diff.get(); 6124 } 6125 6126 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6127 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6128 // Do not build for iterators, they cannot be used in non-rectangular loop 6129 // nests. 6130 if (LCDecl->getType()->isRecordType()) 6131 return std::make_pair(nullptr, nullptr); 6132 // If we subtract, the min is in the condition, otherwise the min is in the 6133 // init value. 6134 Expr *MinExpr = nullptr; 6135 Expr *MaxExpr = nullptr; 6136 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6137 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6138 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6139 : CondDependOnLC.hasValue(); 6140 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6141 : InitDependOnLC.hasValue(); 6142 Expr *Lower = 6143 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6144 Expr *Upper = 6145 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6146 if (!Upper || !Lower) 6147 return std::make_pair(nullptr, nullptr); 6148 6149 if (TestIsLessOp.getValue()) 6150 MinExpr = Lower; 6151 else 6152 MaxExpr = Upper; 6153 6154 // Build minimum/maximum value based on number of iterations. 6155 ExprResult Diff; 6156 QualType VarType = LCDecl->getType().getNonReferenceType(); 6157 6158 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6159 if (!Diff.isUsable()) 6160 return std::make_pair(nullptr, nullptr); 6161 6162 // Upper - Lower [- 1] 6163 if (TestIsStrictOp) 6164 Diff = SemaRef.BuildBinOp( 6165 S, DefaultLoc, BO_Sub, Diff.get(), 6166 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6167 if (!Diff.isUsable()) 6168 return std::make_pair(nullptr, nullptr); 6169 6170 // Upper - Lower [- 1] + Step 6171 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6172 if (!NewStep.isUsable()) 6173 return std::make_pair(nullptr, nullptr); 6174 6175 // Parentheses (for dumping/debugging purposes only). 6176 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6177 if (!Diff.isUsable()) 6178 return std::make_pair(nullptr, nullptr); 6179 6180 // (Upper - Lower [- 1]) / Step 6181 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6182 if (!Diff.isUsable()) 6183 return std::make_pair(nullptr, nullptr); 6184 6185 // ((Upper - Lower [- 1]) / Step) * Step 6186 // Parentheses (for dumping/debugging purposes only). 6187 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6188 if (!Diff.isUsable()) 6189 return std::make_pair(nullptr, nullptr); 6190 6191 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6192 if (!Diff.isUsable()) 6193 return std::make_pair(nullptr, nullptr); 6194 6195 // Convert to the original type or ptrdiff_t, if original type is pointer. 6196 if (!VarType->isAnyPointerType() && 6197 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6198 Diff = SemaRef.PerformImplicitConversion( 6199 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6200 } else if (VarType->isAnyPointerType() && 6201 !SemaRef.Context.hasSameType( 6202 Diff.get()->getType(), 6203 SemaRef.Context.getUnsignedPointerDiffType())) { 6204 Diff = SemaRef.PerformImplicitConversion( 6205 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6206 Sema::AA_Converting, /*AllowExplicit=*/true); 6207 } 6208 if (!Diff.isUsable()) 6209 return std::make_pair(nullptr, nullptr); 6210 6211 // Parentheses (for dumping/debugging purposes only). 6212 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6213 if (!Diff.isUsable()) 6214 return std::make_pair(nullptr, nullptr); 6215 6216 if (TestIsLessOp.getValue()) { 6217 // MinExpr = Lower; 6218 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6219 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6220 if (!Diff.isUsable()) 6221 return std::make_pair(nullptr, nullptr); 6222 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6223 if (!Diff.isUsable()) 6224 return std::make_pair(nullptr, nullptr); 6225 MaxExpr = Diff.get(); 6226 } else { 6227 // MaxExpr = Upper; 6228 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6229 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6230 if (!Diff.isUsable()) 6231 return std::make_pair(nullptr, nullptr); 6232 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6233 if (!Diff.isUsable()) 6234 return std::make_pair(nullptr, nullptr); 6235 MinExpr = Diff.get(); 6236 } 6237 6238 return std::make_pair(MinExpr, MaxExpr); 6239 } 6240 6241 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6242 if (InitDependOnLC || CondDependOnLC) 6243 return Condition; 6244 return nullptr; 6245 } 6246 6247 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6248 Scope *S, Expr *Cond, 6249 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6250 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6251 Sema::TentativeAnalysisScope Trap(SemaRef); 6252 6253 ExprResult NewLB = 6254 InitDependOnLC ? LB : tryBuildCapture(SemaRef, LB, Captures); 6255 ExprResult NewUB = 6256 CondDependOnLC ? UB : tryBuildCapture(SemaRef, UB, Captures); 6257 if (!NewLB.isUsable() || !NewUB.isUsable()) 6258 return nullptr; 6259 6260 ExprResult CondExpr = 6261 SemaRef.BuildBinOp(S, DefaultLoc, 6262 TestIsLessOp.getValue() ? 6263 (TestIsStrictOp ? BO_LT : BO_LE) : 6264 (TestIsStrictOp ? BO_GT : BO_GE), 6265 NewLB.get(), NewUB.get()); 6266 if (CondExpr.isUsable()) { 6267 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6268 SemaRef.Context.BoolTy)) 6269 CondExpr = SemaRef.PerformImplicitConversion( 6270 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6271 /*AllowExplicit=*/true); 6272 } 6273 6274 // Otherwise use original loop condition and evaluate it in runtime. 6275 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6276 } 6277 6278 /// Build reference expression to the counter be used for codegen. 6279 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6280 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6281 DSAStackTy &DSA) const { 6282 auto *VD = dyn_cast<VarDecl>(LCDecl); 6283 if (!VD) { 6284 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6285 DeclRefExpr *Ref = buildDeclRefExpr( 6286 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6287 const DSAStackTy::DSAVarData Data = 6288 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6289 // If the loop control decl is explicitly marked as private, do not mark it 6290 // as captured again. 6291 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6292 Captures.insert(std::make_pair(LCRef, Ref)); 6293 return Ref; 6294 } 6295 return cast<DeclRefExpr>(LCRef); 6296 } 6297 6298 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6299 if (LCDecl && !LCDecl->isInvalidDecl()) { 6300 QualType Type = LCDecl->getType().getNonReferenceType(); 6301 VarDecl *PrivateVar = buildVarDecl( 6302 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6303 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6304 isa<VarDecl>(LCDecl) 6305 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6306 : nullptr); 6307 if (PrivateVar->isInvalidDecl()) 6308 return nullptr; 6309 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6310 } 6311 return nullptr; 6312 } 6313 6314 /// Build initialization of the counter to be used for codegen. 6315 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6316 6317 /// Build step of the counter be used for codegen. 6318 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6319 6320 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6321 Scope *S, Expr *Counter, 6322 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6323 Expr *Inc, OverloadedOperatorKind OOK) { 6324 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6325 if (!Cnt) 6326 return nullptr; 6327 if (Inc) { 6328 assert((OOK == OO_Plus || OOK == OO_Minus) && 6329 "Expected only + or - operations for depend clauses."); 6330 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6331 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6332 if (!Cnt) 6333 return nullptr; 6334 } 6335 ExprResult Diff; 6336 QualType VarType = LCDecl->getType().getNonReferenceType(); 6337 if (VarType->isIntegerType() || VarType->isPointerType() || 6338 SemaRef.getLangOpts().CPlusPlus) { 6339 // Upper - Lower 6340 Expr *Upper = TestIsLessOp.getValue() 6341 ? Cnt 6342 : tryBuildCapture(SemaRef, UB, Captures).get(); 6343 Expr *Lower = TestIsLessOp.getValue() 6344 ? tryBuildCapture(SemaRef, LB, Captures).get() 6345 : Cnt; 6346 if (!Upper || !Lower) 6347 return nullptr; 6348 6349 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6350 6351 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6352 // BuildBinOp already emitted error, this one is to point user to upper 6353 // and lower bound, and to tell what is passed to 'operator-'. 6354 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6355 << Upper->getSourceRange() << Lower->getSourceRange(); 6356 return nullptr; 6357 } 6358 } 6359 6360 if (!Diff.isUsable()) 6361 return nullptr; 6362 6363 // Parentheses (for dumping/debugging purposes only). 6364 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6365 if (!Diff.isUsable()) 6366 return nullptr; 6367 6368 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6369 if (!NewStep.isUsable()) 6370 return nullptr; 6371 // (Upper - Lower) / Step 6372 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6373 if (!Diff.isUsable()) 6374 return nullptr; 6375 6376 return Diff.get(); 6377 } 6378 } // namespace 6379 6380 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6381 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6382 assert(Init && "Expected loop in canonical form."); 6383 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6384 if (AssociatedLoops > 0 && 6385 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6386 DSAStack->loopStart(); 6387 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6388 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6389 if (ValueDecl *D = ISC.getLoopDecl()) { 6390 auto *VD = dyn_cast<VarDecl>(D); 6391 DeclRefExpr *PrivateRef = nullptr; 6392 if (!VD) { 6393 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6394 VD = Private; 6395 } else { 6396 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6397 /*WithInit=*/false); 6398 VD = cast<VarDecl>(PrivateRef->getDecl()); 6399 } 6400 } 6401 DSAStack->addLoopControlVariable(D, VD); 6402 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6403 if (LD != D->getCanonicalDecl()) { 6404 DSAStack->resetPossibleLoopCounter(); 6405 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6406 MarkDeclarationsReferencedInExpr( 6407 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6408 Var->getType().getNonLValueExprType(Context), 6409 ForLoc, /*RefersToCapture=*/true)); 6410 } 6411 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6412 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6413 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6414 // associated for-loop of a simd construct with just one associated 6415 // for-loop may be listed in a linear clause with a constant-linear-step 6416 // that is the increment of the associated for-loop. The loop iteration 6417 // variable(s) in the associated for-loop(s) of a for or parallel for 6418 // construct may be listed in a private or lastprivate clause. 6419 DSAStackTy::DSAVarData DVar = 6420 DSAStack->getTopDSA(D, /*FromParent=*/false); 6421 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6422 // is declared in the loop and it is predetermined as a private. 6423 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6424 OpenMPClauseKind PredeterminedCKind = 6425 isOpenMPSimdDirective(DKind) 6426 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6427 : OMPC_private; 6428 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6429 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6430 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6431 DVar.CKind != OMPC_private))) || 6432 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6433 isOpenMPDistributeDirective(DKind)) && 6434 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6435 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6436 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6437 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6438 << getOpenMPClauseName(DVar.CKind) 6439 << getOpenMPDirectiveName(DKind) 6440 << getOpenMPClauseName(PredeterminedCKind); 6441 if (DVar.RefExpr == nullptr) 6442 DVar.CKind = PredeterminedCKind; 6443 reportOriginalDsa(*this, DSAStack, D, DVar, 6444 /*IsLoopIterVar=*/true); 6445 } else if (LoopDeclRefExpr) { 6446 // Make the loop iteration variable private (for worksharing 6447 // constructs), linear (for simd directives with the only one 6448 // associated loop) or lastprivate (for simd directives with several 6449 // collapsed or ordered loops). 6450 if (DVar.CKind == OMPC_unknown) 6451 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6452 PrivateRef); 6453 } 6454 } 6455 } 6456 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6457 } 6458 } 6459 6460 /// Called on a for stmt to check and extract its iteration space 6461 /// for further processing (such as collapsing). 6462 static bool checkOpenMPIterationSpace( 6463 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6464 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6465 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6466 Expr *OrderedLoopCountExpr, 6467 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6468 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6469 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6470 // OpenMP [2.6, Canonical Loop Form] 6471 // for (init-expr; test-expr; incr-expr) structured-block 6472 auto *For = dyn_cast_or_null<ForStmt>(S); 6473 if (!For) { 6474 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6475 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6476 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6477 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6478 if (TotalNestedLoopCount > 1) { 6479 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6480 SemaRef.Diag(DSA.getConstructLoc(), 6481 diag::note_omp_collapse_ordered_expr) 6482 << 2 << CollapseLoopCountExpr->getSourceRange() 6483 << OrderedLoopCountExpr->getSourceRange(); 6484 else if (CollapseLoopCountExpr) 6485 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6486 diag::note_omp_collapse_ordered_expr) 6487 << 0 << CollapseLoopCountExpr->getSourceRange(); 6488 else 6489 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6490 diag::note_omp_collapse_ordered_expr) 6491 << 1 << OrderedLoopCountExpr->getSourceRange(); 6492 } 6493 return true; 6494 } 6495 assert(For->getBody()); 6496 6497 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 6498 6499 // Check init. 6500 Stmt *Init = For->getInit(); 6501 if (ISC.checkAndSetInit(Init)) 6502 return true; 6503 6504 bool HasErrors = false; 6505 6506 // Check loop variable's type. 6507 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6508 // OpenMP [2.6, Canonical Loop Form] 6509 // Var is one of the following: 6510 // A variable of signed or unsigned integer type. 6511 // For C++, a variable of a random access iterator type. 6512 // For C, a variable of a pointer type. 6513 QualType VarType = LCDecl->getType().getNonReferenceType(); 6514 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6515 !VarType->isPointerType() && 6516 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6517 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6518 << SemaRef.getLangOpts().CPlusPlus; 6519 HasErrors = true; 6520 } 6521 6522 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6523 // a Construct 6524 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6525 // parallel for construct is (are) private. 6526 // The loop iteration variable in the associated for-loop of a simd 6527 // construct with just one associated for-loop is linear with a 6528 // constant-linear-step that is the increment of the associated for-loop. 6529 // Exclude loop var from the list of variables with implicitly defined data 6530 // sharing attributes. 6531 VarsWithImplicitDSA.erase(LCDecl); 6532 6533 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6534 6535 // Check test-expr. 6536 HasErrors |= ISC.checkAndSetCond(For->getCond()); 6537 6538 // Check incr-expr. 6539 HasErrors |= ISC.checkAndSetInc(For->getInc()); 6540 } 6541 6542 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6543 return HasErrors; 6544 6545 // Build the loop's iteration space representation. 6546 ResultIterSpaces[CurrentNestedLoopCount].PreCond = 6547 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 6548 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6549 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6550 (isOpenMPWorksharingDirective(DKind) || 6551 isOpenMPTaskLoopDirective(DKind) || 6552 isOpenMPDistributeDirective(DKind)), 6553 Captures); 6554 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6555 ISC.buildCounterVar(Captures, DSA); 6556 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6557 ISC.buildPrivateCounterVar(); 6558 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6559 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6560 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6561 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6562 ISC.getConditionSrcRange(); 6563 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6564 ISC.getIncrementSrcRange(); 6565 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6566 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6567 ISC.isStrictTestOp(); 6568 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6569 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6570 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6571 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6572 ISC.buildFinalCondition(DSA.getCurScope()); 6573 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6574 ISC.doesInitDependOnLC(); 6575 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6576 ISC.doesCondDependOnLC(); 6577 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6578 ISC.getLoopDependentIdx(); 6579 6580 HasErrors |= 6581 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6582 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6583 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6584 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6585 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6586 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6587 if (!HasErrors && DSA.isOrderedRegion()) { 6588 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6589 if (CurrentNestedLoopCount < 6590 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6591 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6592 CurrentNestedLoopCount, 6593 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6594 DSA.getOrderedRegionParam().second->setLoopCounter( 6595 CurrentNestedLoopCount, 6596 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6597 } 6598 } 6599 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6600 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6601 // Erroneous case - clause has some problems. 6602 continue; 6603 } 6604 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6605 Pair.second.size() <= CurrentNestedLoopCount) { 6606 // Erroneous case - clause has some problems. 6607 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6608 continue; 6609 } 6610 Expr *CntValue; 6611 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6612 CntValue = ISC.buildOrderedLoopData( 6613 DSA.getCurScope(), 6614 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6615 Pair.first->getDependencyLoc()); 6616 else 6617 CntValue = ISC.buildOrderedLoopData( 6618 DSA.getCurScope(), 6619 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6620 Pair.first->getDependencyLoc(), 6621 Pair.second[CurrentNestedLoopCount].first, 6622 Pair.second[CurrentNestedLoopCount].second); 6623 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6624 } 6625 } 6626 6627 return HasErrors; 6628 } 6629 6630 /// Build 'VarRef = Start. 6631 static ExprResult 6632 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6633 ExprResult Start, bool IsNonRectangularLB, 6634 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6635 // Build 'VarRef = Start. 6636 ExprResult NewStart = IsNonRectangularLB 6637 ? Start.get() 6638 : tryBuildCapture(SemaRef, Start.get(), Captures); 6639 if (!NewStart.isUsable()) 6640 return ExprError(); 6641 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6642 VarRef.get()->getType())) { 6643 NewStart = SemaRef.PerformImplicitConversion( 6644 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6645 /*AllowExplicit=*/true); 6646 if (!NewStart.isUsable()) 6647 return ExprError(); 6648 } 6649 6650 ExprResult Init = 6651 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6652 return Init; 6653 } 6654 6655 /// Build 'VarRef = Start + Iter * Step'. 6656 static ExprResult buildCounterUpdate( 6657 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6658 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6659 bool IsNonRectangularLB, 6660 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6661 // Add parentheses (for debugging purposes only). 6662 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6663 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6664 !Step.isUsable()) 6665 return ExprError(); 6666 6667 ExprResult NewStep = Step; 6668 if (Captures) 6669 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6670 if (NewStep.isInvalid()) 6671 return ExprError(); 6672 ExprResult Update = 6673 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6674 if (!Update.isUsable()) 6675 return ExprError(); 6676 6677 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6678 // 'VarRef = Start (+|-) Iter * Step'. 6679 if (!Start.isUsable()) 6680 return ExprError(); 6681 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6682 if (!NewStart.isUsable()) 6683 return ExprError(); 6684 if (Captures && !IsNonRectangularLB) 6685 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6686 if (NewStart.isInvalid()) 6687 return ExprError(); 6688 6689 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6690 ExprResult SavedUpdate = Update; 6691 ExprResult UpdateVal; 6692 if (VarRef.get()->getType()->isOverloadableType() || 6693 NewStart.get()->getType()->isOverloadableType() || 6694 Update.get()->getType()->isOverloadableType()) { 6695 Sema::TentativeAnalysisScope Trap(SemaRef); 6696 6697 Update = 6698 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6699 if (Update.isUsable()) { 6700 UpdateVal = 6701 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6702 VarRef.get(), SavedUpdate.get()); 6703 if (UpdateVal.isUsable()) { 6704 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6705 UpdateVal.get()); 6706 } 6707 } 6708 } 6709 6710 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6711 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6712 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6713 NewStart.get(), SavedUpdate.get()); 6714 if (!Update.isUsable()) 6715 return ExprError(); 6716 6717 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6718 VarRef.get()->getType())) { 6719 Update = SemaRef.PerformImplicitConversion( 6720 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6721 if (!Update.isUsable()) 6722 return ExprError(); 6723 } 6724 6725 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6726 } 6727 return Update; 6728 } 6729 6730 /// Convert integer expression \a E to make it have at least \a Bits 6731 /// bits. 6732 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6733 if (E == nullptr) 6734 return ExprError(); 6735 ASTContext &C = SemaRef.Context; 6736 QualType OldType = E->getType(); 6737 unsigned HasBits = C.getTypeSize(OldType); 6738 if (HasBits >= Bits) 6739 return ExprResult(E); 6740 // OK to convert to signed, because new type has more bits than old. 6741 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6742 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6743 true); 6744 } 6745 6746 /// Check if the given expression \a E is a constant integer that fits 6747 /// into \a Bits bits. 6748 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6749 if (E == nullptr) 6750 return false; 6751 llvm::APSInt Result; 6752 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6753 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6754 return false; 6755 } 6756 6757 /// Build preinits statement for the given declarations. 6758 static Stmt *buildPreInits(ASTContext &Context, 6759 MutableArrayRef<Decl *> PreInits) { 6760 if (!PreInits.empty()) { 6761 return new (Context) DeclStmt( 6762 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6763 SourceLocation(), SourceLocation()); 6764 } 6765 return nullptr; 6766 } 6767 6768 /// Build preinits statement for the given declarations. 6769 static Stmt * 6770 buildPreInits(ASTContext &Context, 6771 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6772 if (!Captures.empty()) { 6773 SmallVector<Decl *, 16> PreInits; 6774 for (const auto &Pair : Captures) 6775 PreInits.push_back(Pair.second->getDecl()); 6776 return buildPreInits(Context, PreInits); 6777 } 6778 return nullptr; 6779 } 6780 6781 /// Build postupdate expression for the given list of postupdates expressions. 6782 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6783 Expr *PostUpdate = nullptr; 6784 if (!PostUpdates.empty()) { 6785 for (Expr *E : PostUpdates) { 6786 Expr *ConvE = S.BuildCStyleCastExpr( 6787 E->getExprLoc(), 6788 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6789 E->getExprLoc(), E) 6790 .get(); 6791 PostUpdate = PostUpdate 6792 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6793 PostUpdate, ConvE) 6794 .get() 6795 : ConvE; 6796 } 6797 } 6798 return PostUpdate; 6799 } 6800 6801 /// Called on a for stmt to check itself and nested loops (if any). 6802 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6803 /// number of collapsed loops otherwise. 6804 static unsigned 6805 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6806 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6807 DSAStackTy &DSA, 6808 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6809 OMPLoopDirective::HelperExprs &Built) { 6810 unsigned NestedLoopCount = 1; 6811 if (CollapseLoopCountExpr) { 6812 // Found 'collapse' clause - calculate collapse number. 6813 Expr::EvalResult Result; 6814 if (!CollapseLoopCountExpr->isValueDependent() && 6815 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6816 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6817 } else { 6818 Built.clear(/*Size=*/1); 6819 return 1; 6820 } 6821 } 6822 unsigned OrderedLoopCount = 1; 6823 if (OrderedLoopCountExpr) { 6824 // Found 'ordered' clause - calculate collapse number. 6825 Expr::EvalResult EVResult; 6826 if (!OrderedLoopCountExpr->isValueDependent() && 6827 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6828 SemaRef.getASTContext())) { 6829 llvm::APSInt Result = EVResult.Val.getInt(); 6830 if (Result.getLimitedValue() < NestedLoopCount) { 6831 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6832 diag::err_omp_wrong_ordered_loop_count) 6833 << OrderedLoopCountExpr->getSourceRange(); 6834 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6835 diag::note_collapse_loop_count) 6836 << CollapseLoopCountExpr->getSourceRange(); 6837 } 6838 OrderedLoopCount = Result.getLimitedValue(); 6839 } else { 6840 Built.clear(/*Size=*/1); 6841 return 1; 6842 } 6843 } 6844 // This is helper routine for loop directives (e.g., 'for', 'simd', 6845 // 'for simd', etc.). 6846 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6847 SmallVector<LoopIterationSpace, 4> IterSpaces( 6848 std::max(OrderedLoopCount, NestedLoopCount)); 6849 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6850 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6851 if (checkOpenMPIterationSpace( 6852 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6853 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6854 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6855 return 0; 6856 // Move on to the next nested for loop, or to the loop body. 6857 // OpenMP [2.8.1, simd construct, Restrictions] 6858 // All loops associated with the construct must be perfectly nested; that 6859 // is, there must be no intervening code nor any OpenMP directive between 6860 // any two loops. 6861 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6862 } 6863 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6864 if (checkOpenMPIterationSpace( 6865 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6866 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6867 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6868 return 0; 6869 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6870 // Handle initialization of captured loop iterator variables. 6871 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6872 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6873 Captures[DRE] = DRE; 6874 } 6875 } 6876 // Move on to the next nested for loop, or to the loop body. 6877 // OpenMP [2.8.1, simd construct, Restrictions] 6878 // All loops associated with the construct must be perfectly nested; that 6879 // is, there must be no intervening code nor any OpenMP directive between 6880 // any two loops. 6881 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6882 } 6883 6884 Built.clear(/* size */ NestedLoopCount); 6885 6886 if (SemaRef.CurContext->isDependentContext()) 6887 return NestedLoopCount; 6888 6889 // An example of what is generated for the following code: 6890 // 6891 // #pragma omp simd collapse(2) ordered(2) 6892 // for (i = 0; i < NI; ++i) 6893 // for (k = 0; k < NK; ++k) 6894 // for (j = J0; j < NJ; j+=2) { 6895 // <loop body> 6896 // } 6897 // 6898 // We generate the code below. 6899 // Note: the loop body may be outlined in CodeGen. 6900 // Note: some counters may be C++ classes, operator- is used to find number of 6901 // iterations and operator+= to calculate counter value. 6902 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6903 // or i64 is currently supported). 6904 // 6905 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6906 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6907 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6908 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6909 // // similar updates for vars in clauses (e.g. 'linear') 6910 // <loop body (using local i and j)> 6911 // } 6912 // i = NI; // assign final values of counters 6913 // j = NJ; 6914 // 6915 6916 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6917 // the iteration counts of the collapsed for loops. 6918 // Precondition tests if there is at least one iteration (all conditions are 6919 // true). 6920 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6921 Expr *N0 = IterSpaces[0].NumIterations; 6922 ExprResult LastIteration32 = 6923 widenIterationCount(/*Bits=*/32, 6924 SemaRef 6925 .PerformImplicitConversion( 6926 N0->IgnoreImpCasts(), N0->getType(), 6927 Sema::AA_Converting, /*AllowExplicit=*/true) 6928 .get(), 6929 SemaRef); 6930 ExprResult LastIteration64 = widenIterationCount( 6931 /*Bits=*/64, 6932 SemaRef 6933 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6934 Sema::AA_Converting, 6935 /*AllowExplicit=*/true) 6936 .get(), 6937 SemaRef); 6938 6939 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6940 return NestedLoopCount; 6941 6942 ASTContext &C = SemaRef.Context; 6943 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6944 6945 Scope *CurScope = DSA.getCurScope(); 6946 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6947 if (PreCond.isUsable()) { 6948 PreCond = 6949 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6950 PreCond.get(), IterSpaces[Cnt].PreCond); 6951 } 6952 Expr *N = IterSpaces[Cnt].NumIterations; 6953 SourceLocation Loc = N->getExprLoc(); 6954 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6955 if (LastIteration32.isUsable()) 6956 LastIteration32 = SemaRef.BuildBinOp( 6957 CurScope, Loc, BO_Mul, LastIteration32.get(), 6958 SemaRef 6959 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6960 Sema::AA_Converting, 6961 /*AllowExplicit=*/true) 6962 .get()); 6963 if (LastIteration64.isUsable()) 6964 LastIteration64 = SemaRef.BuildBinOp( 6965 CurScope, Loc, BO_Mul, LastIteration64.get(), 6966 SemaRef 6967 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6968 Sema::AA_Converting, 6969 /*AllowExplicit=*/true) 6970 .get()); 6971 } 6972 6973 // Choose either the 32-bit or 64-bit version. 6974 ExprResult LastIteration = LastIteration64; 6975 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6976 (LastIteration32.isUsable() && 6977 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6978 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6979 fitsInto( 6980 /*Bits=*/32, 6981 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6982 LastIteration64.get(), SemaRef)))) 6983 LastIteration = LastIteration32; 6984 QualType VType = LastIteration.get()->getType(); 6985 QualType RealVType = VType; 6986 QualType StrideVType = VType; 6987 if (isOpenMPTaskLoopDirective(DKind)) { 6988 VType = 6989 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6990 StrideVType = 6991 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6992 } 6993 6994 if (!LastIteration.isUsable()) 6995 return 0; 6996 6997 // Save the number of iterations. 6998 ExprResult NumIterations = LastIteration; 6999 { 7000 LastIteration = SemaRef.BuildBinOp( 7001 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7002 LastIteration.get(), 7003 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7004 if (!LastIteration.isUsable()) 7005 return 0; 7006 } 7007 7008 // Calculate the last iteration number beforehand instead of doing this on 7009 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7010 llvm::APSInt Result; 7011 bool IsConstant = 7012 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7013 ExprResult CalcLastIteration; 7014 if (!IsConstant) { 7015 ExprResult SaveRef = 7016 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7017 LastIteration = SaveRef; 7018 7019 // Prepare SaveRef + 1. 7020 NumIterations = SemaRef.BuildBinOp( 7021 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7022 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7023 if (!NumIterations.isUsable()) 7024 return 0; 7025 } 7026 7027 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7028 7029 // Build variables passed into runtime, necessary for worksharing directives. 7030 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7031 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7032 isOpenMPDistributeDirective(DKind)) { 7033 // Lower bound variable, initialized with zero. 7034 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7035 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7036 SemaRef.AddInitializerToDecl(LBDecl, 7037 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7038 /*DirectInit*/ false); 7039 7040 // Upper bound variable, initialized with last iteration number. 7041 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7042 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7043 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7044 /*DirectInit*/ false); 7045 7046 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7047 // This will be used to implement clause 'lastprivate'. 7048 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7049 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7050 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7051 SemaRef.AddInitializerToDecl(ILDecl, 7052 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7053 /*DirectInit*/ false); 7054 7055 // Stride variable returned by runtime (we initialize it to 1 by default). 7056 VarDecl *STDecl = 7057 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7058 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7059 SemaRef.AddInitializerToDecl(STDecl, 7060 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7061 /*DirectInit*/ false); 7062 7063 // Build expression: UB = min(UB, LastIteration) 7064 // It is necessary for CodeGen of directives with static scheduling. 7065 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7066 UB.get(), LastIteration.get()); 7067 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7068 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7069 LastIteration.get(), UB.get()); 7070 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7071 CondOp.get()); 7072 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7073 7074 // If we have a combined directive that combines 'distribute', 'for' or 7075 // 'simd' we need to be able to access the bounds of the schedule of the 7076 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7077 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7078 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7079 // Lower bound variable, initialized with zero. 7080 VarDecl *CombLBDecl = 7081 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7082 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7083 SemaRef.AddInitializerToDecl( 7084 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7085 /*DirectInit*/ false); 7086 7087 // Upper bound variable, initialized with last iteration number. 7088 VarDecl *CombUBDecl = 7089 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7090 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7091 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7092 /*DirectInit*/ false); 7093 7094 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7095 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7096 ExprResult CombCondOp = 7097 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7098 LastIteration.get(), CombUB.get()); 7099 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7100 CombCondOp.get()); 7101 CombEUB = 7102 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7103 7104 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7105 // We expect to have at least 2 more parameters than the 'parallel' 7106 // directive does - the lower and upper bounds of the previous schedule. 7107 assert(CD->getNumParams() >= 4 && 7108 "Unexpected number of parameters in loop combined directive"); 7109 7110 // Set the proper type for the bounds given what we learned from the 7111 // enclosed loops. 7112 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7113 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7114 7115 // Previous lower and upper bounds are obtained from the region 7116 // parameters. 7117 PrevLB = 7118 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7119 PrevUB = 7120 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7121 } 7122 } 7123 7124 // Build the iteration variable and its initialization before loop. 7125 ExprResult IV; 7126 ExprResult Init, CombInit; 7127 { 7128 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7129 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7130 Expr *RHS = 7131 (isOpenMPWorksharingDirective(DKind) || 7132 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7133 ? LB.get() 7134 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7135 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7136 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7137 7138 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7139 Expr *CombRHS = 7140 (isOpenMPWorksharingDirective(DKind) || 7141 isOpenMPTaskLoopDirective(DKind) || 7142 isOpenMPDistributeDirective(DKind)) 7143 ? CombLB.get() 7144 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7145 CombInit = 7146 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7147 CombInit = 7148 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7149 } 7150 } 7151 7152 bool UseStrictCompare = 7153 RealVType->hasUnsignedIntegerRepresentation() && 7154 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7155 return LIS.IsStrictCompare; 7156 }); 7157 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7158 // unsigned IV)) for worksharing loops. 7159 SourceLocation CondLoc = AStmt->getBeginLoc(); 7160 Expr *BoundUB = UB.get(); 7161 if (UseStrictCompare) { 7162 BoundUB = 7163 SemaRef 7164 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7165 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7166 .get(); 7167 BoundUB = 7168 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7169 } 7170 ExprResult Cond = 7171 (isOpenMPWorksharingDirective(DKind) || 7172 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7173 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7174 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7175 BoundUB) 7176 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7177 NumIterations.get()); 7178 ExprResult CombDistCond; 7179 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7180 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7181 NumIterations.get()); 7182 } 7183 7184 ExprResult CombCond; 7185 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7186 Expr *BoundCombUB = CombUB.get(); 7187 if (UseStrictCompare) { 7188 BoundCombUB = 7189 SemaRef 7190 .BuildBinOp( 7191 CurScope, CondLoc, BO_Add, BoundCombUB, 7192 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7193 .get(); 7194 BoundCombUB = 7195 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7196 .get(); 7197 } 7198 CombCond = 7199 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7200 IV.get(), BoundCombUB); 7201 } 7202 // Loop increment (IV = IV + 1) 7203 SourceLocation IncLoc = AStmt->getBeginLoc(); 7204 ExprResult Inc = 7205 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7206 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7207 if (!Inc.isUsable()) 7208 return 0; 7209 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7210 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7211 if (!Inc.isUsable()) 7212 return 0; 7213 7214 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7215 // Used for directives with static scheduling. 7216 // In combined construct, add combined version that use CombLB and CombUB 7217 // base variables for the update 7218 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7219 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7220 isOpenMPDistributeDirective(DKind)) { 7221 // LB + ST 7222 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7223 if (!NextLB.isUsable()) 7224 return 0; 7225 // LB = LB + ST 7226 NextLB = 7227 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7228 NextLB = 7229 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7230 if (!NextLB.isUsable()) 7231 return 0; 7232 // UB + ST 7233 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7234 if (!NextUB.isUsable()) 7235 return 0; 7236 // UB = UB + ST 7237 NextUB = 7238 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7239 NextUB = 7240 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7241 if (!NextUB.isUsable()) 7242 return 0; 7243 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7244 CombNextLB = 7245 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7246 if (!NextLB.isUsable()) 7247 return 0; 7248 // LB = LB + ST 7249 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7250 CombNextLB.get()); 7251 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7252 /*DiscardedValue*/ false); 7253 if (!CombNextLB.isUsable()) 7254 return 0; 7255 // UB + ST 7256 CombNextUB = 7257 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7258 if (!CombNextUB.isUsable()) 7259 return 0; 7260 // UB = UB + ST 7261 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7262 CombNextUB.get()); 7263 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7264 /*DiscardedValue*/ false); 7265 if (!CombNextUB.isUsable()) 7266 return 0; 7267 } 7268 } 7269 7270 // Create increment expression for distribute loop when combined in a same 7271 // directive with for as IV = IV + ST; ensure upper bound expression based 7272 // on PrevUB instead of NumIterations - used to implement 'for' when found 7273 // in combination with 'distribute', like in 'distribute parallel for' 7274 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7275 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7276 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7277 DistCond = SemaRef.BuildBinOp( 7278 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7279 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7280 7281 DistInc = 7282 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7283 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7284 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7285 DistInc.get()); 7286 DistInc = 7287 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7288 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7289 7290 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7291 // construct 7292 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7293 ExprResult IsUBGreater = 7294 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7295 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7296 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7297 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7298 CondOp.get()); 7299 PrevEUB = 7300 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7301 7302 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7303 // parallel for is in combination with a distribute directive with 7304 // schedule(static, 1) 7305 Expr *BoundPrevUB = PrevUB.get(); 7306 if (UseStrictCompare) { 7307 BoundPrevUB = 7308 SemaRef 7309 .BuildBinOp( 7310 CurScope, CondLoc, BO_Add, BoundPrevUB, 7311 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7312 .get(); 7313 BoundPrevUB = 7314 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7315 .get(); 7316 } 7317 ParForInDistCond = 7318 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7319 IV.get(), BoundPrevUB); 7320 } 7321 7322 // Build updates and final values of the loop counters. 7323 bool HasErrors = false; 7324 Built.Counters.resize(NestedLoopCount); 7325 Built.Inits.resize(NestedLoopCount); 7326 Built.Updates.resize(NestedLoopCount); 7327 Built.Finals.resize(NestedLoopCount); 7328 Built.DependentCounters.resize(NestedLoopCount); 7329 Built.DependentInits.resize(NestedLoopCount); 7330 Built.FinalsConditions.resize(NestedLoopCount); 7331 { 7332 // We implement the following algorithm for obtaining the 7333 // original loop iteration variable values based on the 7334 // value of the collapsed loop iteration variable IV. 7335 // 7336 // Let n+1 be the number of collapsed loops in the nest. 7337 // Iteration variables (I0, I1, .... In) 7338 // Iteration counts (N0, N1, ... Nn) 7339 // 7340 // Acc = IV; 7341 // 7342 // To compute Ik for loop k, 0 <= k <= n, generate: 7343 // Prod = N(k+1) * N(k+2) * ... * Nn; 7344 // Ik = Acc / Prod; 7345 // Acc -= Ik * Prod; 7346 // 7347 ExprResult Acc = IV; 7348 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7349 LoopIterationSpace &IS = IterSpaces[Cnt]; 7350 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7351 ExprResult Iter; 7352 7353 // Compute prod 7354 ExprResult Prod = 7355 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7356 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7357 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7358 IterSpaces[K].NumIterations); 7359 7360 // Iter = Acc / Prod 7361 // If there is at least one more inner loop to avoid 7362 // multiplication by 1. 7363 if (Cnt + 1 < NestedLoopCount) 7364 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7365 Acc.get(), Prod.get()); 7366 else 7367 Iter = Acc; 7368 if (!Iter.isUsable()) { 7369 HasErrors = true; 7370 break; 7371 } 7372 7373 // Update Acc: 7374 // Acc -= Iter * Prod 7375 // Check if there is at least one more inner loop to avoid 7376 // multiplication by 1. 7377 if (Cnt + 1 < NestedLoopCount) 7378 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7379 Iter.get(), Prod.get()); 7380 else 7381 Prod = Iter; 7382 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7383 Acc.get(), Prod.get()); 7384 7385 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7386 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7387 DeclRefExpr *CounterVar = buildDeclRefExpr( 7388 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7389 /*RefersToCapture=*/true); 7390 ExprResult Init = 7391 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7392 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7393 if (!Init.isUsable()) { 7394 HasErrors = true; 7395 break; 7396 } 7397 ExprResult Update = buildCounterUpdate( 7398 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7399 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7400 if (!Update.isUsable()) { 7401 HasErrors = true; 7402 break; 7403 } 7404 7405 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7406 ExprResult Final = 7407 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7408 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7409 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7410 if (!Final.isUsable()) { 7411 HasErrors = true; 7412 break; 7413 } 7414 7415 if (!Update.isUsable() || !Final.isUsable()) { 7416 HasErrors = true; 7417 break; 7418 } 7419 // Save results 7420 Built.Counters[Cnt] = IS.CounterVar; 7421 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7422 Built.Inits[Cnt] = Init.get(); 7423 Built.Updates[Cnt] = Update.get(); 7424 Built.Finals[Cnt] = Final.get(); 7425 Built.DependentCounters[Cnt] = nullptr; 7426 Built.DependentInits[Cnt] = nullptr; 7427 Built.FinalsConditions[Cnt] = nullptr; 7428 if (IS.IsNonRectangularLB) { 7429 Built.DependentCounters[Cnt] = 7430 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7431 Built.DependentInits[Cnt] = 7432 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7433 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7434 } 7435 } 7436 } 7437 7438 if (HasErrors) 7439 return 0; 7440 7441 // Save results 7442 Built.IterationVarRef = IV.get(); 7443 Built.LastIteration = LastIteration.get(); 7444 Built.NumIterations = NumIterations.get(); 7445 Built.CalcLastIteration = SemaRef 7446 .ActOnFinishFullExpr(CalcLastIteration.get(), 7447 /*DiscardedValue=*/false) 7448 .get(); 7449 Built.PreCond = PreCond.get(); 7450 Built.PreInits = buildPreInits(C, Captures); 7451 Built.Cond = Cond.get(); 7452 Built.Init = Init.get(); 7453 Built.Inc = Inc.get(); 7454 Built.LB = LB.get(); 7455 Built.UB = UB.get(); 7456 Built.IL = IL.get(); 7457 Built.ST = ST.get(); 7458 Built.EUB = EUB.get(); 7459 Built.NLB = NextLB.get(); 7460 Built.NUB = NextUB.get(); 7461 Built.PrevLB = PrevLB.get(); 7462 Built.PrevUB = PrevUB.get(); 7463 Built.DistInc = DistInc.get(); 7464 Built.PrevEUB = PrevEUB.get(); 7465 Built.DistCombinedFields.LB = CombLB.get(); 7466 Built.DistCombinedFields.UB = CombUB.get(); 7467 Built.DistCombinedFields.EUB = CombEUB.get(); 7468 Built.DistCombinedFields.Init = CombInit.get(); 7469 Built.DistCombinedFields.Cond = CombCond.get(); 7470 Built.DistCombinedFields.NLB = CombNextLB.get(); 7471 Built.DistCombinedFields.NUB = CombNextUB.get(); 7472 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7473 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7474 7475 return NestedLoopCount; 7476 } 7477 7478 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7479 auto CollapseClauses = 7480 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7481 if (CollapseClauses.begin() != CollapseClauses.end()) 7482 return (*CollapseClauses.begin())->getNumForLoops(); 7483 return nullptr; 7484 } 7485 7486 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7487 auto OrderedClauses = 7488 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7489 if (OrderedClauses.begin() != OrderedClauses.end()) 7490 return (*OrderedClauses.begin())->getNumForLoops(); 7491 return nullptr; 7492 } 7493 7494 static bool checkSimdlenSafelenSpecified(Sema &S, 7495 const ArrayRef<OMPClause *> Clauses) { 7496 const OMPSafelenClause *Safelen = nullptr; 7497 const OMPSimdlenClause *Simdlen = nullptr; 7498 7499 for (const OMPClause *Clause : Clauses) { 7500 if (Clause->getClauseKind() == OMPC_safelen) 7501 Safelen = cast<OMPSafelenClause>(Clause); 7502 else if (Clause->getClauseKind() == OMPC_simdlen) 7503 Simdlen = cast<OMPSimdlenClause>(Clause); 7504 if (Safelen && Simdlen) 7505 break; 7506 } 7507 7508 if (Simdlen && Safelen) { 7509 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7510 const Expr *SafelenLength = Safelen->getSafelen(); 7511 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7512 SimdlenLength->isInstantiationDependent() || 7513 SimdlenLength->containsUnexpandedParameterPack()) 7514 return false; 7515 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7516 SafelenLength->isInstantiationDependent() || 7517 SafelenLength->containsUnexpandedParameterPack()) 7518 return false; 7519 Expr::EvalResult SimdlenResult, SafelenResult; 7520 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7521 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7522 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7523 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7524 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7525 // If both simdlen and safelen clauses are specified, the value of the 7526 // simdlen parameter must be less than or equal to the value of the safelen 7527 // parameter. 7528 if (SimdlenRes > SafelenRes) { 7529 S.Diag(SimdlenLength->getExprLoc(), 7530 diag::err_omp_wrong_simdlen_safelen_values) 7531 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7532 return true; 7533 } 7534 } 7535 return false; 7536 } 7537 7538 StmtResult 7539 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7540 SourceLocation StartLoc, SourceLocation EndLoc, 7541 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7542 if (!AStmt) 7543 return StmtError(); 7544 7545 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7546 OMPLoopDirective::HelperExprs B; 7547 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7548 // define the nested loops number. 7549 unsigned NestedLoopCount = checkOpenMPLoop( 7550 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7551 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7552 if (NestedLoopCount == 0) 7553 return StmtError(); 7554 7555 assert((CurContext->isDependentContext() || B.builtAll()) && 7556 "omp simd loop exprs were not built"); 7557 7558 if (!CurContext->isDependentContext()) { 7559 // Finalize the clauses that need pre-built expressions for CodeGen. 7560 for (OMPClause *C : Clauses) { 7561 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7562 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7563 B.NumIterations, *this, CurScope, 7564 DSAStack)) 7565 return StmtError(); 7566 } 7567 } 7568 7569 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7570 return StmtError(); 7571 7572 setFunctionHasBranchProtectedScope(); 7573 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7574 Clauses, AStmt, B); 7575 } 7576 7577 StmtResult 7578 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7579 SourceLocation StartLoc, SourceLocation EndLoc, 7580 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7581 if (!AStmt) 7582 return StmtError(); 7583 7584 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7585 OMPLoopDirective::HelperExprs B; 7586 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7587 // define the nested loops number. 7588 unsigned NestedLoopCount = checkOpenMPLoop( 7589 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7590 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7591 if (NestedLoopCount == 0) 7592 return StmtError(); 7593 7594 assert((CurContext->isDependentContext() || B.builtAll()) && 7595 "omp for loop exprs were not built"); 7596 7597 if (!CurContext->isDependentContext()) { 7598 // Finalize the clauses that need pre-built expressions for CodeGen. 7599 for (OMPClause *C : Clauses) { 7600 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7601 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7602 B.NumIterations, *this, CurScope, 7603 DSAStack)) 7604 return StmtError(); 7605 } 7606 } 7607 7608 setFunctionHasBranchProtectedScope(); 7609 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7610 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7611 } 7612 7613 StmtResult Sema::ActOnOpenMPForSimdDirective( 7614 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7615 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7616 if (!AStmt) 7617 return StmtError(); 7618 7619 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7620 OMPLoopDirective::HelperExprs B; 7621 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7622 // define the nested loops number. 7623 unsigned NestedLoopCount = 7624 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7625 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7626 VarsWithImplicitDSA, B); 7627 if (NestedLoopCount == 0) 7628 return StmtError(); 7629 7630 assert((CurContext->isDependentContext() || B.builtAll()) && 7631 "omp for simd loop exprs were not built"); 7632 7633 if (!CurContext->isDependentContext()) { 7634 // Finalize the clauses that need pre-built expressions for CodeGen. 7635 for (OMPClause *C : Clauses) { 7636 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7637 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7638 B.NumIterations, *this, CurScope, 7639 DSAStack)) 7640 return StmtError(); 7641 } 7642 } 7643 7644 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7645 return StmtError(); 7646 7647 setFunctionHasBranchProtectedScope(); 7648 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7649 Clauses, AStmt, B); 7650 } 7651 7652 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7653 Stmt *AStmt, 7654 SourceLocation StartLoc, 7655 SourceLocation EndLoc) { 7656 if (!AStmt) 7657 return StmtError(); 7658 7659 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7660 auto BaseStmt = AStmt; 7661 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7662 BaseStmt = CS->getCapturedStmt(); 7663 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7664 auto S = C->children(); 7665 if (S.begin() == S.end()) 7666 return StmtError(); 7667 // All associated statements must be '#pragma omp section' except for 7668 // the first one. 7669 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7670 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7671 if (SectionStmt) 7672 Diag(SectionStmt->getBeginLoc(), 7673 diag::err_omp_sections_substmt_not_section); 7674 return StmtError(); 7675 } 7676 cast<OMPSectionDirective>(SectionStmt) 7677 ->setHasCancel(DSAStack->isCancelRegion()); 7678 } 7679 } else { 7680 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7681 return StmtError(); 7682 } 7683 7684 setFunctionHasBranchProtectedScope(); 7685 7686 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7687 DSAStack->isCancelRegion()); 7688 } 7689 7690 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7691 SourceLocation StartLoc, 7692 SourceLocation EndLoc) { 7693 if (!AStmt) 7694 return StmtError(); 7695 7696 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7697 7698 setFunctionHasBranchProtectedScope(); 7699 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7700 7701 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7702 DSAStack->isCancelRegion()); 7703 } 7704 7705 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7706 Stmt *AStmt, 7707 SourceLocation StartLoc, 7708 SourceLocation EndLoc) { 7709 if (!AStmt) 7710 return StmtError(); 7711 7712 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7713 7714 setFunctionHasBranchProtectedScope(); 7715 7716 // OpenMP [2.7.3, single Construct, Restrictions] 7717 // The copyprivate clause must not be used with the nowait clause. 7718 const OMPClause *Nowait = nullptr; 7719 const OMPClause *Copyprivate = nullptr; 7720 for (const OMPClause *Clause : Clauses) { 7721 if (Clause->getClauseKind() == OMPC_nowait) 7722 Nowait = Clause; 7723 else if (Clause->getClauseKind() == OMPC_copyprivate) 7724 Copyprivate = Clause; 7725 if (Copyprivate && Nowait) { 7726 Diag(Copyprivate->getBeginLoc(), 7727 diag::err_omp_single_copyprivate_with_nowait); 7728 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7729 return StmtError(); 7730 } 7731 } 7732 7733 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7734 } 7735 7736 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7737 SourceLocation StartLoc, 7738 SourceLocation EndLoc) { 7739 if (!AStmt) 7740 return StmtError(); 7741 7742 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7743 7744 setFunctionHasBranchProtectedScope(); 7745 7746 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7747 } 7748 7749 StmtResult Sema::ActOnOpenMPCriticalDirective( 7750 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7751 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7752 if (!AStmt) 7753 return StmtError(); 7754 7755 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7756 7757 bool ErrorFound = false; 7758 llvm::APSInt Hint; 7759 SourceLocation HintLoc; 7760 bool DependentHint = false; 7761 for (const OMPClause *C : Clauses) { 7762 if (C->getClauseKind() == OMPC_hint) { 7763 if (!DirName.getName()) { 7764 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7765 ErrorFound = true; 7766 } 7767 Expr *E = cast<OMPHintClause>(C)->getHint(); 7768 if (E->isTypeDependent() || E->isValueDependent() || 7769 E->isInstantiationDependent()) { 7770 DependentHint = true; 7771 } else { 7772 Hint = E->EvaluateKnownConstInt(Context); 7773 HintLoc = C->getBeginLoc(); 7774 } 7775 } 7776 } 7777 if (ErrorFound) 7778 return StmtError(); 7779 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7780 if (Pair.first && DirName.getName() && !DependentHint) { 7781 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7782 Diag(StartLoc, diag::err_omp_critical_with_hint); 7783 if (HintLoc.isValid()) 7784 Diag(HintLoc, diag::note_omp_critical_hint_here) 7785 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7786 else 7787 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7788 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7789 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7790 << 1 7791 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7792 /*Radix=*/10, /*Signed=*/false); 7793 } else { 7794 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7795 } 7796 } 7797 } 7798 7799 setFunctionHasBranchProtectedScope(); 7800 7801 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7802 Clauses, AStmt); 7803 if (!Pair.first && DirName.getName() && !DependentHint) 7804 DSAStack->addCriticalWithHint(Dir, Hint); 7805 return Dir; 7806 } 7807 7808 StmtResult Sema::ActOnOpenMPParallelForDirective( 7809 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7810 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7811 if (!AStmt) 7812 return StmtError(); 7813 7814 auto *CS = cast<CapturedStmt>(AStmt); 7815 // 1.2.2 OpenMP Language Terminology 7816 // Structured block - An executable statement with a single entry at the 7817 // top and a single exit at the bottom. 7818 // The point of exit cannot be a branch out of the structured block. 7819 // longjmp() and throw() must not violate the entry/exit criteria. 7820 CS->getCapturedDecl()->setNothrow(); 7821 7822 OMPLoopDirective::HelperExprs B; 7823 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7824 // define the nested loops number. 7825 unsigned NestedLoopCount = 7826 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7827 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7828 VarsWithImplicitDSA, B); 7829 if (NestedLoopCount == 0) 7830 return StmtError(); 7831 7832 assert((CurContext->isDependentContext() || B.builtAll()) && 7833 "omp parallel for loop exprs were not built"); 7834 7835 if (!CurContext->isDependentContext()) { 7836 // Finalize the clauses that need pre-built expressions for CodeGen. 7837 for (OMPClause *C : Clauses) { 7838 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7839 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7840 B.NumIterations, *this, CurScope, 7841 DSAStack)) 7842 return StmtError(); 7843 } 7844 } 7845 7846 setFunctionHasBranchProtectedScope(); 7847 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7848 NestedLoopCount, Clauses, AStmt, B, 7849 DSAStack->isCancelRegion()); 7850 } 7851 7852 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7853 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7854 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7855 if (!AStmt) 7856 return StmtError(); 7857 7858 auto *CS = cast<CapturedStmt>(AStmt); 7859 // 1.2.2 OpenMP Language Terminology 7860 // Structured block - An executable statement with a single entry at the 7861 // top and a single exit at the bottom. 7862 // The point of exit cannot be a branch out of the structured block. 7863 // longjmp() and throw() must not violate the entry/exit criteria. 7864 CS->getCapturedDecl()->setNothrow(); 7865 7866 OMPLoopDirective::HelperExprs B; 7867 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7868 // define the nested loops number. 7869 unsigned NestedLoopCount = 7870 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7871 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7872 VarsWithImplicitDSA, B); 7873 if (NestedLoopCount == 0) 7874 return StmtError(); 7875 7876 if (!CurContext->isDependentContext()) { 7877 // Finalize the clauses that need pre-built expressions for CodeGen. 7878 for (OMPClause *C : Clauses) { 7879 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7880 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7881 B.NumIterations, *this, CurScope, 7882 DSAStack)) 7883 return StmtError(); 7884 } 7885 } 7886 7887 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7888 return StmtError(); 7889 7890 setFunctionHasBranchProtectedScope(); 7891 return OMPParallelForSimdDirective::Create( 7892 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7893 } 7894 7895 StmtResult 7896 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7897 Stmt *AStmt, SourceLocation StartLoc, 7898 SourceLocation EndLoc) { 7899 if (!AStmt) 7900 return StmtError(); 7901 7902 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7903 auto BaseStmt = AStmt; 7904 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7905 BaseStmt = CS->getCapturedStmt(); 7906 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7907 auto S = C->children(); 7908 if (S.begin() == S.end()) 7909 return StmtError(); 7910 // All associated statements must be '#pragma omp section' except for 7911 // the first one. 7912 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7913 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7914 if (SectionStmt) 7915 Diag(SectionStmt->getBeginLoc(), 7916 diag::err_omp_parallel_sections_substmt_not_section); 7917 return StmtError(); 7918 } 7919 cast<OMPSectionDirective>(SectionStmt) 7920 ->setHasCancel(DSAStack->isCancelRegion()); 7921 } 7922 } else { 7923 Diag(AStmt->getBeginLoc(), 7924 diag::err_omp_parallel_sections_not_compound_stmt); 7925 return StmtError(); 7926 } 7927 7928 setFunctionHasBranchProtectedScope(); 7929 7930 return OMPParallelSectionsDirective::Create( 7931 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7932 } 7933 7934 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7935 Stmt *AStmt, SourceLocation StartLoc, 7936 SourceLocation EndLoc) { 7937 if (!AStmt) 7938 return StmtError(); 7939 7940 auto *CS = cast<CapturedStmt>(AStmt); 7941 // 1.2.2 OpenMP Language Terminology 7942 // Structured block - An executable statement with a single entry at the 7943 // top and a single exit at the bottom. 7944 // The point of exit cannot be a branch out of the structured block. 7945 // longjmp() and throw() must not violate the entry/exit criteria. 7946 CS->getCapturedDecl()->setNothrow(); 7947 7948 setFunctionHasBranchProtectedScope(); 7949 7950 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7951 DSAStack->isCancelRegion()); 7952 } 7953 7954 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7955 SourceLocation EndLoc) { 7956 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7957 } 7958 7959 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7960 SourceLocation EndLoc) { 7961 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7962 } 7963 7964 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7965 SourceLocation EndLoc) { 7966 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7967 } 7968 7969 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7970 Stmt *AStmt, 7971 SourceLocation StartLoc, 7972 SourceLocation EndLoc) { 7973 if (!AStmt) 7974 return StmtError(); 7975 7976 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7977 7978 setFunctionHasBranchProtectedScope(); 7979 7980 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7981 AStmt, 7982 DSAStack->getTaskgroupReductionRef()); 7983 } 7984 7985 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7986 SourceLocation StartLoc, 7987 SourceLocation EndLoc) { 7988 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7989 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7990 } 7991 7992 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7993 Stmt *AStmt, 7994 SourceLocation StartLoc, 7995 SourceLocation EndLoc) { 7996 const OMPClause *DependFound = nullptr; 7997 const OMPClause *DependSourceClause = nullptr; 7998 const OMPClause *DependSinkClause = nullptr; 7999 bool ErrorFound = false; 8000 const OMPThreadsClause *TC = nullptr; 8001 const OMPSIMDClause *SC = nullptr; 8002 for (const OMPClause *C : Clauses) { 8003 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8004 DependFound = C; 8005 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8006 if (DependSourceClause) { 8007 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8008 << getOpenMPDirectiveName(OMPD_ordered) 8009 << getOpenMPClauseName(OMPC_depend) << 2; 8010 ErrorFound = true; 8011 } else { 8012 DependSourceClause = C; 8013 } 8014 if (DependSinkClause) { 8015 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8016 << 0; 8017 ErrorFound = true; 8018 } 8019 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8020 if (DependSourceClause) { 8021 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8022 << 1; 8023 ErrorFound = true; 8024 } 8025 DependSinkClause = C; 8026 } 8027 } else if (C->getClauseKind() == OMPC_threads) { 8028 TC = cast<OMPThreadsClause>(C); 8029 } else if (C->getClauseKind() == OMPC_simd) { 8030 SC = cast<OMPSIMDClause>(C); 8031 } 8032 } 8033 if (!ErrorFound && !SC && 8034 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8035 // OpenMP [2.8.1,simd Construct, Restrictions] 8036 // An ordered construct with the simd clause is the only OpenMP construct 8037 // that can appear in the simd region. 8038 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 8039 ErrorFound = true; 8040 } else if (DependFound && (TC || SC)) { 8041 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8042 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8043 ErrorFound = true; 8044 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8045 Diag(DependFound->getBeginLoc(), 8046 diag::err_omp_ordered_directive_without_param); 8047 ErrorFound = true; 8048 } else if (TC || Clauses.empty()) { 8049 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8050 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8051 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8052 << (TC != nullptr); 8053 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8054 ErrorFound = true; 8055 } 8056 } 8057 if ((!AStmt && !DependFound) || ErrorFound) 8058 return StmtError(); 8059 8060 if (AStmt) { 8061 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8062 8063 setFunctionHasBranchProtectedScope(); 8064 } 8065 8066 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8067 } 8068 8069 namespace { 8070 /// Helper class for checking expression in 'omp atomic [update]' 8071 /// construct. 8072 class OpenMPAtomicUpdateChecker { 8073 /// Error results for atomic update expressions. 8074 enum ExprAnalysisErrorCode { 8075 /// A statement is not an expression statement. 8076 NotAnExpression, 8077 /// Expression is not builtin binary or unary operation. 8078 NotABinaryOrUnaryExpression, 8079 /// Unary operation is not post-/pre- increment/decrement operation. 8080 NotAnUnaryIncDecExpression, 8081 /// An expression is not of scalar type. 8082 NotAScalarType, 8083 /// A binary operation is not an assignment operation. 8084 NotAnAssignmentOp, 8085 /// RHS part of the binary operation is not a binary expression. 8086 NotABinaryExpression, 8087 /// RHS part is not additive/multiplicative/shift/biwise binary 8088 /// expression. 8089 NotABinaryOperator, 8090 /// RHS binary operation does not have reference to the updated LHS 8091 /// part. 8092 NotAnUpdateExpression, 8093 /// No errors is found. 8094 NoError 8095 }; 8096 /// Reference to Sema. 8097 Sema &SemaRef; 8098 /// A location for note diagnostics (when error is found). 8099 SourceLocation NoteLoc; 8100 /// 'x' lvalue part of the source atomic expression. 8101 Expr *X; 8102 /// 'expr' rvalue part of the source atomic expression. 8103 Expr *E; 8104 /// Helper expression of the form 8105 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8106 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8107 Expr *UpdateExpr; 8108 /// Is 'x' a LHS in a RHS part of full update expression. It is 8109 /// important for non-associative operations. 8110 bool IsXLHSInRHSPart; 8111 BinaryOperatorKind Op; 8112 SourceLocation OpLoc; 8113 /// true if the source expression is a postfix unary operation, false 8114 /// if it is a prefix unary operation. 8115 bool IsPostfixUpdate; 8116 8117 public: 8118 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8119 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8120 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8121 /// Check specified statement that it is suitable for 'atomic update' 8122 /// constructs and extract 'x', 'expr' and Operation from the original 8123 /// expression. If DiagId and NoteId == 0, then only check is performed 8124 /// without error notification. 8125 /// \param DiagId Diagnostic which should be emitted if error is found. 8126 /// \param NoteId Diagnostic note for the main error message. 8127 /// \return true if statement is not an update expression, false otherwise. 8128 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8129 /// Return the 'x' lvalue part of the source atomic expression. 8130 Expr *getX() const { return X; } 8131 /// Return the 'expr' rvalue part of the source atomic expression. 8132 Expr *getExpr() const { return E; } 8133 /// Return the update expression used in calculation of the updated 8134 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8135 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8136 Expr *getUpdateExpr() const { return UpdateExpr; } 8137 /// Return true if 'x' is LHS in RHS part of full update expression, 8138 /// false otherwise. 8139 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8140 8141 /// true if the source expression is a postfix unary operation, false 8142 /// if it is a prefix unary operation. 8143 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8144 8145 private: 8146 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8147 unsigned NoteId = 0); 8148 }; 8149 } // namespace 8150 8151 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8152 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8153 ExprAnalysisErrorCode ErrorFound = NoError; 8154 SourceLocation ErrorLoc, NoteLoc; 8155 SourceRange ErrorRange, NoteRange; 8156 // Allowed constructs are: 8157 // x = x binop expr; 8158 // x = expr binop x; 8159 if (AtomicBinOp->getOpcode() == BO_Assign) { 8160 X = AtomicBinOp->getLHS(); 8161 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8162 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8163 if (AtomicInnerBinOp->isMultiplicativeOp() || 8164 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8165 AtomicInnerBinOp->isBitwiseOp()) { 8166 Op = AtomicInnerBinOp->getOpcode(); 8167 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8168 Expr *LHS = AtomicInnerBinOp->getLHS(); 8169 Expr *RHS = AtomicInnerBinOp->getRHS(); 8170 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8171 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8172 /*Canonical=*/true); 8173 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8174 /*Canonical=*/true); 8175 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8176 /*Canonical=*/true); 8177 if (XId == LHSId) { 8178 E = RHS; 8179 IsXLHSInRHSPart = true; 8180 } else if (XId == RHSId) { 8181 E = LHS; 8182 IsXLHSInRHSPart = false; 8183 } else { 8184 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8185 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8186 NoteLoc = X->getExprLoc(); 8187 NoteRange = X->getSourceRange(); 8188 ErrorFound = NotAnUpdateExpression; 8189 } 8190 } else { 8191 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8192 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8193 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8194 NoteRange = SourceRange(NoteLoc, NoteLoc); 8195 ErrorFound = NotABinaryOperator; 8196 } 8197 } else { 8198 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8199 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8200 ErrorFound = NotABinaryExpression; 8201 } 8202 } else { 8203 ErrorLoc = AtomicBinOp->getExprLoc(); 8204 ErrorRange = AtomicBinOp->getSourceRange(); 8205 NoteLoc = AtomicBinOp->getOperatorLoc(); 8206 NoteRange = SourceRange(NoteLoc, NoteLoc); 8207 ErrorFound = NotAnAssignmentOp; 8208 } 8209 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8210 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8211 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8212 return true; 8213 } 8214 if (SemaRef.CurContext->isDependentContext()) 8215 E = X = UpdateExpr = nullptr; 8216 return ErrorFound != NoError; 8217 } 8218 8219 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8220 unsigned NoteId) { 8221 ExprAnalysisErrorCode ErrorFound = NoError; 8222 SourceLocation ErrorLoc, NoteLoc; 8223 SourceRange ErrorRange, NoteRange; 8224 // Allowed constructs are: 8225 // x++; 8226 // x--; 8227 // ++x; 8228 // --x; 8229 // x binop= expr; 8230 // x = x binop expr; 8231 // x = expr binop x; 8232 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8233 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8234 if (AtomicBody->getType()->isScalarType() || 8235 AtomicBody->isInstantiationDependent()) { 8236 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8237 AtomicBody->IgnoreParenImpCasts())) { 8238 // Check for Compound Assignment Operation 8239 Op = BinaryOperator::getOpForCompoundAssignment( 8240 AtomicCompAssignOp->getOpcode()); 8241 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8242 E = AtomicCompAssignOp->getRHS(); 8243 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8244 IsXLHSInRHSPart = true; 8245 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8246 AtomicBody->IgnoreParenImpCasts())) { 8247 // Check for Binary Operation 8248 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8249 return true; 8250 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8251 AtomicBody->IgnoreParenImpCasts())) { 8252 // Check for Unary Operation 8253 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8254 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8255 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8256 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8257 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8258 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8259 IsXLHSInRHSPart = true; 8260 } else { 8261 ErrorFound = NotAnUnaryIncDecExpression; 8262 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8263 ErrorRange = AtomicUnaryOp->getSourceRange(); 8264 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8265 NoteRange = SourceRange(NoteLoc, NoteLoc); 8266 } 8267 } else if (!AtomicBody->isInstantiationDependent()) { 8268 ErrorFound = NotABinaryOrUnaryExpression; 8269 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8270 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8271 } 8272 } else { 8273 ErrorFound = NotAScalarType; 8274 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8275 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8276 } 8277 } else { 8278 ErrorFound = NotAnExpression; 8279 NoteLoc = ErrorLoc = S->getBeginLoc(); 8280 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8281 } 8282 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8283 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8284 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8285 return true; 8286 } 8287 if (SemaRef.CurContext->isDependentContext()) 8288 E = X = UpdateExpr = nullptr; 8289 if (ErrorFound == NoError && E && X) { 8290 // Build an update expression of form 'OpaqueValueExpr(x) binop 8291 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8292 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8293 auto *OVEX = new (SemaRef.getASTContext()) 8294 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8295 auto *OVEExpr = new (SemaRef.getASTContext()) 8296 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8297 ExprResult Update = 8298 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8299 IsXLHSInRHSPart ? OVEExpr : OVEX); 8300 if (Update.isInvalid()) 8301 return true; 8302 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8303 Sema::AA_Casting); 8304 if (Update.isInvalid()) 8305 return true; 8306 UpdateExpr = Update.get(); 8307 } 8308 return ErrorFound != NoError; 8309 } 8310 8311 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8312 Stmt *AStmt, 8313 SourceLocation StartLoc, 8314 SourceLocation EndLoc) { 8315 if (!AStmt) 8316 return StmtError(); 8317 8318 auto *CS = cast<CapturedStmt>(AStmt); 8319 // 1.2.2 OpenMP Language Terminology 8320 // Structured block - An executable statement with a single entry at the 8321 // top and a single exit at the bottom. 8322 // The point of exit cannot be a branch out of the structured block. 8323 // longjmp() and throw() must not violate the entry/exit criteria. 8324 OpenMPClauseKind AtomicKind = OMPC_unknown; 8325 SourceLocation AtomicKindLoc; 8326 for (const OMPClause *C : Clauses) { 8327 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8328 C->getClauseKind() == OMPC_update || 8329 C->getClauseKind() == OMPC_capture) { 8330 if (AtomicKind != OMPC_unknown) { 8331 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8332 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8333 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8334 << getOpenMPClauseName(AtomicKind); 8335 } else { 8336 AtomicKind = C->getClauseKind(); 8337 AtomicKindLoc = C->getBeginLoc(); 8338 } 8339 } 8340 } 8341 8342 Stmt *Body = CS->getCapturedStmt(); 8343 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8344 Body = EWC->getSubExpr(); 8345 8346 Expr *X = nullptr; 8347 Expr *V = nullptr; 8348 Expr *E = nullptr; 8349 Expr *UE = nullptr; 8350 bool IsXLHSInRHSPart = false; 8351 bool IsPostfixUpdate = false; 8352 // OpenMP [2.12.6, atomic Construct] 8353 // In the next expressions: 8354 // * x and v (as applicable) are both l-value expressions with scalar type. 8355 // * During the execution of an atomic region, multiple syntactic 8356 // occurrences of x must designate the same storage location. 8357 // * Neither of v and expr (as applicable) may access the storage location 8358 // designated by x. 8359 // * Neither of x and expr (as applicable) may access the storage location 8360 // designated by v. 8361 // * expr is an expression with scalar type. 8362 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8363 // * binop, binop=, ++, and -- are not overloaded operators. 8364 // * The expression x binop expr must be numerically equivalent to x binop 8365 // (expr). This requirement is satisfied if the operators in expr have 8366 // precedence greater than binop, or by using parentheses around expr or 8367 // subexpressions of expr. 8368 // * The expression expr binop x must be numerically equivalent to (expr) 8369 // binop x. This requirement is satisfied if the operators in expr have 8370 // precedence equal to or greater than binop, or by using parentheses around 8371 // expr or subexpressions of expr. 8372 // * For forms that allow multiple occurrences of x, the number of times 8373 // that x is evaluated is unspecified. 8374 if (AtomicKind == OMPC_read) { 8375 enum { 8376 NotAnExpression, 8377 NotAnAssignmentOp, 8378 NotAScalarType, 8379 NotAnLValue, 8380 NoError 8381 } ErrorFound = NoError; 8382 SourceLocation ErrorLoc, NoteLoc; 8383 SourceRange ErrorRange, NoteRange; 8384 // If clause is read: 8385 // v = x; 8386 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8387 const auto *AtomicBinOp = 8388 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8389 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8390 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8391 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8392 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8393 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8394 if (!X->isLValue() || !V->isLValue()) { 8395 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8396 ErrorFound = NotAnLValue; 8397 ErrorLoc = AtomicBinOp->getExprLoc(); 8398 ErrorRange = AtomicBinOp->getSourceRange(); 8399 NoteLoc = NotLValueExpr->getExprLoc(); 8400 NoteRange = NotLValueExpr->getSourceRange(); 8401 } 8402 } else if (!X->isInstantiationDependent() || 8403 !V->isInstantiationDependent()) { 8404 const Expr *NotScalarExpr = 8405 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8406 ? V 8407 : X; 8408 ErrorFound = NotAScalarType; 8409 ErrorLoc = AtomicBinOp->getExprLoc(); 8410 ErrorRange = AtomicBinOp->getSourceRange(); 8411 NoteLoc = NotScalarExpr->getExprLoc(); 8412 NoteRange = NotScalarExpr->getSourceRange(); 8413 } 8414 } else if (!AtomicBody->isInstantiationDependent()) { 8415 ErrorFound = NotAnAssignmentOp; 8416 ErrorLoc = AtomicBody->getExprLoc(); 8417 ErrorRange = AtomicBody->getSourceRange(); 8418 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8419 : AtomicBody->getExprLoc(); 8420 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8421 : AtomicBody->getSourceRange(); 8422 } 8423 } else { 8424 ErrorFound = NotAnExpression; 8425 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8426 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8427 } 8428 if (ErrorFound != NoError) { 8429 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8430 << ErrorRange; 8431 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8432 << NoteRange; 8433 return StmtError(); 8434 } 8435 if (CurContext->isDependentContext()) 8436 V = X = nullptr; 8437 } else if (AtomicKind == OMPC_write) { 8438 enum { 8439 NotAnExpression, 8440 NotAnAssignmentOp, 8441 NotAScalarType, 8442 NotAnLValue, 8443 NoError 8444 } ErrorFound = NoError; 8445 SourceLocation ErrorLoc, NoteLoc; 8446 SourceRange ErrorRange, NoteRange; 8447 // If clause is write: 8448 // x = expr; 8449 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8450 const auto *AtomicBinOp = 8451 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8452 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8453 X = AtomicBinOp->getLHS(); 8454 E = AtomicBinOp->getRHS(); 8455 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8456 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8457 if (!X->isLValue()) { 8458 ErrorFound = NotAnLValue; 8459 ErrorLoc = AtomicBinOp->getExprLoc(); 8460 ErrorRange = AtomicBinOp->getSourceRange(); 8461 NoteLoc = X->getExprLoc(); 8462 NoteRange = X->getSourceRange(); 8463 } 8464 } else if (!X->isInstantiationDependent() || 8465 !E->isInstantiationDependent()) { 8466 const Expr *NotScalarExpr = 8467 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8468 ? E 8469 : X; 8470 ErrorFound = NotAScalarType; 8471 ErrorLoc = AtomicBinOp->getExprLoc(); 8472 ErrorRange = AtomicBinOp->getSourceRange(); 8473 NoteLoc = NotScalarExpr->getExprLoc(); 8474 NoteRange = NotScalarExpr->getSourceRange(); 8475 } 8476 } else if (!AtomicBody->isInstantiationDependent()) { 8477 ErrorFound = NotAnAssignmentOp; 8478 ErrorLoc = AtomicBody->getExprLoc(); 8479 ErrorRange = AtomicBody->getSourceRange(); 8480 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8481 : AtomicBody->getExprLoc(); 8482 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8483 : AtomicBody->getSourceRange(); 8484 } 8485 } else { 8486 ErrorFound = NotAnExpression; 8487 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8488 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8489 } 8490 if (ErrorFound != NoError) { 8491 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8492 << ErrorRange; 8493 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8494 << NoteRange; 8495 return StmtError(); 8496 } 8497 if (CurContext->isDependentContext()) 8498 E = X = nullptr; 8499 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8500 // If clause is update: 8501 // x++; 8502 // x--; 8503 // ++x; 8504 // --x; 8505 // x binop= expr; 8506 // x = x binop expr; 8507 // x = expr binop x; 8508 OpenMPAtomicUpdateChecker Checker(*this); 8509 if (Checker.checkStatement( 8510 Body, (AtomicKind == OMPC_update) 8511 ? diag::err_omp_atomic_update_not_expression_statement 8512 : diag::err_omp_atomic_not_expression_statement, 8513 diag::note_omp_atomic_update)) 8514 return StmtError(); 8515 if (!CurContext->isDependentContext()) { 8516 E = Checker.getExpr(); 8517 X = Checker.getX(); 8518 UE = Checker.getUpdateExpr(); 8519 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8520 } 8521 } else if (AtomicKind == OMPC_capture) { 8522 enum { 8523 NotAnAssignmentOp, 8524 NotACompoundStatement, 8525 NotTwoSubstatements, 8526 NotASpecificExpression, 8527 NoError 8528 } ErrorFound = NoError; 8529 SourceLocation ErrorLoc, NoteLoc; 8530 SourceRange ErrorRange, NoteRange; 8531 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8532 // If clause is a capture: 8533 // v = x++; 8534 // v = x--; 8535 // v = ++x; 8536 // v = --x; 8537 // v = x binop= expr; 8538 // v = x = x binop expr; 8539 // v = x = expr binop x; 8540 const auto *AtomicBinOp = 8541 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8542 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8543 V = AtomicBinOp->getLHS(); 8544 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8545 OpenMPAtomicUpdateChecker Checker(*this); 8546 if (Checker.checkStatement( 8547 Body, diag::err_omp_atomic_capture_not_expression_statement, 8548 diag::note_omp_atomic_update)) 8549 return StmtError(); 8550 E = Checker.getExpr(); 8551 X = Checker.getX(); 8552 UE = Checker.getUpdateExpr(); 8553 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8554 IsPostfixUpdate = Checker.isPostfixUpdate(); 8555 } else if (!AtomicBody->isInstantiationDependent()) { 8556 ErrorLoc = AtomicBody->getExprLoc(); 8557 ErrorRange = AtomicBody->getSourceRange(); 8558 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8559 : AtomicBody->getExprLoc(); 8560 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8561 : AtomicBody->getSourceRange(); 8562 ErrorFound = NotAnAssignmentOp; 8563 } 8564 if (ErrorFound != NoError) { 8565 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8566 << ErrorRange; 8567 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8568 return StmtError(); 8569 } 8570 if (CurContext->isDependentContext()) 8571 UE = V = E = X = nullptr; 8572 } else { 8573 // If clause is a capture: 8574 // { v = x; x = expr; } 8575 // { v = x; x++; } 8576 // { v = x; x--; } 8577 // { v = x; ++x; } 8578 // { v = x; --x; } 8579 // { v = x; x binop= expr; } 8580 // { v = x; x = x binop expr; } 8581 // { v = x; x = expr binop x; } 8582 // { x++; v = x; } 8583 // { x--; v = x; } 8584 // { ++x; v = x; } 8585 // { --x; v = x; } 8586 // { x binop= expr; v = x; } 8587 // { x = x binop expr; v = x; } 8588 // { x = expr binop x; v = x; } 8589 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8590 // Check that this is { expr1; expr2; } 8591 if (CS->size() == 2) { 8592 Stmt *First = CS->body_front(); 8593 Stmt *Second = CS->body_back(); 8594 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8595 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8596 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8597 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8598 // Need to find what subexpression is 'v' and what is 'x'. 8599 OpenMPAtomicUpdateChecker Checker(*this); 8600 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8601 BinaryOperator *BinOp = nullptr; 8602 if (IsUpdateExprFound) { 8603 BinOp = dyn_cast<BinaryOperator>(First); 8604 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8605 } 8606 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8607 // { v = x; x++; } 8608 // { v = x; x--; } 8609 // { v = x; ++x; } 8610 // { v = x; --x; } 8611 // { v = x; x binop= expr; } 8612 // { v = x; x = x binop expr; } 8613 // { v = x; x = expr binop x; } 8614 // Check that the first expression has form v = x. 8615 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8616 llvm::FoldingSetNodeID XId, PossibleXId; 8617 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8618 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8619 IsUpdateExprFound = XId == PossibleXId; 8620 if (IsUpdateExprFound) { 8621 V = BinOp->getLHS(); 8622 X = Checker.getX(); 8623 E = Checker.getExpr(); 8624 UE = Checker.getUpdateExpr(); 8625 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8626 IsPostfixUpdate = true; 8627 } 8628 } 8629 if (!IsUpdateExprFound) { 8630 IsUpdateExprFound = !Checker.checkStatement(First); 8631 BinOp = nullptr; 8632 if (IsUpdateExprFound) { 8633 BinOp = dyn_cast<BinaryOperator>(Second); 8634 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8635 } 8636 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8637 // { x++; v = x; } 8638 // { x--; v = x; } 8639 // { ++x; v = x; } 8640 // { --x; v = x; } 8641 // { x binop= expr; v = x; } 8642 // { x = x binop expr; v = x; } 8643 // { x = expr binop x; v = x; } 8644 // Check that the second expression has form v = x. 8645 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8646 llvm::FoldingSetNodeID XId, PossibleXId; 8647 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8648 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8649 IsUpdateExprFound = XId == PossibleXId; 8650 if (IsUpdateExprFound) { 8651 V = BinOp->getLHS(); 8652 X = Checker.getX(); 8653 E = Checker.getExpr(); 8654 UE = Checker.getUpdateExpr(); 8655 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8656 IsPostfixUpdate = false; 8657 } 8658 } 8659 } 8660 if (!IsUpdateExprFound) { 8661 // { v = x; x = expr; } 8662 auto *FirstExpr = dyn_cast<Expr>(First); 8663 auto *SecondExpr = dyn_cast<Expr>(Second); 8664 if (!FirstExpr || !SecondExpr || 8665 !(FirstExpr->isInstantiationDependent() || 8666 SecondExpr->isInstantiationDependent())) { 8667 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8668 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8669 ErrorFound = NotAnAssignmentOp; 8670 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8671 : First->getBeginLoc(); 8672 NoteRange = ErrorRange = FirstBinOp 8673 ? FirstBinOp->getSourceRange() 8674 : SourceRange(ErrorLoc, ErrorLoc); 8675 } else { 8676 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8677 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8678 ErrorFound = NotAnAssignmentOp; 8679 NoteLoc = ErrorLoc = SecondBinOp 8680 ? SecondBinOp->getOperatorLoc() 8681 : Second->getBeginLoc(); 8682 NoteRange = ErrorRange = 8683 SecondBinOp ? SecondBinOp->getSourceRange() 8684 : SourceRange(ErrorLoc, ErrorLoc); 8685 } else { 8686 Expr *PossibleXRHSInFirst = 8687 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8688 Expr *PossibleXLHSInSecond = 8689 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8690 llvm::FoldingSetNodeID X1Id, X2Id; 8691 PossibleXRHSInFirst->Profile(X1Id, Context, 8692 /*Canonical=*/true); 8693 PossibleXLHSInSecond->Profile(X2Id, Context, 8694 /*Canonical=*/true); 8695 IsUpdateExprFound = X1Id == X2Id; 8696 if (IsUpdateExprFound) { 8697 V = FirstBinOp->getLHS(); 8698 X = SecondBinOp->getLHS(); 8699 E = SecondBinOp->getRHS(); 8700 UE = nullptr; 8701 IsXLHSInRHSPart = false; 8702 IsPostfixUpdate = true; 8703 } else { 8704 ErrorFound = NotASpecificExpression; 8705 ErrorLoc = FirstBinOp->getExprLoc(); 8706 ErrorRange = FirstBinOp->getSourceRange(); 8707 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8708 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8709 } 8710 } 8711 } 8712 } 8713 } 8714 } else { 8715 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8716 NoteRange = ErrorRange = 8717 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8718 ErrorFound = NotTwoSubstatements; 8719 } 8720 } else { 8721 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8722 NoteRange = ErrorRange = 8723 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8724 ErrorFound = NotACompoundStatement; 8725 } 8726 if (ErrorFound != NoError) { 8727 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8728 << ErrorRange; 8729 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8730 return StmtError(); 8731 } 8732 if (CurContext->isDependentContext()) 8733 UE = V = E = X = nullptr; 8734 } 8735 } 8736 8737 setFunctionHasBranchProtectedScope(); 8738 8739 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8740 X, V, E, UE, IsXLHSInRHSPart, 8741 IsPostfixUpdate); 8742 } 8743 8744 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8745 Stmt *AStmt, 8746 SourceLocation StartLoc, 8747 SourceLocation EndLoc) { 8748 if (!AStmt) 8749 return StmtError(); 8750 8751 auto *CS = cast<CapturedStmt>(AStmt); 8752 // 1.2.2 OpenMP Language Terminology 8753 // Structured block - An executable statement with a single entry at the 8754 // top and a single exit at the bottom. 8755 // The point of exit cannot be a branch out of the structured block. 8756 // longjmp() and throw() must not violate the entry/exit criteria. 8757 CS->getCapturedDecl()->setNothrow(); 8758 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8759 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8760 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8761 // 1.2.2 OpenMP Language Terminology 8762 // Structured block - An executable statement with a single entry at the 8763 // top and a single exit at the bottom. 8764 // The point of exit cannot be a branch out of the structured block. 8765 // longjmp() and throw() must not violate the entry/exit criteria. 8766 CS->getCapturedDecl()->setNothrow(); 8767 } 8768 8769 // OpenMP [2.16, Nesting of Regions] 8770 // If specified, a teams construct must be contained within a target 8771 // construct. That target construct must contain no statements or directives 8772 // outside of the teams construct. 8773 if (DSAStack->hasInnerTeamsRegion()) { 8774 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8775 bool OMPTeamsFound = true; 8776 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8777 auto I = CS->body_begin(); 8778 while (I != CS->body_end()) { 8779 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8780 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8781 OMPTeamsFound) { 8782 8783 OMPTeamsFound = false; 8784 break; 8785 } 8786 ++I; 8787 } 8788 assert(I != CS->body_end() && "Not found statement"); 8789 S = *I; 8790 } else { 8791 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8792 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8793 } 8794 if (!OMPTeamsFound) { 8795 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8796 Diag(DSAStack->getInnerTeamsRegionLoc(), 8797 diag::note_omp_nested_teams_construct_here); 8798 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8799 << isa<OMPExecutableDirective>(S); 8800 return StmtError(); 8801 } 8802 } 8803 8804 setFunctionHasBranchProtectedScope(); 8805 8806 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8807 } 8808 8809 StmtResult 8810 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8811 Stmt *AStmt, SourceLocation StartLoc, 8812 SourceLocation EndLoc) { 8813 if (!AStmt) 8814 return StmtError(); 8815 8816 auto *CS = cast<CapturedStmt>(AStmt); 8817 // 1.2.2 OpenMP Language Terminology 8818 // Structured block - An executable statement with a single entry at the 8819 // top and a single exit at the bottom. 8820 // The point of exit cannot be a branch out of the structured block. 8821 // longjmp() and throw() must not violate the entry/exit criteria. 8822 CS->getCapturedDecl()->setNothrow(); 8823 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8824 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8825 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8826 // 1.2.2 OpenMP Language Terminology 8827 // Structured block - An executable statement with a single entry at the 8828 // top and a single exit at the bottom. 8829 // The point of exit cannot be a branch out of the structured block. 8830 // longjmp() and throw() must not violate the entry/exit criteria. 8831 CS->getCapturedDecl()->setNothrow(); 8832 } 8833 8834 setFunctionHasBranchProtectedScope(); 8835 8836 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8837 AStmt); 8838 } 8839 8840 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8841 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8842 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8843 if (!AStmt) 8844 return StmtError(); 8845 8846 auto *CS = cast<CapturedStmt>(AStmt); 8847 // 1.2.2 OpenMP Language Terminology 8848 // Structured block - An executable statement with a single entry at the 8849 // top and a single exit at the bottom. 8850 // The point of exit cannot be a branch out of the structured block. 8851 // longjmp() and throw() must not violate the entry/exit criteria. 8852 CS->getCapturedDecl()->setNothrow(); 8853 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8854 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8855 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8856 // 1.2.2 OpenMP Language Terminology 8857 // Structured block - An executable statement with a single entry at the 8858 // top and a single exit at the bottom. 8859 // The point of exit cannot be a branch out of the structured block. 8860 // longjmp() and throw() must not violate the entry/exit criteria. 8861 CS->getCapturedDecl()->setNothrow(); 8862 } 8863 8864 OMPLoopDirective::HelperExprs B; 8865 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8866 // define the nested loops number. 8867 unsigned NestedLoopCount = 8868 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8869 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8870 VarsWithImplicitDSA, B); 8871 if (NestedLoopCount == 0) 8872 return StmtError(); 8873 8874 assert((CurContext->isDependentContext() || B.builtAll()) && 8875 "omp target parallel for loop exprs were not built"); 8876 8877 if (!CurContext->isDependentContext()) { 8878 // Finalize the clauses that need pre-built expressions for CodeGen. 8879 for (OMPClause *C : Clauses) { 8880 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8881 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8882 B.NumIterations, *this, CurScope, 8883 DSAStack)) 8884 return StmtError(); 8885 } 8886 } 8887 8888 setFunctionHasBranchProtectedScope(); 8889 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8890 NestedLoopCount, Clauses, AStmt, 8891 B, DSAStack->isCancelRegion()); 8892 } 8893 8894 /// Check for existence of a map clause in the list of clauses. 8895 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8896 const OpenMPClauseKind K) { 8897 return llvm::any_of( 8898 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8899 } 8900 8901 template <typename... Params> 8902 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8903 const Params... ClauseTypes) { 8904 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8905 } 8906 8907 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8908 Stmt *AStmt, 8909 SourceLocation StartLoc, 8910 SourceLocation EndLoc) { 8911 if (!AStmt) 8912 return StmtError(); 8913 8914 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8915 8916 // OpenMP [2.10.1, Restrictions, p. 97] 8917 // At least one map clause must appear on the directive. 8918 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8919 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8920 << "'map' or 'use_device_ptr'" 8921 << getOpenMPDirectiveName(OMPD_target_data); 8922 return StmtError(); 8923 } 8924 8925 setFunctionHasBranchProtectedScope(); 8926 8927 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8928 AStmt); 8929 } 8930 8931 StmtResult 8932 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8933 SourceLocation StartLoc, 8934 SourceLocation EndLoc, Stmt *AStmt) { 8935 if (!AStmt) 8936 return StmtError(); 8937 8938 auto *CS = cast<CapturedStmt>(AStmt); 8939 // 1.2.2 OpenMP Language Terminology 8940 // Structured block - An executable statement with a single entry at the 8941 // top and a single exit at the bottom. 8942 // The point of exit cannot be a branch out of the structured block. 8943 // longjmp() and throw() must not violate the entry/exit criteria. 8944 CS->getCapturedDecl()->setNothrow(); 8945 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8946 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8947 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8948 // 1.2.2 OpenMP Language Terminology 8949 // Structured block - An executable statement with a single entry at the 8950 // top and a single exit at the bottom. 8951 // The point of exit cannot be a branch out of the structured block. 8952 // longjmp() and throw() must not violate the entry/exit criteria. 8953 CS->getCapturedDecl()->setNothrow(); 8954 } 8955 8956 // OpenMP [2.10.2, Restrictions, p. 99] 8957 // At least one map clause must appear on the directive. 8958 if (!hasClauses(Clauses, OMPC_map)) { 8959 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8960 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8961 return StmtError(); 8962 } 8963 8964 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8965 AStmt); 8966 } 8967 8968 StmtResult 8969 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8970 SourceLocation StartLoc, 8971 SourceLocation EndLoc, Stmt *AStmt) { 8972 if (!AStmt) 8973 return StmtError(); 8974 8975 auto *CS = cast<CapturedStmt>(AStmt); 8976 // 1.2.2 OpenMP Language Terminology 8977 // Structured block - An executable statement with a single entry at the 8978 // top and a single exit at the bottom. 8979 // The point of exit cannot be a branch out of the structured block. 8980 // longjmp() and throw() must not violate the entry/exit criteria. 8981 CS->getCapturedDecl()->setNothrow(); 8982 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8983 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8984 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8985 // 1.2.2 OpenMP Language Terminology 8986 // Structured block - An executable statement with a single entry at the 8987 // top and a single exit at the bottom. 8988 // The point of exit cannot be a branch out of the structured block. 8989 // longjmp() and throw() must not violate the entry/exit criteria. 8990 CS->getCapturedDecl()->setNothrow(); 8991 } 8992 8993 // OpenMP [2.10.3, Restrictions, p. 102] 8994 // At least one map clause must appear on the directive. 8995 if (!hasClauses(Clauses, OMPC_map)) { 8996 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8997 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8998 return StmtError(); 8999 } 9000 9001 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9002 AStmt); 9003 } 9004 9005 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9006 SourceLocation StartLoc, 9007 SourceLocation EndLoc, 9008 Stmt *AStmt) { 9009 if (!AStmt) 9010 return StmtError(); 9011 9012 auto *CS = cast<CapturedStmt>(AStmt); 9013 // 1.2.2 OpenMP Language Terminology 9014 // Structured block - An executable statement with a single entry at the 9015 // top and a single exit at the bottom. 9016 // The point of exit cannot be a branch out of the structured block. 9017 // longjmp() and throw() must not violate the entry/exit criteria. 9018 CS->getCapturedDecl()->setNothrow(); 9019 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9020 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9021 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9022 // 1.2.2 OpenMP Language Terminology 9023 // Structured block - An executable statement with a single entry at the 9024 // top and a single exit at the bottom. 9025 // The point of exit cannot be a branch out of the structured block. 9026 // longjmp() and throw() must not violate the entry/exit criteria. 9027 CS->getCapturedDecl()->setNothrow(); 9028 } 9029 9030 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9031 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9032 return StmtError(); 9033 } 9034 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9035 AStmt); 9036 } 9037 9038 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9039 Stmt *AStmt, SourceLocation StartLoc, 9040 SourceLocation EndLoc) { 9041 if (!AStmt) 9042 return StmtError(); 9043 9044 auto *CS = cast<CapturedStmt>(AStmt); 9045 // 1.2.2 OpenMP Language Terminology 9046 // Structured block - An executable statement with a single entry at the 9047 // top and a single exit at the bottom. 9048 // The point of exit cannot be a branch out of the structured block. 9049 // longjmp() and throw() must not violate the entry/exit criteria. 9050 CS->getCapturedDecl()->setNothrow(); 9051 9052 setFunctionHasBranchProtectedScope(); 9053 9054 DSAStack->setParentTeamsRegionLoc(StartLoc); 9055 9056 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9057 } 9058 9059 StmtResult 9060 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9061 SourceLocation EndLoc, 9062 OpenMPDirectiveKind CancelRegion) { 9063 if (DSAStack->isParentNowaitRegion()) { 9064 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9065 return StmtError(); 9066 } 9067 if (DSAStack->isParentOrderedRegion()) { 9068 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9069 return StmtError(); 9070 } 9071 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9072 CancelRegion); 9073 } 9074 9075 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9076 SourceLocation StartLoc, 9077 SourceLocation EndLoc, 9078 OpenMPDirectiveKind CancelRegion) { 9079 if (DSAStack->isParentNowaitRegion()) { 9080 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9081 return StmtError(); 9082 } 9083 if (DSAStack->isParentOrderedRegion()) { 9084 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9085 return StmtError(); 9086 } 9087 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9088 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9089 CancelRegion); 9090 } 9091 9092 static bool checkGrainsizeNumTasksClauses(Sema &S, 9093 ArrayRef<OMPClause *> Clauses) { 9094 const OMPClause *PrevClause = nullptr; 9095 bool ErrorFound = false; 9096 for (const OMPClause *C : Clauses) { 9097 if (C->getClauseKind() == OMPC_grainsize || 9098 C->getClauseKind() == OMPC_num_tasks) { 9099 if (!PrevClause) 9100 PrevClause = C; 9101 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9102 S.Diag(C->getBeginLoc(), 9103 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9104 << getOpenMPClauseName(C->getClauseKind()) 9105 << getOpenMPClauseName(PrevClause->getClauseKind()); 9106 S.Diag(PrevClause->getBeginLoc(), 9107 diag::note_omp_previous_grainsize_num_tasks) 9108 << getOpenMPClauseName(PrevClause->getClauseKind()); 9109 ErrorFound = true; 9110 } 9111 } 9112 } 9113 return ErrorFound; 9114 } 9115 9116 static bool checkReductionClauseWithNogroup(Sema &S, 9117 ArrayRef<OMPClause *> Clauses) { 9118 const OMPClause *ReductionClause = nullptr; 9119 const OMPClause *NogroupClause = nullptr; 9120 for (const OMPClause *C : Clauses) { 9121 if (C->getClauseKind() == OMPC_reduction) { 9122 ReductionClause = C; 9123 if (NogroupClause) 9124 break; 9125 continue; 9126 } 9127 if (C->getClauseKind() == OMPC_nogroup) { 9128 NogroupClause = C; 9129 if (ReductionClause) 9130 break; 9131 continue; 9132 } 9133 } 9134 if (ReductionClause && NogroupClause) { 9135 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9136 << SourceRange(NogroupClause->getBeginLoc(), 9137 NogroupClause->getEndLoc()); 9138 return true; 9139 } 9140 return false; 9141 } 9142 9143 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9144 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9145 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9146 if (!AStmt) 9147 return StmtError(); 9148 9149 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9150 OMPLoopDirective::HelperExprs B; 9151 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9152 // define the nested loops number. 9153 unsigned NestedLoopCount = 9154 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9155 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9156 VarsWithImplicitDSA, B); 9157 if (NestedLoopCount == 0) 9158 return StmtError(); 9159 9160 assert((CurContext->isDependentContext() || B.builtAll()) && 9161 "omp for loop exprs were not built"); 9162 9163 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9164 // The grainsize clause and num_tasks clause are mutually exclusive and may 9165 // not appear on the same taskloop directive. 9166 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9167 return StmtError(); 9168 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9169 // If a reduction clause is present on the taskloop directive, the nogroup 9170 // clause must not be specified. 9171 if (checkReductionClauseWithNogroup(*this, Clauses)) 9172 return StmtError(); 9173 9174 setFunctionHasBranchProtectedScope(); 9175 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9176 NestedLoopCount, Clauses, AStmt, B); 9177 } 9178 9179 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9180 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9181 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9182 if (!AStmt) 9183 return StmtError(); 9184 9185 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9186 OMPLoopDirective::HelperExprs B; 9187 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9188 // define the nested loops number. 9189 unsigned NestedLoopCount = 9190 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9191 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9192 VarsWithImplicitDSA, B); 9193 if (NestedLoopCount == 0) 9194 return StmtError(); 9195 9196 assert((CurContext->isDependentContext() || B.builtAll()) && 9197 "omp for loop exprs were not built"); 9198 9199 if (!CurContext->isDependentContext()) { 9200 // Finalize the clauses that need pre-built expressions for CodeGen. 9201 for (OMPClause *C : Clauses) { 9202 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9203 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9204 B.NumIterations, *this, CurScope, 9205 DSAStack)) 9206 return StmtError(); 9207 } 9208 } 9209 9210 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9211 // The grainsize clause and num_tasks clause are mutually exclusive and may 9212 // not appear on the same taskloop directive. 9213 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9214 return StmtError(); 9215 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9216 // If a reduction clause is present on the taskloop directive, the nogroup 9217 // clause must not be specified. 9218 if (checkReductionClauseWithNogroup(*this, Clauses)) 9219 return StmtError(); 9220 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9221 return StmtError(); 9222 9223 setFunctionHasBranchProtectedScope(); 9224 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9225 NestedLoopCount, Clauses, AStmt, B); 9226 } 9227 9228 StmtResult Sema::ActOnOpenMPDistributeDirective( 9229 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9230 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9231 if (!AStmt) 9232 return StmtError(); 9233 9234 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9235 OMPLoopDirective::HelperExprs B; 9236 // In presence of clause 'collapse' with number of loops, it will 9237 // define the nested loops number. 9238 unsigned NestedLoopCount = 9239 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9240 nullptr /*ordered not a clause on distribute*/, AStmt, 9241 *this, *DSAStack, VarsWithImplicitDSA, B); 9242 if (NestedLoopCount == 0) 9243 return StmtError(); 9244 9245 assert((CurContext->isDependentContext() || B.builtAll()) && 9246 "omp for loop exprs were not built"); 9247 9248 setFunctionHasBranchProtectedScope(); 9249 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9250 NestedLoopCount, Clauses, AStmt, B); 9251 } 9252 9253 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9254 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9255 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9256 if (!AStmt) 9257 return StmtError(); 9258 9259 auto *CS = cast<CapturedStmt>(AStmt); 9260 // 1.2.2 OpenMP Language Terminology 9261 // Structured block - An executable statement with a single entry at the 9262 // top and a single exit at the bottom. 9263 // The point of exit cannot be a branch out of the structured block. 9264 // longjmp() and throw() must not violate the entry/exit criteria. 9265 CS->getCapturedDecl()->setNothrow(); 9266 for (int ThisCaptureLevel = 9267 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9268 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9269 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9270 // 1.2.2 OpenMP Language Terminology 9271 // Structured block - An executable statement with a single entry at the 9272 // top and a single exit at the bottom. 9273 // The point of exit cannot be a branch out of the structured block. 9274 // longjmp() and throw() must not violate the entry/exit criteria. 9275 CS->getCapturedDecl()->setNothrow(); 9276 } 9277 9278 OMPLoopDirective::HelperExprs B; 9279 // In presence of clause 'collapse' with number of loops, it will 9280 // define the nested loops number. 9281 unsigned NestedLoopCount = checkOpenMPLoop( 9282 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9283 nullptr /*ordered not a clause on distribute*/, CS, *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 setFunctionHasBranchProtectedScope(); 9292 return OMPDistributeParallelForDirective::Create( 9293 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9294 DSAStack->isCancelRegion()); 9295 } 9296 9297 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9298 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9299 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9300 if (!AStmt) 9301 return StmtError(); 9302 9303 auto *CS = cast<CapturedStmt>(AStmt); 9304 // 1.2.2 OpenMP Language Terminology 9305 // Structured block - An executable statement with a single entry at the 9306 // top and a single exit at the bottom. 9307 // The point of exit cannot be a branch out of the structured block. 9308 // longjmp() and throw() must not violate the entry/exit criteria. 9309 CS->getCapturedDecl()->setNothrow(); 9310 for (int ThisCaptureLevel = 9311 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9312 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9313 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9314 // 1.2.2 OpenMP Language Terminology 9315 // Structured block - An executable statement with a single entry at the 9316 // top and a single exit at the bottom. 9317 // The point of exit cannot be a branch out of the structured block. 9318 // longjmp() and throw() must not violate the entry/exit criteria. 9319 CS->getCapturedDecl()->setNothrow(); 9320 } 9321 9322 OMPLoopDirective::HelperExprs B; 9323 // In presence of clause 'collapse' with number of loops, it will 9324 // define the nested loops number. 9325 unsigned NestedLoopCount = checkOpenMPLoop( 9326 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9327 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9328 VarsWithImplicitDSA, B); 9329 if (NestedLoopCount == 0) 9330 return StmtError(); 9331 9332 assert((CurContext->isDependentContext() || B.builtAll()) && 9333 "omp for loop exprs were not built"); 9334 9335 if (!CurContext->isDependentContext()) { 9336 // Finalize the clauses that need pre-built expressions for CodeGen. 9337 for (OMPClause *C : Clauses) { 9338 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9339 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9340 B.NumIterations, *this, CurScope, 9341 DSAStack)) 9342 return StmtError(); 9343 } 9344 } 9345 9346 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9347 return StmtError(); 9348 9349 setFunctionHasBranchProtectedScope(); 9350 return OMPDistributeParallelForSimdDirective::Create( 9351 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9352 } 9353 9354 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9355 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9356 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9357 if (!AStmt) 9358 return StmtError(); 9359 9360 auto *CS = cast<CapturedStmt>(AStmt); 9361 // 1.2.2 OpenMP Language Terminology 9362 // Structured block - An executable statement with a single entry at the 9363 // top and a single exit at the bottom. 9364 // The point of exit cannot be a branch out of the structured block. 9365 // longjmp() and throw() must not violate the entry/exit criteria. 9366 CS->getCapturedDecl()->setNothrow(); 9367 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9368 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9369 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9370 // 1.2.2 OpenMP Language Terminology 9371 // Structured block - An executable statement with a single entry at the 9372 // top and a single exit at the bottom. 9373 // The point of exit cannot be a branch out of the structured block. 9374 // longjmp() and throw() must not violate the entry/exit criteria. 9375 CS->getCapturedDecl()->setNothrow(); 9376 } 9377 9378 OMPLoopDirective::HelperExprs B; 9379 // In presence of clause 'collapse' with number of loops, it will 9380 // define the nested loops number. 9381 unsigned NestedLoopCount = 9382 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9383 nullptr /*ordered not a clause on distribute*/, CS, *this, 9384 *DSAStack, VarsWithImplicitDSA, B); 9385 if (NestedLoopCount == 0) 9386 return StmtError(); 9387 9388 assert((CurContext->isDependentContext() || B.builtAll()) && 9389 "omp for loop exprs were not built"); 9390 9391 if (!CurContext->isDependentContext()) { 9392 // Finalize the clauses that need pre-built expressions for CodeGen. 9393 for (OMPClause *C : Clauses) { 9394 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9395 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9396 B.NumIterations, *this, CurScope, 9397 DSAStack)) 9398 return StmtError(); 9399 } 9400 } 9401 9402 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9403 return StmtError(); 9404 9405 setFunctionHasBranchProtectedScope(); 9406 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9407 NestedLoopCount, Clauses, AStmt, B); 9408 } 9409 9410 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9411 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9412 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9413 if (!AStmt) 9414 return StmtError(); 9415 9416 auto *CS = cast<CapturedStmt>(AStmt); 9417 // 1.2.2 OpenMP Language Terminology 9418 // Structured block - An executable statement with a single entry at the 9419 // top and a single exit at the bottom. 9420 // The point of exit cannot be a branch out of the structured block. 9421 // longjmp() and throw() must not violate the entry/exit criteria. 9422 CS->getCapturedDecl()->setNothrow(); 9423 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9424 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9425 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9426 // 1.2.2 OpenMP Language Terminology 9427 // Structured block - An executable statement with a single entry at the 9428 // top and a single exit at the bottom. 9429 // The point of exit cannot be a branch out of the structured block. 9430 // longjmp() and throw() must not violate the entry/exit criteria. 9431 CS->getCapturedDecl()->setNothrow(); 9432 } 9433 9434 OMPLoopDirective::HelperExprs B; 9435 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9436 // define the nested loops number. 9437 unsigned NestedLoopCount = checkOpenMPLoop( 9438 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9439 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9440 VarsWithImplicitDSA, B); 9441 if (NestedLoopCount == 0) 9442 return StmtError(); 9443 9444 assert((CurContext->isDependentContext() || B.builtAll()) && 9445 "omp target parallel for simd loop exprs were not built"); 9446 9447 if (!CurContext->isDependentContext()) { 9448 // Finalize the clauses that need pre-built expressions for CodeGen. 9449 for (OMPClause *C : Clauses) { 9450 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9451 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9452 B.NumIterations, *this, CurScope, 9453 DSAStack)) 9454 return StmtError(); 9455 } 9456 } 9457 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9458 return StmtError(); 9459 9460 setFunctionHasBranchProtectedScope(); 9461 return OMPTargetParallelForSimdDirective::Create( 9462 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9463 } 9464 9465 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9466 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9467 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9468 if (!AStmt) 9469 return StmtError(); 9470 9471 auto *CS = cast<CapturedStmt>(AStmt); 9472 // 1.2.2 OpenMP Language Terminology 9473 // Structured block - An executable statement with a single entry at the 9474 // top and a single exit at the bottom. 9475 // The point of exit cannot be a branch out of the structured block. 9476 // longjmp() and throw() must not violate the entry/exit criteria. 9477 CS->getCapturedDecl()->setNothrow(); 9478 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9479 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9480 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9481 // 1.2.2 OpenMP Language Terminology 9482 // Structured block - An executable statement with a single entry at the 9483 // top and a single exit at the bottom. 9484 // The point of exit cannot be a branch out of the structured block. 9485 // longjmp() and throw() must not violate the entry/exit criteria. 9486 CS->getCapturedDecl()->setNothrow(); 9487 } 9488 9489 OMPLoopDirective::HelperExprs B; 9490 // In presence of clause 'collapse' with number of loops, it will define the 9491 // nested loops number. 9492 unsigned NestedLoopCount = 9493 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9494 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9495 VarsWithImplicitDSA, B); 9496 if (NestedLoopCount == 0) 9497 return StmtError(); 9498 9499 assert((CurContext->isDependentContext() || B.builtAll()) && 9500 "omp target simd loop exprs were not built"); 9501 9502 if (!CurContext->isDependentContext()) { 9503 // Finalize the clauses that need pre-built expressions for CodeGen. 9504 for (OMPClause *C : Clauses) { 9505 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9506 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9507 B.NumIterations, *this, CurScope, 9508 DSAStack)) 9509 return StmtError(); 9510 } 9511 } 9512 9513 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9514 return StmtError(); 9515 9516 setFunctionHasBranchProtectedScope(); 9517 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9518 NestedLoopCount, Clauses, AStmt, B); 9519 } 9520 9521 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9522 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9523 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9524 if (!AStmt) 9525 return StmtError(); 9526 9527 auto *CS = cast<CapturedStmt>(AStmt); 9528 // 1.2.2 OpenMP Language Terminology 9529 // Structured block - An executable statement with a single entry at the 9530 // top and a single exit at the bottom. 9531 // The point of exit cannot be a branch out of the structured block. 9532 // longjmp() and throw() must not violate the entry/exit criteria. 9533 CS->getCapturedDecl()->setNothrow(); 9534 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9535 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9536 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9537 // 1.2.2 OpenMP Language Terminology 9538 // Structured block - An executable statement with a single entry at the 9539 // top and a single exit at the bottom. 9540 // The point of exit cannot be a branch out of the structured block. 9541 // longjmp() and throw() must not violate the entry/exit criteria. 9542 CS->getCapturedDecl()->setNothrow(); 9543 } 9544 9545 OMPLoopDirective::HelperExprs B; 9546 // In presence of clause 'collapse' with number of loops, it will 9547 // define the nested loops number. 9548 unsigned NestedLoopCount = 9549 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9550 nullptr /*ordered not a clause on distribute*/, CS, *this, 9551 *DSAStack, VarsWithImplicitDSA, B); 9552 if (NestedLoopCount == 0) 9553 return StmtError(); 9554 9555 assert((CurContext->isDependentContext() || B.builtAll()) && 9556 "omp teams distribute loop exprs were not built"); 9557 9558 setFunctionHasBranchProtectedScope(); 9559 9560 DSAStack->setParentTeamsRegionLoc(StartLoc); 9561 9562 return OMPTeamsDistributeDirective::Create( 9563 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9564 } 9565 9566 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9567 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9568 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9569 if (!AStmt) 9570 return StmtError(); 9571 9572 auto *CS = cast<CapturedStmt>(AStmt); 9573 // 1.2.2 OpenMP Language Terminology 9574 // Structured block - An executable statement with a single entry at the 9575 // top and a single exit at the bottom. 9576 // The point of exit cannot be a branch out of the structured block. 9577 // longjmp() and throw() must not violate the entry/exit criteria. 9578 CS->getCapturedDecl()->setNothrow(); 9579 for (int ThisCaptureLevel = 9580 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9581 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9582 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9583 // 1.2.2 OpenMP Language Terminology 9584 // Structured block - An executable statement with a single entry at the 9585 // top and a single exit at the bottom. 9586 // The point of exit cannot be a branch out of the structured block. 9587 // longjmp() and throw() must not violate the entry/exit criteria. 9588 CS->getCapturedDecl()->setNothrow(); 9589 } 9590 9591 9592 OMPLoopDirective::HelperExprs B; 9593 // In presence of clause 'collapse' with number of loops, it will 9594 // define the nested loops number. 9595 unsigned NestedLoopCount = checkOpenMPLoop( 9596 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9597 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9598 VarsWithImplicitDSA, B); 9599 9600 if (NestedLoopCount == 0) 9601 return StmtError(); 9602 9603 assert((CurContext->isDependentContext() || B.builtAll()) && 9604 "omp teams distribute simd loop exprs were not built"); 9605 9606 if (!CurContext->isDependentContext()) { 9607 // Finalize the clauses that need pre-built expressions for CodeGen. 9608 for (OMPClause *C : Clauses) { 9609 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9610 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9611 B.NumIterations, *this, CurScope, 9612 DSAStack)) 9613 return StmtError(); 9614 } 9615 } 9616 9617 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9618 return StmtError(); 9619 9620 setFunctionHasBranchProtectedScope(); 9621 9622 DSAStack->setParentTeamsRegionLoc(StartLoc); 9623 9624 return OMPTeamsDistributeSimdDirective::Create( 9625 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9626 } 9627 9628 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9629 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9630 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9631 if (!AStmt) 9632 return StmtError(); 9633 9634 auto *CS = cast<CapturedStmt>(AStmt); 9635 // 1.2.2 OpenMP Language Terminology 9636 // Structured block - An executable statement with a single entry at the 9637 // top and a single exit at the bottom. 9638 // The point of exit cannot be a branch out of the structured block. 9639 // longjmp() and throw() must not violate the entry/exit criteria. 9640 CS->getCapturedDecl()->setNothrow(); 9641 9642 for (int ThisCaptureLevel = 9643 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9644 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9645 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9646 // 1.2.2 OpenMP Language Terminology 9647 // Structured block - An executable statement with a single entry at the 9648 // top and a single exit at the bottom. 9649 // The point of exit cannot be a branch out of the structured block. 9650 // longjmp() and throw() must not violate the entry/exit criteria. 9651 CS->getCapturedDecl()->setNothrow(); 9652 } 9653 9654 OMPLoopDirective::HelperExprs B; 9655 // In presence of clause 'collapse' with number of loops, it will 9656 // define the nested loops number. 9657 unsigned NestedLoopCount = checkOpenMPLoop( 9658 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9659 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9660 VarsWithImplicitDSA, B); 9661 9662 if (NestedLoopCount == 0) 9663 return StmtError(); 9664 9665 assert((CurContext->isDependentContext() || B.builtAll()) && 9666 "omp for loop exprs were not built"); 9667 9668 if (!CurContext->isDependentContext()) { 9669 // Finalize the clauses that need pre-built expressions for CodeGen. 9670 for (OMPClause *C : Clauses) { 9671 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9672 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9673 B.NumIterations, *this, CurScope, 9674 DSAStack)) 9675 return StmtError(); 9676 } 9677 } 9678 9679 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9680 return StmtError(); 9681 9682 setFunctionHasBranchProtectedScope(); 9683 9684 DSAStack->setParentTeamsRegionLoc(StartLoc); 9685 9686 return OMPTeamsDistributeParallelForSimdDirective::Create( 9687 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9688 } 9689 9690 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 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 9704 for (int ThisCaptureLevel = 9705 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9706 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9707 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9708 // 1.2.2 OpenMP Language Terminology 9709 // Structured block - An executable statement with a single entry at the 9710 // top and a single exit at the bottom. 9711 // The point of exit cannot be a branch out of the structured block. 9712 // longjmp() and throw() must not violate the entry/exit criteria. 9713 CS->getCapturedDecl()->setNothrow(); 9714 } 9715 9716 OMPLoopDirective::HelperExprs B; 9717 // In presence of clause 'collapse' with number of loops, it will 9718 // define the nested loops number. 9719 unsigned NestedLoopCount = checkOpenMPLoop( 9720 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9721 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9722 VarsWithImplicitDSA, B); 9723 9724 if (NestedLoopCount == 0) 9725 return StmtError(); 9726 9727 assert((CurContext->isDependentContext() || B.builtAll()) && 9728 "omp for loop exprs were not built"); 9729 9730 setFunctionHasBranchProtectedScope(); 9731 9732 DSAStack->setParentTeamsRegionLoc(StartLoc); 9733 9734 return OMPTeamsDistributeParallelForDirective::Create( 9735 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9736 DSAStack->isCancelRegion()); 9737 } 9738 9739 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9740 Stmt *AStmt, 9741 SourceLocation StartLoc, 9742 SourceLocation EndLoc) { 9743 if (!AStmt) 9744 return StmtError(); 9745 9746 auto *CS = cast<CapturedStmt>(AStmt); 9747 // 1.2.2 OpenMP Language Terminology 9748 // Structured block - An executable statement with a single entry at the 9749 // top and a single exit at the bottom. 9750 // The point of exit cannot be a branch out of the structured block. 9751 // longjmp() and throw() must not violate the entry/exit criteria. 9752 CS->getCapturedDecl()->setNothrow(); 9753 9754 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9755 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9756 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9757 // 1.2.2 OpenMP Language Terminology 9758 // Structured block - An executable statement with a single entry at the 9759 // top and a single exit at the bottom. 9760 // The point of exit cannot be a branch out of the structured block. 9761 // longjmp() and throw() must not violate the entry/exit criteria. 9762 CS->getCapturedDecl()->setNothrow(); 9763 } 9764 setFunctionHasBranchProtectedScope(); 9765 9766 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9767 AStmt); 9768 } 9769 9770 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9771 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9772 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9773 if (!AStmt) 9774 return StmtError(); 9775 9776 auto *CS = cast<CapturedStmt>(AStmt); 9777 // 1.2.2 OpenMP Language Terminology 9778 // Structured block - An executable statement with a single entry at the 9779 // top and a single exit at the bottom. 9780 // The point of exit cannot be a branch out of the structured block. 9781 // longjmp() and throw() must not violate the entry/exit criteria. 9782 CS->getCapturedDecl()->setNothrow(); 9783 for (int ThisCaptureLevel = 9784 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9785 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9786 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9787 // 1.2.2 OpenMP Language Terminology 9788 // Structured block - An executable statement with a single entry at the 9789 // top and a single exit at the bottom. 9790 // The point of exit cannot be a branch out of the structured block. 9791 // longjmp() and throw() must not violate the entry/exit criteria. 9792 CS->getCapturedDecl()->setNothrow(); 9793 } 9794 9795 OMPLoopDirective::HelperExprs B; 9796 // In presence of clause 'collapse' with number of loops, it will 9797 // define the nested loops number. 9798 unsigned NestedLoopCount = checkOpenMPLoop( 9799 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9800 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9801 VarsWithImplicitDSA, B); 9802 if (NestedLoopCount == 0) 9803 return StmtError(); 9804 9805 assert((CurContext->isDependentContext() || B.builtAll()) && 9806 "omp target teams distribute loop exprs were not built"); 9807 9808 setFunctionHasBranchProtectedScope(); 9809 return OMPTargetTeamsDistributeDirective::Create( 9810 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9811 } 9812 9813 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 9814 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9815 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9816 if (!AStmt) 9817 return StmtError(); 9818 9819 auto *CS = cast<CapturedStmt>(AStmt); 9820 // 1.2.2 OpenMP Language Terminology 9821 // Structured block - An executable statement with a single entry at the 9822 // top and a single exit at the bottom. 9823 // The point of exit cannot be a branch out of the structured block. 9824 // longjmp() and throw() must not violate the entry/exit criteria. 9825 CS->getCapturedDecl()->setNothrow(); 9826 for (int ThisCaptureLevel = 9827 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 9828 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9829 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9830 // 1.2.2 OpenMP Language Terminology 9831 // Structured block - An executable statement with a single entry at the 9832 // top and a single exit at the bottom. 9833 // The point of exit cannot be a branch out of the structured block. 9834 // longjmp() and throw() must not violate the entry/exit criteria. 9835 CS->getCapturedDecl()->setNothrow(); 9836 } 9837 9838 OMPLoopDirective::HelperExprs B; 9839 // In presence of clause 'collapse' with number of loops, it will 9840 // define the nested loops number. 9841 unsigned NestedLoopCount = checkOpenMPLoop( 9842 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9843 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9844 VarsWithImplicitDSA, B); 9845 if (NestedLoopCount == 0) 9846 return StmtError(); 9847 9848 assert((CurContext->isDependentContext() || B.builtAll()) && 9849 "omp target teams distribute parallel for loop exprs were not built"); 9850 9851 if (!CurContext->isDependentContext()) { 9852 // Finalize the clauses that need pre-built expressions for CodeGen. 9853 for (OMPClause *C : Clauses) { 9854 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9855 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9856 B.NumIterations, *this, CurScope, 9857 DSAStack)) 9858 return StmtError(); 9859 } 9860 } 9861 9862 setFunctionHasBranchProtectedScope(); 9863 return OMPTargetTeamsDistributeParallelForDirective::Create( 9864 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9865 DSAStack->isCancelRegion()); 9866 } 9867 9868 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9869 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9870 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9871 if (!AStmt) 9872 return StmtError(); 9873 9874 auto *CS = cast<CapturedStmt>(AStmt); 9875 // 1.2.2 OpenMP Language Terminology 9876 // Structured block - An executable statement with a single entry at the 9877 // top and a single exit at the bottom. 9878 // The point of exit cannot be a branch out of the structured block. 9879 // longjmp() and throw() must not violate the entry/exit criteria. 9880 CS->getCapturedDecl()->setNothrow(); 9881 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9882 OMPD_target_teams_distribute_parallel_for_simd); 9883 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9884 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9885 // 1.2.2 OpenMP Language Terminology 9886 // Structured block - An executable statement with a single entry at the 9887 // top and a single exit at the bottom. 9888 // The point of exit cannot be a branch out of the structured block. 9889 // longjmp() and throw() must not violate the entry/exit criteria. 9890 CS->getCapturedDecl()->setNothrow(); 9891 } 9892 9893 OMPLoopDirective::HelperExprs B; 9894 // In presence of clause 'collapse' with number of loops, it will 9895 // define the nested loops number. 9896 unsigned NestedLoopCount = 9897 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9898 getCollapseNumberExpr(Clauses), 9899 nullptr /*ordered not a clause on distribute*/, CS, *this, 9900 *DSAStack, VarsWithImplicitDSA, B); 9901 if (NestedLoopCount == 0) 9902 return StmtError(); 9903 9904 assert((CurContext->isDependentContext() || B.builtAll()) && 9905 "omp target teams distribute parallel for simd loop exprs were not " 9906 "built"); 9907 9908 if (!CurContext->isDependentContext()) { 9909 // Finalize the clauses that need pre-built expressions for CodeGen. 9910 for (OMPClause *C : Clauses) { 9911 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9912 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9913 B.NumIterations, *this, CurScope, 9914 DSAStack)) 9915 return StmtError(); 9916 } 9917 } 9918 9919 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9920 return StmtError(); 9921 9922 setFunctionHasBranchProtectedScope(); 9923 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9924 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9925 } 9926 9927 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9928 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9929 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9930 if (!AStmt) 9931 return StmtError(); 9932 9933 auto *CS = cast<CapturedStmt>(AStmt); 9934 // 1.2.2 OpenMP Language Terminology 9935 // Structured block - An executable statement with a single entry at the 9936 // top and a single exit at the bottom. 9937 // The point of exit cannot be a branch out of the structured block. 9938 // longjmp() and throw() must not violate the entry/exit criteria. 9939 CS->getCapturedDecl()->setNothrow(); 9940 for (int ThisCaptureLevel = 9941 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9942 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9943 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9944 // 1.2.2 OpenMP Language Terminology 9945 // Structured block - An executable statement with a single entry at the 9946 // top and a single exit at the bottom. 9947 // The point of exit cannot be a branch out of the structured block. 9948 // longjmp() and throw() must not violate the entry/exit criteria. 9949 CS->getCapturedDecl()->setNothrow(); 9950 } 9951 9952 OMPLoopDirective::HelperExprs B; 9953 // In presence of clause 'collapse' with number of loops, it will 9954 // define the nested loops number. 9955 unsigned NestedLoopCount = checkOpenMPLoop( 9956 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9957 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9958 VarsWithImplicitDSA, B); 9959 if (NestedLoopCount == 0) 9960 return StmtError(); 9961 9962 assert((CurContext->isDependentContext() || B.builtAll()) && 9963 "omp target teams distribute simd loop exprs were not built"); 9964 9965 if (!CurContext->isDependentContext()) { 9966 // Finalize the clauses that need pre-built expressions for CodeGen. 9967 for (OMPClause *C : Clauses) { 9968 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9969 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9970 B.NumIterations, *this, CurScope, 9971 DSAStack)) 9972 return StmtError(); 9973 } 9974 } 9975 9976 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9977 return StmtError(); 9978 9979 setFunctionHasBranchProtectedScope(); 9980 return OMPTargetTeamsDistributeSimdDirective::Create( 9981 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9982 } 9983 9984 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9985 SourceLocation StartLoc, 9986 SourceLocation LParenLoc, 9987 SourceLocation EndLoc) { 9988 OMPClause *Res = nullptr; 9989 switch (Kind) { 9990 case OMPC_final: 9991 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9992 break; 9993 case OMPC_num_threads: 9994 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9995 break; 9996 case OMPC_safelen: 9997 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9998 break; 9999 case OMPC_simdlen: 10000 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10001 break; 10002 case OMPC_allocator: 10003 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10004 break; 10005 case OMPC_collapse: 10006 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10007 break; 10008 case OMPC_ordered: 10009 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10010 break; 10011 case OMPC_device: 10012 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10013 break; 10014 case OMPC_num_teams: 10015 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10016 break; 10017 case OMPC_thread_limit: 10018 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10019 break; 10020 case OMPC_priority: 10021 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10022 break; 10023 case OMPC_grainsize: 10024 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10025 break; 10026 case OMPC_num_tasks: 10027 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10028 break; 10029 case OMPC_hint: 10030 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10031 break; 10032 case OMPC_if: 10033 case OMPC_default: 10034 case OMPC_proc_bind: 10035 case OMPC_schedule: 10036 case OMPC_private: 10037 case OMPC_firstprivate: 10038 case OMPC_lastprivate: 10039 case OMPC_shared: 10040 case OMPC_reduction: 10041 case OMPC_task_reduction: 10042 case OMPC_in_reduction: 10043 case OMPC_linear: 10044 case OMPC_aligned: 10045 case OMPC_copyin: 10046 case OMPC_copyprivate: 10047 case OMPC_nowait: 10048 case OMPC_untied: 10049 case OMPC_mergeable: 10050 case OMPC_threadprivate: 10051 case OMPC_allocate: 10052 case OMPC_flush: 10053 case OMPC_read: 10054 case OMPC_write: 10055 case OMPC_update: 10056 case OMPC_capture: 10057 case OMPC_seq_cst: 10058 case OMPC_depend: 10059 case OMPC_threads: 10060 case OMPC_simd: 10061 case OMPC_map: 10062 case OMPC_nogroup: 10063 case OMPC_dist_schedule: 10064 case OMPC_defaultmap: 10065 case OMPC_unknown: 10066 case OMPC_uniform: 10067 case OMPC_to: 10068 case OMPC_from: 10069 case OMPC_use_device_ptr: 10070 case OMPC_is_device_ptr: 10071 case OMPC_unified_address: 10072 case OMPC_unified_shared_memory: 10073 case OMPC_reverse_offload: 10074 case OMPC_dynamic_allocators: 10075 case OMPC_atomic_default_mem_order: 10076 case OMPC_device_type: 10077 case OMPC_match: 10078 llvm_unreachable("Clause is not allowed."); 10079 } 10080 return Res; 10081 } 10082 10083 // An OpenMP directive such as 'target parallel' has two captured regions: 10084 // for the 'target' and 'parallel' respectively. This function returns 10085 // the region in which to capture expressions associated with a clause. 10086 // A return value of OMPD_unknown signifies that the expression should not 10087 // be captured. 10088 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10089 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10090 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10091 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10092 switch (CKind) { 10093 case OMPC_if: 10094 switch (DKind) { 10095 case OMPD_target_parallel: 10096 case OMPD_target_parallel_for: 10097 case OMPD_target_parallel_for_simd: 10098 // If this clause applies to the nested 'parallel' region, capture within 10099 // the 'target' region, otherwise do not capture. 10100 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10101 CaptureRegion = OMPD_target; 10102 break; 10103 case OMPD_target_teams_distribute_parallel_for: 10104 case OMPD_target_teams_distribute_parallel_for_simd: 10105 // If this clause applies to the nested 'parallel' region, capture within 10106 // the 'teams' region, otherwise do not capture. 10107 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10108 CaptureRegion = OMPD_teams; 10109 break; 10110 case OMPD_teams_distribute_parallel_for: 10111 case OMPD_teams_distribute_parallel_for_simd: 10112 CaptureRegion = OMPD_teams; 10113 break; 10114 case OMPD_target_update: 10115 case OMPD_target_enter_data: 10116 case OMPD_target_exit_data: 10117 CaptureRegion = OMPD_task; 10118 break; 10119 case OMPD_cancel: 10120 case OMPD_parallel: 10121 case OMPD_parallel_sections: 10122 case OMPD_parallel_for: 10123 case OMPD_parallel_for_simd: 10124 case OMPD_target: 10125 case OMPD_target_simd: 10126 case OMPD_target_teams: 10127 case OMPD_target_teams_distribute: 10128 case OMPD_target_teams_distribute_simd: 10129 case OMPD_distribute_parallel_for: 10130 case OMPD_distribute_parallel_for_simd: 10131 case OMPD_task: 10132 case OMPD_taskloop: 10133 case OMPD_taskloop_simd: 10134 case OMPD_target_data: 10135 // Do not capture if-clause expressions. 10136 break; 10137 case OMPD_threadprivate: 10138 case OMPD_allocate: 10139 case OMPD_taskyield: 10140 case OMPD_barrier: 10141 case OMPD_taskwait: 10142 case OMPD_cancellation_point: 10143 case OMPD_flush: 10144 case OMPD_declare_reduction: 10145 case OMPD_declare_mapper: 10146 case OMPD_declare_simd: 10147 case OMPD_declare_variant: 10148 case OMPD_declare_target: 10149 case OMPD_end_declare_target: 10150 case OMPD_teams: 10151 case OMPD_simd: 10152 case OMPD_for: 10153 case OMPD_for_simd: 10154 case OMPD_sections: 10155 case OMPD_section: 10156 case OMPD_single: 10157 case OMPD_master: 10158 case OMPD_critical: 10159 case OMPD_taskgroup: 10160 case OMPD_distribute: 10161 case OMPD_ordered: 10162 case OMPD_atomic: 10163 case OMPD_distribute_simd: 10164 case OMPD_teams_distribute: 10165 case OMPD_teams_distribute_simd: 10166 case OMPD_requires: 10167 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10168 case OMPD_unknown: 10169 llvm_unreachable("Unknown OpenMP directive"); 10170 } 10171 break; 10172 case OMPC_num_threads: 10173 switch (DKind) { 10174 case OMPD_target_parallel: 10175 case OMPD_target_parallel_for: 10176 case OMPD_target_parallel_for_simd: 10177 CaptureRegion = OMPD_target; 10178 break; 10179 case OMPD_teams_distribute_parallel_for: 10180 case OMPD_teams_distribute_parallel_for_simd: 10181 case OMPD_target_teams_distribute_parallel_for: 10182 case OMPD_target_teams_distribute_parallel_for_simd: 10183 CaptureRegion = OMPD_teams; 10184 break; 10185 case OMPD_parallel: 10186 case OMPD_parallel_sections: 10187 case OMPD_parallel_for: 10188 case OMPD_parallel_for_simd: 10189 case OMPD_distribute_parallel_for: 10190 case OMPD_distribute_parallel_for_simd: 10191 // Do not capture num_threads-clause expressions. 10192 break; 10193 case OMPD_target_data: 10194 case OMPD_target_enter_data: 10195 case OMPD_target_exit_data: 10196 case OMPD_target_update: 10197 case OMPD_target: 10198 case OMPD_target_simd: 10199 case OMPD_target_teams: 10200 case OMPD_target_teams_distribute: 10201 case OMPD_target_teams_distribute_simd: 10202 case OMPD_cancel: 10203 case OMPD_task: 10204 case OMPD_taskloop: 10205 case OMPD_taskloop_simd: 10206 case OMPD_threadprivate: 10207 case OMPD_allocate: 10208 case OMPD_taskyield: 10209 case OMPD_barrier: 10210 case OMPD_taskwait: 10211 case OMPD_cancellation_point: 10212 case OMPD_flush: 10213 case OMPD_declare_reduction: 10214 case OMPD_declare_mapper: 10215 case OMPD_declare_simd: 10216 case OMPD_declare_variant: 10217 case OMPD_declare_target: 10218 case OMPD_end_declare_target: 10219 case OMPD_teams: 10220 case OMPD_simd: 10221 case OMPD_for: 10222 case OMPD_for_simd: 10223 case OMPD_sections: 10224 case OMPD_section: 10225 case OMPD_single: 10226 case OMPD_master: 10227 case OMPD_critical: 10228 case OMPD_taskgroup: 10229 case OMPD_distribute: 10230 case OMPD_ordered: 10231 case OMPD_atomic: 10232 case OMPD_distribute_simd: 10233 case OMPD_teams_distribute: 10234 case OMPD_teams_distribute_simd: 10235 case OMPD_requires: 10236 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10237 case OMPD_unknown: 10238 llvm_unreachable("Unknown OpenMP directive"); 10239 } 10240 break; 10241 case OMPC_num_teams: 10242 switch (DKind) { 10243 case OMPD_target_teams: 10244 case OMPD_target_teams_distribute: 10245 case OMPD_target_teams_distribute_simd: 10246 case OMPD_target_teams_distribute_parallel_for: 10247 case OMPD_target_teams_distribute_parallel_for_simd: 10248 CaptureRegion = OMPD_target; 10249 break; 10250 case OMPD_teams_distribute_parallel_for: 10251 case OMPD_teams_distribute_parallel_for_simd: 10252 case OMPD_teams: 10253 case OMPD_teams_distribute: 10254 case OMPD_teams_distribute_simd: 10255 // Do not capture num_teams-clause expressions. 10256 break; 10257 case OMPD_distribute_parallel_for: 10258 case OMPD_distribute_parallel_for_simd: 10259 case OMPD_task: 10260 case OMPD_taskloop: 10261 case OMPD_taskloop_simd: 10262 case OMPD_target_data: 10263 case OMPD_target_enter_data: 10264 case OMPD_target_exit_data: 10265 case OMPD_target_update: 10266 case OMPD_cancel: 10267 case OMPD_parallel: 10268 case OMPD_parallel_sections: 10269 case OMPD_parallel_for: 10270 case OMPD_parallel_for_simd: 10271 case OMPD_target: 10272 case OMPD_target_simd: 10273 case OMPD_target_parallel: 10274 case OMPD_target_parallel_for: 10275 case OMPD_target_parallel_for_simd: 10276 case OMPD_threadprivate: 10277 case OMPD_allocate: 10278 case OMPD_taskyield: 10279 case OMPD_barrier: 10280 case OMPD_taskwait: 10281 case OMPD_cancellation_point: 10282 case OMPD_flush: 10283 case OMPD_declare_reduction: 10284 case OMPD_declare_mapper: 10285 case OMPD_declare_simd: 10286 case OMPD_declare_variant: 10287 case OMPD_declare_target: 10288 case OMPD_end_declare_target: 10289 case OMPD_simd: 10290 case OMPD_for: 10291 case OMPD_for_simd: 10292 case OMPD_sections: 10293 case OMPD_section: 10294 case OMPD_single: 10295 case OMPD_master: 10296 case OMPD_critical: 10297 case OMPD_taskgroup: 10298 case OMPD_distribute: 10299 case OMPD_ordered: 10300 case OMPD_atomic: 10301 case OMPD_distribute_simd: 10302 case OMPD_requires: 10303 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10304 case OMPD_unknown: 10305 llvm_unreachable("Unknown OpenMP directive"); 10306 } 10307 break; 10308 case OMPC_thread_limit: 10309 switch (DKind) { 10310 case OMPD_target_teams: 10311 case OMPD_target_teams_distribute: 10312 case OMPD_target_teams_distribute_simd: 10313 case OMPD_target_teams_distribute_parallel_for: 10314 case OMPD_target_teams_distribute_parallel_for_simd: 10315 CaptureRegion = OMPD_target; 10316 break; 10317 case OMPD_teams_distribute_parallel_for: 10318 case OMPD_teams_distribute_parallel_for_simd: 10319 case OMPD_teams: 10320 case OMPD_teams_distribute: 10321 case OMPD_teams_distribute_simd: 10322 // Do not capture thread_limit-clause expressions. 10323 break; 10324 case OMPD_distribute_parallel_for: 10325 case OMPD_distribute_parallel_for_simd: 10326 case OMPD_task: 10327 case OMPD_taskloop: 10328 case OMPD_taskloop_simd: 10329 case OMPD_target_data: 10330 case OMPD_target_enter_data: 10331 case OMPD_target_exit_data: 10332 case OMPD_target_update: 10333 case OMPD_cancel: 10334 case OMPD_parallel: 10335 case OMPD_parallel_sections: 10336 case OMPD_parallel_for: 10337 case OMPD_parallel_for_simd: 10338 case OMPD_target: 10339 case OMPD_target_simd: 10340 case OMPD_target_parallel: 10341 case OMPD_target_parallel_for: 10342 case OMPD_target_parallel_for_simd: 10343 case OMPD_threadprivate: 10344 case OMPD_allocate: 10345 case OMPD_taskyield: 10346 case OMPD_barrier: 10347 case OMPD_taskwait: 10348 case OMPD_cancellation_point: 10349 case OMPD_flush: 10350 case OMPD_declare_reduction: 10351 case OMPD_declare_mapper: 10352 case OMPD_declare_simd: 10353 case OMPD_declare_variant: 10354 case OMPD_declare_target: 10355 case OMPD_end_declare_target: 10356 case OMPD_simd: 10357 case OMPD_for: 10358 case OMPD_for_simd: 10359 case OMPD_sections: 10360 case OMPD_section: 10361 case OMPD_single: 10362 case OMPD_master: 10363 case OMPD_critical: 10364 case OMPD_taskgroup: 10365 case OMPD_distribute: 10366 case OMPD_ordered: 10367 case OMPD_atomic: 10368 case OMPD_distribute_simd: 10369 case OMPD_requires: 10370 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10371 case OMPD_unknown: 10372 llvm_unreachable("Unknown OpenMP directive"); 10373 } 10374 break; 10375 case OMPC_schedule: 10376 switch (DKind) { 10377 case OMPD_parallel_for: 10378 case OMPD_parallel_for_simd: 10379 case OMPD_distribute_parallel_for: 10380 case OMPD_distribute_parallel_for_simd: 10381 case OMPD_teams_distribute_parallel_for: 10382 case OMPD_teams_distribute_parallel_for_simd: 10383 case OMPD_target_parallel_for: 10384 case OMPD_target_parallel_for_simd: 10385 case OMPD_target_teams_distribute_parallel_for: 10386 case OMPD_target_teams_distribute_parallel_for_simd: 10387 CaptureRegion = OMPD_parallel; 10388 break; 10389 case OMPD_for: 10390 case OMPD_for_simd: 10391 // Do not capture schedule-clause expressions. 10392 break; 10393 case OMPD_task: 10394 case OMPD_taskloop: 10395 case OMPD_taskloop_simd: 10396 case OMPD_target_data: 10397 case OMPD_target_enter_data: 10398 case OMPD_target_exit_data: 10399 case OMPD_target_update: 10400 case OMPD_teams: 10401 case OMPD_teams_distribute: 10402 case OMPD_teams_distribute_simd: 10403 case OMPD_target_teams_distribute: 10404 case OMPD_target_teams_distribute_simd: 10405 case OMPD_target: 10406 case OMPD_target_simd: 10407 case OMPD_target_parallel: 10408 case OMPD_cancel: 10409 case OMPD_parallel: 10410 case OMPD_parallel_sections: 10411 case OMPD_threadprivate: 10412 case OMPD_allocate: 10413 case OMPD_taskyield: 10414 case OMPD_barrier: 10415 case OMPD_taskwait: 10416 case OMPD_cancellation_point: 10417 case OMPD_flush: 10418 case OMPD_declare_reduction: 10419 case OMPD_declare_mapper: 10420 case OMPD_declare_simd: 10421 case OMPD_declare_variant: 10422 case OMPD_declare_target: 10423 case OMPD_end_declare_target: 10424 case OMPD_simd: 10425 case OMPD_sections: 10426 case OMPD_section: 10427 case OMPD_single: 10428 case OMPD_master: 10429 case OMPD_critical: 10430 case OMPD_taskgroup: 10431 case OMPD_distribute: 10432 case OMPD_ordered: 10433 case OMPD_atomic: 10434 case OMPD_distribute_simd: 10435 case OMPD_target_teams: 10436 case OMPD_requires: 10437 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10438 case OMPD_unknown: 10439 llvm_unreachable("Unknown OpenMP directive"); 10440 } 10441 break; 10442 case OMPC_dist_schedule: 10443 switch (DKind) { 10444 case OMPD_teams_distribute_parallel_for: 10445 case OMPD_teams_distribute_parallel_for_simd: 10446 case OMPD_teams_distribute: 10447 case OMPD_teams_distribute_simd: 10448 case OMPD_target_teams_distribute_parallel_for: 10449 case OMPD_target_teams_distribute_parallel_for_simd: 10450 case OMPD_target_teams_distribute: 10451 case OMPD_target_teams_distribute_simd: 10452 CaptureRegion = OMPD_teams; 10453 break; 10454 case OMPD_distribute_parallel_for: 10455 case OMPD_distribute_parallel_for_simd: 10456 case OMPD_distribute: 10457 case OMPD_distribute_simd: 10458 // Do not capture thread_limit-clause expressions. 10459 break; 10460 case OMPD_parallel_for: 10461 case OMPD_parallel_for_simd: 10462 case OMPD_target_parallel_for_simd: 10463 case OMPD_target_parallel_for: 10464 case OMPD_task: 10465 case OMPD_taskloop: 10466 case OMPD_taskloop_simd: 10467 case OMPD_target_data: 10468 case OMPD_target_enter_data: 10469 case OMPD_target_exit_data: 10470 case OMPD_target_update: 10471 case OMPD_teams: 10472 case OMPD_target: 10473 case OMPD_target_simd: 10474 case OMPD_target_parallel: 10475 case OMPD_cancel: 10476 case OMPD_parallel: 10477 case OMPD_parallel_sections: 10478 case OMPD_threadprivate: 10479 case OMPD_allocate: 10480 case OMPD_taskyield: 10481 case OMPD_barrier: 10482 case OMPD_taskwait: 10483 case OMPD_cancellation_point: 10484 case OMPD_flush: 10485 case OMPD_declare_reduction: 10486 case OMPD_declare_mapper: 10487 case OMPD_declare_simd: 10488 case OMPD_declare_variant: 10489 case OMPD_declare_target: 10490 case OMPD_end_declare_target: 10491 case OMPD_simd: 10492 case OMPD_for: 10493 case OMPD_for_simd: 10494 case OMPD_sections: 10495 case OMPD_section: 10496 case OMPD_single: 10497 case OMPD_master: 10498 case OMPD_critical: 10499 case OMPD_taskgroup: 10500 case OMPD_ordered: 10501 case OMPD_atomic: 10502 case OMPD_target_teams: 10503 case OMPD_requires: 10504 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10505 case OMPD_unknown: 10506 llvm_unreachable("Unknown OpenMP directive"); 10507 } 10508 break; 10509 case OMPC_device: 10510 switch (DKind) { 10511 case OMPD_target_update: 10512 case OMPD_target_enter_data: 10513 case OMPD_target_exit_data: 10514 case OMPD_target: 10515 case OMPD_target_simd: 10516 case OMPD_target_teams: 10517 case OMPD_target_parallel: 10518 case OMPD_target_teams_distribute: 10519 case OMPD_target_teams_distribute_simd: 10520 case OMPD_target_parallel_for: 10521 case OMPD_target_parallel_for_simd: 10522 case OMPD_target_teams_distribute_parallel_for: 10523 case OMPD_target_teams_distribute_parallel_for_simd: 10524 CaptureRegion = OMPD_task; 10525 break; 10526 case OMPD_target_data: 10527 // Do not capture device-clause expressions. 10528 break; 10529 case OMPD_teams_distribute_parallel_for: 10530 case OMPD_teams_distribute_parallel_for_simd: 10531 case OMPD_teams: 10532 case OMPD_teams_distribute: 10533 case OMPD_teams_distribute_simd: 10534 case OMPD_distribute_parallel_for: 10535 case OMPD_distribute_parallel_for_simd: 10536 case OMPD_task: 10537 case OMPD_taskloop: 10538 case OMPD_taskloop_simd: 10539 case OMPD_cancel: 10540 case OMPD_parallel: 10541 case OMPD_parallel_sections: 10542 case OMPD_parallel_for: 10543 case OMPD_parallel_for_simd: 10544 case OMPD_threadprivate: 10545 case OMPD_allocate: 10546 case OMPD_taskyield: 10547 case OMPD_barrier: 10548 case OMPD_taskwait: 10549 case OMPD_cancellation_point: 10550 case OMPD_flush: 10551 case OMPD_declare_reduction: 10552 case OMPD_declare_mapper: 10553 case OMPD_declare_simd: 10554 case OMPD_declare_variant: 10555 case OMPD_declare_target: 10556 case OMPD_end_declare_target: 10557 case OMPD_simd: 10558 case OMPD_for: 10559 case OMPD_for_simd: 10560 case OMPD_sections: 10561 case OMPD_section: 10562 case OMPD_single: 10563 case OMPD_master: 10564 case OMPD_critical: 10565 case OMPD_taskgroup: 10566 case OMPD_distribute: 10567 case OMPD_ordered: 10568 case OMPD_atomic: 10569 case OMPD_distribute_simd: 10570 case OMPD_requires: 10571 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10572 case OMPD_unknown: 10573 llvm_unreachable("Unknown OpenMP directive"); 10574 } 10575 break; 10576 case OMPC_firstprivate: 10577 case OMPC_lastprivate: 10578 case OMPC_reduction: 10579 case OMPC_task_reduction: 10580 case OMPC_in_reduction: 10581 case OMPC_linear: 10582 case OMPC_default: 10583 case OMPC_proc_bind: 10584 case OMPC_final: 10585 case OMPC_safelen: 10586 case OMPC_simdlen: 10587 case OMPC_allocator: 10588 case OMPC_collapse: 10589 case OMPC_private: 10590 case OMPC_shared: 10591 case OMPC_aligned: 10592 case OMPC_copyin: 10593 case OMPC_copyprivate: 10594 case OMPC_ordered: 10595 case OMPC_nowait: 10596 case OMPC_untied: 10597 case OMPC_mergeable: 10598 case OMPC_threadprivate: 10599 case OMPC_allocate: 10600 case OMPC_flush: 10601 case OMPC_read: 10602 case OMPC_write: 10603 case OMPC_update: 10604 case OMPC_capture: 10605 case OMPC_seq_cst: 10606 case OMPC_depend: 10607 case OMPC_threads: 10608 case OMPC_simd: 10609 case OMPC_map: 10610 case OMPC_priority: 10611 case OMPC_grainsize: 10612 case OMPC_nogroup: 10613 case OMPC_num_tasks: 10614 case OMPC_hint: 10615 case OMPC_defaultmap: 10616 case OMPC_unknown: 10617 case OMPC_uniform: 10618 case OMPC_to: 10619 case OMPC_from: 10620 case OMPC_use_device_ptr: 10621 case OMPC_is_device_ptr: 10622 case OMPC_unified_address: 10623 case OMPC_unified_shared_memory: 10624 case OMPC_reverse_offload: 10625 case OMPC_dynamic_allocators: 10626 case OMPC_atomic_default_mem_order: 10627 case OMPC_device_type: 10628 case OMPC_match: 10629 llvm_unreachable("Unexpected OpenMP clause."); 10630 } 10631 return CaptureRegion; 10632 } 10633 10634 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10635 Expr *Condition, SourceLocation StartLoc, 10636 SourceLocation LParenLoc, 10637 SourceLocation NameModifierLoc, 10638 SourceLocation ColonLoc, 10639 SourceLocation EndLoc) { 10640 Expr *ValExpr = Condition; 10641 Stmt *HelperValStmt = nullptr; 10642 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10643 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10644 !Condition->isInstantiationDependent() && 10645 !Condition->containsUnexpandedParameterPack()) { 10646 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10647 if (Val.isInvalid()) 10648 return nullptr; 10649 10650 ValExpr = Val.get(); 10651 10652 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10653 CaptureRegion = 10654 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10655 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10656 ValExpr = MakeFullExpr(ValExpr).get(); 10657 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10658 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10659 HelperValStmt = buildPreInits(Context, Captures); 10660 } 10661 } 10662 10663 return new (Context) 10664 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10665 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10666 } 10667 10668 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10669 SourceLocation StartLoc, 10670 SourceLocation LParenLoc, 10671 SourceLocation EndLoc) { 10672 Expr *ValExpr = Condition; 10673 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10674 !Condition->isInstantiationDependent() && 10675 !Condition->containsUnexpandedParameterPack()) { 10676 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10677 if (Val.isInvalid()) 10678 return nullptr; 10679 10680 ValExpr = MakeFullExpr(Val.get()).get(); 10681 } 10682 10683 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10684 } 10685 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10686 Expr *Op) { 10687 if (!Op) 10688 return ExprError(); 10689 10690 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10691 public: 10692 IntConvertDiagnoser() 10693 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10694 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10695 QualType T) override { 10696 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10697 } 10698 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10699 QualType T) override { 10700 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10701 } 10702 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10703 QualType T, 10704 QualType ConvTy) override { 10705 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10706 } 10707 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 10708 QualType ConvTy) override { 10709 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10710 << ConvTy->isEnumeralType() << ConvTy; 10711 } 10712 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 10713 QualType T) override { 10714 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 10715 } 10716 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 10717 QualType ConvTy) override { 10718 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10719 << ConvTy->isEnumeralType() << ConvTy; 10720 } 10721 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 10722 QualType) override { 10723 llvm_unreachable("conversion functions are permitted"); 10724 } 10725 } ConvertDiagnoser; 10726 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 10727 } 10728 10729 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 10730 OpenMPClauseKind CKind, 10731 bool StrictlyPositive) { 10732 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 10733 !ValExpr->isInstantiationDependent()) { 10734 SourceLocation Loc = ValExpr->getExprLoc(); 10735 ExprResult Value = 10736 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 10737 if (Value.isInvalid()) 10738 return false; 10739 10740 ValExpr = Value.get(); 10741 // The expression must evaluate to a non-negative integer value. 10742 llvm::APSInt Result; 10743 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 10744 Result.isSigned() && 10745 !((!StrictlyPositive && Result.isNonNegative()) || 10746 (StrictlyPositive && Result.isStrictlyPositive()))) { 10747 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 10748 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10749 << ValExpr->getSourceRange(); 10750 return false; 10751 } 10752 } 10753 return true; 10754 } 10755 10756 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 10757 SourceLocation StartLoc, 10758 SourceLocation LParenLoc, 10759 SourceLocation EndLoc) { 10760 Expr *ValExpr = NumThreads; 10761 Stmt *HelperValStmt = nullptr; 10762 10763 // OpenMP [2.5, Restrictions] 10764 // The num_threads expression must evaluate to a positive integer value. 10765 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 10766 /*StrictlyPositive=*/true)) 10767 return nullptr; 10768 10769 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10770 OpenMPDirectiveKind CaptureRegion = 10771 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 10772 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10773 ValExpr = MakeFullExpr(ValExpr).get(); 10774 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10775 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10776 HelperValStmt = buildPreInits(Context, Captures); 10777 } 10778 10779 return new (Context) OMPNumThreadsClause( 10780 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 10781 } 10782 10783 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 10784 OpenMPClauseKind CKind, 10785 bool StrictlyPositive) { 10786 if (!E) 10787 return ExprError(); 10788 if (E->isValueDependent() || E->isTypeDependent() || 10789 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 10790 return E; 10791 llvm::APSInt Result; 10792 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 10793 if (ICE.isInvalid()) 10794 return ExprError(); 10795 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 10796 (!StrictlyPositive && !Result.isNonNegative())) { 10797 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 10798 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10799 << E->getSourceRange(); 10800 return ExprError(); 10801 } 10802 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 10803 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 10804 << E->getSourceRange(); 10805 return ExprError(); 10806 } 10807 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 10808 DSAStack->setAssociatedLoops(Result.getExtValue()); 10809 else if (CKind == OMPC_ordered) 10810 DSAStack->setAssociatedLoops(Result.getExtValue()); 10811 return ICE; 10812 } 10813 10814 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 10815 SourceLocation LParenLoc, 10816 SourceLocation EndLoc) { 10817 // OpenMP [2.8.1, simd construct, Description] 10818 // The parameter of the safelen clause must be a constant 10819 // positive integer expression. 10820 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 10821 if (Safelen.isInvalid()) 10822 return nullptr; 10823 return new (Context) 10824 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 10825 } 10826 10827 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 10828 SourceLocation LParenLoc, 10829 SourceLocation EndLoc) { 10830 // OpenMP [2.8.1, simd construct, Description] 10831 // The parameter of the simdlen clause must be a constant 10832 // positive integer expression. 10833 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 10834 if (Simdlen.isInvalid()) 10835 return nullptr; 10836 return new (Context) 10837 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 10838 } 10839 10840 /// Tries to find omp_allocator_handle_t type. 10841 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 10842 DSAStackTy *Stack) { 10843 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 10844 if (!OMPAllocatorHandleT.isNull()) 10845 return true; 10846 // Build the predefined allocator expressions. 10847 bool ErrorFound = false; 10848 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 10849 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 10850 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 10851 StringRef Allocator = 10852 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 10853 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 10854 auto *VD = dyn_cast_or_null<ValueDecl>( 10855 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 10856 if (!VD) { 10857 ErrorFound = true; 10858 break; 10859 } 10860 QualType AllocatorType = 10861 VD->getType().getNonLValueExprType(S.getASTContext()); 10862 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10863 if (!Res.isUsable()) { 10864 ErrorFound = true; 10865 break; 10866 } 10867 if (OMPAllocatorHandleT.isNull()) 10868 OMPAllocatorHandleT = AllocatorType; 10869 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10870 ErrorFound = true; 10871 break; 10872 } 10873 Stack->setAllocator(AllocatorKind, Res.get()); 10874 } 10875 if (ErrorFound) { 10876 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10877 return false; 10878 } 10879 OMPAllocatorHandleT.addConst(); 10880 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10881 return true; 10882 } 10883 10884 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10885 SourceLocation LParenLoc, 10886 SourceLocation EndLoc) { 10887 // OpenMP [2.11.3, allocate Directive, Description] 10888 // allocator is an expression of omp_allocator_handle_t type. 10889 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10890 return nullptr; 10891 10892 ExprResult Allocator = DefaultLvalueConversion(A); 10893 if (Allocator.isInvalid()) 10894 return nullptr; 10895 Allocator = PerformImplicitConversion(Allocator.get(), 10896 DSAStack->getOMPAllocatorHandleT(), 10897 Sema::AA_Initializing, 10898 /*AllowExplicit=*/true); 10899 if (Allocator.isInvalid()) 10900 return nullptr; 10901 return new (Context) 10902 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10903 } 10904 10905 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10906 SourceLocation StartLoc, 10907 SourceLocation LParenLoc, 10908 SourceLocation EndLoc) { 10909 // OpenMP [2.7.1, loop construct, Description] 10910 // OpenMP [2.8.1, simd construct, Description] 10911 // OpenMP [2.9.6, distribute construct, Description] 10912 // The parameter of the collapse clause must be a constant 10913 // positive integer expression. 10914 ExprResult NumForLoopsResult = 10915 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10916 if (NumForLoopsResult.isInvalid()) 10917 return nullptr; 10918 return new (Context) 10919 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10920 } 10921 10922 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10923 SourceLocation EndLoc, 10924 SourceLocation LParenLoc, 10925 Expr *NumForLoops) { 10926 // OpenMP [2.7.1, loop construct, Description] 10927 // OpenMP [2.8.1, simd construct, Description] 10928 // OpenMP [2.9.6, distribute construct, Description] 10929 // The parameter of the ordered clause must be a constant 10930 // positive integer expression if any. 10931 if (NumForLoops && LParenLoc.isValid()) { 10932 ExprResult NumForLoopsResult = 10933 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10934 if (NumForLoopsResult.isInvalid()) 10935 return nullptr; 10936 NumForLoops = NumForLoopsResult.get(); 10937 } else { 10938 NumForLoops = nullptr; 10939 } 10940 auto *Clause = OMPOrderedClause::Create( 10941 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10942 StartLoc, LParenLoc, EndLoc); 10943 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10944 return Clause; 10945 } 10946 10947 OMPClause *Sema::ActOnOpenMPSimpleClause( 10948 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10949 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10950 OMPClause *Res = nullptr; 10951 switch (Kind) { 10952 case OMPC_default: 10953 Res = 10954 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10955 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10956 break; 10957 case OMPC_proc_bind: 10958 Res = ActOnOpenMPProcBindClause( 10959 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10960 LParenLoc, EndLoc); 10961 break; 10962 case OMPC_atomic_default_mem_order: 10963 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10964 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10965 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10966 break; 10967 case OMPC_if: 10968 case OMPC_final: 10969 case OMPC_num_threads: 10970 case OMPC_safelen: 10971 case OMPC_simdlen: 10972 case OMPC_allocator: 10973 case OMPC_collapse: 10974 case OMPC_schedule: 10975 case OMPC_private: 10976 case OMPC_firstprivate: 10977 case OMPC_lastprivate: 10978 case OMPC_shared: 10979 case OMPC_reduction: 10980 case OMPC_task_reduction: 10981 case OMPC_in_reduction: 10982 case OMPC_linear: 10983 case OMPC_aligned: 10984 case OMPC_copyin: 10985 case OMPC_copyprivate: 10986 case OMPC_ordered: 10987 case OMPC_nowait: 10988 case OMPC_untied: 10989 case OMPC_mergeable: 10990 case OMPC_threadprivate: 10991 case OMPC_allocate: 10992 case OMPC_flush: 10993 case OMPC_read: 10994 case OMPC_write: 10995 case OMPC_update: 10996 case OMPC_capture: 10997 case OMPC_seq_cst: 10998 case OMPC_depend: 10999 case OMPC_device: 11000 case OMPC_threads: 11001 case OMPC_simd: 11002 case OMPC_map: 11003 case OMPC_num_teams: 11004 case OMPC_thread_limit: 11005 case OMPC_priority: 11006 case OMPC_grainsize: 11007 case OMPC_nogroup: 11008 case OMPC_num_tasks: 11009 case OMPC_hint: 11010 case OMPC_dist_schedule: 11011 case OMPC_defaultmap: 11012 case OMPC_unknown: 11013 case OMPC_uniform: 11014 case OMPC_to: 11015 case OMPC_from: 11016 case OMPC_use_device_ptr: 11017 case OMPC_is_device_ptr: 11018 case OMPC_unified_address: 11019 case OMPC_unified_shared_memory: 11020 case OMPC_reverse_offload: 11021 case OMPC_dynamic_allocators: 11022 case OMPC_device_type: 11023 case OMPC_match: 11024 llvm_unreachable("Clause is not allowed."); 11025 } 11026 return Res; 11027 } 11028 11029 static std::string 11030 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11031 ArrayRef<unsigned> Exclude = llvm::None) { 11032 SmallString<256> Buffer; 11033 llvm::raw_svector_ostream Out(Buffer); 11034 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11035 unsigned Skipped = Exclude.size(); 11036 auto S = Exclude.begin(), E = Exclude.end(); 11037 for (unsigned I = First; I < Last; ++I) { 11038 if (std::find(S, E, I) != E) { 11039 --Skipped; 11040 continue; 11041 } 11042 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11043 if (I == Bound - Skipped) 11044 Out << " or "; 11045 else if (I != Bound + 1 - Skipped) 11046 Out << ", "; 11047 } 11048 return Out.str(); 11049 } 11050 11051 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11052 SourceLocation KindKwLoc, 11053 SourceLocation StartLoc, 11054 SourceLocation LParenLoc, 11055 SourceLocation EndLoc) { 11056 if (Kind == OMPC_DEFAULT_unknown) { 11057 static_assert(OMPC_DEFAULT_unknown > 0, 11058 "OMPC_DEFAULT_unknown not greater than 0"); 11059 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11060 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11061 /*Last=*/OMPC_DEFAULT_unknown) 11062 << getOpenMPClauseName(OMPC_default); 11063 return nullptr; 11064 } 11065 switch (Kind) { 11066 case OMPC_DEFAULT_none: 11067 DSAStack->setDefaultDSANone(KindKwLoc); 11068 break; 11069 case OMPC_DEFAULT_shared: 11070 DSAStack->setDefaultDSAShared(KindKwLoc); 11071 break; 11072 case OMPC_DEFAULT_unknown: 11073 llvm_unreachable("Clause kind is not allowed."); 11074 break; 11075 } 11076 return new (Context) 11077 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11078 } 11079 11080 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11081 SourceLocation KindKwLoc, 11082 SourceLocation StartLoc, 11083 SourceLocation LParenLoc, 11084 SourceLocation EndLoc) { 11085 if (Kind == OMPC_PROC_BIND_unknown) { 11086 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11087 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11088 /*Last=*/OMPC_PROC_BIND_unknown) 11089 << getOpenMPClauseName(OMPC_proc_bind); 11090 return nullptr; 11091 } 11092 return new (Context) 11093 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11094 } 11095 11096 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11097 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11098 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11099 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11100 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11101 << getListOfPossibleValues( 11102 OMPC_atomic_default_mem_order, /*First=*/0, 11103 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11104 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11105 return nullptr; 11106 } 11107 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11108 LParenLoc, EndLoc); 11109 } 11110 11111 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11112 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11113 SourceLocation StartLoc, SourceLocation LParenLoc, 11114 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11115 SourceLocation EndLoc) { 11116 OMPClause *Res = nullptr; 11117 switch (Kind) { 11118 case OMPC_schedule: 11119 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11120 assert(Argument.size() == NumberOfElements && 11121 ArgumentLoc.size() == NumberOfElements); 11122 Res = ActOnOpenMPScheduleClause( 11123 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11124 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11125 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11126 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11127 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11128 break; 11129 case OMPC_if: 11130 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11131 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11132 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11133 DelimLoc, EndLoc); 11134 break; 11135 case OMPC_dist_schedule: 11136 Res = ActOnOpenMPDistScheduleClause( 11137 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11138 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11139 break; 11140 case OMPC_defaultmap: 11141 enum { Modifier, DefaultmapKind }; 11142 Res = ActOnOpenMPDefaultmapClause( 11143 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11144 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11145 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11146 EndLoc); 11147 break; 11148 case OMPC_final: 11149 case OMPC_num_threads: 11150 case OMPC_safelen: 11151 case OMPC_simdlen: 11152 case OMPC_allocator: 11153 case OMPC_collapse: 11154 case OMPC_default: 11155 case OMPC_proc_bind: 11156 case OMPC_private: 11157 case OMPC_firstprivate: 11158 case OMPC_lastprivate: 11159 case OMPC_shared: 11160 case OMPC_reduction: 11161 case OMPC_task_reduction: 11162 case OMPC_in_reduction: 11163 case OMPC_linear: 11164 case OMPC_aligned: 11165 case OMPC_copyin: 11166 case OMPC_copyprivate: 11167 case OMPC_ordered: 11168 case OMPC_nowait: 11169 case OMPC_untied: 11170 case OMPC_mergeable: 11171 case OMPC_threadprivate: 11172 case OMPC_allocate: 11173 case OMPC_flush: 11174 case OMPC_read: 11175 case OMPC_write: 11176 case OMPC_update: 11177 case OMPC_capture: 11178 case OMPC_seq_cst: 11179 case OMPC_depend: 11180 case OMPC_device: 11181 case OMPC_threads: 11182 case OMPC_simd: 11183 case OMPC_map: 11184 case OMPC_num_teams: 11185 case OMPC_thread_limit: 11186 case OMPC_priority: 11187 case OMPC_grainsize: 11188 case OMPC_nogroup: 11189 case OMPC_num_tasks: 11190 case OMPC_hint: 11191 case OMPC_unknown: 11192 case OMPC_uniform: 11193 case OMPC_to: 11194 case OMPC_from: 11195 case OMPC_use_device_ptr: 11196 case OMPC_is_device_ptr: 11197 case OMPC_unified_address: 11198 case OMPC_unified_shared_memory: 11199 case OMPC_reverse_offload: 11200 case OMPC_dynamic_allocators: 11201 case OMPC_atomic_default_mem_order: 11202 case OMPC_device_type: 11203 case OMPC_match: 11204 llvm_unreachable("Clause is not allowed."); 11205 } 11206 return Res; 11207 } 11208 11209 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11210 OpenMPScheduleClauseModifier M2, 11211 SourceLocation M1Loc, SourceLocation M2Loc) { 11212 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11213 SmallVector<unsigned, 2> Excluded; 11214 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11215 Excluded.push_back(M2); 11216 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11217 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11218 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11219 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11220 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11221 << getListOfPossibleValues(OMPC_schedule, 11222 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11223 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11224 Excluded) 11225 << getOpenMPClauseName(OMPC_schedule); 11226 return true; 11227 } 11228 return false; 11229 } 11230 11231 OMPClause *Sema::ActOnOpenMPScheduleClause( 11232 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11233 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11234 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11235 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11236 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11237 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11238 return nullptr; 11239 // OpenMP, 2.7.1, Loop Construct, Restrictions 11240 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11241 // but not both. 11242 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11243 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11244 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11245 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11246 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11247 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11248 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11249 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11250 return nullptr; 11251 } 11252 if (Kind == OMPC_SCHEDULE_unknown) { 11253 std::string Values; 11254 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11255 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11256 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11257 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11258 Exclude); 11259 } else { 11260 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11261 /*Last=*/OMPC_SCHEDULE_unknown); 11262 } 11263 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11264 << Values << getOpenMPClauseName(OMPC_schedule); 11265 return nullptr; 11266 } 11267 // OpenMP, 2.7.1, Loop Construct, Restrictions 11268 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11269 // schedule(guided). 11270 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11271 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11272 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11273 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11274 diag::err_omp_schedule_nonmonotonic_static); 11275 return nullptr; 11276 } 11277 Expr *ValExpr = ChunkSize; 11278 Stmt *HelperValStmt = nullptr; 11279 if (ChunkSize) { 11280 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11281 !ChunkSize->isInstantiationDependent() && 11282 !ChunkSize->containsUnexpandedParameterPack()) { 11283 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11284 ExprResult Val = 11285 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11286 if (Val.isInvalid()) 11287 return nullptr; 11288 11289 ValExpr = Val.get(); 11290 11291 // OpenMP [2.7.1, Restrictions] 11292 // chunk_size must be a loop invariant integer expression with a positive 11293 // value. 11294 llvm::APSInt Result; 11295 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11296 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11297 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11298 << "schedule" << 1 << ChunkSize->getSourceRange(); 11299 return nullptr; 11300 } 11301 } else if (getOpenMPCaptureRegionForClause( 11302 DSAStack->getCurrentDirective(), OMPC_schedule) != 11303 OMPD_unknown && 11304 !CurContext->isDependentContext()) { 11305 ValExpr = MakeFullExpr(ValExpr).get(); 11306 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11307 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11308 HelperValStmt = buildPreInits(Context, Captures); 11309 } 11310 } 11311 } 11312 11313 return new (Context) 11314 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11315 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11316 } 11317 11318 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11319 SourceLocation StartLoc, 11320 SourceLocation EndLoc) { 11321 OMPClause *Res = nullptr; 11322 switch (Kind) { 11323 case OMPC_ordered: 11324 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11325 break; 11326 case OMPC_nowait: 11327 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11328 break; 11329 case OMPC_untied: 11330 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11331 break; 11332 case OMPC_mergeable: 11333 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11334 break; 11335 case OMPC_read: 11336 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11337 break; 11338 case OMPC_write: 11339 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11340 break; 11341 case OMPC_update: 11342 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11343 break; 11344 case OMPC_capture: 11345 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11346 break; 11347 case OMPC_seq_cst: 11348 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11349 break; 11350 case OMPC_threads: 11351 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11352 break; 11353 case OMPC_simd: 11354 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11355 break; 11356 case OMPC_nogroup: 11357 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11358 break; 11359 case OMPC_unified_address: 11360 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11361 break; 11362 case OMPC_unified_shared_memory: 11363 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11364 break; 11365 case OMPC_reverse_offload: 11366 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11367 break; 11368 case OMPC_dynamic_allocators: 11369 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11370 break; 11371 case OMPC_if: 11372 case OMPC_final: 11373 case OMPC_num_threads: 11374 case OMPC_safelen: 11375 case OMPC_simdlen: 11376 case OMPC_allocator: 11377 case OMPC_collapse: 11378 case OMPC_schedule: 11379 case OMPC_private: 11380 case OMPC_firstprivate: 11381 case OMPC_lastprivate: 11382 case OMPC_shared: 11383 case OMPC_reduction: 11384 case OMPC_task_reduction: 11385 case OMPC_in_reduction: 11386 case OMPC_linear: 11387 case OMPC_aligned: 11388 case OMPC_copyin: 11389 case OMPC_copyprivate: 11390 case OMPC_default: 11391 case OMPC_proc_bind: 11392 case OMPC_threadprivate: 11393 case OMPC_allocate: 11394 case OMPC_flush: 11395 case OMPC_depend: 11396 case OMPC_device: 11397 case OMPC_map: 11398 case OMPC_num_teams: 11399 case OMPC_thread_limit: 11400 case OMPC_priority: 11401 case OMPC_grainsize: 11402 case OMPC_num_tasks: 11403 case OMPC_hint: 11404 case OMPC_dist_schedule: 11405 case OMPC_defaultmap: 11406 case OMPC_unknown: 11407 case OMPC_uniform: 11408 case OMPC_to: 11409 case OMPC_from: 11410 case OMPC_use_device_ptr: 11411 case OMPC_is_device_ptr: 11412 case OMPC_atomic_default_mem_order: 11413 case OMPC_device_type: 11414 case OMPC_match: 11415 llvm_unreachable("Clause is not allowed."); 11416 } 11417 return Res; 11418 } 11419 11420 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11421 SourceLocation EndLoc) { 11422 DSAStack->setNowaitRegion(); 11423 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11424 } 11425 11426 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11427 SourceLocation EndLoc) { 11428 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11429 } 11430 11431 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11432 SourceLocation EndLoc) { 11433 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11434 } 11435 11436 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11437 SourceLocation EndLoc) { 11438 return new (Context) OMPReadClause(StartLoc, EndLoc); 11439 } 11440 11441 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11442 SourceLocation EndLoc) { 11443 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11444 } 11445 11446 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11447 SourceLocation EndLoc) { 11448 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11449 } 11450 11451 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11452 SourceLocation EndLoc) { 11453 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11454 } 11455 11456 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11457 SourceLocation EndLoc) { 11458 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11459 } 11460 11461 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11462 SourceLocation EndLoc) { 11463 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11464 } 11465 11466 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11467 SourceLocation EndLoc) { 11468 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11469 } 11470 11471 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11472 SourceLocation EndLoc) { 11473 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11474 } 11475 11476 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11477 SourceLocation EndLoc) { 11478 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11479 } 11480 11481 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11482 SourceLocation EndLoc) { 11483 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11484 } 11485 11486 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11487 SourceLocation EndLoc) { 11488 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11489 } 11490 11491 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11492 SourceLocation EndLoc) { 11493 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11494 } 11495 11496 OMPClause *Sema::ActOnOpenMPVarListClause( 11497 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11498 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11499 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11500 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11501 OpenMPLinearClauseKind LinKind, 11502 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11503 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11504 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11505 SourceLocation StartLoc = Locs.StartLoc; 11506 SourceLocation LParenLoc = Locs.LParenLoc; 11507 SourceLocation EndLoc = Locs.EndLoc; 11508 OMPClause *Res = nullptr; 11509 switch (Kind) { 11510 case OMPC_private: 11511 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11512 break; 11513 case OMPC_firstprivate: 11514 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11515 break; 11516 case OMPC_lastprivate: 11517 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11518 break; 11519 case OMPC_shared: 11520 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11521 break; 11522 case OMPC_reduction: 11523 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11524 EndLoc, ReductionOrMapperIdScopeSpec, 11525 ReductionOrMapperId); 11526 break; 11527 case OMPC_task_reduction: 11528 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11529 EndLoc, ReductionOrMapperIdScopeSpec, 11530 ReductionOrMapperId); 11531 break; 11532 case OMPC_in_reduction: 11533 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11534 EndLoc, ReductionOrMapperIdScopeSpec, 11535 ReductionOrMapperId); 11536 break; 11537 case OMPC_linear: 11538 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11539 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11540 break; 11541 case OMPC_aligned: 11542 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11543 ColonLoc, EndLoc); 11544 break; 11545 case OMPC_copyin: 11546 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11547 break; 11548 case OMPC_copyprivate: 11549 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11550 break; 11551 case OMPC_flush: 11552 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11553 break; 11554 case OMPC_depend: 11555 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11556 StartLoc, LParenLoc, EndLoc); 11557 break; 11558 case OMPC_map: 11559 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11560 ReductionOrMapperIdScopeSpec, 11561 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11562 DepLinMapLoc, ColonLoc, VarList, Locs); 11563 break; 11564 case OMPC_to: 11565 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11566 ReductionOrMapperId, Locs); 11567 break; 11568 case OMPC_from: 11569 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11570 ReductionOrMapperId, Locs); 11571 break; 11572 case OMPC_use_device_ptr: 11573 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11574 break; 11575 case OMPC_is_device_ptr: 11576 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11577 break; 11578 case OMPC_allocate: 11579 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11580 ColonLoc, EndLoc); 11581 break; 11582 case OMPC_if: 11583 case OMPC_final: 11584 case OMPC_num_threads: 11585 case OMPC_safelen: 11586 case OMPC_simdlen: 11587 case OMPC_allocator: 11588 case OMPC_collapse: 11589 case OMPC_default: 11590 case OMPC_proc_bind: 11591 case OMPC_schedule: 11592 case OMPC_ordered: 11593 case OMPC_nowait: 11594 case OMPC_untied: 11595 case OMPC_mergeable: 11596 case OMPC_threadprivate: 11597 case OMPC_read: 11598 case OMPC_write: 11599 case OMPC_update: 11600 case OMPC_capture: 11601 case OMPC_seq_cst: 11602 case OMPC_device: 11603 case OMPC_threads: 11604 case OMPC_simd: 11605 case OMPC_num_teams: 11606 case OMPC_thread_limit: 11607 case OMPC_priority: 11608 case OMPC_grainsize: 11609 case OMPC_nogroup: 11610 case OMPC_num_tasks: 11611 case OMPC_hint: 11612 case OMPC_dist_schedule: 11613 case OMPC_defaultmap: 11614 case OMPC_unknown: 11615 case OMPC_uniform: 11616 case OMPC_unified_address: 11617 case OMPC_unified_shared_memory: 11618 case OMPC_reverse_offload: 11619 case OMPC_dynamic_allocators: 11620 case OMPC_atomic_default_mem_order: 11621 case OMPC_device_type: 11622 case OMPC_match: 11623 llvm_unreachable("Clause is not allowed."); 11624 } 11625 return Res; 11626 } 11627 11628 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11629 ExprObjectKind OK, SourceLocation Loc) { 11630 ExprResult Res = BuildDeclRefExpr( 11631 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11632 if (!Res.isUsable()) 11633 return ExprError(); 11634 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11635 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11636 if (!Res.isUsable()) 11637 return ExprError(); 11638 } 11639 if (VK != VK_LValue && Res.get()->isGLValue()) { 11640 Res = DefaultLvalueConversion(Res.get()); 11641 if (!Res.isUsable()) 11642 return ExprError(); 11643 } 11644 return Res; 11645 } 11646 11647 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11648 SourceLocation StartLoc, 11649 SourceLocation LParenLoc, 11650 SourceLocation EndLoc) { 11651 SmallVector<Expr *, 8> Vars; 11652 SmallVector<Expr *, 8> PrivateCopies; 11653 for (Expr *RefExpr : VarList) { 11654 assert(RefExpr && "NULL expr in OpenMP private clause."); 11655 SourceLocation ELoc; 11656 SourceRange ERange; 11657 Expr *SimpleRefExpr = RefExpr; 11658 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11659 if (Res.second) { 11660 // It will be analyzed later. 11661 Vars.push_back(RefExpr); 11662 PrivateCopies.push_back(nullptr); 11663 } 11664 ValueDecl *D = Res.first; 11665 if (!D) 11666 continue; 11667 11668 QualType Type = D->getType(); 11669 auto *VD = dyn_cast<VarDecl>(D); 11670 11671 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11672 // A variable that appears in a private clause must not have an incomplete 11673 // type or a reference type. 11674 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11675 continue; 11676 Type = Type.getNonReferenceType(); 11677 11678 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11679 // A variable that is privatized must not have a const-qualified type 11680 // unless it is of class type with a mutable member. This restriction does 11681 // not apply to the firstprivate clause. 11682 // 11683 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11684 // A variable that appears in a private clause must not have a 11685 // const-qualified type unless it is of class type with a mutable member. 11686 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11687 continue; 11688 11689 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11690 // in a Construct] 11691 // Variables with the predetermined data-sharing attributes may not be 11692 // listed in data-sharing attributes clauses, except for the cases 11693 // listed below. For these exceptions only, listing a predetermined 11694 // variable in a data-sharing attribute clause is allowed and overrides 11695 // the variable's predetermined data-sharing attributes. 11696 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11697 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 11698 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11699 << getOpenMPClauseName(OMPC_private); 11700 reportOriginalDsa(*this, DSAStack, D, DVar); 11701 continue; 11702 } 11703 11704 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11705 // Variably modified types are not supported for tasks. 11706 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11707 isOpenMPTaskingDirective(CurrDir)) { 11708 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11709 << getOpenMPClauseName(OMPC_private) << Type 11710 << getOpenMPDirectiveName(CurrDir); 11711 bool IsDecl = 11712 !VD || 11713 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11714 Diag(D->getLocation(), 11715 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11716 << D; 11717 continue; 11718 } 11719 11720 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11721 // A list item cannot appear in both a map clause and a data-sharing 11722 // attribute clause on the same construct 11723 // 11724 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11725 // A list item cannot appear in both a map clause and a data-sharing 11726 // attribute clause on the same construct unless the construct is a 11727 // combined construct. 11728 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 11729 CurrDir == OMPD_target) { 11730 OpenMPClauseKind ConflictKind; 11731 if (DSAStack->checkMappableExprComponentListsForDecl( 11732 VD, /*CurrentRegionOnly=*/true, 11733 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 11734 OpenMPClauseKind WhereFoundClauseKind) -> bool { 11735 ConflictKind = WhereFoundClauseKind; 11736 return true; 11737 })) { 11738 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11739 << getOpenMPClauseName(OMPC_private) 11740 << getOpenMPClauseName(ConflictKind) 11741 << getOpenMPDirectiveName(CurrDir); 11742 reportOriginalDsa(*this, DSAStack, D, DVar); 11743 continue; 11744 } 11745 } 11746 11747 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 11748 // A variable of class type (or array thereof) that appears in a private 11749 // clause requires an accessible, unambiguous default constructor for the 11750 // class type. 11751 // Generate helper private variable and initialize it with the default 11752 // value. The address of the original variable is replaced by the address of 11753 // the new private variable in CodeGen. This new variable is not added to 11754 // IdResolver, so the code in the OpenMP region uses original variable for 11755 // proper diagnostics. 11756 Type = Type.getUnqualifiedType(); 11757 VarDecl *VDPrivate = 11758 buildVarDecl(*this, ELoc, Type, D->getName(), 11759 D->hasAttrs() ? &D->getAttrs() : nullptr, 11760 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11761 ActOnUninitializedDecl(VDPrivate); 11762 if (VDPrivate->isInvalidDecl()) 11763 continue; 11764 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11765 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 11766 11767 DeclRefExpr *Ref = nullptr; 11768 if (!VD && !CurContext->isDependentContext()) 11769 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11770 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 11771 Vars.push_back((VD || CurContext->isDependentContext()) 11772 ? RefExpr->IgnoreParens() 11773 : Ref); 11774 PrivateCopies.push_back(VDPrivateRefExpr); 11775 } 11776 11777 if (Vars.empty()) 11778 return nullptr; 11779 11780 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11781 PrivateCopies); 11782 } 11783 11784 namespace { 11785 class DiagsUninitializedSeveretyRAII { 11786 private: 11787 DiagnosticsEngine &Diags; 11788 SourceLocation SavedLoc; 11789 bool IsIgnored = false; 11790 11791 public: 11792 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 11793 bool IsIgnored) 11794 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 11795 if (!IsIgnored) { 11796 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 11797 /*Map*/ diag::Severity::Ignored, Loc); 11798 } 11799 } 11800 ~DiagsUninitializedSeveretyRAII() { 11801 if (!IsIgnored) 11802 Diags.popMappings(SavedLoc); 11803 } 11804 }; 11805 } 11806 11807 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 11808 SourceLocation StartLoc, 11809 SourceLocation LParenLoc, 11810 SourceLocation EndLoc) { 11811 SmallVector<Expr *, 8> Vars; 11812 SmallVector<Expr *, 8> PrivateCopies; 11813 SmallVector<Expr *, 8> Inits; 11814 SmallVector<Decl *, 4> ExprCaptures; 11815 bool IsImplicitClause = 11816 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 11817 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 11818 11819 for (Expr *RefExpr : VarList) { 11820 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 11821 SourceLocation ELoc; 11822 SourceRange ERange; 11823 Expr *SimpleRefExpr = RefExpr; 11824 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11825 if (Res.second) { 11826 // It will be analyzed later. 11827 Vars.push_back(RefExpr); 11828 PrivateCopies.push_back(nullptr); 11829 Inits.push_back(nullptr); 11830 } 11831 ValueDecl *D = Res.first; 11832 if (!D) 11833 continue; 11834 11835 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 11836 QualType Type = D->getType(); 11837 auto *VD = dyn_cast<VarDecl>(D); 11838 11839 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11840 // A variable that appears in a private clause must not have an incomplete 11841 // type or a reference type. 11842 if (RequireCompleteType(ELoc, Type, 11843 diag::err_omp_firstprivate_incomplete_type)) 11844 continue; 11845 Type = Type.getNonReferenceType(); 11846 11847 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 11848 // A variable of class type (or array thereof) that appears in a private 11849 // clause requires an accessible, unambiguous copy constructor for the 11850 // class type. 11851 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11852 11853 // If an implicit firstprivate variable found it was checked already. 11854 DSAStackTy::DSAVarData TopDVar; 11855 if (!IsImplicitClause) { 11856 DSAStackTy::DSAVarData DVar = 11857 DSAStack->getTopDSA(D, /*FromParent=*/false); 11858 TopDVar = DVar; 11859 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11860 bool IsConstant = ElemType.isConstant(Context); 11861 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 11862 // A list item that specifies a given variable may not appear in more 11863 // than one clause on the same directive, except that a variable may be 11864 // specified in both firstprivate and lastprivate clauses. 11865 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11866 // A list item may appear in a firstprivate or lastprivate clause but not 11867 // both. 11868 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 11869 (isOpenMPDistributeDirective(CurrDir) || 11870 DVar.CKind != OMPC_lastprivate) && 11871 DVar.RefExpr) { 11872 Diag(ELoc, diag::err_omp_wrong_dsa) 11873 << getOpenMPClauseName(DVar.CKind) 11874 << getOpenMPClauseName(OMPC_firstprivate); 11875 reportOriginalDsa(*this, DSAStack, D, DVar); 11876 continue; 11877 } 11878 11879 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11880 // in a Construct] 11881 // Variables with the predetermined data-sharing attributes may not be 11882 // listed in data-sharing attributes clauses, except for the cases 11883 // listed below. For these exceptions only, listing a predetermined 11884 // variable in a data-sharing attribute clause is allowed and overrides 11885 // the variable's predetermined data-sharing attributes. 11886 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11887 // in a Construct, C/C++, p.2] 11888 // Variables with const-qualified type having no mutable member may be 11889 // listed in a firstprivate clause, even if they are static data members. 11890 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11891 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11892 Diag(ELoc, diag::err_omp_wrong_dsa) 11893 << getOpenMPClauseName(DVar.CKind) 11894 << getOpenMPClauseName(OMPC_firstprivate); 11895 reportOriginalDsa(*this, DSAStack, D, DVar); 11896 continue; 11897 } 11898 11899 // OpenMP [2.9.3.4, Restrictions, p.2] 11900 // A list item that is private within a parallel region must not appear 11901 // in a firstprivate clause on a worksharing construct if any of the 11902 // worksharing regions arising from the worksharing construct ever bind 11903 // to any of the parallel regions arising from the parallel construct. 11904 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11905 // A list item that is private within a teams region must not appear in a 11906 // firstprivate clause on a distribute construct if any of the distribute 11907 // regions arising from the distribute construct ever bind to any of the 11908 // teams regions arising from the teams construct. 11909 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11910 // A list item that appears in a reduction clause of a teams construct 11911 // must not appear in a firstprivate clause on a distribute construct if 11912 // any of the distribute regions arising from the distribute construct 11913 // ever bind to any of the teams regions arising from the teams construct. 11914 if ((isOpenMPWorksharingDirective(CurrDir) || 11915 isOpenMPDistributeDirective(CurrDir)) && 11916 !isOpenMPParallelDirective(CurrDir) && 11917 !isOpenMPTeamsDirective(CurrDir)) { 11918 DVar = DSAStack->getImplicitDSA(D, true); 11919 if (DVar.CKind != OMPC_shared && 11920 (isOpenMPParallelDirective(DVar.DKind) || 11921 isOpenMPTeamsDirective(DVar.DKind) || 11922 DVar.DKind == OMPD_unknown)) { 11923 Diag(ELoc, diag::err_omp_required_access) 11924 << getOpenMPClauseName(OMPC_firstprivate) 11925 << getOpenMPClauseName(OMPC_shared); 11926 reportOriginalDsa(*this, DSAStack, D, DVar); 11927 continue; 11928 } 11929 } 11930 // OpenMP [2.9.3.4, Restrictions, p.3] 11931 // A list item that appears in a reduction clause of a parallel construct 11932 // must not appear in a firstprivate clause on a worksharing or task 11933 // construct if any of the worksharing or task regions arising from the 11934 // worksharing or task construct ever bind to any of the parallel regions 11935 // arising from the parallel construct. 11936 // OpenMP [2.9.3.4, Restrictions, p.4] 11937 // A list item that appears in a reduction clause in worksharing 11938 // construct must not appear in a firstprivate clause in a task construct 11939 // encountered during execution of any of the worksharing regions arising 11940 // from the worksharing construct. 11941 if (isOpenMPTaskingDirective(CurrDir)) { 11942 DVar = DSAStack->hasInnermostDSA( 11943 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11944 [](OpenMPDirectiveKind K) { 11945 return isOpenMPParallelDirective(K) || 11946 isOpenMPWorksharingDirective(K) || 11947 isOpenMPTeamsDirective(K); 11948 }, 11949 /*FromParent=*/true); 11950 if (DVar.CKind == OMPC_reduction && 11951 (isOpenMPParallelDirective(DVar.DKind) || 11952 isOpenMPWorksharingDirective(DVar.DKind) || 11953 isOpenMPTeamsDirective(DVar.DKind))) { 11954 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11955 << getOpenMPDirectiveName(DVar.DKind); 11956 reportOriginalDsa(*this, DSAStack, D, DVar); 11957 continue; 11958 } 11959 } 11960 11961 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11962 // A list item cannot appear in both a map clause and a data-sharing 11963 // attribute clause on the same construct 11964 // 11965 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11966 // A list item cannot appear in both a map clause and a data-sharing 11967 // attribute clause on the same construct unless the construct is a 11968 // combined construct. 11969 if ((LangOpts.OpenMP <= 45 && 11970 isOpenMPTargetExecutionDirective(CurrDir)) || 11971 CurrDir == OMPD_target) { 11972 OpenMPClauseKind ConflictKind; 11973 if (DSAStack->checkMappableExprComponentListsForDecl( 11974 VD, /*CurrentRegionOnly=*/true, 11975 [&ConflictKind]( 11976 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11977 OpenMPClauseKind WhereFoundClauseKind) { 11978 ConflictKind = WhereFoundClauseKind; 11979 return true; 11980 })) { 11981 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11982 << getOpenMPClauseName(OMPC_firstprivate) 11983 << getOpenMPClauseName(ConflictKind) 11984 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11985 reportOriginalDsa(*this, DSAStack, D, DVar); 11986 continue; 11987 } 11988 } 11989 } 11990 11991 // Variably modified types are not supported for tasks. 11992 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11993 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11994 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11995 << getOpenMPClauseName(OMPC_firstprivate) << Type 11996 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11997 bool IsDecl = 11998 !VD || 11999 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12000 Diag(D->getLocation(), 12001 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12002 << D; 12003 continue; 12004 } 12005 12006 Type = Type.getUnqualifiedType(); 12007 VarDecl *VDPrivate = 12008 buildVarDecl(*this, ELoc, Type, D->getName(), 12009 D->hasAttrs() ? &D->getAttrs() : nullptr, 12010 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12011 // Generate helper private variable and initialize it with the value of the 12012 // original variable. The address of the original variable is replaced by 12013 // the address of the new private variable in the CodeGen. This new variable 12014 // is not added to IdResolver, so the code in the OpenMP region uses 12015 // original variable for proper diagnostics and variable capturing. 12016 Expr *VDInitRefExpr = nullptr; 12017 // For arrays generate initializer for single element and replace it by the 12018 // original array element in CodeGen. 12019 if (Type->isArrayType()) { 12020 VarDecl *VDInit = 12021 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12022 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12023 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12024 ElemType = ElemType.getUnqualifiedType(); 12025 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12026 ".firstprivate.temp"); 12027 InitializedEntity Entity = 12028 InitializedEntity::InitializeVariable(VDInitTemp); 12029 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12030 12031 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12032 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12033 if (Result.isInvalid()) 12034 VDPrivate->setInvalidDecl(); 12035 else 12036 VDPrivate->setInit(Result.getAs<Expr>()); 12037 // Remove temp variable declaration. 12038 Context.Deallocate(VDInitTemp); 12039 } else { 12040 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12041 ".firstprivate.temp"); 12042 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12043 RefExpr->getExprLoc()); 12044 AddInitializerToDecl(VDPrivate, 12045 DefaultLvalueConversion(VDInitRefExpr).get(), 12046 /*DirectInit=*/false); 12047 } 12048 if (VDPrivate->isInvalidDecl()) { 12049 if (IsImplicitClause) { 12050 Diag(RefExpr->getExprLoc(), 12051 diag::note_omp_task_predetermined_firstprivate_here); 12052 } 12053 continue; 12054 } 12055 CurContext->addDecl(VDPrivate); 12056 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12057 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12058 RefExpr->getExprLoc()); 12059 DeclRefExpr *Ref = nullptr; 12060 if (!VD && !CurContext->isDependentContext()) { 12061 if (TopDVar.CKind == OMPC_lastprivate) { 12062 Ref = TopDVar.PrivateCopy; 12063 } else { 12064 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12065 if (!isOpenMPCapturedDecl(D)) 12066 ExprCaptures.push_back(Ref->getDecl()); 12067 } 12068 } 12069 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12070 Vars.push_back((VD || CurContext->isDependentContext()) 12071 ? RefExpr->IgnoreParens() 12072 : Ref); 12073 PrivateCopies.push_back(VDPrivateRefExpr); 12074 Inits.push_back(VDInitRefExpr); 12075 } 12076 12077 if (Vars.empty()) 12078 return nullptr; 12079 12080 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12081 Vars, PrivateCopies, Inits, 12082 buildPreInits(Context, ExprCaptures)); 12083 } 12084 12085 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12086 SourceLocation StartLoc, 12087 SourceLocation LParenLoc, 12088 SourceLocation EndLoc) { 12089 SmallVector<Expr *, 8> Vars; 12090 SmallVector<Expr *, 8> SrcExprs; 12091 SmallVector<Expr *, 8> DstExprs; 12092 SmallVector<Expr *, 8> AssignmentOps; 12093 SmallVector<Decl *, 4> ExprCaptures; 12094 SmallVector<Expr *, 4> ExprPostUpdates; 12095 for (Expr *RefExpr : VarList) { 12096 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12097 SourceLocation ELoc; 12098 SourceRange ERange; 12099 Expr *SimpleRefExpr = RefExpr; 12100 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12101 if (Res.second) { 12102 // It will be analyzed later. 12103 Vars.push_back(RefExpr); 12104 SrcExprs.push_back(nullptr); 12105 DstExprs.push_back(nullptr); 12106 AssignmentOps.push_back(nullptr); 12107 } 12108 ValueDecl *D = Res.first; 12109 if (!D) 12110 continue; 12111 12112 QualType Type = D->getType(); 12113 auto *VD = dyn_cast<VarDecl>(D); 12114 12115 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12116 // A variable that appears in a lastprivate clause must not have an 12117 // incomplete type or a reference type. 12118 if (RequireCompleteType(ELoc, Type, 12119 diag::err_omp_lastprivate_incomplete_type)) 12120 continue; 12121 Type = Type.getNonReferenceType(); 12122 12123 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12124 // A variable that is privatized must not have a const-qualified type 12125 // unless it is of class type with a mutable member. This restriction does 12126 // not apply to the firstprivate clause. 12127 // 12128 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12129 // A variable that appears in a lastprivate clause must not have a 12130 // const-qualified type unless it is of class type with a mutable member. 12131 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12132 continue; 12133 12134 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12135 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12136 // in a Construct] 12137 // Variables with the predetermined data-sharing attributes may not be 12138 // listed in data-sharing attributes clauses, except for the cases 12139 // listed below. 12140 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12141 // A list item may appear in a firstprivate or lastprivate clause but not 12142 // both. 12143 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12144 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12145 (isOpenMPDistributeDirective(CurrDir) || 12146 DVar.CKind != OMPC_firstprivate) && 12147 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12148 Diag(ELoc, diag::err_omp_wrong_dsa) 12149 << getOpenMPClauseName(DVar.CKind) 12150 << getOpenMPClauseName(OMPC_lastprivate); 12151 reportOriginalDsa(*this, DSAStack, D, DVar); 12152 continue; 12153 } 12154 12155 // OpenMP [2.14.3.5, Restrictions, p.2] 12156 // A list item that is private within a parallel region, or that appears in 12157 // the reduction clause of a parallel construct, must not appear in a 12158 // lastprivate clause on a worksharing construct if any of the corresponding 12159 // worksharing regions ever binds to any of the corresponding parallel 12160 // regions. 12161 DSAStackTy::DSAVarData TopDVar = DVar; 12162 if (isOpenMPWorksharingDirective(CurrDir) && 12163 !isOpenMPParallelDirective(CurrDir) && 12164 !isOpenMPTeamsDirective(CurrDir)) { 12165 DVar = DSAStack->getImplicitDSA(D, true); 12166 if (DVar.CKind != OMPC_shared) { 12167 Diag(ELoc, diag::err_omp_required_access) 12168 << getOpenMPClauseName(OMPC_lastprivate) 12169 << getOpenMPClauseName(OMPC_shared); 12170 reportOriginalDsa(*this, DSAStack, D, DVar); 12171 continue; 12172 } 12173 } 12174 12175 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12176 // A variable of class type (or array thereof) that appears in a 12177 // lastprivate clause requires an accessible, unambiguous default 12178 // constructor for the class type, unless the list item is also specified 12179 // in a firstprivate clause. 12180 // A variable of class type (or array thereof) that appears in a 12181 // lastprivate clause requires an accessible, unambiguous copy assignment 12182 // operator for the class type. 12183 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12184 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12185 Type.getUnqualifiedType(), ".lastprivate.src", 12186 D->hasAttrs() ? &D->getAttrs() : nullptr); 12187 DeclRefExpr *PseudoSrcExpr = 12188 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12189 VarDecl *DstVD = 12190 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12191 D->hasAttrs() ? &D->getAttrs() : nullptr); 12192 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12193 // For arrays generate assignment operation for single element and replace 12194 // it by the original array element in CodeGen. 12195 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12196 PseudoDstExpr, PseudoSrcExpr); 12197 if (AssignmentOp.isInvalid()) 12198 continue; 12199 AssignmentOp = 12200 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12201 if (AssignmentOp.isInvalid()) 12202 continue; 12203 12204 DeclRefExpr *Ref = nullptr; 12205 if (!VD && !CurContext->isDependentContext()) { 12206 if (TopDVar.CKind == OMPC_firstprivate) { 12207 Ref = TopDVar.PrivateCopy; 12208 } else { 12209 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12210 if (!isOpenMPCapturedDecl(D)) 12211 ExprCaptures.push_back(Ref->getDecl()); 12212 } 12213 if (TopDVar.CKind == OMPC_firstprivate || 12214 (!isOpenMPCapturedDecl(D) && 12215 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12216 ExprResult RefRes = DefaultLvalueConversion(Ref); 12217 if (!RefRes.isUsable()) 12218 continue; 12219 ExprResult PostUpdateRes = 12220 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12221 RefRes.get()); 12222 if (!PostUpdateRes.isUsable()) 12223 continue; 12224 ExprPostUpdates.push_back( 12225 IgnoredValueConversions(PostUpdateRes.get()).get()); 12226 } 12227 } 12228 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12229 Vars.push_back((VD || CurContext->isDependentContext()) 12230 ? RefExpr->IgnoreParens() 12231 : Ref); 12232 SrcExprs.push_back(PseudoSrcExpr); 12233 DstExprs.push_back(PseudoDstExpr); 12234 AssignmentOps.push_back(AssignmentOp.get()); 12235 } 12236 12237 if (Vars.empty()) 12238 return nullptr; 12239 12240 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12241 Vars, SrcExprs, DstExprs, AssignmentOps, 12242 buildPreInits(Context, ExprCaptures), 12243 buildPostUpdate(*this, ExprPostUpdates)); 12244 } 12245 12246 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12247 SourceLocation StartLoc, 12248 SourceLocation LParenLoc, 12249 SourceLocation EndLoc) { 12250 SmallVector<Expr *, 8> Vars; 12251 for (Expr *RefExpr : VarList) { 12252 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12253 SourceLocation ELoc; 12254 SourceRange ERange; 12255 Expr *SimpleRefExpr = RefExpr; 12256 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12257 if (Res.second) { 12258 // It will be analyzed later. 12259 Vars.push_back(RefExpr); 12260 } 12261 ValueDecl *D = Res.first; 12262 if (!D) 12263 continue; 12264 12265 auto *VD = dyn_cast<VarDecl>(D); 12266 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12267 // in a Construct] 12268 // Variables with the predetermined data-sharing attributes may not be 12269 // listed in data-sharing attributes clauses, except for the cases 12270 // listed below. For these exceptions only, listing a predetermined 12271 // variable in a data-sharing attribute clause is allowed and overrides 12272 // the variable's predetermined data-sharing attributes. 12273 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12274 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12275 DVar.RefExpr) { 12276 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12277 << getOpenMPClauseName(OMPC_shared); 12278 reportOriginalDsa(*this, DSAStack, D, DVar); 12279 continue; 12280 } 12281 12282 DeclRefExpr *Ref = nullptr; 12283 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12284 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12285 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12286 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12287 ? RefExpr->IgnoreParens() 12288 : Ref); 12289 } 12290 12291 if (Vars.empty()) 12292 return nullptr; 12293 12294 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12295 } 12296 12297 namespace { 12298 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12299 DSAStackTy *Stack; 12300 12301 public: 12302 bool VisitDeclRefExpr(DeclRefExpr *E) { 12303 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12304 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12305 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12306 return false; 12307 if (DVar.CKind != OMPC_unknown) 12308 return true; 12309 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12310 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12311 /*FromParent=*/true); 12312 return DVarPrivate.CKind != OMPC_unknown; 12313 } 12314 return false; 12315 } 12316 bool VisitStmt(Stmt *S) { 12317 for (Stmt *Child : S->children()) { 12318 if (Child && Visit(Child)) 12319 return true; 12320 } 12321 return false; 12322 } 12323 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12324 }; 12325 } // namespace 12326 12327 namespace { 12328 // Transform MemberExpression for specified FieldDecl of current class to 12329 // DeclRefExpr to specified OMPCapturedExprDecl. 12330 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12331 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12332 ValueDecl *Field = nullptr; 12333 DeclRefExpr *CapturedExpr = nullptr; 12334 12335 public: 12336 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12337 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12338 12339 ExprResult TransformMemberExpr(MemberExpr *E) { 12340 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12341 E->getMemberDecl() == Field) { 12342 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12343 return CapturedExpr; 12344 } 12345 return BaseTransform::TransformMemberExpr(E); 12346 } 12347 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12348 }; 12349 } // namespace 12350 12351 template <typename T, typename U> 12352 static T filterLookupForUDReductionAndMapper( 12353 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12354 for (U &Set : Lookups) { 12355 for (auto *D : Set) { 12356 if (T Res = Gen(cast<ValueDecl>(D))) 12357 return Res; 12358 } 12359 } 12360 return T(); 12361 } 12362 12363 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12364 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12365 12366 for (auto RD : D->redecls()) { 12367 // Don't bother with extra checks if we already know this one isn't visible. 12368 if (RD == D) 12369 continue; 12370 12371 auto ND = cast<NamedDecl>(RD); 12372 if (LookupResult::isVisible(SemaRef, ND)) 12373 return ND; 12374 } 12375 12376 return nullptr; 12377 } 12378 12379 static void 12380 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12381 SourceLocation Loc, QualType Ty, 12382 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12383 // Find all of the associated namespaces and classes based on the 12384 // arguments we have. 12385 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12386 Sema::AssociatedClassSet AssociatedClasses; 12387 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12388 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12389 AssociatedClasses); 12390 12391 // C++ [basic.lookup.argdep]p3: 12392 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12393 // and let Y be the lookup set produced by argument dependent 12394 // lookup (defined as follows). If X contains [...] then Y is 12395 // empty. Otherwise Y is the set of declarations found in the 12396 // namespaces associated with the argument types as described 12397 // below. The set of declarations found by the lookup of the name 12398 // is the union of X and Y. 12399 // 12400 // Here, we compute Y and add its members to the overloaded 12401 // candidate set. 12402 for (auto *NS : AssociatedNamespaces) { 12403 // When considering an associated namespace, the lookup is the 12404 // same as the lookup performed when the associated namespace is 12405 // used as a qualifier (3.4.3.2) except that: 12406 // 12407 // -- Any using-directives in the associated namespace are 12408 // ignored. 12409 // 12410 // -- Any namespace-scope friend functions declared in 12411 // associated classes are visible within their respective 12412 // namespaces even if they are not visible during an ordinary 12413 // lookup (11.4). 12414 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12415 for (auto *D : R) { 12416 auto *Underlying = D; 12417 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12418 Underlying = USD->getTargetDecl(); 12419 12420 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12421 !isa<OMPDeclareMapperDecl>(Underlying)) 12422 continue; 12423 12424 if (!SemaRef.isVisible(D)) { 12425 D = findAcceptableDecl(SemaRef, D); 12426 if (!D) 12427 continue; 12428 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12429 Underlying = USD->getTargetDecl(); 12430 } 12431 Lookups.emplace_back(); 12432 Lookups.back().addDecl(Underlying); 12433 } 12434 } 12435 } 12436 12437 static ExprResult 12438 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12439 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12440 const DeclarationNameInfo &ReductionId, QualType Ty, 12441 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12442 if (ReductionIdScopeSpec.isInvalid()) 12443 return ExprError(); 12444 SmallVector<UnresolvedSet<8>, 4> Lookups; 12445 if (S) { 12446 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12447 Lookup.suppressDiagnostics(); 12448 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12449 NamedDecl *D = Lookup.getRepresentativeDecl(); 12450 do { 12451 S = S->getParent(); 12452 } while (S && !S->isDeclScope(D)); 12453 if (S) 12454 S = S->getParent(); 12455 Lookups.emplace_back(); 12456 Lookups.back().append(Lookup.begin(), Lookup.end()); 12457 Lookup.clear(); 12458 } 12459 } else if (auto *ULE = 12460 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12461 Lookups.push_back(UnresolvedSet<8>()); 12462 Decl *PrevD = nullptr; 12463 for (NamedDecl *D : ULE->decls()) { 12464 if (D == PrevD) 12465 Lookups.push_back(UnresolvedSet<8>()); 12466 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12467 Lookups.back().addDecl(DRD); 12468 PrevD = D; 12469 } 12470 } 12471 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12472 Ty->isInstantiationDependentType() || 12473 Ty->containsUnexpandedParameterPack() || 12474 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12475 return !D->isInvalidDecl() && 12476 (D->getType()->isDependentType() || 12477 D->getType()->isInstantiationDependentType() || 12478 D->getType()->containsUnexpandedParameterPack()); 12479 })) { 12480 UnresolvedSet<8> ResSet; 12481 for (const UnresolvedSet<8> &Set : Lookups) { 12482 if (Set.empty()) 12483 continue; 12484 ResSet.append(Set.begin(), Set.end()); 12485 // The last item marks the end of all declarations at the specified scope. 12486 ResSet.addDecl(Set[Set.size() - 1]); 12487 } 12488 return UnresolvedLookupExpr::Create( 12489 SemaRef.Context, /*NamingClass=*/nullptr, 12490 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12491 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12492 } 12493 // Lookup inside the classes. 12494 // C++ [over.match.oper]p3: 12495 // For a unary operator @ with an operand of a type whose 12496 // cv-unqualified version is T1, and for a binary operator @ with 12497 // a left operand of a type whose cv-unqualified version is T1 and 12498 // a right operand of a type whose cv-unqualified version is T2, 12499 // three sets of candidate functions, designated member 12500 // candidates, non-member candidates and built-in candidates, are 12501 // constructed as follows: 12502 // -- If T1 is a complete class type or a class currently being 12503 // defined, the set of member candidates is the result of the 12504 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12505 // the set of member candidates is empty. 12506 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12507 Lookup.suppressDiagnostics(); 12508 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12509 // Complete the type if it can be completed. 12510 // If the type is neither complete nor being defined, bail out now. 12511 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12512 TyRec->getDecl()->getDefinition()) { 12513 Lookup.clear(); 12514 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12515 if (Lookup.empty()) { 12516 Lookups.emplace_back(); 12517 Lookups.back().append(Lookup.begin(), Lookup.end()); 12518 } 12519 } 12520 } 12521 // Perform ADL. 12522 if (SemaRef.getLangOpts().CPlusPlus) 12523 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12524 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12525 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12526 if (!D->isInvalidDecl() && 12527 SemaRef.Context.hasSameType(D->getType(), Ty)) 12528 return D; 12529 return nullptr; 12530 })) 12531 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12532 VK_LValue, Loc); 12533 if (SemaRef.getLangOpts().CPlusPlus) { 12534 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12535 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12536 if (!D->isInvalidDecl() && 12537 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12538 !Ty.isMoreQualifiedThan(D->getType())) 12539 return D; 12540 return nullptr; 12541 })) { 12542 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12543 /*DetectVirtual=*/false); 12544 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12545 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12546 VD->getType().getUnqualifiedType()))) { 12547 if (SemaRef.CheckBaseClassAccess( 12548 Loc, VD->getType(), Ty, Paths.front(), 12549 /*DiagID=*/0) != Sema::AR_inaccessible) { 12550 SemaRef.BuildBasePathArray(Paths, BasePath); 12551 return SemaRef.BuildDeclRefExpr( 12552 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12553 } 12554 } 12555 } 12556 } 12557 } 12558 if (ReductionIdScopeSpec.isSet()) { 12559 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12560 return ExprError(); 12561 } 12562 return ExprEmpty(); 12563 } 12564 12565 namespace { 12566 /// Data for the reduction-based clauses. 12567 struct ReductionData { 12568 /// List of original reduction items. 12569 SmallVector<Expr *, 8> Vars; 12570 /// List of private copies of the reduction items. 12571 SmallVector<Expr *, 8> Privates; 12572 /// LHS expressions for the reduction_op expressions. 12573 SmallVector<Expr *, 8> LHSs; 12574 /// RHS expressions for the reduction_op expressions. 12575 SmallVector<Expr *, 8> RHSs; 12576 /// Reduction operation expression. 12577 SmallVector<Expr *, 8> ReductionOps; 12578 /// Taskgroup descriptors for the corresponding reduction items in 12579 /// in_reduction clauses. 12580 SmallVector<Expr *, 8> TaskgroupDescriptors; 12581 /// List of captures for clause. 12582 SmallVector<Decl *, 4> ExprCaptures; 12583 /// List of postupdate expressions. 12584 SmallVector<Expr *, 4> ExprPostUpdates; 12585 ReductionData() = delete; 12586 /// Reserves required memory for the reduction data. 12587 ReductionData(unsigned Size) { 12588 Vars.reserve(Size); 12589 Privates.reserve(Size); 12590 LHSs.reserve(Size); 12591 RHSs.reserve(Size); 12592 ReductionOps.reserve(Size); 12593 TaskgroupDescriptors.reserve(Size); 12594 ExprCaptures.reserve(Size); 12595 ExprPostUpdates.reserve(Size); 12596 } 12597 /// Stores reduction item and reduction operation only (required for dependent 12598 /// reduction item). 12599 void push(Expr *Item, Expr *ReductionOp) { 12600 Vars.emplace_back(Item); 12601 Privates.emplace_back(nullptr); 12602 LHSs.emplace_back(nullptr); 12603 RHSs.emplace_back(nullptr); 12604 ReductionOps.emplace_back(ReductionOp); 12605 TaskgroupDescriptors.emplace_back(nullptr); 12606 } 12607 /// Stores reduction data. 12608 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12609 Expr *TaskgroupDescriptor) { 12610 Vars.emplace_back(Item); 12611 Privates.emplace_back(Private); 12612 LHSs.emplace_back(LHS); 12613 RHSs.emplace_back(RHS); 12614 ReductionOps.emplace_back(ReductionOp); 12615 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12616 } 12617 }; 12618 } // namespace 12619 12620 static bool checkOMPArraySectionConstantForReduction( 12621 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12622 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12623 const Expr *Length = OASE->getLength(); 12624 if (Length == nullptr) { 12625 // For array sections of the form [1:] or [:], we would need to analyze 12626 // the lower bound... 12627 if (OASE->getColonLoc().isValid()) 12628 return false; 12629 12630 // This is an array subscript which has implicit length 1! 12631 SingleElement = true; 12632 ArraySizes.push_back(llvm::APSInt::get(1)); 12633 } else { 12634 Expr::EvalResult Result; 12635 if (!Length->EvaluateAsInt(Result, Context)) 12636 return false; 12637 12638 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12639 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12640 ArraySizes.push_back(ConstantLengthValue); 12641 } 12642 12643 // Get the base of this array section and walk up from there. 12644 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12645 12646 // We require length = 1 for all array sections except the right-most to 12647 // guarantee that the memory region is contiguous and has no holes in it. 12648 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12649 Length = TempOASE->getLength(); 12650 if (Length == nullptr) { 12651 // For array sections of the form [1:] or [:], we would need to analyze 12652 // the lower bound... 12653 if (OASE->getColonLoc().isValid()) 12654 return false; 12655 12656 // This is an array subscript which has implicit length 1! 12657 ArraySizes.push_back(llvm::APSInt::get(1)); 12658 } else { 12659 Expr::EvalResult Result; 12660 if (!Length->EvaluateAsInt(Result, Context)) 12661 return false; 12662 12663 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12664 if (ConstantLengthValue.getSExtValue() != 1) 12665 return false; 12666 12667 ArraySizes.push_back(ConstantLengthValue); 12668 } 12669 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12670 } 12671 12672 // If we have a single element, we don't need to add the implicit lengths. 12673 if (!SingleElement) { 12674 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12675 // Has implicit length 1! 12676 ArraySizes.push_back(llvm::APSInt::get(1)); 12677 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12678 } 12679 } 12680 12681 // This array section can be privatized as a single value or as a constant 12682 // sized array. 12683 return true; 12684 } 12685 12686 static bool actOnOMPReductionKindClause( 12687 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12688 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12689 SourceLocation ColonLoc, SourceLocation EndLoc, 12690 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12691 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12692 DeclarationName DN = ReductionId.getName(); 12693 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12694 BinaryOperatorKind BOK = BO_Comma; 12695 12696 ASTContext &Context = S.Context; 12697 // OpenMP [2.14.3.6, reduction clause] 12698 // C 12699 // reduction-identifier is either an identifier or one of the following 12700 // operators: +, -, *, &, |, ^, && and || 12701 // C++ 12702 // reduction-identifier is either an id-expression or one of the following 12703 // operators: +, -, *, &, |, ^, && and || 12704 switch (OOK) { 12705 case OO_Plus: 12706 case OO_Minus: 12707 BOK = BO_Add; 12708 break; 12709 case OO_Star: 12710 BOK = BO_Mul; 12711 break; 12712 case OO_Amp: 12713 BOK = BO_And; 12714 break; 12715 case OO_Pipe: 12716 BOK = BO_Or; 12717 break; 12718 case OO_Caret: 12719 BOK = BO_Xor; 12720 break; 12721 case OO_AmpAmp: 12722 BOK = BO_LAnd; 12723 break; 12724 case OO_PipePipe: 12725 BOK = BO_LOr; 12726 break; 12727 case OO_New: 12728 case OO_Delete: 12729 case OO_Array_New: 12730 case OO_Array_Delete: 12731 case OO_Slash: 12732 case OO_Percent: 12733 case OO_Tilde: 12734 case OO_Exclaim: 12735 case OO_Equal: 12736 case OO_Less: 12737 case OO_Greater: 12738 case OO_LessEqual: 12739 case OO_GreaterEqual: 12740 case OO_PlusEqual: 12741 case OO_MinusEqual: 12742 case OO_StarEqual: 12743 case OO_SlashEqual: 12744 case OO_PercentEqual: 12745 case OO_CaretEqual: 12746 case OO_AmpEqual: 12747 case OO_PipeEqual: 12748 case OO_LessLess: 12749 case OO_GreaterGreater: 12750 case OO_LessLessEqual: 12751 case OO_GreaterGreaterEqual: 12752 case OO_EqualEqual: 12753 case OO_ExclaimEqual: 12754 case OO_Spaceship: 12755 case OO_PlusPlus: 12756 case OO_MinusMinus: 12757 case OO_Comma: 12758 case OO_ArrowStar: 12759 case OO_Arrow: 12760 case OO_Call: 12761 case OO_Subscript: 12762 case OO_Conditional: 12763 case OO_Coawait: 12764 case NUM_OVERLOADED_OPERATORS: 12765 llvm_unreachable("Unexpected reduction identifier"); 12766 case OO_None: 12767 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 12768 if (II->isStr("max")) 12769 BOK = BO_GT; 12770 else if (II->isStr("min")) 12771 BOK = BO_LT; 12772 } 12773 break; 12774 } 12775 SourceRange ReductionIdRange; 12776 if (ReductionIdScopeSpec.isValid()) 12777 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 12778 else 12779 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 12780 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 12781 12782 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 12783 bool FirstIter = true; 12784 for (Expr *RefExpr : VarList) { 12785 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 12786 // OpenMP [2.1, C/C++] 12787 // A list item is a variable or array section, subject to the restrictions 12788 // specified in Section 2.4 on page 42 and in each of the sections 12789 // describing clauses and directives for which a list appears. 12790 // OpenMP [2.14.3.3, Restrictions, p.1] 12791 // A variable that is part of another variable (as an array or 12792 // structure element) cannot appear in a private clause. 12793 if (!FirstIter && IR != ER) 12794 ++IR; 12795 FirstIter = false; 12796 SourceLocation ELoc; 12797 SourceRange ERange; 12798 Expr *SimpleRefExpr = RefExpr; 12799 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 12800 /*AllowArraySection=*/true); 12801 if (Res.second) { 12802 // Try to find 'declare reduction' corresponding construct before using 12803 // builtin/overloaded operators. 12804 QualType Type = Context.DependentTy; 12805 CXXCastPath BasePath; 12806 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12807 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12808 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12809 Expr *ReductionOp = nullptr; 12810 if (S.CurContext->isDependentContext() && 12811 (DeclareReductionRef.isUnset() || 12812 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 12813 ReductionOp = DeclareReductionRef.get(); 12814 // It will be analyzed later. 12815 RD.push(RefExpr, ReductionOp); 12816 } 12817 ValueDecl *D = Res.first; 12818 if (!D) 12819 continue; 12820 12821 Expr *TaskgroupDescriptor = nullptr; 12822 QualType Type; 12823 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 12824 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 12825 if (ASE) { 12826 Type = ASE->getType().getNonReferenceType(); 12827 } else if (OASE) { 12828 QualType BaseType = 12829 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 12830 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 12831 Type = ATy->getElementType(); 12832 else 12833 Type = BaseType->getPointeeType(); 12834 Type = Type.getNonReferenceType(); 12835 } else { 12836 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 12837 } 12838 auto *VD = dyn_cast<VarDecl>(D); 12839 12840 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12841 // A variable that appears in a private clause must not have an incomplete 12842 // type or a reference type. 12843 if (S.RequireCompleteType(ELoc, D->getType(), 12844 diag::err_omp_reduction_incomplete_type)) 12845 continue; 12846 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12847 // A list item that appears in a reduction clause must not be 12848 // const-qualified. 12849 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 12850 /*AcceptIfMutable*/ false, ASE || OASE)) 12851 continue; 12852 12853 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 12854 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 12855 // If a list-item is a reference type then it must bind to the same object 12856 // for all threads of the team. 12857 if (!ASE && !OASE) { 12858 if (VD) { 12859 VarDecl *VDDef = VD->getDefinition(); 12860 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 12861 DSARefChecker Check(Stack); 12862 if (Check.Visit(VDDef->getInit())) { 12863 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 12864 << getOpenMPClauseName(ClauseKind) << ERange; 12865 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 12866 continue; 12867 } 12868 } 12869 } 12870 12871 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12872 // in a Construct] 12873 // Variables with the predetermined data-sharing attributes may not be 12874 // listed in data-sharing attributes clauses, except for the cases 12875 // listed below. For these exceptions only, listing a predetermined 12876 // variable in a data-sharing attribute clause is allowed and overrides 12877 // the variable's predetermined data-sharing attributes. 12878 // OpenMP [2.14.3.6, Restrictions, p.3] 12879 // Any number of reduction clauses can be specified on the directive, 12880 // but a list item can appear only once in the reduction clauses for that 12881 // directive. 12882 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 12883 if (DVar.CKind == OMPC_reduction) { 12884 S.Diag(ELoc, diag::err_omp_once_referenced) 12885 << getOpenMPClauseName(ClauseKind); 12886 if (DVar.RefExpr) 12887 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12888 continue; 12889 } 12890 if (DVar.CKind != OMPC_unknown) { 12891 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12892 << getOpenMPClauseName(DVar.CKind) 12893 << getOpenMPClauseName(OMPC_reduction); 12894 reportOriginalDsa(S, Stack, D, DVar); 12895 continue; 12896 } 12897 12898 // OpenMP [2.14.3.6, Restrictions, p.1] 12899 // A list item that appears in a reduction clause of a worksharing 12900 // construct must be shared in the parallel regions to which any of the 12901 // worksharing regions arising from the worksharing construct bind. 12902 if (isOpenMPWorksharingDirective(CurrDir) && 12903 !isOpenMPParallelDirective(CurrDir) && 12904 !isOpenMPTeamsDirective(CurrDir)) { 12905 DVar = Stack->getImplicitDSA(D, true); 12906 if (DVar.CKind != OMPC_shared) { 12907 S.Diag(ELoc, diag::err_omp_required_access) 12908 << getOpenMPClauseName(OMPC_reduction) 12909 << getOpenMPClauseName(OMPC_shared); 12910 reportOriginalDsa(S, Stack, D, DVar); 12911 continue; 12912 } 12913 } 12914 } 12915 12916 // Try to find 'declare reduction' corresponding construct before using 12917 // builtin/overloaded operators. 12918 CXXCastPath BasePath; 12919 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12920 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12921 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12922 if (DeclareReductionRef.isInvalid()) 12923 continue; 12924 if (S.CurContext->isDependentContext() && 12925 (DeclareReductionRef.isUnset() || 12926 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12927 RD.push(RefExpr, DeclareReductionRef.get()); 12928 continue; 12929 } 12930 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12931 // Not allowed reduction identifier is found. 12932 S.Diag(ReductionId.getBeginLoc(), 12933 diag::err_omp_unknown_reduction_identifier) 12934 << Type << ReductionIdRange; 12935 continue; 12936 } 12937 12938 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12939 // The type of a list item that appears in a reduction clause must be valid 12940 // for the reduction-identifier. For a max or min reduction in C, the type 12941 // of the list item must be an allowed arithmetic data type: char, int, 12942 // float, double, or _Bool, possibly modified with long, short, signed, or 12943 // unsigned. For a max or min reduction in C++, the type of the list item 12944 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12945 // double, or bool, possibly modified with long, short, signed, or unsigned. 12946 if (DeclareReductionRef.isUnset()) { 12947 if ((BOK == BO_GT || BOK == BO_LT) && 12948 !(Type->isScalarType() || 12949 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12950 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12951 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12952 if (!ASE && !OASE) { 12953 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12954 VarDecl::DeclarationOnly; 12955 S.Diag(D->getLocation(), 12956 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12957 << D; 12958 } 12959 continue; 12960 } 12961 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12962 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12963 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12964 << getOpenMPClauseName(ClauseKind); 12965 if (!ASE && !OASE) { 12966 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12967 VarDecl::DeclarationOnly; 12968 S.Diag(D->getLocation(), 12969 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12970 << D; 12971 } 12972 continue; 12973 } 12974 } 12975 12976 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12977 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12978 D->hasAttrs() ? &D->getAttrs() : nullptr); 12979 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12980 D->hasAttrs() ? &D->getAttrs() : nullptr); 12981 QualType PrivateTy = Type; 12982 12983 // Try if we can determine constant lengths for all array sections and avoid 12984 // the VLA. 12985 bool ConstantLengthOASE = false; 12986 if (OASE) { 12987 bool SingleElement; 12988 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12989 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12990 Context, OASE, SingleElement, ArraySizes); 12991 12992 // If we don't have a single element, we must emit a constant array type. 12993 if (ConstantLengthOASE && !SingleElement) { 12994 for (llvm::APSInt &Size : ArraySizes) 12995 PrivateTy = Context.getConstantArrayType( 12996 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12997 } 12998 } 12999 13000 if ((OASE && !ConstantLengthOASE) || 13001 (!OASE && !ASE && 13002 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13003 if (!Context.getTargetInfo().isVLASupported()) { 13004 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13005 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13006 S.Diag(ELoc, diag::note_vla_unsupported); 13007 } else { 13008 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13009 S.targetDiag(ELoc, diag::note_vla_unsupported); 13010 } 13011 continue; 13012 } 13013 // For arrays/array sections only: 13014 // Create pseudo array type for private copy. The size for this array will 13015 // be generated during codegen. 13016 // For array subscripts or single variables Private Ty is the same as Type 13017 // (type of the variable or single array element). 13018 PrivateTy = Context.getVariableArrayType( 13019 Type, 13020 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13021 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13022 } else if (!ASE && !OASE && 13023 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13024 PrivateTy = D->getType().getNonReferenceType(); 13025 } 13026 // Private copy. 13027 VarDecl *PrivateVD = 13028 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13029 D->hasAttrs() ? &D->getAttrs() : nullptr, 13030 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13031 // Add initializer for private variable. 13032 Expr *Init = nullptr; 13033 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13034 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13035 if (DeclareReductionRef.isUsable()) { 13036 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13037 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13038 if (DRD->getInitializer()) { 13039 Init = DRDRef; 13040 RHSVD->setInit(DRDRef); 13041 RHSVD->setInitStyle(VarDecl::CallInit); 13042 } 13043 } else { 13044 switch (BOK) { 13045 case BO_Add: 13046 case BO_Xor: 13047 case BO_Or: 13048 case BO_LOr: 13049 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13050 if (Type->isScalarType() || Type->isAnyComplexType()) 13051 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13052 break; 13053 case BO_Mul: 13054 case BO_LAnd: 13055 if (Type->isScalarType() || Type->isAnyComplexType()) { 13056 // '*' and '&&' reduction ops - initializer is '1'. 13057 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13058 } 13059 break; 13060 case BO_And: { 13061 // '&' reduction op - initializer is '~0'. 13062 QualType OrigType = Type; 13063 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13064 Type = ComplexTy->getElementType(); 13065 if (Type->isRealFloatingType()) { 13066 llvm::APFloat InitValue = 13067 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13068 /*isIEEE=*/true); 13069 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13070 Type, ELoc); 13071 } else if (Type->isScalarType()) { 13072 uint64_t Size = Context.getTypeSize(Type); 13073 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13074 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13075 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13076 } 13077 if (Init && OrigType->isAnyComplexType()) { 13078 // Init = 0xFFFF + 0xFFFFi; 13079 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13080 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13081 } 13082 Type = OrigType; 13083 break; 13084 } 13085 case BO_LT: 13086 case BO_GT: { 13087 // 'min' reduction op - initializer is 'Largest representable number in 13088 // the reduction list item type'. 13089 // 'max' reduction op - initializer is 'Least representable number in 13090 // the reduction list item type'. 13091 if (Type->isIntegerType() || Type->isPointerType()) { 13092 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13093 uint64_t Size = Context.getTypeSize(Type); 13094 QualType IntTy = 13095 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13096 llvm::APInt InitValue = 13097 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13098 : llvm::APInt::getMinValue(Size) 13099 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13100 : llvm::APInt::getMaxValue(Size); 13101 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13102 if (Type->isPointerType()) { 13103 // Cast to pointer type. 13104 ExprResult CastExpr = S.BuildCStyleCastExpr( 13105 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13106 if (CastExpr.isInvalid()) 13107 continue; 13108 Init = CastExpr.get(); 13109 } 13110 } else if (Type->isRealFloatingType()) { 13111 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13112 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13113 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13114 Type, ELoc); 13115 } 13116 break; 13117 } 13118 case BO_PtrMemD: 13119 case BO_PtrMemI: 13120 case BO_MulAssign: 13121 case BO_Div: 13122 case BO_Rem: 13123 case BO_Sub: 13124 case BO_Shl: 13125 case BO_Shr: 13126 case BO_LE: 13127 case BO_GE: 13128 case BO_EQ: 13129 case BO_NE: 13130 case BO_Cmp: 13131 case BO_AndAssign: 13132 case BO_XorAssign: 13133 case BO_OrAssign: 13134 case BO_Assign: 13135 case BO_AddAssign: 13136 case BO_SubAssign: 13137 case BO_DivAssign: 13138 case BO_RemAssign: 13139 case BO_ShlAssign: 13140 case BO_ShrAssign: 13141 case BO_Comma: 13142 llvm_unreachable("Unexpected reduction operation"); 13143 } 13144 } 13145 if (Init && DeclareReductionRef.isUnset()) 13146 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13147 else if (!Init) 13148 S.ActOnUninitializedDecl(RHSVD); 13149 if (RHSVD->isInvalidDecl()) 13150 continue; 13151 if (!RHSVD->hasInit() && 13152 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13153 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13154 << Type << ReductionIdRange; 13155 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13156 VarDecl::DeclarationOnly; 13157 S.Diag(D->getLocation(), 13158 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13159 << D; 13160 continue; 13161 } 13162 // Store initializer for single element in private copy. Will be used during 13163 // codegen. 13164 PrivateVD->setInit(RHSVD->getInit()); 13165 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13166 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13167 ExprResult ReductionOp; 13168 if (DeclareReductionRef.isUsable()) { 13169 QualType RedTy = DeclareReductionRef.get()->getType(); 13170 QualType PtrRedTy = Context.getPointerType(RedTy); 13171 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13172 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13173 if (!BasePath.empty()) { 13174 LHS = S.DefaultLvalueConversion(LHS.get()); 13175 RHS = S.DefaultLvalueConversion(RHS.get()); 13176 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13177 CK_UncheckedDerivedToBase, LHS.get(), 13178 &BasePath, LHS.get()->getValueKind()); 13179 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13180 CK_UncheckedDerivedToBase, RHS.get(), 13181 &BasePath, RHS.get()->getValueKind()); 13182 } 13183 FunctionProtoType::ExtProtoInfo EPI; 13184 QualType Params[] = {PtrRedTy, PtrRedTy}; 13185 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13186 auto *OVE = new (Context) OpaqueValueExpr( 13187 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13188 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13189 Expr *Args[] = {LHS.get(), RHS.get()}; 13190 ReductionOp = 13191 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13192 } else { 13193 ReductionOp = S.BuildBinOp( 13194 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13195 if (ReductionOp.isUsable()) { 13196 if (BOK != BO_LT && BOK != BO_GT) { 13197 ReductionOp = 13198 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13199 BO_Assign, LHSDRE, ReductionOp.get()); 13200 } else { 13201 auto *ConditionalOp = new (Context) 13202 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13203 Type, VK_LValue, OK_Ordinary); 13204 ReductionOp = 13205 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13206 BO_Assign, LHSDRE, ConditionalOp); 13207 } 13208 if (ReductionOp.isUsable()) 13209 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13210 /*DiscardedValue*/ false); 13211 } 13212 if (!ReductionOp.isUsable()) 13213 continue; 13214 } 13215 13216 // OpenMP [2.15.4.6, Restrictions, p.2] 13217 // A list item that appears in an in_reduction clause of a task construct 13218 // must appear in a task_reduction clause of a construct associated with a 13219 // taskgroup region that includes the participating task in its taskgroup 13220 // set. The construct associated with the innermost region that meets this 13221 // condition must specify the same reduction-identifier as the in_reduction 13222 // clause. 13223 if (ClauseKind == OMPC_in_reduction) { 13224 SourceRange ParentSR; 13225 BinaryOperatorKind ParentBOK; 13226 const Expr *ParentReductionOp; 13227 Expr *ParentBOKTD, *ParentReductionOpTD; 13228 DSAStackTy::DSAVarData ParentBOKDSA = 13229 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13230 ParentBOKTD); 13231 DSAStackTy::DSAVarData ParentReductionOpDSA = 13232 Stack->getTopMostTaskgroupReductionData( 13233 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13234 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13235 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13236 if (!IsParentBOK && !IsParentReductionOp) { 13237 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13238 continue; 13239 } 13240 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13241 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13242 IsParentReductionOp) { 13243 bool EmitError = true; 13244 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13245 llvm::FoldingSetNodeID RedId, ParentRedId; 13246 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13247 DeclareReductionRef.get()->Profile(RedId, Context, 13248 /*Canonical=*/true); 13249 EmitError = RedId != ParentRedId; 13250 } 13251 if (EmitError) { 13252 S.Diag(ReductionId.getBeginLoc(), 13253 diag::err_omp_reduction_identifier_mismatch) 13254 << ReductionIdRange << RefExpr->getSourceRange(); 13255 S.Diag(ParentSR.getBegin(), 13256 diag::note_omp_previous_reduction_identifier) 13257 << ParentSR 13258 << (IsParentBOK ? ParentBOKDSA.RefExpr 13259 : ParentReductionOpDSA.RefExpr) 13260 ->getSourceRange(); 13261 continue; 13262 } 13263 } 13264 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13265 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13266 } 13267 13268 DeclRefExpr *Ref = nullptr; 13269 Expr *VarsExpr = RefExpr->IgnoreParens(); 13270 if (!VD && !S.CurContext->isDependentContext()) { 13271 if (ASE || OASE) { 13272 TransformExprToCaptures RebuildToCapture(S, D); 13273 VarsExpr = 13274 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13275 Ref = RebuildToCapture.getCapturedExpr(); 13276 } else { 13277 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13278 } 13279 if (!S.isOpenMPCapturedDecl(D)) { 13280 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13281 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13282 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13283 if (!RefRes.isUsable()) 13284 continue; 13285 ExprResult PostUpdateRes = 13286 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13287 RefRes.get()); 13288 if (!PostUpdateRes.isUsable()) 13289 continue; 13290 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13291 Stack->getCurrentDirective() == OMPD_taskgroup) { 13292 S.Diag(RefExpr->getExprLoc(), 13293 diag::err_omp_reduction_non_addressable_expression) 13294 << RefExpr->getSourceRange(); 13295 continue; 13296 } 13297 RD.ExprPostUpdates.emplace_back( 13298 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13299 } 13300 } 13301 } 13302 // All reduction items are still marked as reduction (to do not increase 13303 // code base size). 13304 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13305 if (CurrDir == OMPD_taskgroup) { 13306 if (DeclareReductionRef.isUsable()) 13307 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13308 DeclareReductionRef.get()); 13309 else 13310 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13311 } 13312 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13313 TaskgroupDescriptor); 13314 } 13315 return RD.Vars.empty(); 13316 } 13317 13318 OMPClause *Sema::ActOnOpenMPReductionClause( 13319 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13320 SourceLocation ColonLoc, SourceLocation EndLoc, 13321 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13322 ArrayRef<Expr *> UnresolvedReductions) { 13323 ReductionData RD(VarList.size()); 13324 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13325 StartLoc, LParenLoc, ColonLoc, EndLoc, 13326 ReductionIdScopeSpec, ReductionId, 13327 UnresolvedReductions, RD)) 13328 return nullptr; 13329 13330 return OMPReductionClause::Create( 13331 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13332 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13333 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13334 buildPreInits(Context, RD.ExprCaptures), 13335 buildPostUpdate(*this, RD.ExprPostUpdates)); 13336 } 13337 13338 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13339 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13340 SourceLocation ColonLoc, SourceLocation EndLoc, 13341 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13342 ArrayRef<Expr *> UnresolvedReductions) { 13343 ReductionData RD(VarList.size()); 13344 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13345 StartLoc, LParenLoc, ColonLoc, EndLoc, 13346 ReductionIdScopeSpec, ReductionId, 13347 UnresolvedReductions, RD)) 13348 return nullptr; 13349 13350 return OMPTaskReductionClause::Create( 13351 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13352 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13353 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13354 buildPreInits(Context, RD.ExprCaptures), 13355 buildPostUpdate(*this, RD.ExprPostUpdates)); 13356 } 13357 13358 OMPClause *Sema::ActOnOpenMPInReductionClause( 13359 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13360 SourceLocation ColonLoc, SourceLocation EndLoc, 13361 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13362 ArrayRef<Expr *> UnresolvedReductions) { 13363 ReductionData RD(VarList.size()); 13364 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13365 StartLoc, LParenLoc, ColonLoc, EndLoc, 13366 ReductionIdScopeSpec, ReductionId, 13367 UnresolvedReductions, RD)) 13368 return nullptr; 13369 13370 return OMPInReductionClause::Create( 13371 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13372 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13373 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13374 buildPreInits(Context, RD.ExprCaptures), 13375 buildPostUpdate(*this, RD.ExprPostUpdates)); 13376 } 13377 13378 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13379 SourceLocation LinLoc) { 13380 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13381 LinKind == OMPC_LINEAR_unknown) { 13382 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13383 return true; 13384 } 13385 return false; 13386 } 13387 13388 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13389 OpenMPLinearClauseKind LinKind, 13390 QualType Type) { 13391 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13392 // A variable must not have an incomplete type or a reference type. 13393 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13394 return true; 13395 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13396 !Type->isReferenceType()) { 13397 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13398 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13399 return true; 13400 } 13401 Type = Type.getNonReferenceType(); 13402 13403 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13404 // A variable that is privatized must not have a const-qualified type 13405 // unless it is of class type with a mutable member. This restriction does 13406 // not apply to the firstprivate clause. 13407 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13408 return true; 13409 13410 // A list item must be of integral or pointer type. 13411 Type = Type.getUnqualifiedType().getCanonicalType(); 13412 const auto *Ty = Type.getTypePtrOrNull(); 13413 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13414 !Ty->isPointerType())) { 13415 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13416 if (D) { 13417 bool IsDecl = 13418 !VD || 13419 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13420 Diag(D->getLocation(), 13421 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13422 << D; 13423 } 13424 return true; 13425 } 13426 return false; 13427 } 13428 13429 OMPClause *Sema::ActOnOpenMPLinearClause( 13430 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13431 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13432 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13433 SmallVector<Expr *, 8> Vars; 13434 SmallVector<Expr *, 8> Privates; 13435 SmallVector<Expr *, 8> Inits; 13436 SmallVector<Decl *, 4> ExprCaptures; 13437 SmallVector<Expr *, 4> ExprPostUpdates; 13438 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13439 LinKind = OMPC_LINEAR_val; 13440 for (Expr *RefExpr : VarList) { 13441 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13442 SourceLocation ELoc; 13443 SourceRange ERange; 13444 Expr *SimpleRefExpr = RefExpr; 13445 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13446 if (Res.second) { 13447 // It will be analyzed later. 13448 Vars.push_back(RefExpr); 13449 Privates.push_back(nullptr); 13450 Inits.push_back(nullptr); 13451 } 13452 ValueDecl *D = Res.first; 13453 if (!D) 13454 continue; 13455 13456 QualType Type = D->getType(); 13457 auto *VD = dyn_cast<VarDecl>(D); 13458 13459 // OpenMP [2.14.3.7, linear clause] 13460 // A list-item cannot appear in more than one linear clause. 13461 // A list-item that appears in a linear clause cannot appear in any 13462 // other data-sharing attribute clause. 13463 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13464 if (DVar.RefExpr) { 13465 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13466 << getOpenMPClauseName(OMPC_linear); 13467 reportOriginalDsa(*this, DSAStack, D, DVar); 13468 continue; 13469 } 13470 13471 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13472 continue; 13473 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13474 13475 // Build private copy of original var. 13476 VarDecl *Private = 13477 buildVarDecl(*this, ELoc, Type, D->getName(), 13478 D->hasAttrs() ? &D->getAttrs() : nullptr, 13479 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13480 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13481 // Build var to save initial value. 13482 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13483 Expr *InitExpr; 13484 DeclRefExpr *Ref = nullptr; 13485 if (!VD && !CurContext->isDependentContext()) { 13486 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13487 if (!isOpenMPCapturedDecl(D)) { 13488 ExprCaptures.push_back(Ref->getDecl()); 13489 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13490 ExprResult RefRes = DefaultLvalueConversion(Ref); 13491 if (!RefRes.isUsable()) 13492 continue; 13493 ExprResult PostUpdateRes = 13494 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13495 SimpleRefExpr, RefRes.get()); 13496 if (!PostUpdateRes.isUsable()) 13497 continue; 13498 ExprPostUpdates.push_back( 13499 IgnoredValueConversions(PostUpdateRes.get()).get()); 13500 } 13501 } 13502 } 13503 if (LinKind == OMPC_LINEAR_uval) 13504 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13505 else 13506 InitExpr = VD ? SimpleRefExpr : Ref; 13507 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13508 /*DirectInit=*/false); 13509 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13510 13511 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13512 Vars.push_back((VD || CurContext->isDependentContext()) 13513 ? RefExpr->IgnoreParens() 13514 : Ref); 13515 Privates.push_back(PrivateRef); 13516 Inits.push_back(InitRef); 13517 } 13518 13519 if (Vars.empty()) 13520 return nullptr; 13521 13522 Expr *StepExpr = Step; 13523 Expr *CalcStepExpr = nullptr; 13524 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13525 !Step->isInstantiationDependent() && 13526 !Step->containsUnexpandedParameterPack()) { 13527 SourceLocation StepLoc = Step->getBeginLoc(); 13528 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13529 if (Val.isInvalid()) 13530 return nullptr; 13531 StepExpr = Val.get(); 13532 13533 // Build var to save the step value. 13534 VarDecl *SaveVar = 13535 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13536 ExprResult SaveRef = 13537 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13538 ExprResult CalcStep = 13539 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13540 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13541 13542 // Warn about zero linear step (it would be probably better specified as 13543 // making corresponding variables 'const'). 13544 llvm::APSInt Result; 13545 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13546 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13547 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13548 << (Vars.size() > 1); 13549 if (!IsConstant && CalcStep.isUsable()) { 13550 // Calculate the step beforehand instead of doing this on each iteration. 13551 // (This is not used if the number of iterations may be kfold-ed). 13552 CalcStepExpr = CalcStep.get(); 13553 } 13554 } 13555 13556 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13557 ColonLoc, EndLoc, Vars, Privates, Inits, 13558 StepExpr, CalcStepExpr, 13559 buildPreInits(Context, ExprCaptures), 13560 buildPostUpdate(*this, ExprPostUpdates)); 13561 } 13562 13563 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13564 Expr *NumIterations, Sema &SemaRef, 13565 Scope *S, DSAStackTy *Stack) { 13566 // Walk the vars and build update/final expressions for the CodeGen. 13567 SmallVector<Expr *, 8> Updates; 13568 SmallVector<Expr *, 8> Finals; 13569 SmallVector<Expr *, 8> UsedExprs; 13570 Expr *Step = Clause.getStep(); 13571 Expr *CalcStep = Clause.getCalcStep(); 13572 // OpenMP [2.14.3.7, linear clause] 13573 // If linear-step is not specified it is assumed to be 1. 13574 if (!Step) 13575 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13576 else if (CalcStep) 13577 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13578 bool HasErrors = false; 13579 auto CurInit = Clause.inits().begin(); 13580 auto CurPrivate = Clause.privates().begin(); 13581 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13582 for (Expr *RefExpr : Clause.varlists()) { 13583 SourceLocation ELoc; 13584 SourceRange ERange; 13585 Expr *SimpleRefExpr = RefExpr; 13586 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13587 ValueDecl *D = Res.first; 13588 if (Res.second || !D) { 13589 Updates.push_back(nullptr); 13590 Finals.push_back(nullptr); 13591 HasErrors = true; 13592 continue; 13593 } 13594 auto &&Info = Stack->isLoopControlVariable(D); 13595 // OpenMP [2.15.11, distribute simd Construct] 13596 // A list item may not appear in a linear clause, unless it is the loop 13597 // iteration variable. 13598 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13599 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13600 SemaRef.Diag(ELoc, 13601 diag::err_omp_linear_distribute_var_non_loop_iteration); 13602 Updates.push_back(nullptr); 13603 Finals.push_back(nullptr); 13604 HasErrors = true; 13605 continue; 13606 } 13607 Expr *InitExpr = *CurInit; 13608 13609 // Build privatized reference to the current linear var. 13610 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13611 Expr *CapturedRef; 13612 if (LinKind == OMPC_LINEAR_uval) 13613 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13614 else 13615 CapturedRef = 13616 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13617 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13618 /*RefersToCapture=*/true); 13619 13620 // Build update: Var = InitExpr + IV * Step 13621 ExprResult Update; 13622 if (!Info.first) 13623 Update = buildCounterUpdate( 13624 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13625 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13626 else 13627 Update = *CurPrivate; 13628 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13629 /*DiscardedValue*/ false); 13630 13631 // Build final: Var = InitExpr + NumIterations * Step 13632 ExprResult Final; 13633 if (!Info.first) 13634 Final = 13635 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13636 InitExpr, NumIterations, Step, /*Subtract=*/false, 13637 /*IsNonRectangularLB=*/false); 13638 else 13639 Final = *CurPrivate; 13640 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13641 /*DiscardedValue*/ false); 13642 13643 if (!Update.isUsable() || !Final.isUsable()) { 13644 Updates.push_back(nullptr); 13645 Finals.push_back(nullptr); 13646 UsedExprs.push_back(nullptr); 13647 HasErrors = true; 13648 } else { 13649 Updates.push_back(Update.get()); 13650 Finals.push_back(Final.get()); 13651 if (!Info.first) 13652 UsedExprs.push_back(SimpleRefExpr); 13653 } 13654 ++CurInit; 13655 ++CurPrivate; 13656 } 13657 if (Expr *S = Clause.getStep()) 13658 UsedExprs.push_back(S); 13659 // Fill the remaining part with the nullptr. 13660 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13661 Clause.setUpdates(Updates); 13662 Clause.setFinals(Finals); 13663 Clause.setUsedExprs(UsedExprs); 13664 return HasErrors; 13665 } 13666 13667 OMPClause *Sema::ActOnOpenMPAlignedClause( 13668 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13669 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13670 SmallVector<Expr *, 8> Vars; 13671 for (Expr *RefExpr : VarList) { 13672 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13673 SourceLocation ELoc; 13674 SourceRange ERange; 13675 Expr *SimpleRefExpr = RefExpr; 13676 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13677 if (Res.second) { 13678 // It will be analyzed later. 13679 Vars.push_back(RefExpr); 13680 } 13681 ValueDecl *D = Res.first; 13682 if (!D) 13683 continue; 13684 13685 QualType QType = D->getType(); 13686 auto *VD = dyn_cast<VarDecl>(D); 13687 13688 // OpenMP [2.8.1, simd construct, Restrictions] 13689 // The type of list items appearing in the aligned clause must be 13690 // array, pointer, reference to array, or reference to pointer. 13691 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13692 const Type *Ty = QType.getTypePtrOrNull(); 13693 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 13694 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 13695 << QType << getLangOpts().CPlusPlus << ERange; 13696 bool IsDecl = 13697 !VD || 13698 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13699 Diag(D->getLocation(), 13700 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13701 << D; 13702 continue; 13703 } 13704 13705 // OpenMP [2.8.1, simd construct, Restrictions] 13706 // A list-item cannot appear in more than one aligned clause. 13707 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 13708 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 13709 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 13710 << getOpenMPClauseName(OMPC_aligned); 13711 continue; 13712 } 13713 13714 DeclRefExpr *Ref = nullptr; 13715 if (!VD && isOpenMPCapturedDecl(D)) 13716 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13717 Vars.push_back(DefaultFunctionArrayConversion( 13718 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 13719 .get()); 13720 } 13721 13722 // OpenMP [2.8.1, simd construct, Description] 13723 // The parameter of the aligned clause, alignment, must be a constant 13724 // positive integer expression. 13725 // If no optional parameter is specified, implementation-defined default 13726 // alignments for SIMD instructions on the target platforms are assumed. 13727 if (Alignment != nullptr) { 13728 ExprResult AlignResult = 13729 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 13730 if (AlignResult.isInvalid()) 13731 return nullptr; 13732 Alignment = AlignResult.get(); 13733 } 13734 if (Vars.empty()) 13735 return nullptr; 13736 13737 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 13738 EndLoc, Vars, Alignment); 13739 } 13740 13741 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 13742 SourceLocation StartLoc, 13743 SourceLocation LParenLoc, 13744 SourceLocation EndLoc) { 13745 SmallVector<Expr *, 8> Vars; 13746 SmallVector<Expr *, 8> SrcExprs; 13747 SmallVector<Expr *, 8> DstExprs; 13748 SmallVector<Expr *, 8> AssignmentOps; 13749 for (Expr *RefExpr : VarList) { 13750 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 13751 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13752 // It will be analyzed later. 13753 Vars.push_back(RefExpr); 13754 SrcExprs.push_back(nullptr); 13755 DstExprs.push_back(nullptr); 13756 AssignmentOps.push_back(nullptr); 13757 continue; 13758 } 13759 13760 SourceLocation ELoc = RefExpr->getExprLoc(); 13761 // OpenMP [2.1, C/C++] 13762 // A list item is a variable name. 13763 // OpenMP [2.14.4.1, Restrictions, p.1] 13764 // A list item that appears in a copyin clause must be threadprivate. 13765 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 13766 if (!DE || !isa<VarDecl>(DE->getDecl())) { 13767 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 13768 << 0 << RefExpr->getSourceRange(); 13769 continue; 13770 } 13771 13772 Decl *D = DE->getDecl(); 13773 auto *VD = cast<VarDecl>(D); 13774 13775 QualType Type = VD->getType(); 13776 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 13777 // It will be analyzed later. 13778 Vars.push_back(DE); 13779 SrcExprs.push_back(nullptr); 13780 DstExprs.push_back(nullptr); 13781 AssignmentOps.push_back(nullptr); 13782 continue; 13783 } 13784 13785 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 13786 // A list item that appears in a copyin clause must be threadprivate. 13787 if (!DSAStack->isThreadPrivate(VD)) { 13788 Diag(ELoc, diag::err_omp_required_access) 13789 << getOpenMPClauseName(OMPC_copyin) 13790 << getOpenMPDirectiveName(OMPD_threadprivate); 13791 continue; 13792 } 13793 13794 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13795 // A variable of class type (or array thereof) that appears in a 13796 // copyin clause requires an accessible, unambiguous copy assignment 13797 // operator for the class type. 13798 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13799 VarDecl *SrcVD = 13800 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 13801 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13802 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 13803 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 13804 VarDecl *DstVD = 13805 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 13806 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13807 DeclRefExpr *PseudoDstExpr = 13808 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 13809 // For arrays generate assignment operation for single element and replace 13810 // it by the original array element in CodeGen. 13811 ExprResult AssignmentOp = 13812 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 13813 PseudoSrcExpr); 13814 if (AssignmentOp.isInvalid()) 13815 continue; 13816 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 13817 /*DiscardedValue*/ false); 13818 if (AssignmentOp.isInvalid()) 13819 continue; 13820 13821 DSAStack->addDSA(VD, DE, OMPC_copyin); 13822 Vars.push_back(DE); 13823 SrcExprs.push_back(PseudoSrcExpr); 13824 DstExprs.push_back(PseudoDstExpr); 13825 AssignmentOps.push_back(AssignmentOp.get()); 13826 } 13827 13828 if (Vars.empty()) 13829 return nullptr; 13830 13831 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13832 SrcExprs, DstExprs, AssignmentOps); 13833 } 13834 13835 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 13836 SourceLocation StartLoc, 13837 SourceLocation LParenLoc, 13838 SourceLocation EndLoc) { 13839 SmallVector<Expr *, 8> Vars; 13840 SmallVector<Expr *, 8> SrcExprs; 13841 SmallVector<Expr *, 8> DstExprs; 13842 SmallVector<Expr *, 8> AssignmentOps; 13843 for (Expr *RefExpr : VarList) { 13844 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13845 SourceLocation ELoc; 13846 SourceRange ERange; 13847 Expr *SimpleRefExpr = RefExpr; 13848 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13849 if (Res.second) { 13850 // It will be analyzed later. 13851 Vars.push_back(RefExpr); 13852 SrcExprs.push_back(nullptr); 13853 DstExprs.push_back(nullptr); 13854 AssignmentOps.push_back(nullptr); 13855 } 13856 ValueDecl *D = Res.first; 13857 if (!D) 13858 continue; 13859 13860 QualType Type = D->getType(); 13861 auto *VD = dyn_cast<VarDecl>(D); 13862 13863 // OpenMP [2.14.4.2, Restrictions, p.2] 13864 // A list item that appears in a copyprivate clause may not appear in a 13865 // private or firstprivate clause on the single construct. 13866 if (!VD || !DSAStack->isThreadPrivate(VD)) { 13867 DSAStackTy::DSAVarData DVar = 13868 DSAStack->getTopDSA(D, /*FromParent=*/false); 13869 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 13870 DVar.RefExpr) { 13871 Diag(ELoc, diag::err_omp_wrong_dsa) 13872 << getOpenMPClauseName(DVar.CKind) 13873 << getOpenMPClauseName(OMPC_copyprivate); 13874 reportOriginalDsa(*this, DSAStack, D, DVar); 13875 continue; 13876 } 13877 13878 // OpenMP [2.11.4.2, Restrictions, p.1] 13879 // All list items that appear in a copyprivate clause must be either 13880 // threadprivate or private in the enclosing context. 13881 if (DVar.CKind == OMPC_unknown) { 13882 DVar = DSAStack->getImplicitDSA(D, false); 13883 if (DVar.CKind == OMPC_shared) { 13884 Diag(ELoc, diag::err_omp_required_access) 13885 << getOpenMPClauseName(OMPC_copyprivate) 13886 << "threadprivate or private in the enclosing context"; 13887 reportOriginalDsa(*this, DSAStack, D, DVar); 13888 continue; 13889 } 13890 } 13891 } 13892 13893 // Variably modified types are not supported. 13894 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 13895 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13896 << getOpenMPClauseName(OMPC_copyprivate) << Type 13897 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13898 bool IsDecl = 13899 !VD || 13900 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13901 Diag(D->getLocation(), 13902 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13903 << D; 13904 continue; 13905 } 13906 13907 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13908 // A variable of class type (or array thereof) that appears in a 13909 // copyin clause requires an accessible, unambiguous copy assignment 13910 // operator for the class type. 13911 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13912 .getUnqualifiedType(); 13913 VarDecl *SrcVD = 13914 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13915 D->hasAttrs() ? &D->getAttrs() : nullptr); 13916 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13917 VarDecl *DstVD = 13918 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13919 D->hasAttrs() ? &D->getAttrs() : nullptr); 13920 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13921 ExprResult AssignmentOp = BuildBinOp( 13922 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13923 if (AssignmentOp.isInvalid()) 13924 continue; 13925 AssignmentOp = 13926 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13927 if (AssignmentOp.isInvalid()) 13928 continue; 13929 13930 // No need to mark vars as copyprivate, they are already threadprivate or 13931 // implicitly private. 13932 assert(VD || isOpenMPCapturedDecl(D)); 13933 Vars.push_back( 13934 VD ? RefExpr->IgnoreParens() 13935 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13936 SrcExprs.push_back(PseudoSrcExpr); 13937 DstExprs.push_back(PseudoDstExpr); 13938 AssignmentOps.push_back(AssignmentOp.get()); 13939 } 13940 13941 if (Vars.empty()) 13942 return nullptr; 13943 13944 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13945 Vars, SrcExprs, DstExprs, AssignmentOps); 13946 } 13947 13948 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13949 SourceLocation StartLoc, 13950 SourceLocation LParenLoc, 13951 SourceLocation EndLoc) { 13952 if (VarList.empty()) 13953 return nullptr; 13954 13955 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13956 } 13957 13958 OMPClause * 13959 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13960 SourceLocation DepLoc, SourceLocation ColonLoc, 13961 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13962 SourceLocation LParenLoc, SourceLocation EndLoc) { 13963 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13964 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13965 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13966 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13967 return nullptr; 13968 } 13969 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13970 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13971 DepKind == OMPC_DEPEND_sink)) { 13972 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13973 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13974 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13975 /*Last=*/OMPC_DEPEND_unknown, Except) 13976 << getOpenMPClauseName(OMPC_depend); 13977 return nullptr; 13978 } 13979 SmallVector<Expr *, 8> Vars; 13980 DSAStackTy::OperatorOffsetTy OpsOffs; 13981 llvm::APSInt DepCounter(/*BitWidth=*/32); 13982 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13983 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13984 if (const Expr *OrderedCountExpr = 13985 DSAStack->getParentOrderedRegionParam().first) { 13986 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13987 TotalDepCount.setIsUnsigned(/*Val=*/true); 13988 } 13989 } 13990 for (Expr *RefExpr : VarList) { 13991 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13992 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13993 // It will be analyzed later. 13994 Vars.push_back(RefExpr); 13995 continue; 13996 } 13997 13998 SourceLocation ELoc = RefExpr->getExprLoc(); 13999 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14000 if (DepKind == OMPC_DEPEND_sink) { 14001 if (DSAStack->getParentOrderedRegionParam().first && 14002 DepCounter >= TotalDepCount) { 14003 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14004 continue; 14005 } 14006 ++DepCounter; 14007 // OpenMP [2.13.9, Summary] 14008 // depend(dependence-type : vec), where dependence-type is: 14009 // 'sink' and where vec is the iteration vector, which has the form: 14010 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14011 // where n is the value specified by the ordered clause in the loop 14012 // directive, xi denotes the loop iteration variable of the i-th nested 14013 // loop associated with the loop directive, and di is a constant 14014 // non-negative integer. 14015 if (CurContext->isDependentContext()) { 14016 // It will be analyzed later. 14017 Vars.push_back(RefExpr); 14018 continue; 14019 } 14020 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14021 OverloadedOperatorKind OOK = OO_None; 14022 SourceLocation OOLoc; 14023 Expr *LHS = SimpleExpr; 14024 Expr *RHS = nullptr; 14025 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14026 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14027 OOLoc = BO->getOperatorLoc(); 14028 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14029 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14030 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14031 OOK = OCE->getOperator(); 14032 OOLoc = OCE->getOperatorLoc(); 14033 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14034 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14035 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14036 OOK = MCE->getMethodDecl() 14037 ->getNameInfo() 14038 .getName() 14039 .getCXXOverloadedOperator(); 14040 OOLoc = MCE->getCallee()->getExprLoc(); 14041 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14042 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14043 } 14044 SourceLocation ELoc; 14045 SourceRange ERange; 14046 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14047 if (Res.second) { 14048 // It will be analyzed later. 14049 Vars.push_back(RefExpr); 14050 } 14051 ValueDecl *D = Res.first; 14052 if (!D) 14053 continue; 14054 14055 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14056 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14057 continue; 14058 } 14059 if (RHS) { 14060 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14061 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14062 if (RHSRes.isInvalid()) 14063 continue; 14064 } 14065 if (!CurContext->isDependentContext() && 14066 DSAStack->getParentOrderedRegionParam().first && 14067 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14068 const ValueDecl *VD = 14069 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14070 if (VD) 14071 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14072 << 1 << VD; 14073 else 14074 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14075 continue; 14076 } 14077 OpsOffs.emplace_back(RHS, OOK); 14078 } else { 14079 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14080 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14081 (ASE && 14082 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14083 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14084 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14085 << RefExpr->getSourceRange(); 14086 continue; 14087 } 14088 14089 ExprResult Res; 14090 { 14091 Sema::TentativeAnalysisScope Trap(*this); 14092 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14093 RefExpr->IgnoreParenImpCasts()); 14094 } 14095 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14096 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14097 << RefExpr->getSourceRange(); 14098 continue; 14099 } 14100 } 14101 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14102 } 14103 14104 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14105 TotalDepCount > VarList.size() && 14106 DSAStack->getParentOrderedRegionParam().first && 14107 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14108 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14109 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14110 } 14111 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14112 Vars.empty()) 14113 return nullptr; 14114 14115 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14116 DepKind, DepLoc, ColonLoc, Vars, 14117 TotalDepCount.getZExtValue()); 14118 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14119 DSAStack->isParentOrderedRegion()) 14120 DSAStack->addDoacrossDependClause(C, OpsOffs); 14121 return C; 14122 } 14123 14124 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14125 SourceLocation LParenLoc, 14126 SourceLocation EndLoc) { 14127 Expr *ValExpr = Device; 14128 Stmt *HelperValStmt = nullptr; 14129 14130 // OpenMP [2.9.1, Restrictions] 14131 // The device expression must evaluate to a non-negative integer value. 14132 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14133 /*StrictlyPositive=*/false)) 14134 return nullptr; 14135 14136 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14137 OpenMPDirectiveKind CaptureRegion = 14138 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14139 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14140 ValExpr = MakeFullExpr(ValExpr).get(); 14141 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14142 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14143 HelperValStmt = buildPreInits(Context, Captures); 14144 } 14145 14146 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14147 StartLoc, LParenLoc, EndLoc); 14148 } 14149 14150 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14151 DSAStackTy *Stack, QualType QTy, 14152 bool FullCheck = true) { 14153 NamedDecl *ND; 14154 if (QTy->isIncompleteType(&ND)) { 14155 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14156 return false; 14157 } 14158 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14159 !QTy.isTrivialType(SemaRef.Context)) 14160 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14161 return true; 14162 } 14163 14164 /// Return true if it can be proven that the provided array expression 14165 /// (array section or array subscript) does NOT specify the whole size of the 14166 /// array whose base type is \a BaseQTy. 14167 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14168 const Expr *E, 14169 QualType BaseQTy) { 14170 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14171 14172 // If this is an array subscript, it refers to the whole size if the size of 14173 // the dimension is constant and equals 1. Also, an array section assumes the 14174 // format of an array subscript if no colon is used. 14175 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14176 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14177 return ATy->getSize().getSExtValue() != 1; 14178 // Size can't be evaluated statically. 14179 return false; 14180 } 14181 14182 assert(OASE && "Expecting array section if not an array subscript."); 14183 const Expr *LowerBound = OASE->getLowerBound(); 14184 const Expr *Length = OASE->getLength(); 14185 14186 // If there is a lower bound that does not evaluates to zero, we are not 14187 // covering the whole dimension. 14188 if (LowerBound) { 14189 Expr::EvalResult Result; 14190 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14191 return false; // Can't get the integer value as a constant. 14192 14193 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14194 if (ConstLowerBound.getSExtValue()) 14195 return true; 14196 } 14197 14198 // If we don't have a length we covering the whole dimension. 14199 if (!Length) 14200 return false; 14201 14202 // If the base is a pointer, we don't have a way to get the size of the 14203 // pointee. 14204 if (BaseQTy->isPointerType()) 14205 return false; 14206 14207 // We can only check if the length is the same as the size of the dimension 14208 // if we have a constant array. 14209 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14210 if (!CATy) 14211 return false; 14212 14213 Expr::EvalResult Result; 14214 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14215 return false; // Can't get the integer value as a constant. 14216 14217 llvm::APSInt ConstLength = Result.Val.getInt(); 14218 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14219 } 14220 14221 // Return true if it can be proven that the provided array expression (array 14222 // section or array subscript) does NOT specify a single element of the array 14223 // whose base type is \a BaseQTy. 14224 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14225 const Expr *E, 14226 QualType BaseQTy) { 14227 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14228 14229 // An array subscript always refer to a single element. Also, an array section 14230 // assumes the format of an array subscript if no colon is used. 14231 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14232 return false; 14233 14234 assert(OASE && "Expecting array section if not an array subscript."); 14235 const Expr *Length = OASE->getLength(); 14236 14237 // If we don't have a length we have to check if the array has unitary size 14238 // for this dimension. Also, we should always expect a length if the base type 14239 // is pointer. 14240 if (!Length) { 14241 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14242 return ATy->getSize().getSExtValue() != 1; 14243 // We cannot assume anything. 14244 return false; 14245 } 14246 14247 // Check if the length evaluates to 1. 14248 Expr::EvalResult Result; 14249 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14250 return false; // Can't get the integer value as a constant. 14251 14252 llvm::APSInt ConstLength = Result.Val.getInt(); 14253 return ConstLength.getSExtValue() != 1; 14254 } 14255 14256 // Return the expression of the base of the mappable expression or null if it 14257 // cannot be determined and do all the necessary checks to see if the expression 14258 // is valid as a standalone mappable expression. In the process, record all the 14259 // components of the expression. 14260 static const Expr *checkMapClauseExpressionBase( 14261 Sema &SemaRef, Expr *E, 14262 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14263 OpenMPClauseKind CKind, bool NoDiagnose) { 14264 SourceLocation ELoc = E->getExprLoc(); 14265 SourceRange ERange = E->getSourceRange(); 14266 14267 // The base of elements of list in a map clause have to be either: 14268 // - a reference to variable or field. 14269 // - a member expression. 14270 // - an array expression. 14271 // 14272 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14273 // reference to 'r'. 14274 // 14275 // If we have: 14276 // 14277 // struct SS { 14278 // Bla S; 14279 // foo() { 14280 // #pragma omp target map (S.Arr[:12]); 14281 // } 14282 // } 14283 // 14284 // We want to retrieve the member expression 'this->S'; 14285 14286 const Expr *RelevantExpr = nullptr; 14287 14288 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14289 // If a list item is an array section, it must specify contiguous storage. 14290 // 14291 // For this restriction it is sufficient that we make sure only references 14292 // to variables or fields and array expressions, and that no array sections 14293 // exist except in the rightmost expression (unless they cover the whole 14294 // dimension of the array). E.g. these would be invalid: 14295 // 14296 // r.ArrS[3:5].Arr[6:7] 14297 // 14298 // r.ArrS[3:5].x 14299 // 14300 // but these would be valid: 14301 // r.ArrS[3].Arr[6:7] 14302 // 14303 // r.ArrS[3].x 14304 14305 bool AllowUnitySizeArraySection = true; 14306 bool AllowWholeSizeArraySection = true; 14307 14308 while (!RelevantExpr) { 14309 E = E->IgnoreParenImpCasts(); 14310 14311 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14312 if (!isa<VarDecl>(CurE->getDecl())) 14313 return nullptr; 14314 14315 RelevantExpr = CurE; 14316 14317 // If we got a reference to a declaration, we should not expect any array 14318 // section before that. 14319 AllowUnitySizeArraySection = false; 14320 AllowWholeSizeArraySection = false; 14321 14322 // Record the component. 14323 CurComponents.emplace_back(CurE, CurE->getDecl()); 14324 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14325 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14326 14327 if (isa<CXXThisExpr>(BaseE)) 14328 // We found a base expression: this->Val. 14329 RelevantExpr = CurE; 14330 else 14331 E = BaseE; 14332 14333 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14334 if (!NoDiagnose) { 14335 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14336 << CurE->getSourceRange(); 14337 return nullptr; 14338 } 14339 if (RelevantExpr) 14340 return nullptr; 14341 continue; 14342 } 14343 14344 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14345 14346 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14347 // A bit-field cannot appear in a map clause. 14348 // 14349 if (FD->isBitField()) { 14350 if (!NoDiagnose) { 14351 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14352 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14353 return nullptr; 14354 } 14355 if (RelevantExpr) 14356 return nullptr; 14357 continue; 14358 } 14359 14360 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14361 // If the type of a list item is a reference to a type T then the type 14362 // will be considered to be T for all purposes of this clause. 14363 QualType CurType = BaseE->getType().getNonReferenceType(); 14364 14365 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14366 // A list item cannot be a variable that is a member of a structure with 14367 // a union type. 14368 // 14369 if (CurType->isUnionType()) { 14370 if (!NoDiagnose) { 14371 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14372 << CurE->getSourceRange(); 14373 return nullptr; 14374 } 14375 continue; 14376 } 14377 14378 // If we got a member expression, we should not expect any array section 14379 // before that: 14380 // 14381 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14382 // If a list item is an element of a structure, only the rightmost symbol 14383 // of the variable reference can be an array section. 14384 // 14385 AllowUnitySizeArraySection = false; 14386 AllowWholeSizeArraySection = false; 14387 14388 // Record the component. 14389 CurComponents.emplace_back(CurE, FD); 14390 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14391 E = CurE->getBase()->IgnoreParenImpCasts(); 14392 14393 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14394 if (!NoDiagnose) { 14395 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14396 << 0 << CurE->getSourceRange(); 14397 return nullptr; 14398 } 14399 continue; 14400 } 14401 14402 // If we got an array subscript that express the whole dimension we 14403 // can have any array expressions before. If it only expressing part of 14404 // the dimension, we can only have unitary-size array expressions. 14405 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14406 E->getType())) 14407 AllowWholeSizeArraySection = false; 14408 14409 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14410 Expr::EvalResult Result; 14411 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14412 if (!Result.Val.getInt().isNullValue()) { 14413 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14414 diag::err_omp_invalid_map_this_expr); 14415 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14416 diag::note_omp_invalid_subscript_on_this_ptr_map); 14417 } 14418 } 14419 RelevantExpr = TE; 14420 } 14421 14422 // Record the component - we don't have any declaration associated. 14423 CurComponents.emplace_back(CurE, nullptr); 14424 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14425 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14426 E = CurE->getBase()->IgnoreParenImpCasts(); 14427 14428 QualType CurType = 14429 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14430 14431 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14432 // If the type of a list item is a reference to a type T then the type 14433 // will be considered to be T for all purposes of this clause. 14434 if (CurType->isReferenceType()) 14435 CurType = CurType->getPointeeType(); 14436 14437 bool IsPointer = CurType->isAnyPointerType(); 14438 14439 if (!IsPointer && !CurType->isArrayType()) { 14440 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14441 << 0 << CurE->getSourceRange(); 14442 return nullptr; 14443 } 14444 14445 bool NotWhole = 14446 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14447 bool NotUnity = 14448 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14449 14450 if (AllowWholeSizeArraySection) { 14451 // Any array section is currently allowed. Allowing a whole size array 14452 // section implies allowing a unity array section as well. 14453 // 14454 // If this array section refers to the whole dimension we can still 14455 // accept other array sections before this one, except if the base is a 14456 // pointer. Otherwise, only unitary sections are accepted. 14457 if (NotWhole || IsPointer) 14458 AllowWholeSizeArraySection = false; 14459 } else if (AllowUnitySizeArraySection && NotUnity) { 14460 // A unity or whole array section is not allowed and that is not 14461 // compatible with the properties of the current array section. 14462 SemaRef.Diag( 14463 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14464 << CurE->getSourceRange(); 14465 return nullptr; 14466 } 14467 14468 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14469 Expr::EvalResult ResultR; 14470 Expr::EvalResult ResultL; 14471 if (CurE->getLength()->EvaluateAsInt(ResultR, 14472 SemaRef.getASTContext())) { 14473 if (!ResultR.Val.getInt().isOneValue()) { 14474 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14475 diag::err_omp_invalid_map_this_expr); 14476 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14477 diag::note_omp_invalid_length_on_this_ptr_mapping); 14478 } 14479 } 14480 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14481 ResultL, SemaRef.getASTContext())) { 14482 if (!ResultL.Val.getInt().isNullValue()) { 14483 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14484 diag::err_omp_invalid_map_this_expr); 14485 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14486 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14487 } 14488 } 14489 RelevantExpr = TE; 14490 } 14491 14492 // Record the component - we don't have any declaration associated. 14493 CurComponents.emplace_back(CurE, nullptr); 14494 } else { 14495 if (!NoDiagnose) { 14496 // If nothing else worked, this is not a valid map clause expression. 14497 SemaRef.Diag( 14498 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14499 << ERange; 14500 } 14501 return nullptr; 14502 } 14503 } 14504 14505 return RelevantExpr; 14506 } 14507 14508 // Return true if expression E associated with value VD has conflicts with other 14509 // map information. 14510 static bool checkMapConflicts( 14511 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14512 bool CurrentRegionOnly, 14513 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14514 OpenMPClauseKind CKind) { 14515 assert(VD && E); 14516 SourceLocation ELoc = E->getExprLoc(); 14517 SourceRange ERange = E->getSourceRange(); 14518 14519 // In order to easily check the conflicts we need to match each component of 14520 // the expression under test with the components of the expressions that are 14521 // already in the stack. 14522 14523 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14524 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14525 "Map clause expression with unexpected base!"); 14526 14527 // Variables to help detecting enclosing problems in data environment nests. 14528 bool IsEnclosedByDataEnvironmentExpr = false; 14529 const Expr *EnclosingExpr = nullptr; 14530 14531 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14532 VD, CurrentRegionOnly, 14533 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14534 ERange, CKind, &EnclosingExpr, 14535 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14536 StackComponents, 14537 OpenMPClauseKind) { 14538 assert(!StackComponents.empty() && 14539 "Map clause expression with no components!"); 14540 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14541 "Map clause expression with unexpected base!"); 14542 (void)VD; 14543 14544 // The whole expression in the stack. 14545 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14546 14547 // Expressions must start from the same base. Here we detect at which 14548 // point both expressions diverge from each other and see if we can 14549 // detect if the memory referred to both expressions is contiguous and 14550 // do not overlap. 14551 auto CI = CurComponents.rbegin(); 14552 auto CE = CurComponents.rend(); 14553 auto SI = StackComponents.rbegin(); 14554 auto SE = StackComponents.rend(); 14555 for (; CI != CE && SI != SE; ++CI, ++SI) { 14556 14557 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14558 // At most one list item can be an array item derived from a given 14559 // variable in map clauses of the same construct. 14560 if (CurrentRegionOnly && 14561 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14562 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14563 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14564 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14565 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14566 diag::err_omp_multiple_array_items_in_map_clause) 14567 << CI->getAssociatedExpression()->getSourceRange(); 14568 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14569 diag::note_used_here) 14570 << SI->getAssociatedExpression()->getSourceRange(); 14571 return true; 14572 } 14573 14574 // Do both expressions have the same kind? 14575 if (CI->getAssociatedExpression()->getStmtClass() != 14576 SI->getAssociatedExpression()->getStmtClass()) 14577 break; 14578 14579 // Are we dealing with different variables/fields? 14580 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14581 break; 14582 } 14583 // Check if the extra components of the expressions in the enclosing 14584 // data environment are redundant for the current base declaration. 14585 // If they are, the maps completely overlap, which is legal. 14586 for (; SI != SE; ++SI) { 14587 QualType Type; 14588 if (const auto *ASE = 14589 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14590 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14591 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14592 SI->getAssociatedExpression())) { 14593 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14594 Type = 14595 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14596 } 14597 if (Type.isNull() || Type->isAnyPointerType() || 14598 checkArrayExpressionDoesNotReferToWholeSize( 14599 SemaRef, SI->getAssociatedExpression(), Type)) 14600 break; 14601 } 14602 14603 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14604 // List items of map clauses in the same construct must not share 14605 // original storage. 14606 // 14607 // If the expressions are exactly the same or one is a subset of the 14608 // other, it means they are sharing storage. 14609 if (CI == CE && SI == SE) { 14610 if (CurrentRegionOnly) { 14611 if (CKind == OMPC_map) { 14612 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14613 } else { 14614 assert(CKind == OMPC_to || CKind == OMPC_from); 14615 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14616 << ERange; 14617 } 14618 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14619 << RE->getSourceRange(); 14620 return true; 14621 } 14622 // If we find the same expression in the enclosing data environment, 14623 // that is legal. 14624 IsEnclosedByDataEnvironmentExpr = true; 14625 return false; 14626 } 14627 14628 QualType DerivedType = 14629 std::prev(CI)->getAssociatedDeclaration()->getType(); 14630 SourceLocation DerivedLoc = 14631 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14632 14633 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14634 // If the type of a list item is a reference to a type T then the type 14635 // will be considered to be T for all purposes of this clause. 14636 DerivedType = DerivedType.getNonReferenceType(); 14637 14638 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14639 // A variable for which the type is pointer and an array section 14640 // derived from that variable must not appear as list items of map 14641 // clauses of the same construct. 14642 // 14643 // Also, cover one of the cases in: 14644 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14645 // If any part of the original storage of a list item has corresponding 14646 // storage in the device data environment, all of the original storage 14647 // must have corresponding storage in the device data environment. 14648 // 14649 if (DerivedType->isAnyPointerType()) { 14650 if (CI == CE || SI == SE) { 14651 SemaRef.Diag( 14652 DerivedLoc, 14653 diag::err_omp_pointer_mapped_along_with_derived_section) 14654 << DerivedLoc; 14655 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14656 << RE->getSourceRange(); 14657 return true; 14658 } 14659 if (CI->getAssociatedExpression()->getStmtClass() != 14660 SI->getAssociatedExpression()->getStmtClass() || 14661 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14662 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14663 assert(CI != CE && SI != SE); 14664 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14665 << DerivedLoc; 14666 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14667 << RE->getSourceRange(); 14668 return true; 14669 } 14670 } 14671 14672 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14673 // List items of map clauses in the same construct must not share 14674 // original storage. 14675 // 14676 // An expression is a subset of the other. 14677 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14678 if (CKind == OMPC_map) { 14679 if (CI != CE || SI != SE) { 14680 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14681 // a pointer. 14682 auto Begin = 14683 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14684 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14685 auto It = Begin; 14686 while (It != End && !It->getAssociatedDeclaration()) 14687 std::advance(It, 1); 14688 assert(It != End && 14689 "Expected at least one component with the declaration."); 14690 if (It != Begin && It->getAssociatedDeclaration() 14691 ->getType() 14692 .getCanonicalType() 14693 ->isAnyPointerType()) { 14694 IsEnclosedByDataEnvironmentExpr = false; 14695 EnclosingExpr = nullptr; 14696 return false; 14697 } 14698 } 14699 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14700 } else { 14701 assert(CKind == OMPC_to || CKind == OMPC_from); 14702 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14703 << ERange; 14704 } 14705 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14706 << RE->getSourceRange(); 14707 return true; 14708 } 14709 14710 // The current expression uses the same base as other expression in the 14711 // data environment but does not contain it completely. 14712 if (!CurrentRegionOnly && SI != SE) 14713 EnclosingExpr = RE; 14714 14715 // The current expression is a subset of the expression in the data 14716 // environment. 14717 IsEnclosedByDataEnvironmentExpr |= 14718 (!CurrentRegionOnly && CI != CE && SI == SE); 14719 14720 return false; 14721 }); 14722 14723 if (CurrentRegionOnly) 14724 return FoundError; 14725 14726 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14727 // If any part of the original storage of a list item has corresponding 14728 // storage in the device data environment, all of the original storage must 14729 // have corresponding storage in the device data environment. 14730 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 14731 // If a list item is an element of a structure, and a different element of 14732 // the structure has a corresponding list item in the device data environment 14733 // prior to a task encountering the construct associated with the map clause, 14734 // then the list item must also have a corresponding list item in the device 14735 // data environment prior to the task encountering the construct. 14736 // 14737 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 14738 SemaRef.Diag(ELoc, 14739 diag::err_omp_original_storage_is_shared_and_does_not_contain) 14740 << ERange; 14741 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 14742 << EnclosingExpr->getSourceRange(); 14743 return true; 14744 } 14745 14746 return FoundError; 14747 } 14748 14749 // Look up the user-defined mapper given the mapper name and mapped type, and 14750 // build a reference to it. 14751 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 14752 CXXScopeSpec &MapperIdScopeSpec, 14753 const DeclarationNameInfo &MapperId, 14754 QualType Type, 14755 Expr *UnresolvedMapper) { 14756 if (MapperIdScopeSpec.isInvalid()) 14757 return ExprError(); 14758 // Get the actual type for the array type. 14759 if (Type->isArrayType()) { 14760 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 14761 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 14762 } 14763 // Find all user-defined mappers with the given MapperId. 14764 SmallVector<UnresolvedSet<8>, 4> Lookups; 14765 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 14766 Lookup.suppressDiagnostics(); 14767 if (S) { 14768 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 14769 NamedDecl *D = Lookup.getRepresentativeDecl(); 14770 while (S && !S->isDeclScope(D)) 14771 S = S->getParent(); 14772 if (S) 14773 S = S->getParent(); 14774 Lookups.emplace_back(); 14775 Lookups.back().append(Lookup.begin(), Lookup.end()); 14776 Lookup.clear(); 14777 } 14778 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 14779 // Extract the user-defined mappers with the given MapperId. 14780 Lookups.push_back(UnresolvedSet<8>()); 14781 for (NamedDecl *D : ULE->decls()) { 14782 auto *DMD = cast<OMPDeclareMapperDecl>(D); 14783 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 14784 Lookups.back().addDecl(DMD); 14785 } 14786 } 14787 // Defer the lookup for dependent types. The results will be passed through 14788 // UnresolvedMapper on instantiation. 14789 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 14790 Type->isInstantiationDependentType() || 14791 Type->containsUnexpandedParameterPack() || 14792 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14793 return !D->isInvalidDecl() && 14794 (D->getType()->isDependentType() || 14795 D->getType()->isInstantiationDependentType() || 14796 D->getType()->containsUnexpandedParameterPack()); 14797 })) { 14798 UnresolvedSet<8> URS; 14799 for (const UnresolvedSet<8> &Set : Lookups) { 14800 if (Set.empty()) 14801 continue; 14802 URS.append(Set.begin(), Set.end()); 14803 } 14804 return UnresolvedLookupExpr::Create( 14805 SemaRef.Context, /*NamingClass=*/nullptr, 14806 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 14807 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 14808 } 14809 SourceLocation Loc = MapperId.getLoc(); 14810 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14811 // The type must be of struct, union or class type in C and C++ 14812 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 14813 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 14814 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 14815 return ExprError(); 14816 } 14817 // Perform argument dependent lookup. 14818 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 14819 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 14820 // Return the first user-defined mapper with the desired type. 14821 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14822 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 14823 if (!D->isInvalidDecl() && 14824 SemaRef.Context.hasSameType(D->getType(), Type)) 14825 return D; 14826 return nullptr; 14827 })) 14828 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14829 // Find the first user-defined mapper with a type derived from the desired 14830 // type. 14831 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14832 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 14833 if (!D->isInvalidDecl() && 14834 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 14835 !Type.isMoreQualifiedThan(D->getType())) 14836 return D; 14837 return nullptr; 14838 })) { 14839 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14840 /*DetectVirtual=*/false); 14841 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 14842 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14843 VD->getType().getUnqualifiedType()))) { 14844 if (SemaRef.CheckBaseClassAccess( 14845 Loc, VD->getType(), Type, Paths.front(), 14846 /*DiagID=*/0) != Sema::AR_inaccessible) { 14847 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14848 } 14849 } 14850 } 14851 } 14852 // Report error if a mapper is specified, but cannot be found. 14853 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 14854 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 14855 << Type << MapperId.getName(); 14856 return ExprError(); 14857 } 14858 return ExprEmpty(); 14859 } 14860 14861 namespace { 14862 // Utility struct that gathers all the related lists associated with a mappable 14863 // expression. 14864 struct MappableVarListInfo { 14865 // The list of expressions. 14866 ArrayRef<Expr *> VarList; 14867 // The list of processed expressions. 14868 SmallVector<Expr *, 16> ProcessedVarList; 14869 // The mappble components for each expression. 14870 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 14871 // The base declaration of the variable. 14872 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 14873 // The reference to the user-defined mapper associated with every expression. 14874 SmallVector<Expr *, 16> UDMapperList; 14875 14876 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 14877 // We have a list of components and base declarations for each entry in the 14878 // variable list. 14879 VarComponents.reserve(VarList.size()); 14880 VarBaseDeclarations.reserve(VarList.size()); 14881 } 14882 }; 14883 } 14884 14885 // Check the validity of the provided variable list for the provided clause kind 14886 // \a CKind. In the check process the valid expressions, mappable expression 14887 // components, variables, and user-defined mappers are extracted and used to 14888 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 14889 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 14890 // and \a MapperId are expected to be valid if the clause kind is 'map'. 14891 static void checkMappableExpressionList( 14892 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 14893 MappableVarListInfo &MVLI, SourceLocation StartLoc, 14894 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 14895 ArrayRef<Expr *> UnresolvedMappers, 14896 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 14897 bool IsMapTypeImplicit = false) { 14898 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 14899 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 14900 "Unexpected clause kind with mappable expressions!"); 14901 14902 // If the identifier of user-defined mapper is not specified, it is "default". 14903 // We do not change the actual name in this clause to distinguish whether a 14904 // mapper is specified explicitly, i.e., it is not explicitly specified when 14905 // MapperId.getName() is empty. 14906 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 14907 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14908 MapperId.setName(DeclNames.getIdentifier( 14909 &SemaRef.getASTContext().Idents.get("default"))); 14910 } 14911 14912 // Iterators to find the current unresolved mapper expression. 14913 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14914 bool UpdateUMIt = false; 14915 Expr *UnresolvedMapper = nullptr; 14916 14917 // Keep track of the mappable components and base declarations in this clause. 14918 // Each entry in the list is going to have a list of components associated. We 14919 // record each set of the components so that we can build the clause later on. 14920 // In the end we should have the same amount of declarations and component 14921 // lists. 14922 14923 for (Expr *RE : MVLI.VarList) { 14924 assert(RE && "Null expr in omp to/from/map clause"); 14925 SourceLocation ELoc = RE->getExprLoc(); 14926 14927 // Find the current unresolved mapper expression. 14928 if (UpdateUMIt && UMIt != UMEnd) { 14929 UMIt++; 14930 assert( 14931 UMIt != UMEnd && 14932 "Expect the size of UnresolvedMappers to match with that of VarList"); 14933 } 14934 UpdateUMIt = true; 14935 if (UMIt != UMEnd) 14936 UnresolvedMapper = *UMIt; 14937 14938 const Expr *VE = RE->IgnoreParenLValueCasts(); 14939 14940 if (VE->isValueDependent() || VE->isTypeDependent() || 14941 VE->isInstantiationDependent() || 14942 VE->containsUnexpandedParameterPack()) { 14943 // Try to find the associated user-defined mapper. 14944 ExprResult ER = buildUserDefinedMapperRef( 14945 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14946 VE->getType().getCanonicalType(), UnresolvedMapper); 14947 if (ER.isInvalid()) 14948 continue; 14949 MVLI.UDMapperList.push_back(ER.get()); 14950 // We can only analyze this information once the missing information is 14951 // resolved. 14952 MVLI.ProcessedVarList.push_back(RE); 14953 continue; 14954 } 14955 14956 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14957 14958 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14959 SemaRef.Diag(ELoc, 14960 diag::err_omp_expected_named_var_member_or_array_expression) 14961 << RE->getSourceRange(); 14962 continue; 14963 } 14964 14965 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14966 ValueDecl *CurDeclaration = nullptr; 14967 14968 // Obtain the array or member expression bases if required. Also, fill the 14969 // components array with all the components identified in the process. 14970 const Expr *BE = checkMapClauseExpressionBase( 14971 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14972 if (!BE) 14973 continue; 14974 14975 assert(!CurComponents.empty() && 14976 "Invalid mappable expression information."); 14977 14978 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14979 // Add store "this" pointer to class in DSAStackTy for future checking 14980 DSAS->addMappedClassesQualTypes(TE->getType()); 14981 // Try to find the associated user-defined mapper. 14982 ExprResult ER = buildUserDefinedMapperRef( 14983 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14984 VE->getType().getCanonicalType(), UnresolvedMapper); 14985 if (ER.isInvalid()) 14986 continue; 14987 MVLI.UDMapperList.push_back(ER.get()); 14988 // Skip restriction checking for variable or field declarations 14989 MVLI.ProcessedVarList.push_back(RE); 14990 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14991 MVLI.VarComponents.back().append(CurComponents.begin(), 14992 CurComponents.end()); 14993 MVLI.VarBaseDeclarations.push_back(nullptr); 14994 continue; 14995 } 14996 14997 // For the following checks, we rely on the base declaration which is 14998 // expected to be associated with the last component. The declaration is 14999 // expected to be a variable or a field (if 'this' is being mapped). 15000 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15001 assert(CurDeclaration && "Null decl on map clause."); 15002 assert( 15003 CurDeclaration->isCanonicalDecl() && 15004 "Expecting components to have associated only canonical declarations."); 15005 15006 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15007 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15008 15009 assert((VD || FD) && "Only variables or fields are expected here!"); 15010 (void)FD; 15011 15012 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15013 // threadprivate variables cannot appear in a map clause. 15014 // OpenMP 4.5 [2.10.5, target update Construct] 15015 // threadprivate variables cannot appear in a from clause. 15016 if (VD && DSAS->isThreadPrivate(VD)) { 15017 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15018 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15019 << getOpenMPClauseName(CKind); 15020 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15021 continue; 15022 } 15023 15024 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15025 // A list item cannot appear in both a map clause and a data-sharing 15026 // attribute clause on the same construct. 15027 15028 // Check conflicts with other map clause expressions. We check the conflicts 15029 // with the current construct separately from the enclosing data 15030 // environment, because the restrictions are different. We only have to 15031 // check conflicts across regions for the map clauses. 15032 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15033 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15034 break; 15035 if (CKind == OMPC_map && 15036 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15037 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15038 break; 15039 15040 // OpenMP 4.5 [2.10.5, target update Construct] 15041 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15042 // If the type of a list item is a reference to a type T then the type will 15043 // be considered to be T for all purposes of this clause. 15044 auto I = llvm::find_if( 15045 CurComponents, 15046 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15047 return MC.getAssociatedDeclaration(); 15048 }); 15049 assert(I != CurComponents.end() && "Null decl on map clause."); 15050 QualType Type = 15051 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15052 15053 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15054 // A list item in a to or from clause must have a mappable type. 15055 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15056 // A list item must have a mappable type. 15057 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15058 DSAS, Type)) 15059 continue; 15060 15061 if (CKind == OMPC_map) { 15062 // target enter data 15063 // OpenMP [2.10.2, Restrictions, p. 99] 15064 // A map-type must be specified in all map clauses and must be either 15065 // to or alloc. 15066 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15067 if (DKind == OMPD_target_enter_data && 15068 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15069 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15070 << (IsMapTypeImplicit ? 1 : 0) 15071 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15072 << getOpenMPDirectiveName(DKind); 15073 continue; 15074 } 15075 15076 // target exit_data 15077 // OpenMP [2.10.3, Restrictions, p. 102] 15078 // A map-type must be specified in all map clauses and must be either 15079 // from, release, or delete. 15080 if (DKind == OMPD_target_exit_data && 15081 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15082 MapType == OMPC_MAP_delete)) { 15083 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15084 << (IsMapTypeImplicit ? 1 : 0) 15085 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15086 << getOpenMPDirectiveName(DKind); 15087 continue; 15088 } 15089 15090 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15091 // A list item cannot appear in both a map clause and a data-sharing 15092 // attribute clause on the same construct 15093 // 15094 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15095 // A list item cannot appear in both a map clause and a data-sharing 15096 // attribute clause on the same construct unless the construct is a 15097 // combined construct. 15098 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15099 isOpenMPTargetExecutionDirective(DKind)) || 15100 DKind == OMPD_target)) { 15101 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15102 if (isOpenMPPrivate(DVar.CKind)) { 15103 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15104 << getOpenMPClauseName(DVar.CKind) 15105 << getOpenMPClauseName(OMPC_map) 15106 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15107 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15108 continue; 15109 } 15110 } 15111 } 15112 15113 // Try to find the associated user-defined mapper. 15114 ExprResult ER = buildUserDefinedMapperRef( 15115 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15116 Type.getCanonicalType(), UnresolvedMapper); 15117 if (ER.isInvalid()) 15118 continue; 15119 MVLI.UDMapperList.push_back(ER.get()); 15120 15121 // Save the current expression. 15122 MVLI.ProcessedVarList.push_back(RE); 15123 15124 // Store the components in the stack so that they can be used to check 15125 // against other clauses later on. 15126 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15127 /*WhereFoundClauseKind=*/OMPC_map); 15128 15129 // Save the components and declaration to create the clause. For purposes of 15130 // the clause creation, any component list that has has base 'this' uses 15131 // null as base declaration. 15132 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15133 MVLI.VarComponents.back().append(CurComponents.begin(), 15134 CurComponents.end()); 15135 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15136 : CurDeclaration); 15137 } 15138 } 15139 15140 OMPClause *Sema::ActOnOpenMPMapClause( 15141 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15142 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15143 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15144 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15145 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15146 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15147 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15148 OMPC_MAP_MODIFIER_unknown, 15149 OMPC_MAP_MODIFIER_unknown}; 15150 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15151 15152 // Process map-type-modifiers, flag errors for duplicate modifiers. 15153 unsigned Count = 0; 15154 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15155 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15156 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15157 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15158 continue; 15159 } 15160 assert(Count < OMPMapClause::NumberOfModifiers && 15161 "Modifiers exceed the allowed number of map type modifiers"); 15162 Modifiers[Count] = MapTypeModifiers[I]; 15163 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15164 ++Count; 15165 } 15166 15167 MappableVarListInfo MVLI(VarList); 15168 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15169 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15170 MapType, IsMapTypeImplicit); 15171 15172 // We need to produce a map clause even if we don't have variables so that 15173 // other diagnostics related with non-existing map clauses are accurate. 15174 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15175 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15176 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15177 MapperIdScopeSpec.getWithLocInContext(Context), 15178 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15179 } 15180 15181 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15182 TypeResult ParsedType) { 15183 assert(ParsedType.isUsable()); 15184 15185 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15186 if (ReductionType.isNull()) 15187 return QualType(); 15188 15189 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15190 // A type name in a declare reduction directive cannot be a function type, an 15191 // array type, a reference type, or a type qualified with const, volatile or 15192 // restrict. 15193 if (ReductionType.hasQualifiers()) { 15194 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15195 return QualType(); 15196 } 15197 15198 if (ReductionType->isFunctionType()) { 15199 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15200 return QualType(); 15201 } 15202 if (ReductionType->isReferenceType()) { 15203 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15204 return QualType(); 15205 } 15206 if (ReductionType->isArrayType()) { 15207 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15208 return QualType(); 15209 } 15210 return ReductionType; 15211 } 15212 15213 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15214 Scope *S, DeclContext *DC, DeclarationName Name, 15215 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15216 AccessSpecifier AS, Decl *PrevDeclInScope) { 15217 SmallVector<Decl *, 8> Decls; 15218 Decls.reserve(ReductionTypes.size()); 15219 15220 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15221 forRedeclarationInCurContext()); 15222 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15223 // A reduction-identifier may not be re-declared in the current scope for the 15224 // same type or for a type that is compatible according to the base language 15225 // rules. 15226 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15227 OMPDeclareReductionDecl *PrevDRD = nullptr; 15228 bool InCompoundScope = true; 15229 if (S != nullptr) { 15230 // Find previous declaration with the same name not referenced in other 15231 // declarations. 15232 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15233 InCompoundScope = 15234 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15235 LookupName(Lookup, S); 15236 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15237 /*AllowInlineNamespace=*/false); 15238 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15239 LookupResult::Filter Filter = Lookup.makeFilter(); 15240 while (Filter.hasNext()) { 15241 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15242 if (InCompoundScope) { 15243 auto I = UsedAsPrevious.find(PrevDecl); 15244 if (I == UsedAsPrevious.end()) 15245 UsedAsPrevious[PrevDecl] = false; 15246 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15247 UsedAsPrevious[D] = true; 15248 } 15249 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15250 PrevDecl->getLocation(); 15251 } 15252 Filter.done(); 15253 if (InCompoundScope) { 15254 for (const auto &PrevData : UsedAsPrevious) { 15255 if (!PrevData.second) { 15256 PrevDRD = PrevData.first; 15257 break; 15258 } 15259 } 15260 } 15261 } else if (PrevDeclInScope != nullptr) { 15262 auto *PrevDRDInScope = PrevDRD = 15263 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15264 do { 15265 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15266 PrevDRDInScope->getLocation(); 15267 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15268 } while (PrevDRDInScope != nullptr); 15269 } 15270 for (const auto &TyData : ReductionTypes) { 15271 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15272 bool Invalid = false; 15273 if (I != PreviousRedeclTypes.end()) { 15274 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15275 << TyData.first; 15276 Diag(I->second, diag::note_previous_definition); 15277 Invalid = true; 15278 } 15279 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15280 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15281 Name, TyData.first, PrevDRD); 15282 DC->addDecl(DRD); 15283 DRD->setAccess(AS); 15284 Decls.push_back(DRD); 15285 if (Invalid) 15286 DRD->setInvalidDecl(); 15287 else 15288 PrevDRD = DRD; 15289 } 15290 15291 return DeclGroupPtrTy::make( 15292 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15293 } 15294 15295 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15296 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15297 15298 // Enter new function scope. 15299 PushFunctionScope(); 15300 setFunctionHasBranchProtectedScope(); 15301 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15302 15303 if (S != nullptr) 15304 PushDeclContext(S, DRD); 15305 else 15306 CurContext = DRD; 15307 15308 PushExpressionEvaluationContext( 15309 ExpressionEvaluationContext::PotentiallyEvaluated); 15310 15311 QualType ReductionType = DRD->getType(); 15312 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15313 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15314 // uses semantics of argument handles by value, but it should be passed by 15315 // reference. C lang does not support references, so pass all parameters as 15316 // pointers. 15317 // Create 'T omp_in;' variable. 15318 VarDecl *OmpInParm = 15319 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15320 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15321 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15322 // uses semantics of argument handles by value, but it should be passed by 15323 // reference. C lang does not support references, so pass all parameters as 15324 // pointers. 15325 // Create 'T omp_out;' variable. 15326 VarDecl *OmpOutParm = 15327 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15328 if (S != nullptr) { 15329 PushOnScopeChains(OmpInParm, S); 15330 PushOnScopeChains(OmpOutParm, S); 15331 } else { 15332 DRD->addDecl(OmpInParm); 15333 DRD->addDecl(OmpOutParm); 15334 } 15335 Expr *InE = 15336 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15337 Expr *OutE = 15338 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15339 DRD->setCombinerData(InE, OutE); 15340 } 15341 15342 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15343 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15344 DiscardCleanupsInEvaluationContext(); 15345 PopExpressionEvaluationContext(); 15346 15347 PopDeclContext(); 15348 PopFunctionScopeInfo(); 15349 15350 if (Combiner != nullptr) 15351 DRD->setCombiner(Combiner); 15352 else 15353 DRD->setInvalidDecl(); 15354 } 15355 15356 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15357 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15358 15359 // Enter new function scope. 15360 PushFunctionScope(); 15361 setFunctionHasBranchProtectedScope(); 15362 15363 if (S != nullptr) 15364 PushDeclContext(S, DRD); 15365 else 15366 CurContext = DRD; 15367 15368 PushExpressionEvaluationContext( 15369 ExpressionEvaluationContext::PotentiallyEvaluated); 15370 15371 QualType ReductionType = DRD->getType(); 15372 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15373 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15374 // uses semantics of argument handles by value, but it should be passed by 15375 // reference. C lang does not support references, so pass all parameters as 15376 // pointers. 15377 // Create 'T omp_priv;' variable. 15378 VarDecl *OmpPrivParm = 15379 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15380 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15381 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15382 // uses semantics of argument handles by value, but it should be passed by 15383 // reference. C lang does not support references, so pass all parameters as 15384 // pointers. 15385 // Create 'T omp_orig;' variable. 15386 VarDecl *OmpOrigParm = 15387 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15388 if (S != nullptr) { 15389 PushOnScopeChains(OmpPrivParm, S); 15390 PushOnScopeChains(OmpOrigParm, S); 15391 } else { 15392 DRD->addDecl(OmpPrivParm); 15393 DRD->addDecl(OmpOrigParm); 15394 } 15395 Expr *OrigE = 15396 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15397 Expr *PrivE = 15398 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15399 DRD->setInitializerData(OrigE, PrivE); 15400 return OmpPrivParm; 15401 } 15402 15403 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15404 VarDecl *OmpPrivParm) { 15405 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15406 DiscardCleanupsInEvaluationContext(); 15407 PopExpressionEvaluationContext(); 15408 15409 PopDeclContext(); 15410 PopFunctionScopeInfo(); 15411 15412 if (Initializer != nullptr) { 15413 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15414 } else if (OmpPrivParm->hasInit()) { 15415 DRD->setInitializer(OmpPrivParm->getInit(), 15416 OmpPrivParm->isDirectInit() 15417 ? OMPDeclareReductionDecl::DirectInit 15418 : OMPDeclareReductionDecl::CopyInit); 15419 } else { 15420 DRD->setInvalidDecl(); 15421 } 15422 } 15423 15424 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15425 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15426 for (Decl *D : DeclReductions.get()) { 15427 if (IsValid) { 15428 if (S) 15429 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15430 /*AddToContext=*/false); 15431 } else { 15432 D->setInvalidDecl(); 15433 } 15434 } 15435 return DeclReductions; 15436 } 15437 15438 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15439 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15440 QualType T = TInfo->getType(); 15441 if (D.isInvalidType()) 15442 return true; 15443 15444 if (getLangOpts().CPlusPlus) { 15445 // Check that there are no default arguments (C++ only). 15446 CheckExtraCXXDefaultArguments(D); 15447 } 15448 15449 return CreateParsedType(T, TInfo); 15450 } 15451 15452 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15453 TypeResult ParsedType) { 15454 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15455 15456 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15457 assert(!MapperType.isNull() && "Expect valid mapper type"); 15458 15459 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15460 // The type must be of struct, union or class type in C and C++ 15461 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15462 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15463 return QualType(); 15464 } 15465 return MapperType; 15466 } 15467 15468 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15469 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15470 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15471 Decl *PrevDeclInScope) { 15472 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15473 forRedeclarationInCurContext()); 15474 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15475 // A mapper-identifier may not be redeclared in the current scope for the 15476 // same type or for a type that is compatible according to the base language 15477 // rules. 15478 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15479 OMPDeclareMapperDecl *PrevDMD = nullptr; 15480 bool InCompoundScope = true; 15481 if (S != nullptr) { 15482 // Find previous declaration with the same name not referenced in other 15483 // declarations. 15484 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15485 InCompoundScope = 15486 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15487 LookupName(Lookup, S); 15488 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15489 /*AllowInlineNamespace=*/false); 15490 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15491 LookupResult::Filter Filter = Lookup.makeFilter(); 15492 while (Filter.hasNext()) { 15493 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15494 if (InCompoundScope) { 15495 auto I = UsedAsPrevious.find(PrevDecl); 15496 if (I == UsedAsPrevious.end()) 15497 UsedAsPrevious[PrevDecl] = false; 15498 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15499 UsedAsPrevious[D] = true; 15500 } 15501 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15502 PrevDecl->getLocation(); 15503 } 15504 Filter.done(); 15505 if (InCompoundScope) { 15506 for (const auto &PrevData : UsedAsPrevious) { 15507 if (!PrevData.second) { 15508 PrevDMD = PrevData.first; 15509 break; 15510 } 15511 } 15512 } 15513 } else if (PrevDeclInScope) { 15514 auto *PrevDMDInScope = PrevDMD = 15515 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15516 do { 15517 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15518 PrevDMDInScope->getLocation(); 15519 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15520 } while (PrevDMDInScope != nullptr); 15521 } 15522 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15523 bool Invalid = false; 15524 if (I != PreviousRedeclTypes.end()) { 15525 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15526 << MapperType << Name; 15527 Diag(I->second, diag::note_previous_definition); 15528 Invalid = true; 15529 } 15530 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15531 MapperType, VN, PrevDMD); 15532 DC->addDecl(DMD); 15533 DMD->setAccess(AS); 15534 if (Invalid) 15535 DMD->setInvalidDecl(); 15536 15537 // Enter new function scope. 15538 PushFunctionScope(); 15539 setFunctionHasBranchProtectedScope(); 15540 15541 CurContext = DMD; 15542 15543 return DMD; 15544 } 15545 15546 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15547 Scope *S, 15548 QualType MapperType, 15549 SourceLocation StartLoc, 15550 DeclarationName VN) { 15551 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15552 if (S) 15553 PushOnScopeChains(VD, S); 15554 else 15555 DMD->addDecl(VD); 15556 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15557 DMD->setMapperVarRef(MapperVarRefExpr); 15558 } 15559 15560 Sema::DeclGroupPtrTy 15561 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15562 ArrayRef<OMPClause *> ClauseList) { 15563 PopDeclContext(); 15564 PopFunctionScopeInfo(); 15565 15566 if (D) { 15567 if (S) 15568 PushOnScopeChains(D, S, /*AddToContext=*/false); 15569 D->CreateClauses(Context, ClauseList); 15570 } 15571 15572 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15573 } 15574 15575 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15576 SourceLocation StartLoc, 15577 SourceLocation LParenLoc, 15578 SourceLocation EndLoc) { 15579 Expr *ValExpr = NumTeams; 15580 Stmt *HelperValStmt = nullptr; 15581 15582 // OpenMP [teams Constrcut, Restrictions] 15583 // The num_teams expression must evaluate to a positive integer value. 15584 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15585 /*StrictlyPositive=*/true)) 15586 return nullptr; 15587 15588 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15589 OpenMPDirectiveKind CaptureRegion = 15590 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15591 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15592 ValExpr = MakeFullExpr(ValExpr).get(); 15593 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15594 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15595 HelperValStmt = buildPreInits(Context, Captures); 15596 } 15597 15598 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15599 StartLoc, LParenLoc, EndLoc); 15600 } 15601 15602 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15603 SourceLocation StartLoc, 15604 SourceLocation LParenLoc, 15605 SourceLocation EndLoc) { 15606 Expr *ValExpr = ThreadLimit; 15607 Stmt *HelperValStmt = nullptr; 15608 15609 // OpenMP [teams Constrcut, Restrictions] 15610 // The thread_limit expression must evaluate to a positive integer value. 15611 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15612 /*StrictlyPositive=*/true)) 15613 return nullptr; 15614 15615 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15616 OpenMPDirectiveKind CaptureRegion = 15617 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15618 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15619 ValExpr = MakeFullExpr(ValExpr).get(); 15620 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15621 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15622 HelperValStmt = buildPreInits(Context, Captures); 15623 } 15624 15625 return new (Context) OMPThreadLimitClause( 15626 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15627 } 15628 15629 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15630 SourceLocation StartLoc, 15631 SourceLocation LParenLoc, 15632 SourceLocation EndLoc) { 15633 Expr *ValExpr = Priority; 15634 15635 // OpenMP [2.9.1, task Constrcut] 15636 // The priority-value is a non-negative numerical scalar expression. 15637 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 15638 /*StrictlyPositive=*/false)) 15639 return nullptr; 15640 15641 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15642 } 15643 15644 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15645 SourceLocation StartLoc, 15646 SourceLocation LParenLoc, 15647 SourceLocation EndLoc) { 15648 Expr *ValExpr = Grainsize; 15649 15650 // OpenMP [2.9.2, taskloop Constrcut] 15651 // The parameter of the grainsize clause must be a positive integer 15652 // expression. 15653 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 15654 /*StrictlyPositive=*/true)) 15655 return nullptr; 15656 15657 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15658 } 15659 15660 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15661 SourceLocation StartLoc, 15662 SourceLocation LParenLoc, 15663 SourceLocation EndLoc) { 15664 Expr *ValExpr = NumTasks; 15665 15666 // OpenMP [2.9.2, taskloop Constrcut] 15667 // The parameter of the num_tasks clause must be a positive integer 15668 // expression. 15669 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 15670 /*StrictlyPositive=*/true)) 15671 return nullptr; 15672 15673 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15674 } 15675 15676 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15677 SourceLocation LParenLoc, 15678 SourceLocation EndLoc) { 15679 // OpenMP [2.13.2, critical construct, Description] 15680 // ... where hint-expression is an integer constant expression that evaluates 15681 // to a valid lock hint. 15682 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15683 if (HintExpr.isInvalid()) 15684 return nullptr; 15685 return new (Context) 15686 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 15687 } 15688 15689 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 15690 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 15691 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 15692 SourceLocation EndLoc) { 15693 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 15694 std::string Values; 15695 Values += "'"; 15696 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 15697 Values += "'"; 15698 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 15699 << Values << getOpenMPClauseName(OMPC_dist_schedule); 15700 return nullptr; 15701 } 15702 Expr *ValExpr = ChunkSize; 15703 Stmt *HelperValStmt = nullptr; 15704 if (ChunkSize) { 15705 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 15706 !ChunkSize->isInstantiationDependent() && 15707 !ChunkSize->containsUnexpandedParameterPack()) { 15708 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 15709 ExprResult Val = 15710 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 15711 if (Val.isInvalid()) 15712 return nullptr; 15713 15714 ValExpr = Val.get(); 15715 15716 // OpenMP [2.7.1, Restrictions] 15717 // chunk_size must be a loop invariant integer expression with a positive 15718 // value. 15719 llvm::APSInt Result; 15720 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 15721 if (Result.isSigned() && !Result.isStrictlyPositive()) { 15722 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 15723 << "dist_schedule" << ChunkSize->getSourceRange(); 15724 return nullptr; 15725 } 15726 } else if (getOpenMPCaptureRegionForClause( 15727 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 15728 OMPD_unknown && 15729 !CurContext->isDependentContext()) { 15730 ValExpr = MakeFullExpr(ValExpr).get(); 15731 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15732 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15733 HelperValStmt = buildPreInits(Context, Captures); 15734 } 15735 } 15736 } 15737 15738 return new (Context) 15739 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 15740 Kind, ValExpr, HelperValStmt); 15741 } 15742 15743 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 15744 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 15745 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 15746 SourceLocation KindLoc, SourceLocation EndLoc) { 15747 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 15748 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 15749 std::string Value; 15750 SourceLocation Loc; 15751 Value += "'"; 15752 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 15753 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15754 OMPC_DEFAULTMAP_MODIFIER_tofrom); 15755 Loc = MLoc; 15756 } else { 15757 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15758 OMPC_DEFAULTMAP_scalar); 15759 Loc = KindLoc; 15760 } 15761 Value += "'"; 15762 Diag(Loc, diag::err_omp_unexpected_clause_value) 15763 << Value << getOpenMPClauseName(OMPC_defaultmap); 15764 return nullptr; 15765 } 15766 DSAStack->setDefaultDMAToFromScalar(StartLoc); 15767 15768 return new (Context) 15769 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 15770 } 15771 15772 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 15773 DeclContext *CurLexicalContext = getCurLexicalContext(); 15774 if (!CurLexicalContext->isFileContext() && 15775 !CurLexicalContext->isExternCContext() && 15776 !CurLexicalContext->isExternCXXContext() && 15777 !isa<CXXRecordDecl>(CurLexicalContext) && 15778 !isa<ClassTemplateDecl>(CurLexicalContext) && 15779 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 15780 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 15781 Diag(Loc, diag::err_omp_region_not_file_context); 15782 return false; 15783 } 15784 ++DeclareTargetNestingLevel; 15785 return true; 15786 } 15787 15788 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 15789 assert(DeclareTargetNestingLevel > 0 && 15790 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 15791 --DeclareTargetNestingLevel; 15792 } 15793 15794 NamedDecl * 15795 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 15796 const DeclarationNameInfo &Id, 15797 NamedDeclSetType &SameDirectiveDecls) { 15798 LookupResult Lookup(*this, Id, LookupOrdinaryName); 15799 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 15800 15801 if (Lookup.isAmbiguous()) 15802 return nullptr; 15803 Lookup.suppressDiagnostics(); 15804 15805 if (!Lookup.isSingleResult()) { 15806 VarOrFuncDeclFilterCCC CCC(*this); 15807 if (TypoCorrection Corrected = 15808 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 15809 CTK_ErrorRecovery)) { 15810 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 15811 << Id.getName()); 15812 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 15813 return nullptr; 15814 } 15815 15816 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 15817 return nullptr; 15818 } 15819 15820 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 15821 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 15822 !isa<FunctionTemplateDecl>(ND)) { 15823 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 15824 return nullptr; 15825 } 15826 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 15827 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 15828 return ND; 15829 } 15830 15831 void Sema::ActOnOpenMPDeclareTargetName( 15832 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 15833 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 15834 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 15835 isa<FunctionTemplateDecl>(ND)) && 15836 "Expected variable, function or function template."); 15837 15838 // Diagnose marking after use as it may lead to incorrect diagnosis and 15839 // codegen. 15840 if (LangOpts.OpenMP >= 50 && 15841 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 15842 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 15843 15844 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15845 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 15846 if (DevTy.hasValue() && *DevTy != DT) { 15847 Diag(Loc, diag::err_omp_device_type_mismatch) 15848 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 15849 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 15850 return; 15851 } 15852 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15853 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 15854 if (!Res) { 15855 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 15856 SourceRange(Loc, Loc)); 15857 ND->addAttr(A); 15858 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15859 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 15860 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 15861 } else if (*Res != MT) { 15862 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 15863 } 15864 } 15865 15866 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 15867 Sema &SemaRef, Decl *D) { 15868 if (!D || !isa<VarDecl>(D)) 15869 return; 15870 auto *VD = cast<VarDecl>(D); 15871 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15872 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15873 if (SemaRef.LangOpts.OpenMP >= 50 && 15874 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 15875 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 15876 VD->hasGlobalStorage()) { 15877 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15878 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15879 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 15880 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 15881 // If a lambda declaration and definition appears between a 15882 // declare target directive and the matching end declare target 15883 // directive, all variables that are captured by the lambda 15884 // expression must also appear in a to clause. 15885 SemaRef.Diag(VD->getLocation(), 15886 diag::err_omp_lambda_capture_in_declare_target_not_to); 15887 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 15888 << VD << 0 << SR; 15889 return; 15890 } 15891 } 15892 if (MapTy.hasValue()) 15893 return; 15894 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 15895 SemaRef.Diag(SL, diag::note_used_here) << SR; 15896 } 15897 15898 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 15899 Sema &SemaRef, DSAStackTy *Stack, 15900 ValueDecl *VD) { 15901 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 15902 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 15903 /*FullCheck=*/false); 15904 } 15905 15906 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 15907 SourceLocation IdLoc) { 15908 if (!D || D->isInvalidDecl()) 15909 return; 15910 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 15911 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 15912 if (auto *VD = dyn_cast<VarDecl>(D)) { 15913 // Only global variables can be marked as declare target. 15914 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 15915 !VD->isStaticDataMember()) 15916 return; 15917 // 2.10.6: threadprivate variable cannot appear in a declare target 15918 // directive. 15919 if (DSAStack->isThreadPrivate(VD)) { 15920 Diag(SL, diag::err_omp_threadprivate_in_target); 15921 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 15922 return; 15923 } 15924 } 15925 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 15926 D = FTD->getTemplatedDecl(); 15927 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 15928 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15929 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 15930 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 15931 Diag(IdLoc, diag::err_omp_function_in_link_clause); 15932 Diag(FD->getLocation(), diag::note_defined_here) << FD; 15933 return; 15934 } 15935 // Mark the function as must be emitted for the device. 15936 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15937 OMPDeclareTargetDeclAttr::getDeviceType(FD); 15938 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 15939 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 15940 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 15941 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 15942 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 15943 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 15944 } 15945 if (auto *VD = dyn_cast<ValueDecl>(D)) { 15946 // Problem if any with var declared with incomplete type will be reported 15947 // as normal, so no need to check it here. 15948 if ((E || !VD->getType()->isIncompleteType()) && 15949 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 15950 return; 15951 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 15952 // Checking declaration inside declare target region. 15953 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 15954 isa<FunctionTemplateDecl>(D)) { 15955 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 15956 Context, OMPDeclareTargetDeclAttr::MT_To, 15957 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 15958 D->addAttr(A); 15959 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15960 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 15961 } 15962 return; 15963 } 15964 } 15965 if (!E) 15966 return; 15967 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 15968 } 15969 15970 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15971 CXXScopeSpec &MapperIdScopeSpec, 15972 DeclarationNameInfo &MapperId, 15973 const OMPVarListLocTy &Locs, 15974 ArrayRef<Expr *> UnresolvedMappers) { 15975 MappableVarListInfo MVLI(VarList); 15976 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15977 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15978 if (MVLI.ProcessedVarList.empty()) 15979 return nullptr; 15980 15981 return OMPToClause::Create( 15982 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15983 MVLI.VarComponents, MVLI.UDMapperList, 15984 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15985 } 15986 15987 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15988 CXXScopeSpec &MapperIdScopeSpec, 15989 DeclarationNameInfo &MapperId, 15990 const OMPVarListLocTy &Locs, 15991 ArrayRef<Expr *> UnresolvedMappers) { 15992 MappableVarListInfo MVLI(VarList); 15993 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15994 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15995 if (MVLI.ProcessedVarList.empty()) 15996 return nullptr; 15997 15998 return OMPFromClause::Create( 15999 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16000 MVLI.VarComponents, MVLI.UDMapperList, 16001 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16002 } 16003 16004 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16005 const OMPVarListLocTy &Locs) { 16006 MappableVarListInfo MVLI(VarList); 16007 SmallVector<Expr *, 8> PrivateCopies; 16008 SmallVector<Expr *, 8> Inits; 16009 16010 for (Expr *RefExpr : VarList) { 16011 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16012 SourceLocation ELoc; 16013 SourceRange ERange; 16014 Expr *SimpleRefExpr = RefExpr; 16015 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16016 if (Res.second) { 16017 // It will be analyzed later. 16018 MVLI.ProcessedVarList.push_back(RefExpr); 16019 PrivateCopies.push_back(nullptr); 16020 Inits.push_back(nullptr); 16021 } 16022 ValueDecl *D = Res.first; 16023 if (!D) 16024 continue; 16025 16026 QualType Type = D->getType(); 16027 Type = Type.getNonReferenceType().getUnqualifiedType(); 16028 16029 auto *VD = dyn_cast<VarDecl>(D); 16030 16031 // Item should be a pointer or reference to pointer. 16032 if (!Type->isPointerType()) { 16033 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16034 << 0 << RefExpr->getSourceRange(); 16035 continue; 16036 } 16037 16038 // Build the private variable and the expression that refers to it. 16039 auto VDPrivate = 16040 buildVarDecl(*this, ELoc, Type, D->getName(), 16041 D->hasAttrs() ? &D->getAttrs() : nullptr, 16042 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16043 if (VDPrivate->isInvalidDecl()) 16044 continue; 16045 16046 CurContext->addDecl(VDPrivate); 16047 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16048 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16049 16050 // Add temporary variable to initialize the private copy of the pointer. 16051 VarDecl *VDInit = 16052 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16053 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16054 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16055 AddInitializerToDecl(VDPrivate, 16056 DefaultLvalueConversion(VDInitRefExpr).get(), 16057 /*DirectInit=*/false); 16058 16059 // If required, build a capture to implement the privatization initialized 16060 // with the current list item value. 16061 DeclRefExpr *Ref = nullptr; 16062 if (!VD) 16063 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16064 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16065 PrivateCopies.push_back(VDPrivateRefExpr); 16066 Inits.push_back(VDInitRefExpr); 16067 16068 // We need to add a data sharing attribute for this variable to make sure it 16069 // is correctly captured. A variable that shows up in a use_device_ptr has 16070 // similar properties of a first private variable. 16071 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16072 16073 // Create a mappable component for the list item. List items in this clause 16074 // only need a component. 16075 MVLI.VarBaseDeclarations.push_back(D); 16076 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16077 MVLI.VarComponents.back().push_back( 16078 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16079 } 16080 16081 if (MVLI.ProcessedVarList.empty()) 16082 return nullptr; 16083 16084 return OMPUseDevicePtrClause::Create( 16085 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16086 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16087 } 16088 16089 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16090 const OMPVarListLocTy &Locs) { 16091 MappableVarListInfo MVLI(VarList); 16092 for (Expr *RefExpr : VarList) { 16093 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16094 SourceLocation ELoc; 16095 SourceRange ERange; 16096 Expr *SimpleRefExpr = RefExpr; 16097 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16098 if (Res.second) { 16099 // It will be analyzed later. 16100 MVLI.ProcessedVarList.push_back(RefExpr); 16101 } 16102 ValueDecl *D = Res.first; 16103 if (!D) 16104 continue; 16105 16106 QualType Type = D->getType(); 16107 // item should be a pointer or array or reference to pointer or array 16108 if (!Type.getNonReferenceType()->isPointerType() && 16109 !Type.getNonReferenceType()->isArrayType()) { 16110 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16111 << 0 << RefExpr->getSourceRange(); 16112 continue; 16113 } 16114 16115 // Check if the declaration in the clause does not show up in any data 16116 // sharing attribute. 16117 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16118 if (isOpenMPPrivate(DVar.CKind)) { 16119 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16120 << getOpenMPClauseName(DVar.CKind) 16121 << getOpenMPClauseName(OMPC_is_device_ptr) 16122 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16123 reportOriginalDsa(*this, DSAStack, D, DVar); 16124 continue; 16125 } 16126 16127 const Expr *ConflictExpr; 16128 if (DSAStack->checkMappableExprComponentListsForDecl( 16129 D, /*CurrentRegionOnly=*/true, 16130 [&ConflictExpr]( 16131 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16132 OpenMPClauseKind) -> bool { 16133 ConflictExpr = R.front().getAssociatedExpression(); 16134 return true; 16135 })) { 16136 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16137 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16138 << ConflictExpr->getSourceRange(); 16139 continue; 16140 } 16141 16142 // Store the components in the stack so that they can be used to check 16143 // against other clauses later on. 16144 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16145 DSAStack->addMappableExpressionComponents( 16146 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16147 16148 // Record the expression we've just processed. 16149 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16150 16151 // Create a mappable component for the list item. List items in this clause 16152 // only need a component. We use a null declaration to signal fields in 16153 // 'this'. 16154 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16155 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16156 "Unexpected device pointer expression!"); 16157 MVLI.VarBaseDeclarations.push_back( 16158 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16159 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16160 MVLI.VarComponents.back().push_back(MC); 16161 } 16162 16163 if (MVLI.ProcessedVarList.empty()) 16164 return nullptr; 16165 16166 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16167 MVLI.VarBaseDeclarations, 16168 MVLI.VarComponents); 16169 } 16170 16171 OMPClause *Sema::ActOnOpenMPAllocateClause( 16172 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16173 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16174 if (Allocator) { 16175 // OpenMP [2.11.4 allocate Clause, Description] 16176 // allocator is an expression of omp_allocator_handle_t type. 16177 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16178 return nullptr; 16179 16180 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16181 if (AllocatorRes.isInvalid()) 16182 return nullptr; 16183 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16184 DSAStack->getOMPAllocatorHandleT(), 16185 Sema::AA_Initializing, 16186 /*AllowExplicit=*/true); 16187 if (AllocatorRes.isInvalid()) 16188 return nullptr; 16189 Allocator = AllocatorRes.get(); 16190 } else { 16191 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16192 // allocate clauses that appear on a target construct or on constructs in a 16193 // target region must specify an allocator expression unless a requires 16194 // directive with the dynamic_allocators clause is present in the same 16195 // compilation unit. 16196 if (LangOpts.OpenMPIsDevice && 16197 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16198 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16199 } 16200 // Analyze and build list of variables. 16201 SmallVector<Expr *, 8> Vars; 16202 for (Expr *RefExpr : VarList) { 16203 assert(RefExpr && "NULL expr in OpenMP private clause."); 16204 SourceLocation ELoc; 16205 SourceRange ERange; 16206 Expr *SimpleRefExpr = RefExpr; 16207 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16208 if (Res.second) { 16209 // It will be analyzed later. 16210 Vars.push_back(RefExpr); 16211 } 16212 ValueDecl *D = Res.first; 16213 if (!D) 16214 continue; 16215 16216 auto *VD = dyn_cast<VarDecl>(D); 16217 DeclRefExpr *Ref = nullptr; 16218 if (!VD && !CurContext->isDependentContext()) 16219 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16220 Vars.push_back((VD || CurContext->isDependentContext()) 16221 ? RefExpr->IgnoreParens() 16222 : Ref); 16223 } 16224 16225 if (Vars.empty()) 16226 return nullptr; 16227 16228 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16229 ColonLoc, EndLoc, Vars); 16230 } 16231