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 Expr *Score = nullptr; 5116 OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown; 5117 if (Data.CtxScore.isUsable()) { 5118 ST = OMPDeclareVariantAttr::ScoreSpecified; 5119 Score = Data.CtxScore.get(); 5120 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5121 !Score->isInstantiationDependent() && 5122 !Score->containsUnexpandedParameterPack()) { 5123 llvm::APSInt Result; 5124 ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result); 5125 if (ICE.isInvalid()) 5126 return; 5127 } 5128 } 5129 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5130 Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, Data.ImplVendor, 5131 SR); 5132 FD->addAttr(NewAttr); 5133 } 5134 5135 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5136 FunctionDecl *Func, 5137 bool MightBeOdrUse) { 5138 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5139 5140 if (!Func->isDependentContext() && Func->hasAttrs()) { 5141 for (OMPDeclareVariantAttr *A : 5142 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5143 // TODO: add checks for active OpenMP context where possible. 5144 Expr *VariantRef = A->getVariantFuncRef(); 5145 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5146 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5147 if (!F->isDefined() && F->isTemplateInstantiation()) 5148 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5149 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5150 } 5151 } 5152 } 5153 5154 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5155 Stmt *AStmt, 5156 SourceLocation StartLoc, 5157 SourceLocation EndLoc) { 5158 if (!AStmt) 5159 return StmtError(); 5160 5161 auto *CS = cast<CapturedStmt>(AStmt); 5162 // 1.2.2 OpenMP Language Terminology 5163 // Structured block - An executable statement with a single entry at the 5164 // top and a single exit at the bottom. 5165 // The point of exit cannot be a branch out of the structured block. 5166 // longjmp() and throw() must not violate the entry/exit criteria. 5167 CS->getCapturedDecl()->setNothrow(); 5168 5169 setFunctionHasBranchProtectedScope(); 5170 5171 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5172 DSAStack->isCancelRegion()); 5173 } 5174 5175 namespace { 5176 /// Iteration space of a single for loop. 5177 struct LoopIterationSpace final { 5178 /// True if the condition operator is the strict compare operator (<, > or 5179 /// !=). 5180 bool IsStrictCompare = false; 5181 /// Condition of the loop. 5182 Expr *PreCond = nullptr; 5183 /// This expression calculates the number of iterations in the loop. 5184 /// It is always possible to calculate it before starting the loop. 5185 Expr *NumIterations = nullptr; 5186 /// The loop counter variable. 5187 Expr *CounterVar = nullptr; 5188 /// Private loop counter variable. 5189 Expr *PrivateCounterVar = nullptr; 5190 /// This is initializer for the initial value of #CounterVar. 5191 Expr *CounterInit = nullptr; 5192 /// This is step for the #CounterVar used to generate its update: 5193 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5194 Expr *CounterStep = nullptr; 5195 /// Should step be subtracted? 5196 bool Subtract = false; 5197 /// Source range of the loop init. 5198 SourceRange InitSrcRange; 5199 /// Source range of the loop condition. 5200 SourceRange CondSrcRange; 5201 /// Source range of the loop increment. 5202 SourceRange IncSrcRange; 5203 /// Minimum value that can have the loop control variable. Used to support 5204 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5205 /// since only such variables can be used in non-loop invariant expressions. 5206 Expr *MinValue = nullptr; 5207 /// Maximum value that can have the loop control variable. Used to support 5208 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5209 /// since only such variables can be used in non-loop invariant expressions. 5210 Expr *MaxValue = nullptr; 5211 /// true, if the lower bound depends on the outer loop control var. 5212 bool IsNonRectangularLB = false; 5213 /// true, if the upper bound depends on the outer loop control var. 5214 bool IsNonRectangularUB = false; 5215 /// Index of the loop this loop depends on and forms non-rectangular loop 5216 /// nest. 5217 unsigned LoopDependentIdx = 0; 5218 /// Final condition for the non-rectangular loop nest support. It is used to 5219 /// check that the number of iterations for this particular counter must be 5220 /// finished. 5221 Expr *FinalCondition = nullptr; 5222 }; 5223 5224 /// Helper class for checking canonical form of the OpenMP loops and 5225 /// extracting iteration space of each loop in the loop nest, that will be used 5226 /// for IR generation. 5227 class OpenMPIterationSpaceChecker { 5228 /// Reference to Sema. 5229 Sema &SemaRef; 5230 /// Data-sharing stack. 5231 DSAStackTy &Stack; 5232 /// A location for diagnostics (when there is no some better location). 5233 SourceLocation DefaultLoc; 5234 /// A location for diagnostics (when increment is not compatible). 5235 SourceLocation ConditionLoc; 5236 /// A source location for referring to loop init later. 5237 SourceRange InitSrcRange; 5238 /// A source location for referring to condition later. 5239 SourceRange ConditionSrcRange; 5240 /// A source location for referring to increment later. 5241 SourceRange IncrementSrcRange; 5242 /// Loop variable. 5243 ValueDecl *LCDecl = nullptr; 5244 /// Reference to loop variable. 5245 Expr *LCRef = nullptr; 5246 /// Lower bound (initializer for the var). 5247 Expr *LB = nullptr; 5248 /// Upper bound. 5249 Expr *UB = nullptr; 5250 /// Loop step (increment). 5251 Expr *Step = nullptr; 5252 /// This flag is true when condition is one of: 5253 /// Var < UB 5254 /// Var <= UB 5255 /// UB > Var 5256 /// UB >= Var 5257 /// This will have no value when the condition is != 5258 llvm::Optional<bool> TestIsLessOp; 5259 /// This flag is true when condition is strict ( < or > ). 5260 bool TestIsStrictOp = false; 5261 /// This flag is true when step is subtracted on each iteration. 5262 bool SubtractStep = false; 5263 /// The outer loop counter this loop depends on (if any). 5264 const ValueDecl *DepDecl = nullptr; 5265 /// Contains number of loop (starts from 1) on which loop counter init 5266 /// expression of this loop depends on. 5267 Optional<unsigned> InitDependOnLC; 5268 /// Contains number of loop (starts from 1) on which loop counter condition 5269 /// expression of this loop depends on. 5270 Optional<unsigned> CondDependOnLC; 5271 /// Checks if the provide statement depends on the loop counter. 5272 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5273 /// Original condition required for checking of the exit condition for 5274 /// non-rectangular loop. 5275 Expr *Condition = nullptr; 5276 5277 public: 5278 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5279 SourceLocation DefaultLoc) 5280 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5281 ConditionLoc(DefaultLoc) {} 5282 /// Check init-expr for canonical loop form and save loop counter 5283 /// variable - #Var and its initialization value - #LB. 5284 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5285 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5286 /// for less/greater and for strict/non-strict comparison. 5287 bool checkAndSetCond(Expr *S); 5288 /// Check incr-expr for canonical loop form and return true if it 5289 /// does not conform, otherwise save loop step (#Step). 5290 bool checkAndSetInc(Expr *S); 5291 /// Return the loop counter variable. 5292 ValueDecl *getLoopDecl() const { return LCDecl; } 5293 /// Return the reference expression to loop counter variable. 5294 Expr *getLoopDeclRefExpr() const { return LCRef; } 5295 /// Source range of the loop init. 5296 SourceRange getInitSrcRange() const { return InitSrcRange; } 5297 /// Source range of the loop condition. 5298 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5299 /// Source range of the loop increment. 5300 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5301 /// True if the step should be subtracted. 5302 bool shouldSubtractStep() const { return SubtractStep; } 5303 /// True, if the compare operator is strict (<, > or !=). 5304 bool isStrictTestOp() const { return TestIsStrictOp; } 5305 /// Build the expression to calculate the number of iterations. 5306 Expr *buildNumIterations( 5307 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5308 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5309 /// Build the precondition expression for the loops. 5310 Expr * 5311 buildPreCond(Scope *S, Expr *Cond, 5312 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5313 /// Build reference expression to the counter be used for codegen. 5314 DeclRefExpr * 5315 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5316 DSAStackTy &DSA) const; 5317 /// Build reference expression to the private counter be used for 5318 /// codegen. 5319 Expr *buildPrivateCounterVar() const; 5320 /// Build initialization of the counter be used for codegen. 5321 Expr *buildCounterInit() const; 5322 /// Build step of the counter be used for codegen. 5323 Expr *buildCounterStep() const; 5324 /// Build loop data with counter value for depend clauses in ordered 5325 /// directives. 5326 Expr * 5327 buildOrderedLoopData(Scope *S, Expr *Counter, 5328 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5329 SourceLocation Loc, Expr *Inc = nullptr, 5330 OverloadedOperatorKind OOK = OO_Amp); 5331 /// Builds the minimum value for the loop counter. 5332 std::pair<Expr *, Expr *> buildMinMaxValues( 5333 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5334 /// Builds final condition for the non-rectangular loops. 5335 Expr *buildFinalCondition(Scope *S) const; 5336 /// Return true if any expression is dependent. 5337 bool dependent() const; 5338 /// Returns true if the initializer forms non-rectangular loop. 5339 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5340 /// Returns true if the condition forms non-rectangular loop. 5341 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5342 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5343 unsigned getLoopDependentIdx() const { 5344 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5345 } 5346 5347 private: 5348 /// Check the right-hand side of an assignment in the increment 5349 /// expression. 5350 bool checkAndSetIncRHS(Expr *RHS); 5351 /// Helper to set loop counter variable and its initializer. 5352 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5353 bool EmitDiags); 5354 /// Helper to set upper bound. 5355 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5356 SourceRange SR, SourceLocation SL); 5357 /// Helper to set loop increment. 5358 bool setStep(Expr *NewStep, bool Subtract); 5359 }; 5360 5361 bool OpenMPIterationSpaceChecker::dependent() const { 5362 if (!LCDecl) { 5363 assert(!LB && !UB && !Step); 5364 return false; 5365 } 5366 return LCDecl->getType()->isDependentType() || 5367 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5368 (Step && Step->isValueDependent()); 5369 } 5370 5371 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5372 Expr *NewLCRefExpr, 5373 Expr *NewLB, bool EmitDiags) { 5374 // State consistency checking to ensure correct usage. 5375 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5376 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5377 if (!NewLCDecl || !NewLB) 5378 return true; 5379 LCDecl = getCanonicalDecl(NewLCDecl); 5380 LCRef = NewLCRefExpr; 5381 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5382 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5383 if ((Ctor->isCopyOrMoveConstructor() || 5384 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5385 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5386 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5387 LB = NewLB; 5388 if (EmitDiags) 5389 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5390 return false; 5391 } 5392 5393 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5394 llvm::Optional<bool> LessOp, 5395 bool StrictOp, SourceRange SR, 5396 SourceLocation SL) { 5397 // State consistency checking to ensure correct usage. 5398 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5399 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5400 if (!NewUB) 5401 return true; 5402 UB = NewUB; 5403 if (LessOp) 5404 TestIsLessOp = LessOp; 5405 TestIsStrictOp = StrictOp; 5406 ConditionSrcRange = SR; 5407 ConditionLoc = SL; 5408 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5409 return false; 5410 } 5411 5412 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5413 // State consistency checking to ensure correct usage. 5414 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5415 if (!NewStep) 5416 return true; 5417 if (!NewStep->isValueDependent()) { 5418 // Check that the step is integer expression. 5419 SourceLocation StepLoc = NewStep->getBeginLoc(); 5420 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5421 StepLoc, getExprAsWritten(NewStep)); 5422 if (Val.isInvalid()) 5423 return true; 5424 NewStep = Val.get(); 5425 5426 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5427 // If test-expr is of form var relational-op b and relational-op is < or 5428 // <= then incr-expr must cause var to increase on each iteration of the 5429 // loop. If test-expr is of form var relational-op b and relational-op is 5430 // > or >= then incr-expr must cause var to decrease on each iteration of 5431 // the loop. 5432 // If test-expr is of form b relational-op var and relational-op is < or 5433 // <= then incr-expr must cause var to decrease on each iteration of the 5434 // loop. If test-expr is of form b relational-op var and relational-op is 5435 // > or >= then incr-expr must cause var to increase on each iteration of 5436 // the loop. 5437 llvm::APSInt Result; 5438 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5439 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5440 bool IsConstNeg = 5441 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5442 bool IsConstPos = 5443 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5444 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5445 5446 // != with increment is treated as <; != with decrement is treated as > 5447 if (!TestIsLessOp.hasValue()) 5448 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5449 if (UB && (IsConstZero || 5450 (TestIsLessOp.getValue() ? 5451 (IsConstNeg || (IsUnsigned && Subtract)) : 5452 (IsConstPos || (IsUnsigned && !Subtract))))) { 5453 SemaRef.Diag(NewStep->getExprLoc(), 5454 diag::err_omp_loop_incr_not_compatible) 5455 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5456 SemaRef.Diag(ConditionLoc, 5457 diag::note_omp_loop_cond_requres_compatible_incr) 5458 << TestIsLessOp.getValue() << ConditionSrcRange; 5459 return true; 5460 } 5461 if (TestIsLessOp.getValue() == Subtract) { 5462 NewStep = 5463 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5464 .get(); 5465 Subtract = !Subtract; 5466 } 5467 } 5468 5469 Step = NewStep; 5470 SubtractStep = Subtract; 5471 return false; 5472 } 5473 5474 namespace { 5475 /// Checker for the non-rectangular loops. Checks if the initializer or 5476 /// condition expression references loop counter variable. 5477 class LoopCounterRefChecker final 5478 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5479 Sema &SemaRef; 5480 DSAStackTy &Stack; 5481 const ValueDecl *CurLCDecl = nullptr; 5482 const ValueDecl *DepDecl = nullptr; 5483 const ValueDecl *PrevDepDecl = nullptr; 5484 bool IsInitializer = true; 5485 unsigned BaseLoopId = 0; 5486 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5487 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5488 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5489 << (IsInitializer ? 0 : 1); 5490 return false; 5491 } 5492 const auto &&Data = Stack.isLoopControlVariable(VD); 5493 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5494 // The type of the loop iterator on which we depend may not have a random 5495 // access iterator type. 5496 if (Data.first && VD->getType()->isRecordType()) { 5497 SmallString<128> Name; 5498 llvm::raw_svector_ostream OS(Name); 5499 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5500 /*Qualified=*/true); 5501 SemaRef.Diag(E->getExprLoc(), 5502 diag::err_omp_wrong_dependency_iterator_type) 5503 << OS.str(); 5504 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5505 return false; 5506 } 5507 if (Data.first && 5508 (DepDecl || (PrevDepDecl && 5509 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5510 if (!DepDecl && PrevDepDecl) 5511 DepDecl = PrevDepDecl; 5512 SmallString<128> Name; 5513 llvm::raw_svector_ostream OS(Name); 5514 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5515 /*Qualified=*/true); 5516 SemaRef.Diag(E->getExprLoc(), 5517 diag::err_omp_invariant_or_linear_dependency) 5518 << OS.str(); 5519 return false; 5520 } 5521 if (Data.first) { 5522 DepDecl = VD; 5523 BaseLoopId = Data.first; 5524 } 5525 return Data.first; 5526 } 5527 5528 public: 5529 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5530 const ValueDecl *VD = E->getDecl(); 5531 if (isa<VarDecl>(VD)) 5532 return checkDecl(E, VD); 5533 return false; 5534 } 5535 bool VisitMemberExpr(const MemberExpr *E) { 5536 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5537 const ValueDecl *VD = E->getMemberDecl(); 5538 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5539 return checkDecl(E, VD); 5540 } 5541 return false; 5542 } 5543 bool VisitStmt(const Stmt *S) { 5544 bool Res = false; 5545 for (const Stmt *Child : S->children()) 5546 Res = (Child && Visit(Child)) || Res; 5547 return Res; 5548 } 5549 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5550 const ValueDecl *CurLCDecl, bool IsInitializer, 5551 const ValueDecl *PrevDepDecl = nullptr) 5552 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5553 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5554 unsigned getBaseLoopId() const { 5555 assert(CurLCDecl && "Expected loop dependency."); 5556 return BaseLoopId; 5557 } 5558 const ValueDecl *getDepDecl() const { 5559 assert(CurLCDecl && "Expected loop dependency."); 5560 return DepDecl; 5561 } 5562 }; 5563 } // namespace 5564 5565 Optional<unsigned> 5566 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5567 bool IsInitializer) { 5568 // Check for the non-rectangular loops. 5569 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5570 DepDecl); 5571 if (LoopStmtChecker.Visit(S)) { 5572 DepDecl = LoopStmtChecker.getDepDecl(); 5573 return LoopStmtChecker.getBaseLoopId(); 5574 } 5575 return llvm::None; 5576 } 5577 5578 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5579 // Check init-expr for canonical loop form and save loop counter 5580 // variable - #Var and its initialization value - #LB. 5581 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5582 // var = lb 5583 // integer-type var = lb 5584 // random-access-iterator-type var = lb 5585 // pointer-type var = lb 5586 // 5587 if (!S) { 5588 if (EmitDiags) { 5589 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5590 } 5591 return true; 5592 } 5593 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5594 if (!ExprTemp->cleanupsHaveSideEffects()) 5595 S = ExprTemp->getSubExpr(); 5596 5597 InitSrcRange = S->getSourceRange(); 5598 if (Expr *E = dyn_cast<Expr>(S)) 5599 S = E->IgnoreParens(); 5600 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5601 if (BO->getOpcode() == BO_Assign) { 5602 Expr *LHS = BO->getLHS()->IgnoreParens(); 5603 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5604 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5605 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5606 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5607 EmitDiags); 5608 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5609 } 5610 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5611 if (ME->isArrow() && 5612 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5613 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5614 EmitDiags); 5615 } 5616 } 5617 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5618 if (DS->isSingleDecl()) { 5619 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5620 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5621 // Accept non-canonical init form here but emit ext. warning. 5622 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5623 SemaRef.Diag(S->getBeginLoc(), 5624 diag::ext_omp_loop_not_canonical_init) 5625 << S->getSourceRange(); 5626 return setLCDeclAndLB( 5627 Var, 5628 buildDeclRefExpr(SemaRef, Var, 5629 Var->getType().getNonReferenceType(), 5630 DS->getBeginLoc()), 5631 Var->getInit(), EmitDiags); 5632 } 5633 } 5634 } 5635 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5636 if (CE->getOperator() == OO_Equal) { 5637 Expr *LHS = CE->getArg(0); 5638 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5639 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5640 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5641 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5642 EmitDiags); 5643 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5644 } 5645 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5646 if (ME->isArrow() && 5647 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5648 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5649 EmitDiags); 5650 } 5651 } 5652 } 5653 5654 if (dependent() || SemaRef.CurContext->isDependentContext()) 5655 return false; 5656 if (EmitDiags) { 5657 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5658 << S->getSourceRange(); 5659 } 5660 return true; 5661 } 5662 5663 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5664 /// variable (which may be the loop variable) if possible. 5665 static const ValueDecl *getInitLCDecl(const Expr *E) { 5666 if (!E) 5667 return nullptr; 5668 E = getExprAsWritten(E); 5669 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5670 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5671 if ((Ctor->isCopyOrMoveConstructor() || 5672 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5673 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5674 E = CE->getArg(0)->IgnoreParenImpCasts(); 5675 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5676 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5677 return getCanonicalDecl(VD); 5678 } 5679 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5680 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5681 return getCanonicalDecl(ME->getMemberDecl()); 5682 return nullptr; 5683 } 5684 5685 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5686 // Check test-expr for canonical form, save upper-bound UB, flags for 5687 // less/greater and for strict/non-strict comparison. 5688 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5689 // var relational-op b 5690 // b relational-op var 5691 // 5692 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5693 if (!S) { 5694 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5695 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5696 return true; 5697 } 5698 Condition = S; 5699 S = getExprAsWritten(S); 5700 SourceLocation CondLoc = S->getBeginLoc(); 5701 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5702 if (BO->isRelationalOp()) { 5703 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5704 return setUB(BO->getRHS(), 5705 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5706 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5707 BO->getSourceRange(), BO->getOperatorLoc()); 5708 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5709 return setUB(BO->getLHS(), 5710 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5711 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5712 BO->getSourceRange(), BO->getOperatorLoc()); 5713 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5714 return setUB( 5715 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5716 /*LessOp=*/llvm::None, 5717 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5718 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5719 if (CE->getNumArgs() == 2) { 5720 auto Op = CE->getOperator(); 5721 switch (Op) { 5722 case OO_Greater: 5723 case OO_GreaterEqual: 5724 case OO_Less: 5725 case OO_LessEqual: 5726 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5727 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5728 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5729 CE->getOperatorLoc()); 5730 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5731 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5732 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5733 CE->getOperatorLoc()); 5734 break; 5735 case OO_ExclaimEqual: 5736 if (IneqCondIsCanonical) 5737 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5738 : CE->getArg(0), 5739 /*LessOp=*/llvm::None, 5740 /*StrictOp=*/true, CE->getSourceRange(), 5741 CE->getOperatorLoc()); 5742 break; 5743 default: 5744 break; 5745 } 5746 } 5747 } 5748 if (dependent() || SemaRef.CurContext->isDependentContext()) 5749 return false; 5750 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5751 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5752 return true; 5753 } 5754 5755 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5756 // RHS of canonical loop form increment can be: 5757 // var + incr 5758 // incr + var 5759 // var - incr 5760 // 5761 RHS = RHS->IgnoreParenImpCasts(); 5762 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5763 if (BO->isAdditiveOp()) { 5764 bool IsAdd = BO->getOpcode() == BO_Add; 5765 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5766 return setStep(BO->getRHS(), !IsAdd); 5767 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5768 return setStep(BO->getLHS(), /*Subtract=*/false); 5769 } 5770 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5771 bool IsAdd = CE->getOperator() == OO_Plus; 5772 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5773 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5774 return setStep(CE->getArg(1), !IsAdd); 5775 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5776 return setStep(CE->getArg(0), /*Subtract=*/false); 5777 } 5778 } 5779 if (dependent() || SemaRef.CurContext->isDependentContext()) 5780 return false; 5781 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5782 << RHS->getSourceRange() << LCDecl; 5783 return true; 5784 } 5785 5786 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5787 // Check incr-expr for canonical loop form and return true if it 5788 // does not conform. 5789 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5790 // ++var 5791 // var++ 5792 // --var 5793 // var-- 5794 // var += incr 5795 // var -= incr 5796 // var = var + incr 5797 // var = incr + var 5798 // var = var - incr 5799 // 5800 if (!S) { 5801 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5802 return true; 5803 } 5804 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5805 if (!ExprTemp->cleanupsHaveSideEffects()) 5806 S = ExprTemp->getSubExpr(); 5807 5808 IncrementSrcRange = S->getSourceRange(); 5809 S = S->IgnoreParens(); 5810 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5811 if (UO->isIncrementDecrementOp() && 5812 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5813 return setStep(SemaRef 5814 .ActOnIntegerConstant(UO->getBeginLoc(), 5815 (UO->isDecrementOp() ? -1 : 1)) 5816 .get(), 5817 /*Subtract=*/false); 5818 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5819 switch (BO->getOpcode()) { 5820 case BO_AddAssign: 5821 case BO_SubAssign: 5822 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5823 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5824 break; 5825 case BO_Assign: 5826 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5827 return checkAndSetIncRHS(BO->getRHS()); 5828 break; 5829 default: 5830 break; 5831 } 5832 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5833 switch (CE->getOperator()) { 5834 case OO_PlusPlus: 5835 case OO_MinusMinus: 5836 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5837 return setStep(SemaRef 5838 .ActOnIntegerConstant( 5839 CE->getBeginLoc(), 5840 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5841 .get(), 5842 /*Subtract=*/false); 5843 break; 5844 case OO_PlusEqual: 5845 case OO_MinusEqual: 5846 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5847 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5848 break; 5849 case OO_Equal: 5850 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5851 return checkAndSetIncRHS(CE->getArg(1)); 5852 break; 5853 default: 5854 break; 5855 } 5856 } 5857 if (dependent() || SemaRef.CurContext->isDependentContext()) 5858 return false; 5859 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5860 << S->getSourceRange() << LCDecl; 5861 return true; 5862 } 5863 5864 static ExprResult 5865 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5866 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5867 if (SemaRef.CurContext->isDependentContext()) 5868 return ExprResult(Capture); 5869 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5870 return SemaRef.PerformImplicitConversion( 5871 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5872 /*AllowExplicit=*/true); 5873 auto I = Captures.find(Capture); 5874 if (I != Captures.end()) 5875 return buildCapture(SemaRef, Capture, I->second); 5876 DeclRefExpr *Ref = nullptr; 5877 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5878 Captures[Capture] = Ref; 5879 return Res; 5880 } 5881 5882 /// Build the expression to calculate the number of iterations. 5883 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5884 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5885 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5886 ExprResult Diff; 5887 QualType VarType = LCDecl->getType().getNonReferenceType(); 5888 if (VarType->isIntegerType() || VarType->isPointerType() || 5889 SemaRef.getLangOpts().CPlusPlus) { 5890 Expr *LBVal = LB; 5891 Expr *UBVal = UB; 5892 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5893 // max(LB(MinVal), LB(MaxVal)) 5894 if (InitDependOnLC) { 5895 const LoopIterationSpace &IS = 5896 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5897 InitDependOnLC.getValueOr( 5898 CondDependOnLC.getValueOr(0))]; 5899 if (!IS.MinValue || !IS.MaxValue) 5900 return nullptr; 5901 // OuterVar = Min 5902 ExprResult MinValue = 5903 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5904 if (!MinValue.isUsable()) 5905 return nullptr; 5906 5907 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5908 IS.CounterVar, MinValue.get()); 5909 if (!LBMinVal.isUsable()) 5910 return nullptr; 5911 // OuterVar = Min, LBVal 5912 LBMinVal = 5913 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5914 if (!LBMinVal.isUsable()) 5915 return nullptr; 5916 // (OuterVar = Min, LBVal) 5917 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5918 if (!LBMinVal.isUsable()) 5919 return nullptr; 5920 5921 // OuterVar = Max 5922 ExprResult MaxValue = 5923 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5924 if (!MaxValue.isUsable()) 5925 return nullptr; 5926 5927 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5928 IS.CounterVar, MaxValue.get()); 5929 if (!LBMaxVal.isUsable()) 5930 return nullptr; 5931 // OuterVar = Max, LBVal 5932 LBMaxVal = 5933 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5934 if (!LBMaxVal.isUsable()) 5935 return nullptr; 5936 // (OuterVar = Max, LBVal) 5937 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5938 if (!LBMaxVal.isUsable()) 5939 return nullptr; 5940 5941 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 5942 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 5943 if (!LBMin || !LBMax) 5944 return nullptr; 5945 // LB(MinVal) < LB(MaxVal) 5946 ExprResult MinLessMaxRes = 5947 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 5948 if (!MinLessMaxRes.isUsable()) 5949 return nullptr; 5950 Expr *MinLessMax = 5951 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 5952 if (!MinLessMax) 5953 return nullptr; 5954 if (TestIsLessOp.getValue()) { 5955 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 5956 // LB(MaxVal)) 5957 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5958 MinLessMax, LBMin, LBMax); 5959 if (!MinLB.isUsable()) 5960 return nullptr; 5961 LBVal = MinLB.get(); 5962 } else { 5963 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 5964 // LB(MaxVal)) 5965 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5966 MinLessMax, LBMax, LBMin); 5967 if (!MaxLB.isUsable()) 5968 return nullptr; 5969 LBVal = MaxLB.get(); 5970 } 5971 } 5972 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 5973 // min(UB(MinVal), UB(MaxVal)) 5974 if (CondDependOnLC) { 5975 const LoopIterationSpace &IS = 5976 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5977 InitDependOnLC.getValueOr( 5978 CondDependOnLC.getValueOr(0))]; 5979 if (!IS.MinValue || !IS.MaxValue) 5980 return nullptr; 5981 // OuterVar = Min 5982 ExprResult MinValue = 5983 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5984 if (!MinValue.isUsable()) 5985 return nullptr; 5986 5987 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5988 IS.CounterVar, MinValue.get()); 5989 if (!UBMinVal.isUsable()) 5990 return nullptr; 5991 // OuterVar = Min, UBVal 5992 UBMinVal = 5993 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 5994 if (!UBMinVal.isUsable()) 5995 return nullptr; 5996 // (OuterVar = Min, UBVal) 5997 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 5998 if (!UBMinVal.isUsable()) 5999 return nullptr; 6000 6001 // OuterVar = Max 6002 ExprResult MaxValue = 6003 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6004 if (!MaxValue.isUsable()) 6005 return nullptr; 6006 6007 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6008 IS.CounterVar, MaxValue.get()); 6009 if (!UBMaxVal.isUsable()) 6010 return nullptr; 6011 // OuterVar = Max, UBVal 6012 UBMaxVal = 6013 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6014 if (!UBMaxVal.isUsable()) 6015 return nullptr; 6016 // (OuterVar = Max, UBVal) 6017 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6018 if (!UBMaxVal.isUsable()) 6019 return nullptr; 6020 6021 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6022 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6023 if (!UBMin || !UBMax) 6024 return nullptr; 6025 // UB(MinVal) > UB(MaxVal) 6026 ExprResult MinGreaterMaxRes = 6027 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6028 if (!MinGreaterMaxRes.isUsable()) 6029 return nullptr; 6030 Expr *MinGreaterMax = 6031 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6032 if (!MinGreaterMax) 6033 return nullptr; 6034 if (TestIsLessOp.getValue()) { 6035 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6036 // UB(MaxVal)) 6037 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6038 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6039 if (!MaxUB.isUsable()) 6040 return nullptr; 6041 UBVal = MaxUB.get(); 6042 } else { 6043 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6044 // UB(MaxVal)) 6045 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6046 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6047 if (!MinUB.isUsable()) 6048 return nullptr; 6049 UBVal = MinUB.get(); 6050 } 6051 } 6052 // Upper - Lower 6053 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6054 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6055 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6056 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6057 if (!Upper || !Lower) 6058 return nullptr; 6059 6060 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6061 6062 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6063 // BuildBinOp already emitted error, this one is to point user to upper 6064 // and lower bound, and to tell what is passed to 'operator-'. 6065 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6066 << Upper->getSourceRange() << Lower->getSourceRange(); 6067 return nullptr; 6068 } 6069 } 6070 6071 if (!Diff.isUsable()) 6072 return nullptr; 6073 6074 // Upper - Lower [- 1] 6075 if (TestIsStrictOp) 6076 Diff = SemaRef.BuildBinOp( 6077 S, DefaultLoc, BO_Sub, Diff.get(), 6078 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6079 if (!Diff.isUsable()) 6080 return nullptr; 6081 6082 // Upper - Lower [- 1] + Step 6083 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6084 if (!NewStep.isUsable()) 6085 return nullptr; 6086 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6087 if (!Diff.isUsable()) 6088 return nullptr; 6089 6090 // Parentheses (for dumping/debugging purposes only). 6091 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6092 if (!Diff.isUsable()) 6093 return nullptr; 6094 6095 // (Upper - Lower [- 1] + Step) / Step 6096 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6097 if (!Diff.isUsable()) 6098 return nullptr; 6099 6100 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6101 QualType Type = Diff.get()->getType(); 6102 ASTContext &C = SemaRef.Context; 6103 bool UseVarType = VarType->hasIntegerRepresentation() && 6104 C.getTypeSize(Type) > C.getTypeSize(VarType); 6105 if (!Type->isIntegerType() || UseVarType) { 6106 unsigned NewSize = 6107 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6108 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6109 : Type->hasSignedIntegerRepresentation(); 6110 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6111 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6112 Diff = SemaRef.PerformImplicitConversion( 6113 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6114 if (!Diff.isUsable()) 6115 return nullptr; 6116 } 6117 } 6118 if (LimitedType) { 6119 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6120 if (NewSize != C.getTypeSize(Type)) { 6121 if (NewSize < C.getTypeSize(Type)) { 6122 assert(NewSize == 64 && "incorrect loop var size"); 6123 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6124 << InitSrcRange << ConditionSrcRange; 6125 } 6126 QualType NewType = C.getIntTypeForBitwidth( 6127 NewSize, Type->hasSignedIntegerRepresentation() || 6128 C.getTypeSize(Type) < NewSize); 6129 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6130 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6131 Sema::AA_Converting, true); 6132 if (!Diff.isUsable()) 6133 return nullptr; 6134 } 6135 } 6136 } 6137 6138 return Diff.get(); 6139 } 6140 6141 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6142 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6143 // Do not build for iterators, they cannot be used in non-rectangular loop 6144 // nests. 6145 if (LCDecl->getType()->isRecordType()) 6146 return std::make_pair(nullptr, nullptr); 6147 // If we subtract, the min is in the condition, otherwise the min is in the 6148 // init value. 6149 Expr *MinExpr = nullptr; 6150 Expr *MaxExpr = nullptr; 6151 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6152 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6153 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6154 : CondDependOnLC.hasValue(); 6155 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6156 : InitDependOnLC.hasValue(); 6157 Expr *Lower = 6158 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6159 Expr *Upper = 6160 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6161 if (!Upper || !Lower) 6162 return std::make_pair(nullptr, nullptr); 6163 6164 if (TestIsLessOp.getValue()) 6165 MinExpr = Lower; 6166 else 6167 MaxExpr = Upper; 6168 6169 // Build minimum/maximum value based on number of iterations. 6170 ExprResult Diff; 6171 QualType VarType = LCDecl->getType().getNonReferenceType(); 6172 6173 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6174 if (!Diff.isUsable()) 6175 return std::make_pair(nullptr, nullptr); 6176 6177 // Upper - Lower [- 1] 6178 if (TestIsStrictOp) 6179 Diff = SemaRef.BuildBinOp( 6180 S, DefaultLoc, BO_Sub, Diff.get(), 6181 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6182 if (!Diff.isUsable()) 6183 return std::make_pair(nullptr, nullptr); 6184 6185 // Upper - Lower [- 1] + Step 6186 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6187 if (!NewStep.isUsable()) 6188 return std::make_pair(nullptr, nullptr); 6189 6190 // Parentheses (for dumping/debugging purposes only). 6191 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6192 if (!Diff.isUsable()) 6193 return std::make_pair(nullptr, nullptr); 6194 6195 // (Upper - Lower [- 1]) / Step 6196 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6197 if (!Diff.isUsable()) 6198 return std::make_pair(nullptr, nullptr); 6199 6200 // ((Upper - Lower [- 1]) / Step) * Step 6201 // Parentheses (for dumping/debugging purposes only). 6202 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6203 if (!Diff.isUsable()) 6204 return std::make_pair(nullptr, nullptr); 6205 6206 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6207 if (!Diff.isUsable()) 6208 return std::make_pair(nullptr, nullptr); 6209 6210 // Convert to the original type or ptrdiff_t, if original type is pointer. 6211 if (!VarType->isAnyPointerType() && 6212 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6213 Diff = SemaRef.PerformImplicitConversion( 6214 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6215 } else if (VarType->isAnyPointerType() && 6216 !SemaRef.Context.hasSameType( 6217 Diff.get()->getType(), 6218 SemaRef.Context.getUnsignedPointerDiffType())) { 6219 Diff = SemaRef.PerformImplicitConversion( 6220 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6221 Sema::AA_Converting, /*AllowExplicit=*/true); 6222 } 6223 if (!Diff.isUsable()) 6224 return std::make_pair(nullptr, nullptr); 6225 6226 // Parentheses (for dumping/debugging purposes only). 6227 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6228 if (!Diff.isUsable()) 6229 return std::make_pair(nullptr, nullptr); 6230 6231 if (TestIsLessOp.getValue()) { 6232 // MinExpr = Lower; 6233 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6234 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6235 if (!Diff.isUsable()) 6236 return std::make_pair(nullptr, nullptr); 6237 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6238 if (!Diff.isUsable()) 6239 return std::make_pair(nullptr, nullptr); 6240 MaxExpr = Diff.get(); 6241 } else { 6242 // MaxExpr = Upper; 6243 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6244 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6245 if (!Diff.isUsable()) 6246 return std::make_pair(nullptr, nullptr); 6247 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6248 if (!Diff.isUsable()) 6249 return std::make_pair(nullptr, nullptr); 6250 MinExpr = Diff.get(); 6251 } 6252 6253 return std::make_pair(MinExpr, MaxExpr); 6254 } 6255 6256 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6257 if (InitDependOnLC || CondDependOnLC) 6258 return Condition; 6259 return nullptr; 6260 } 6261 6262 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6263 Scope *S, Expr *Cond, 6264 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6265 // Do not build a precondition when the condition/initialization is dependent 6266 // to prevent pessimistic early loop exit. 6267 // TODO: this can be improved by calculating min/max values but not sure that 6268 // it will be very effective. 6269 if (CondDependOnLC || InitDependOnLC) 6270 return SemaRef.PerformImplicitConversion( 6271 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6272 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6273 /*AllowExplicit=*/true).get(); 6274 6275 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6276 Sema::TentativeAnalysisScope Trap(SemaRef); 6277 6278 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6279 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6280 if (!NewLB.isUsable() || !NewUB.isUsable()) 6281 return nullptr; 6282 6283 ExprResult CondExpr = 6284 SemaRef.BuildBinOp(S, DefaultLoc, 6285 TestIsLessOp.getValue() ? 6286 (TestIsStrictOp ? BO_LT : BO_LE) : 6287 (TestIsStrictOp ? BO_GT : BO_GE), 6288 NewLB.get(), NewUB.get()); 6289 if (CondExpr.isUsable()) { 6290 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6291 SemaRef.Context.BoolTy)) 6292 CondExpr = SemaRef.PerformImplicitConversion( 6293 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6294 /*AllowExplicit=*/true); 6295 } 6296 6297 // Otherwise use original loop condition and evaluate it in runtime. 6298 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6299 } 6300 6301 /// Build reference expression to the counter be used for codegen. 6302 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6303 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6304 DSAStackTy &DSA) const { 6305 auto *VD = dyn_cast<VarDecl>(LCDecl); 6306 if (!VD) { 6307 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6308 DeclRefExpr *Ref = buildDeclRefExpr( 6309 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6310 const DSAStackTy::DSAVarData Data = 6311 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6312 // If the loop control decl is explicitly marked as private, do not mark it 6313 // as captured again. 6314 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6315 Captures.insert(std::make_pair(LCRef, Ref)); 6316 return Ref; 6317 } 6318 return cast<DeclRefExpr>(LCRef); 6319 } 6320 6321 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6322 if (LCDecl && !LCDecl->isInvalidDecl()) { 6323 QualType Type = LCDecl->getType().getNonReferenceType(); 6324 VarDecl *PrivateVar = buildVarDecl( 6325 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6326 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6327 isa<VarDecl>(LCDecl) 6328 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6329 : nullptr); 6330 if (PrivateVar->isInvalidDecl()) 6331 return nullptr; 6332 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6333 } 6334 return nullptr; 6335 } 6336 6337 /// Build initialization of the counter to be used for codegen. 6338 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6339 6340 /// Build step of the counter be used for codegen. 6341 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6342 6343 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6344 Scope *S, Expr *Counter, 6345 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6346 Expr *Inc, OverloadedOperatorKind OOK) { 6347 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6348 if (!Cnt) 6349 return nullptr; 6350 if (Inc) { 6351 assert((OOK == OO_Plus || OOK == OO_Minus) && 6352 "Expected only + or - operations for depend clauses."); 6353 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6354 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6355 if (!Cnt) 6356 return nullptr; 6357 } 6358 ExprResult Diff; 6359 QualType VarType = LCDecl->getType().getNonReferenceType(); 6360 if (VarType->isIntegerType() || VarType->isPointerType() || 6361 SemaRef.getLangOpts().CPlusPlus) { 6362 // Upper - Lower 6363 Expr *Upper = TestIsLessOp.getValue() 6364 ? Cnt 6365 : tryBuildCapture(SemaRef, UB, Captures).get(); 6366 Expr *Lower = TestIsLessOp.getValue() 6367 ? tryBuildCapture(SemaRef, LB, Captures).get() 6368 : Cnt; 6369 if (!Upper || !Lower) 6370 return nullptr; 6371 6372 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6373 6374 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6375 // BuildBinOp already emitted error, this one is to point user to upper 6376 // and lower bound, and to tell what is passed to 'operator-'. 6377 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6378 << Upper->getSourceRange() << Lower->getSourceRange(); 6379 return nullptr; 6380 } 6381 } 6382 6383 if (!Diff.isUsable()) 6384 return nullptr; 6385 6386 // Parentheses (for dumping/debugging purposes only). 6387 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6388 if (!Diff.isUsable()) 6389 return nullptr; 6390 6391 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6392 if (!NewStep.isUsable()) 6393 return nullptr; 6394 // (Upper - Lower) / Step 6395 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6396 if (!Diff.isUsable()) 6397 return nullptr; 6398 6399 return Diff.get(); 6400 } 6401 } // namespace 6402 6403 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6404 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6405 assert(Init && "Expected loop in canonical form."); 6406 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6407 if (AssociatedLoops > 0 && 6408 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6409 DSAStack->loopStart(); 6410 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6411 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6412 if (ValueDecl *D = ISC.getLoopDecl()) { 6413 auto *VD = dyn_cast<VarDecl>(D); 6414 DeclRefExpr *PrivateRef = nullptr; 6415 if (!VD) { 6416 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6417 VD = Private; 6418 } else { 6419 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6420 /*WithInit=*/false); 6421 VD = cast<VarDecl>(PrivateRef->getDecl()); 6422 } 6423 } 6424 DSAStack->addLoopControlVariable(D, VD); 6425 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6426 if (LD != D->getCanonicalDecl()) { 6427 DSAStack->resetPossibleLoopCounter(); 6428 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6429 MarkDeclarationsReferencedInExpr( 6430 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6431 Var->getType().getNonLValueExprType(Context), 6432 ForLoc, /*RefersToCapture=*/true)); 6433 } 6434 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6435 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6436 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6437 // associated for-loop of a simd construct with just one associated 6438 // for-loop may be listed in a linear clause with a constant-linear-step 6439 // that is the increment of the associated for-loop. The loop iteration 6440 // variable(s) in the associated for-loop(s) of a for or parallel for 6441 // construct may be listed in a private or lastprivate clause. 6442 DSAStackTy::DSAVarData DVar = 6443 DSAStack->getTopDSA(D, /*FromParent=*/false); 6444 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6445 // is declared in the loop and it is predetermined as a private. 6446 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6447 OpenMPClauseKind PredeterminedCKind = 6448 isOpenMPSimdDirective(DKind) 6449 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6450 : OMPC_private; 6451 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6452 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6453 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6454 DVar.CKind != OMPC_private))) || 6455 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6456 isOpenMPDistributeDirective(DKind)) && 6457 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6458 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6459 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6460 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6461 << getOpenMPClauseName(DVar.CKind) 6462 << getOpenMPDirectiveName(DKind) 6463 << getOpenMPClauseName(PredeterminedCKind); 6464 if (DVar.RefExpr == nullptr) 6465 DVar.CKind = PredeterminedCKind; 6466 reportOriginalDsa(*this, DSAStack, D, DVar, 6467 /*IsLoopIterVar=*/true); 6468 } else if (LoopDeclRefExpr) { 6469 // Make the loop iteration variable private (for worksharing 6470 // constructs), linear (for simd directives with the only one 6471 // associated loop) or lastprivate (for simd directives with several 6472 // collapsed or ordered loops). 6473 if (DVar.CKind == OMPC_unknown) 6474 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6475 PrivateRef); 6476 } 6477 } 6478 } 6479 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6480 } 6481 } 6482 6483 /// Called on a for stmt to check and extract its iteration space 6484 /// for further processing (such as collapsing). 6485 static bool checkOpenMPIterationSpace( 6486 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6487 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6488 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6489 Expr *OrderedLoopCountExpr, 6490 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6491 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6492 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6493 // OpenMP [2.6, Canonical Loop Form] 6494 // for (init-expr; test-expr; incr-expr) structured-block 6495 auto *For = dyn_cast_or_null<ForStmt>(S); 6496 if (!For) { 6497 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6498 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6499 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6500 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6501 if (TotalNestedLoopCount > 1) { 6502 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6503 SemaRef.Diag(DSA.getConstructLoc(), 6504 diag::note_omp_collapse_ordered_expr) 6505 << 2 << CollapseLoopCountExpr->getSourceRange() 6506 << OrderedLoopCountExpr->getSourceRange(); 6507 else if (CollapseLoopCountExpr) 6508 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6509 diag::note_omp_collapse_ordered_expr) 6510 << 0 << CollapseLoopCountExpr->getSourceRange(); 6511 else 6512 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6513 diag::note_omp_collapse_ordered_expr) 6514 << 1 << OrderedLoopCountExpr->getSourceRange(); 6515 } 6516 return true; 6517 } 6518 assert(For->getBody()); 6519 6520 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 6521 6522 // Check init. 6523 Stmt *Init = For->getInit(); 6524 if (ISC.checkAndSetInit(Init)) 6525 return true; 6526 6527 bool HasErrors = false; 6528 6529 // Check loop variable's type. 6530 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6531 // OpenMP [2.6, Canonical Loop Form] 6532 // Var is one of the following: 6533 // A variable of signed or unsigned integer type. 6534 // For C++, a variable of a random access iterator type. 6535 // For C, a variable of a pointer type. 6536 QualType VarType = LCDecl->getType().getNonReferenceType(); 6537 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6538 !VarType->isPointerType() && 6539 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6540 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6541 << SemaRef.getLangOpts().CPlusPlus; 6542 HasErrors = true; 6543 } 6544 6545 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6546 // a Construct 6547 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6548 // parallel for construct is (are) private. 6549 // The loop iteration variable in the associated for-loop of a simd 6550 // construct with just one associated for-loop is linear with a 6551 // constant-linear-step that is the increment of the associated for-loop. 6552 // Exclude loop var from the list of variables with implicitly defined data 6553 // sharing attributes. 6554 VarsWithImplicitDSA.erase(LCDecl); 6555 6556 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6557 6558 // Check test-expr. 6559 HasErrors |= ISC.checkAndSetCond(For->getCond()); 6560 6561 // Check incr-expr. 6562 HasErrors |= ISC.checkAndSetInc(For->getInc()); 6563 } 6564 6565 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6566 return HasErrors; 6567 6568 // Build the loop's iteration space representation. 6569 ResultIterSpaces[CurrentNestedLoopCount].PreCond = 6570 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 6571 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6572 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6573 (isOpenMPWorksharingDirective(DKind) || 6574 isOpenMPTaskLoopDirective(DKind) || 6575 isOpenMPDistributeDirective(DKind)), 6576 Captures); 6577 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6578 ISC.buildCounterVar(Captures, DSA); 6579 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6580 ISC.buildPrivateCounterVar(); 6581 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6582 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6583 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6584 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6585 ISC.getConditionSrcRange(); 6586 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6587 ISC.getIncrementSrcRange(); 6588 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6589 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6590 ISC.isStrictTestOp(); 6591 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6592 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6593 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6594 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6595 ISC.buildFinalCondition(DSA.getCurScope()); 6596 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6597 ISC.doesInitDependOnLC(); 6598 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6599 ISC.doesCondDependOnLC(); 6600 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6601 ISC.getLoopDependentIdx(); 6602 6603 HasErrors |= 6604 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6605 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6606 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6607 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6608 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6609 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6610 if (!HasErrors && DSA.isOrderedRegion()) { 6611 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6612 if (CurrentNestedLoopCount < 6613 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6614 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6615 CurrentNestedLoopCount, 6616 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6617 DSA.getOrderedRegionParam().second->setLoopCounter( 6618 CurrentNestedLoopCount, 6619 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6620 } 6621 } 6622 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6623 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6624 // Erroneous case - clause has some problems. 6625 continue; 6626 } 6627 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6628 Pair.second.size() <= CurrentNestedLoopCount) { 6629 // Erroneous case - clause has some problems. 6630 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6631 continue; 6632 } 6633 Expr *CntValue; 6634 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6635 CntValue = ISC.buildOrderedLoopData( 6636 DSA.getCurScope(), 6637 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6638 Pair.first->getDependencyLoc()); 6639 else 6640 CntValue = ISC.buildOrderedLoopData( 6641 DSA.getCurScope(), 6642 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6643 Pair.first->getDependencyLoc(), 6644 Pair.second[CurrentNestedLoopCount].first, 6645 Pair.second[CurrentNestedLoopCount].second); 6646 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6647 } 6648 } 6649 6650 return HasErrors; 6651 } 6652 6653 /// Build 'VarRef = Start. 6654 static ExprResult 6655 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6656 ExprResult Start, bool IsNonRectangularLB, 6657 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6658 // Build 'VarRef = Start. 6659 ExprResult NewStart = IsNonRectangularLB 6660 ? Start.get() 6661 : tryBuildCapture(SemaRef, Start.get(), Captures); 6662 if (!NewStart.isUsable()) 6663 return ExprError(); 6664 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6665 VarRef.get()->getType())) { 6666 NewStart = SemaRef.PerformImplicitConversion( 6667 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6668 /*AllowExplicit=*/true); 6669 if (!NewStart.isUsable()) 6670 return ExprError(); 6671 } 6672 6673 ExprResult Init = 6674 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6675 return Init; 6676 } 6677 6678 /// Build 'VarRef = Start + Iter * Step'. 6679 static ExprResult buildCounterUpdate( 6680 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6681 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6682 bool IsNonRectangularLB, 6683 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6684 // Add parentheses (for debugging purposes only). 6685 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6686 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6687 !Step.isUsable()) 6688 return ExprError(); 6689 6690 ExprResult NewStep = Step; 6691 if (Captures) 6692 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6693 if (NewStep.isInvalid()) 6694 return ExprError(); 6695 ExprResult Update = 6696 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6697 if (!Update.isUsable()) 6698 return ExprError(); 6699 6700 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6701 // 'VarRef = Start (+|-) Iter * Step'. 6702 if (!Start.isUsable()) 6703 return ExprError(); 6704 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6705 if (!NewStart.isUsable()) 6706 return ExprError(); 6707 if (Captures && !IsNonRectangularLB) 6708 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6709 if (NewStart.isInvalid()) 6710 return ExprError(); 6711 6712 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6713 ExprResult SavedUpdate = Update; 6714 ExprResult UpdateVal; 6715 if (VarRef.get()->getType()->isOverloadableType() || 6716 NewStart.get()->getType()->isOverloadableType() || 6717 Update.get()->getType()->isOverloadableType()) { 6718 Sema::TentativeAnalysisScope Trap(SemaRef); 6719 6720 Update = 6721 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6722 if (Update.isUsable()) { 6723 UpdateVal = 6724 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6725 VarRef.get(), SavedUpdate.get()); 6726 if (UpdateVal.isUsable()) { 6727 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6728 UpdateVal.get()); 6729 } 6730 } 6731 } 6732 6733 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6734 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6735 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6736 NewStart.get(), SavedUpdate.get()); 6737 if (!Update.isUsable()) 6738 return ExprError(); 6739 6740 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6741 VarRef.get()->getType())) { 6742 Update = SemaRef.PerformImplicitConversion( 6743 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6744 if (!Update.isUsable()) 6745 return ExprError(); 6746 } 6747 6748 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6749 } 6750 return Update; 6751 } 6752 6753 /// Convert integer expression \a E to make it have at least \a Bits 6754 /// bits. 6755 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6756 if (E == nullptr) 6757 return ExprError(); 6758 ASTContext &C = SemaRef.Context; 6759 QualType OldType = E->getType(); 6760 unsigned HasBits = C.getTypeSize(OldType); 6761 if (HasBits >= Bits) 6762 return ExprResult(E); 6763 // OK to convert to signed, because new type has more bits than old. 6764 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6765 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6766 true); 6767 } 6768 6769 /// Check if the given expression \a E is a constant integer that fits 6770 /// into \a Bits bits. 6771 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6772 if (E == nullptr) 6773 return false; 6774 llvm::APSInt Result; 6775 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6776 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6777 return false; 6778 } 6779 6780 /// Build preinits statement for the given declarations. 6781 static Stmt *buildPreInits(ASTContext &Context, 6782 MutableArrayRef<Decl *> PreInits) { 6783 if (!PreInits.empty()) { 6784 return new (Context) DeclStmt( 6785 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6786 SourceLocation(), SourceLocation()); 6787 } 6788 return nullptr; 6789 } 6790 6791 /// Build preinits statement for the given declarations. 6792 static Stmt * 6793 buildPreInits(ASTContext &Context, 6794 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6795 if (!Captures.empty()) { 6796 SmallVector<Decl *, 16> PreInits; 6797 for (const auto &Pair : Captures) 6798 PreInits.push_back(Pair.second->getDecl()); 6799 return buildPreInits(Context, PreInits); 6800 } 6801 return nullptr; 6802 } 6803 6804 /// Build postupdate expression for the given list of postupdates expressions. 6805 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6806 Expr *PostUpdate = nullptr; 6807 if (!PostUpdates.empty()) { 6808 for (Expr *E : PostUpdates) { 6809 Expr *ConvE = S.BuildCStyleCastExpr( 6810 E->getExprLoc(), 6811 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6812 E->getExprLoc(), E) 6813 .get(); 6814 PostUpdate = PostUpdate 6815 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6816 PostUpdate, ConvE) 6817 .get() 6818 : ConvE; 6819 } 6820 } 6821 return PostUpdate; 6822 } 6823 6824 /// Called on a for stmt to check itself and nested loops (if any). 6825 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6826 /// number of collapsed loops otherwise. 6827 static unsigned 6828 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6829 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6830 DSAStackTy &DSA, 6831 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6832 OMPLoopDirective::HelperExprs &Built) { 6833 unsigned NestedLoopCount = 1; 6834 if (CollapseLoopCountExpr) { 6835 // Found 'collapse' clause - calculate collapse number. 6836 Expr::EvalResult Result; 6837 if (!CollapseLoopCountExpr->isValueDependent() && 6838 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6839 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6840 } else { 6841 Built.clear(/*Size=*/1); 6842 return 1; 6843 } 6844 } 6845 unsigned OrderedLoopCount = 1; 6846 if (OrderedLoopCountExpr) { 6847 // Found 'ordered' clause - calculate collapse number. 6848 Expr::EvalResult EVResult; 6849 if (!OrderedLoopCountExpr->isValueDependent() && 6850 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6851 SemaRef.getASTContext())) { 6852 llvm::APSInt Result = EVResult.Val.getInt(); 6853 if (Result.getLimitedValue() < NestedLoopCount) { 6854 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6855 diag::err_omp_wrong_ordered_loop_count) 6856 << OrderedLoopCountExpr->getSourceRange(); 6857 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6858 diag::note_collapse_loop_count) 6859 << CollapseLoopCountExpr->getSourceRange(); 6860 } 6861 OrderedLoopCount = Result.getLimitedValue(); 6862 } else { 6863 Built.clear(/*Size=*/1); 6864 return 1; 6865 } 6866 } 6867 // This is helper routine for loop directives (e.g., 'for', 'simd', 6868 // 'for simd', etc.). 6869 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6870 SmallVector<LoopIterationSpace, 4> IterSpaces( 6871 std::max(OrderedLoopCount, NestedLoopCount)); 6872 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6873 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6874 if (checkOpenMPIterationSpace( 6875 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6876 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6877 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6878 return 0; 6879 // Move on to the next nested for loop, or to the loop body. 6880 // OpenMP [2.8.1, simd construct, Restrictions] 6881 // All loops associated with the construct must be perfectly nested; that 6882 // is, there must be no intervening code nor any OpenMP directive between 6883 // any two loops. 6884 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6885 } 6886 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6887 if (checkOpenMPIterationSpace( 6888 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6889 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6890 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6891 return 0; 6892 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6893 // Handle initialization of captured loop iterator variables. 6894 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6895 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6896 Captures[DRE] = DRE; 6897 } 6898 } 6899 // Move on to the next nested for loop, or to the loop body. 6900 // OpenMP [2.8.1, simd construct, Restrictions] 6901 // All loops associated with the construct must be perfectly nested; that 6902 // is, there must be no intervening code nor any OpenMP directive between 6903 // any two loops. 6904 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6905 } 6906 6907 Built.clear(/* size */ NestedLoopCount); 6908 6909 if (SemaRef.CurContext->isDependentContext()) 6910 return NestedLoopCount; 6911 6912 // An example of what is generated for the following code: 6913 // 6914 // #pragma omp simd collapse(2) ordered(2) 6915 // for (i = 0; i < NI; ++i) 6916 // for (k = 0; k < NK; ++k) 6917 // for (j = J0; j < NJ; j+=2) { 6918 // <loop body> 6919 // } 6920 // 6921 // We generate the code below. 6922 // Note: the loop body may be outlined in CodeGen. 6923 // Note: some counters may be C++ classes, operator- is used to find number of 6924 // iterations and operator+= to calculate counter value. 6925 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6926 // or i64 is currently supported). 6927 // 6928 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6929 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6930 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6931 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6932 // // similar updates for vars in clauses (e.g. 'linear') 6933 // <loop body (using local i and j)> 6934 // } 6935 // i = NI; // assign final values of counters 6936 // j = NJ; 6937 // 6938 6939 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6940 // the iteration counts of the collapsed for loops. 6941 // Precondition tests if there is at least one iteration (all conditions are 6942 // true). 6943 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6944 Expr *N0 = IterSpaces[0].NumIterations; 6945 ExprResult LastIteration32 = 6946 widenIterationCount(/*Bits=*/32, 6947 SemaRef 6948 .PerformImplicitConversion( 6949 N0->IgnoreImpCasts(), N0->getType(), 6950 Sema::AA_Converting, /*AllowExplicit=*/true) 6951 .get(), 6952 SemaRef); 6953 ExprResult LastIteration64 = widenIterationCount( 6954 /*Bits=*/64, 6955 SemaRef 6956 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6957 Sema::AA_Converting, 6958 /*AllowExplicit=*/true) 6959 .get(), 6960 SemaRef); 6961 6962 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6963 return NestedLoopCount; 6964 6965 ASTContext &C = SemaRef.Context; 6966 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6967 6968 Scope *CurScope = DSA.getCurScope(); 6969 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6970 if (PreCond.isUsable()) { 6971 PreCond = 6972 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6973 PreCond.get(), IterSpaces[Cnt].PreCond); 6974 } 6975 Expr *N = IterSpaces[Cnt].NumIterations; 6976 SourceLocation Loc = N->getExprLoc(); 6977 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6978 if (LastIteration32.isUsable()) 6979 LastIteration32 = SemaRef.BuildBinOp( 6980 CurScope, Loc, BO_Mul, LastIteration32.get(), 6981 SemaRef 6982 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6983 Sema::AA_Converting, 6984 /*AllowExplicit=*/true) 6985 .get()); 6986 if (LastIteration64.isUsable()) 6987 LastIteration64 = SemaRef.BuildBinOp( 6988 CurScope, Loc, BO_Mul, LastIteration64.get(), 6989 SemaRef 6990 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6991 Sema::AA_Converting, 6992 /*AllowExplicit=*/true) 6993 .get()); 6994 } 6995 6996 // Choose either the 32-bit or 64-bit version. 6997 ExprResult LastIteration = LastIteration64; 6998 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6999 (LastIteration32.isUsable() && 7000 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7001 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7002 fitsInto( 7003 /*Bits=*/32, 7004 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7005 LastIteration64.get(), SemaRef)))) 7006 LastIteration = LastIteration32; 7007 QualType VType = LastIteration.get()->getType(); 7008 QualType RealVType = VType; 7009 QualType StrideVType = VType; 7010 if (isOpenMPTaskLoopDirective(DKind)) { 7011 VType = 7012 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7013 StrideVType = 7014 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7015 } 7016 7017 if (!LastIteration.isUsable()) 7018 return 0; 7019 7020 // Save the number of iterations. 7021 ExprResult NumIterations = LastIteration; 7022 { 7023 LastIteration = SemaRef.BuildBinOp( 7024 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7025 LastIteration.get(), 7026 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7027 if (!LastIteration.isUsable()) 7028 return 0; 7029 } 7030 7031 // Calculate the last iteration number beforehand instead of doing this on 7032 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7033 llvm::APSInt Result; 7034 bool IsConstant = 7035 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7036 ExprResult CalcLastIteration; 7037 if (!IsConstant) { 7038 ExprResult SaveRef = 7039 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7040 LastIteration = SaveRef; 7041 7042 // Prepare SaveRef + 1. 7043 NumIterations = SemaRef.BuildBinOp( 7044 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7045 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7046 if (!NumIterations.isUsable()) 7047 return 0; 7048 } 7049 7050 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7051 7052 // Build variables passed into runtime, necessary for worksharing directives. 7053 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7054 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7055 isOpenMPDistributeDirective(DKind)) { 7056 // Lower bound variable, initialized with zero. 7057 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7058 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7059 SemaRef.AddInitializerToDecl(LBDecl, 7060 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7061 /*DirectInit*/ false); 7062 7063 // Upper bound variable, initialized with last iteration number. 7064 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7065 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7066 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7067 /*DirectInit*/ false); 7068 7069 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7070 // This will be used to implement clause 'lastprivate'. 7071 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7072 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7073 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7074 SemaRef.AddInitializerToDecl(ILDecl, 7075 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7076 /*DirectInit*/ false); 7077 7078 // Stride variable returned by runtime (we initialize it to 1 by default). 7079 VarDecl *STDecl = 7080 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7081 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7082 SemaRef.AddInitializerToDecl(STDecl, 7083 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7084 /*DirectInit*/ false); 7085 7086 // Build expression: UB = min(UB, LastIteration) 7087 // It is necessary for CodeGen of directives with static scheduling. 7088 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7089 UB.get(), LastIteration.get()); 7090 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7091 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7092 LastIteration.get(), UB.get()); 7093 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7094 CondOp.get()); 7095 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7096 7097 // If we have a combined directive that combines 'distribute', 'for' or 7098 // 'simd' we need to be able to access the bounds of the schedule of the 7099 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7100 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7101 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7102 // Lower bound variable, initialized with zero. 7103 VarDecl *CombLBDecl = 7104 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7105 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7106 SemaRef.AddInitializerToDecl( 7107 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7108 /*DirectInit*/ false); 7109 7110 // Upper bound variable, initialized with last iteration number. 7111 VarDecl *CombUBDecl = 7112 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7113 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7114 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7115 /*DirectInit*/ false); 7116 7117 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7118 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7119 ExprResult CombCondOp = 7120 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7121 LastIteration.get(), CombUB.get()); 7122 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7123 CombCondOp.get()); 7124 CombEUB = 7125 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7126 7127 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7128 // We expect to have at least 2 more parameters than the 'parallel' 7129 // directive does - the lower and upper bounds of the previous schedule. 7130 assert(CD->getNumParams() >= 4 && 7131 "Unexpected number of parameters in loop combined directive"); 7132 7133 // Set the proper type for the bounds given what we learned from the 7134 // enclosed loops. 7135 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7136 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7137 7138 // Previous lower and upper bounds are obtained from the region 7139 // parameters. 7140 PrevLB = 7141 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7142 PrevUB = 7143 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7144 } 7145 } 7146 7147 // Build the iteration variable and its initialization before loop. 7148 ExprResult IV; 7149 ExprResult Init, CombInit; 7150 { 7151 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7152 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7153 Expr *RHS = 7154 (isOpenMPWorksharingDirective(DKind) || 7155 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7156 ? LB.get() 7157 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7158 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7159 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7160 7161 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7162 Expr *CombRHS = 7163 (isOpenMPWorksharingDirective(DKind) || 7164 isOpenMPTaskLoopDirective(DKind) || 7165 isOpenMPDistributeDirective(DKind)) 7166 ? CombLB.get() 7167 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7168 CombInit = 7169 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7170 CombInit = 7171 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7172 } 7173 } 7174 7175 bool UseStrictCompare = 7176 RealVType->hasUnsignedIntegerRepresentation() && 7177 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7178 return LIS.IsStrictCompare; 7179 }); 7180 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7181 // unsigned IV)) for worksharing loops. 7182 SourceLocation CondLoc = AStmt->getBeginLoc(); 7183 Expr *BoundUB = UB.get(); 7184 if (UseStrictCompare) { 7185 BoundUB = 7186 SemaRef 7187 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7188 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7189 .get(); 7190 BoundUB = 7191 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7192 } 7193 ExprResult Cond = 7194 (isOpenMPWorksharingDirective(DKind) || 7195 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7196 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7197 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7198 BoundUB) 7199 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7200 NumIterations.get()); 7201 ExprResult CombDistCond; 7202 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7203 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7204 NumIterations.get()); 7205 } 7206 7207 ExprResult CombCond; 7208 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7209 Expr *BoundCombUB = CombUB.get(); 7210 if (UseStrictCompare) { 7211 BoundCombUB = 7212 SemaRef 7213 .BuildBinOp( 7214 CurScope, CondLoc, BO_Add, BoundCombUB, 7215 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7216 .get(); 7217 BoundCombUB = 7218 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7219 .get(); 7220 } 7221 CombCond = 7222 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7223 IV.get(), BoundCombUB); 7224 } 7225 // Loop increment (IV = IV + 1) 7226 SourceLocation IncLoc = AStmt->getBeginLoc(); 7227 ExprResult Inc = 7228 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7229 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7230 if (!Inc.isUsable()) 7231 return 0; 7232 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7233 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7234 if (!Inc.isUsable()) 7235 return 0; 7236 7237 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7238 // Used for directives with static scheduling. 7239 // In combined construct, add combined version that use CombLB and CombUB 7240 // base variables for the update 7241 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7242 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7243 isOpenMPDistributeDirective(DKind)) { 7244 // LB + ST 7245 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7246 if (!NextLB.isUsable()) 7247 return 0; 7248 // LB = LB + ST 7249 NextLB = 7250 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7251 NextLB = 7252 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7253 if (!NextLB.isUsable()) 7254 return 0; 7255 // UB + ST 7256 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7257 if (!NextUB.isUsable()) 7258 return 0; 7259 // UB = UB + ST 7260 NextUB = 7261 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7262 NextUB = 7263 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7264 if (!NextUB.isUsable()) 7265 return 0; 7266 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7267 CombNextLB = 7268 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7269 if (!NextLB.isUsable()) 7270 return 0; 7271 // LB = LB + ST 7272 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7273 CombNextLB.get()); 7274 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7275 /*DiscardedValue*/ false); 7276 if (!CombNextLB.isUsable()) 7277 return 0; 7278 // UB + ST 7279 CombNextUB = 7280 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7281 if (!CombNextUB.isUsable()) 7282 return 0; 7283 // UB = UB + ST 7284 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7285 CombNextUB.get()); 7286 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7287 /*DiscardedValue*/ false); 7288 if (!CombNextUB.isUsable()) 7289 return 0; 7290 } 7291 } 7292 7293 // Create increment expression for distribute loop when combined in a same 7294 // directive with for as IV = IV + ST; ensure upper bound expression based 7295 // on PrevUB instead of NumIterations - used to implement 'for' when found 7296 // in combination with 'distribute', like in 'distribute parallel for' 7297 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7298 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7299 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7300 DistCond = SemaRef.BuildBinOp( 7301 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7302 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7303 7304 DistInc = 7305 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7306 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7307 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7308 DistInc.get()); 7309 DistInc = 7310 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7311 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7312 7313 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7314 // construct 7315 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7316 ExprResult IsUBGreater = 7317 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7318 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7319 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7320 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7321 CondOp.get()); 7322 PrevEUB = 7323 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7324 7325 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7326 // parallel for is in combination with a distribute directive with 7327 // schedule(static, 1) 7328 Expr *BoundPrevUB = PrevUB.get(); 7329 if (UseStrictCompare) { 7330 BoundPrevUB = 7331 SemaRef 7332 .BuildBinOp( 7333 CurScope, CondLoc, BO_Add, BoundPrevUB, 7334 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7335 .get(); 7336 BoundPrevUB = 7337 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7338 .get(); 7339 } 7340 ParForInDistCond = 7341 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7342 IV.get(), BoundPrevUB); 7343 } 7344 7345 // Build updates and final values of the loop counters. 7346 bool HasErrors = false; 7347 Built.Counters.resize(NestedLoopCount); 7348 Built.Inits.resize(NestedLoopCount); 7349 Built.Updates.resize(NestedLoopCount); 7350 Built.Finals.resize(NestedLoopCount); 7351 Built.DependentCounters.resize(NestedLoopCount); 7352 Built.DependentInits.resize(NestedLoopCount); 7353 Built.FinalsConditions.resize(NestedLoopCount); 7354 { 7355 // We implement the following algorithm for obtaining the 7356 // original loop iteration variable values based on the 7357 // value of the collapsed loop iteration variable IV. 7358 // 7359 // Let n+1 be the number of collapsed loops in the nest. 7360 // Iteration variables (I0, I1, .... In) 7361 // Iteration counts (N0, N1, ... Nn) 7362 // 7363 // Acc = IV; 7364 // 7365 // To compute Ik for loop k, 0 <= k <= n, generate: 7366 // Prod = N(k+1) * N(k+2) * ... * Nn; 7367 // Ik = Acc / Prod; 7368 // Acc -= Ik * Prod; 7369 // 7370 ExprResult Acc = IV; 7371 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7372 LoopIterationSpace &IS = IterSpaces[Cnt]; 7373 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7374 ExprResult Iter; 7375 7376 // Compute prod 7377 ExprResult Prod = 7378 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7379 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7380 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7381 IterSpaces[K].NumIterations); 7382 7383 // Iter = Acc / Prod 7384 // If there is at least one more inner loop to avoid 7385 // multiplication by 1. 7386 if (Cnt + 1 < NestedLoopCount) 7387 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7388 Acc.get(), Prod.get()); 7389 else 7390 Iter = Acc; 7391 if (!Iter.isUsable()) { 7392 HasErrors = true; 7393 break; 7394 } 7395 7396 // Update Acc: 7397 // Acc -= Iter * Prod 7398 // Check if there is at least one more inner loop to avoid 7399 // multiplication by 1. 7400 if (Cnt + 1 < NestedLoopCount) 7401 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7402 Iter.get(), Prod.get()); 7403 else 7404 Prod = Iter; 7405 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7406 Acc.get(), Prod.get()); 7407 7408 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7409 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7410 DeclRefExpr *CounterVar = buildDeclRefExpr( 7411 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7412 /*RefersToCapture=*/true); 7413 ExprResult Init = 7414 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7415 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7416 if (!Init.isUsable()) { 7417 HasErrors = true; 7418 break; 7419 } 7420 ExprResult Update = buildCounterUpdate( 7421 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7422 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7423 if (!Update.isUsable()) { 7424 HasErrors = true; 7425 break; 7426 } 7427 7428 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7429 ExprResult Final = 7430 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7431 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7432 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7433 if (!Final.isUsable()) { 7434 HasErrors = true; 7435 break; 7436 } 7437 7438 if (!Update.isUsable() || !Final.isUsable()) { 7439 HasErrors = true; 7440 break; 7441 } 7442 // Save results 7443 Built.Counters[Cnt] = IS.CounterVar; 7444 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7445 Built.Inits[Cnt] = Init.get(); 7446 Built.Updates[Cnt] = Update.get(); 7447 Built.Finals[Cnt] = Final.get(); 7448 Built.DependentCounters[Cnt] = nullptr; 7449 Built.DependentInits[Cnt] = nullptr; 7450 Built.FinalsConditions[Cnt] = nullptr; 7451 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7452 Built.DependentCounters[Cnt] = 7453 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7454 Built.DependentInits[Cnt] = 7455 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7456 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7457 } 7458 } 7459 } 7460 7461 if (HasErrors) 7462 return 0; 7463 7464 // Save results 7465 Built.IterationVarRef = IV.get(); 7466 Built.LastIteration = LastIteration.get(); 7467 Built.NumIterations = NumIterations.get(); 7468 Built.CalcLastIteration = SemaRef 7469 .ActOnFinishFullExpr(CalcLastIteration.get(), 7470 /*DiscardedValue=*/false) 7471 .get(); 7472 Built.PreCond = PreCond.get(); 7473 Built.PreInits = buildPreInits(C, Captures); 7474 Built.Cond = Cond.get(); 7475 Built.Init = Init.get(); 7476 Built.Inc = Inc.get(); 7477 Built.LB = LB.get(); 7478 Built.UB = UB.get(); 7479 Built.IL = IL.get(); 7480 Built.ST = ST.get(); 7481 Built.EUB = EUB.get(); 7482 Built.NLB = NextLB.get(); 7483 Built.NUB = NextUB.get(); 7484 Built.PrevLB = PrevLB.get(); 7485 Built.PrevUB = PrevUB.get(); 7486 Built.DistInc = DistInc.get(); 7487 Built.PrevEUB = PrevEUB.get(); 7488 Built.DistCombinedFields.LB = CombLB.get(); 7489 Built.DistCombinedFields.UB = CombUB.get(); 7490 Built.DistCombinedFields.EUB = CombEUB.get(); 7491 Built.DistCombinedFields.Init = CombInit.get(); 7492 Built.DistCombinedFields.Cond = CombCond.get(); 7493 Built.DistCombinedFields.NLB = CombNextLB.get(); 7494 Built.DistCombinedFields.NUB = CombNextUB.get(); 7495 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7496 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7497 7498 return NestedLoopCount; 7499 } 7500 7501 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7502 auto CollapseClauses = 7503 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7504 if (CollapseClauses.begin() != CollapseClauses.end()) 7505 return (*CollapseClauses.begin())->getNumForLoops(); 7506 return nullptr; 7507 } 7508 7509 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7510 auto OrderedClauses = 7511 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7512 if (OrderedClauses.begin() != OrderedClauses.end()) 7513 return (*OrderedClauses.begin())->getNumForLoops(); 7514 return nullptr; 7515 } 7516 7517 static bool checkSimdlenSafelenSpecified(Sema &S, 7518 const ArrayRef<OMPClause *> Clauses) { 7519 const OMPSafelenClause *Safelen = nullptr; 7520 const OMPSimdlenClause *Simdlen = nullptr; 7521 7522 for (const OMPClause *Clause : Clauses) { 7523 if (Clause->getClauseKind() == OMPC_safelen) 7524 Safelen = cast<OMPSafelenClause>(Clause); 7525 else if (Clause->getClauseKind() == OMPC_simdlen) 7526 Simdlen = cast<OMPSimdlenClause>(Clause); 7527 if (Safelen && Simdlen) 7528 break; 7529 } 7530 7531 if (Simdlen && Safelen) { 7532 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7533 const Expr *SafelenLength = Safelen->getSafelen(); 7534 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7535 SimdlenLength->isInstantiationDependent() || 7536 SimdlenLength->containsUnexpandedParameterPack()) 7537 return false; 7538 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7539 SafelenLength->isInstantiationDependent() || 7540 SafelenLength->containsUnexpandedParameterPack()) 7541 return false; 7542 Expr::EvalResult SimdlenResult, SafelenResult; 7543 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7544 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7545 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7546 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7547 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7548 // If both simdlen and safelen clauses are specified, the value of the 7549 // simdlen parameter must be less than or equal to the value of the safelen 7550 // parameter. 7551 if (SimdlenRes > SafelenRes) { 7552 S.Diag(SimdlenLength->getExprLoc(), 7553 diag::err_omp_wrong_simdlen_safelen_values) 7554 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7555 return true; 7556 } 7557 } 7558 return false; 7559 } 7560 7561 StmtResult 7562 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7563 SourceLocation StartLoc, SourceLocation EndLoc, 7564 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7565 if (!AStmt) 7566 return StmtError(); 7567 7568 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7569 OMPLoopDirective::HelperExprs B; 7570 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7571 // define the nested loops number. 7572 unsigned NestedLoopCount = checkOpenMPLoop( 7573 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7574 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7575 if (NestedLoopCount == 0) 7576 return StmtError(); 7577 7578 assert((CurContext->isDependentContext() || B.builtAll()) && 7579 "omp simd loop exprs were not built"); 7580 7581 if (!CurContext->isDependentContext()) { 7582 // Finalize the clauses that need pre-built expressions for CodeGen. 7583 for (OMPClause *C : Clauses) { 7584 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7585 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7586 B.NumIterations, *this, CurScope, 7587 DSAStack)) 7588 return StmtError(); 7589 } 7590 } 7591 7592 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7593 return StmtError(); 7594 7595 setFunctionHasBranchProtectedScope(); 7596 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7597 Clauses, AStmt, B); 7598 } 7599 7600 StmtResult 7601 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7602 SourceLocation StartLoc, SourceLocation EndLoc, 7603 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7604 if (!AStmt) 7605 return StmtError(); 7606 7607 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7608 OMPLoopDirective::HelperExprs B; 7609 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7610 // define the nested loops number. 7611 unsigned NestedLoopCount = checkOpenMPLoop( 7612 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7613 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7614 if (NestedLoopCount == 0) 7615 return StmtError(); 7616 7617 assert((CurContext->isDependentContext() || B.builtAll()) && 7618 "omp for loop exprs were not built"); 7619 7620 if (!CurContext->isDependentContext()) { 7621 // Finalize the clauses that need pre-built expressions for CodeGen. 7622 for (OMPClause *C : Clauses) { 7623 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7624 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7625 B.NumIterations, *this, CurScope, 7626 DSAStack)) 7627 return StmtError(); 7628 } 7629 } 7630 7631 setFunctionHasBranchProtectedScope(); 7632 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7633 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7634 } 7635 7636 StmtResult Sema::ActOnOpenMPForSimdDirective( 7637 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7638 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7639 if (!AStmt) 7640 return StmtError(); 7641 7642 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7643 OMPLoopDirective::HelperExprs B; 7644 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7645 // define the nested loops number. 7646 unsigned NestedLoopCount = 7647 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7648 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7649 VarsWithImplicitDSA, B); 7650 if (NestedLoopCount == 0) 7651 return StmtError(); 7652 7653 assert((CurContext->isDependentContext() || B.builtAll()) && 7654 "omp for simd loop exprs were not built"); 7655 7656 if (!CurContext->isDependentContext()) { 7657 // Finalize the clauses that need pre-built expressions for CodeGen. 7658 for (OMPClause *C : Clauses) { 7659 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7660 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7661 B.NumIterations, *this, CurScope, 7662 DSAStack)) 7663 return StmtError(); 7664 } 7665 } 7666 7667 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7668 return StmtError(); 7669 7670 setFunctionHasBranchProtectedScope(); 7671 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7672 Clauses, AStmt, B); 7673 } 7674 7675 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7676 Stmt *AStmt, 7677 SourceLocation StartLoc, 7678 SourceLocation EndLoc) { 7679 if (!AStmt) 7680 return StmtError(); 7681 7682 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7683 auto BaseStmt = AStmt; 7684 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7685 BaseStmt = CS->getCapturedStmt(); 7686 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7687 auto S = C->children(); 7688 if (S.begin() == S.end()) 7689 return StmtError(); 7690 // All associated statements must be '#pragma omp section' except for 7691 // the first one. 7692 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7693 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7694 if (SectionStmt) 7695 Diag(SectionStmt->getBeginLoc(), 7696 diag::err_omp_sections_substmt_not_section); 7697 return StmtError(); 7698 } 7699 cast<OMPSectionDirective>(SectionStmt) 7700 ->setHasCancel(DSAStack->isCancelRegion()); 7701 } 7702 } else { 7703 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7704 return StmtError(); 7705 } 7706 7707 setFunctionHasBranchProtectedScope(); 7708 7709 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7710 DSAStack->isCancelRegion()); 7711 } 7712 7713 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7714 SourceLocation StartLoc, 7715 SourceLocation EndLoc) { 7716 if (!AStmt) 7717 return StmtError(); 7718 7719 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7720 7721 setFunctionHasBranchProtectedScope(); 7722 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7723 7724 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7725 DSAStack->isCancelRegion()); 7726 } 7727 7728 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7729 Stmt *AStmt, 7730 SourceLocation StartLoc, 7731 SourceLocation EndLoc) { 7732 if (!AStmt) 7733 return StmtError(); 7734 7735 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7736 7737 setFunctionHasBranchProtectedScope(); 7738 7739 // OpenMP [2.7.3, single Construct, Restrictions] 7740 // The copyprivate clause must not be used with the nowait clause. 7741 const OMPClause *Nowait = nullptr; 7742 const OMPClause *Copyprivate = nullptr; 7743 for (const OMPClause *Clause : Clauses) { 7744 if (Clause->getClauseKind() == OMPC_nowait) 7745 Nowait = Clause; 7746 else if (Clause->getClauseKind() == OMPC_copyprivate) 7747 Copyprivate = Clause; 7748 if (Copyprivate && Nowait) { 7749 Diag(Copyprivate->getBeginLoc(), 7750 diag::err_omp_single_copyprivate_with_nowait); 7751 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7752 return StmtError(); 7753 } 7754 } 7755 7756 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7757 } 7758 7759 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7760 SourceLocation StartLoc, 7761 SourceLocation EndLoc) { 7762 if (!AStmt) 7763 return StmtError(); 7764 7765 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7766 7767 setFunctionHasBranchProtectedScope(); 7768 7769 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7770 } 7771 7772 StmtResult Sema::ActOnOpenMPCriticalDirective( 7773 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7774 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7775 if (!AStmt) 7776 return StmtError(); 7777 7778 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7779 7780 bool ErrorFound = false; 7781 llvm::APSInt Hint; 7782 SourceLocation HintLoc; 7783 bool DependentHint = false; 7784 for (const OMPClause *C : Clauses) { 7785 if (C->getClauseKind() == OMPC_hint) { 7786 if (!DirName.getName()) { 7787 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7788 ErrorFound = true; 7789 } 7790 Expr *E = cast<OMPHintClause>(C)->getHint(); 7791 if (E->isTypeDependent() || E->isValueDependent() || 7792 E->isInstantiationDependent()) { 7793 DependentHint = true; 7794 } else { 7795 Hint = E->EvaluateKnownConstInt(Context); 7796 HintLoc = C->getBeginLoc(); 7797 } 7798 } 7799 } 7800 if (ErrorFound) 7801 return StmtError(); 7802 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7803 if (Pair.first && DirName.getName() && !DependentHint) { 7804 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7805 Diag(StartLoc, diag::err_omp_critical_with_hint); 7806 if (HintLoc.isValid()) 7807 Diag(HintLoc, diag::note_omp_critical_hint_here) 7808 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7809 else 7810 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7811 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7812 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7813 << 1 7814 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7815 /*Radix=*/10, /*Signed=*/false); 7816 } else { 7817 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7818 } 7819 } 7820 } 7821 7822 setFunctionHasBranchProtectedScope(); 7823 7824 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7825 Clauses, AStmt); 7826 if (!Pair.first && DirName.getName() && !DependentHint) 7827 DSAStack->addCriticalWithHint(Dir, Hint); 7828 return Dir; 7829 } 7830 7831 StmtResult Sema::ActOnOpenMPParallelForDirective( 7832 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7833 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7834 if (!AStmt) 7835 return StmtError(); 7836 7837 auto *CS = cast<CapturedStmt>(AStmt); 7838 // 1.2.2 OpenMP Language Terminology 7839 // Structured block - An executable statement with a single entry at the 7840 // top and a single exit at the bottom. 7841 // The point of exit cannot be a branch out of the structured block. 7842 // longjmp() and throw() must not violate the entry/exit criteria. 7843 CS->getCapturedDecl()->setNothrow(); 7844 7845 OMPLoopDirective::HelperExprs B; 7846 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7847 // define the nested loops number. 7848 unsigned NestedLoopCount = 7849 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7850 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7851 VarsWithImplicitDSA, B); 7852 if (NestedLoopCount == 0) 7853 return StmtError(); 7854 7855 assert((CurContext->isDependentContext() || B.builtAll()) && 7856 "omp parallel for loop exprs were not built"); 7857 7858 if (!CurContext->isDependentContext()) { 7859 // Finalize the clauses that need pre-built expressions for CodeGen. 7860 for (OMPClause *C : Clauses) { 7861 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7862 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7863 B.NumIterations, *this, CurScope, 7864 DSAStack)) 7865 return StmtError(); 7866 } 7867 } 7868 7869 setFunctionHasBranchProtectedScope(); 7870 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7871 NestedLoopCount, Clauses, AStmt, B, 7872 DSAStack->isCancelRegion()); 7873 } 7874 7875 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7876 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7877 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7878 if (!AStmt) 7879 return StmtError(); 7880 7881 auto *CS = cast<CapturedStmt>(AStmt); 7882 // 1.2.2 OpenMP Language Terminology 7883 // Structured block - An executable statement with a single entry at the 7884 // top and a single exit at the bottom. 7885 // The point of exit cannot be a branch out of the structured block. 7886 // longjmp() and throw() must not violate the entry/exit criteria. 7887 CS->getCapturedDecl()->setNothrow(); 7888 7889 OMPLoopDirective::HelperExprs B; 7890 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7891 // define the nested loops number. 7892 unsigned NestedLoopCount = 7893 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7894 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7895 VarsWithImplicitDSA, B); 7896 if (NestedLoopCount == 0) 7897 return StmtError(); 7898 7899 if (!CurContext->isDependentContext()) { 7900 // Finalize the clauses that need pre-built expressions for CodeGen. 7901 for (OMPClause *C : Clauses) { 7902 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7903 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7904 B.NumIterations, *this, CurScope, 7905 DSAStack)) 7906 return StmtError(); 7907 } 7908 } 7909 7910 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7911 return StmtError(); 7912 7913 setFunctionHasBranchProtectedScope(); 7914 return OMPParallelForSimdDirective::Create( 7915 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7916 } 7917 7918 StmtResult 7919 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7920 Stmt *AStmt, SourceLocation StartLoc, 7921 SourceLocation EndLoc) { 7922 if (!AStmt) 7923 return StmtError(); 7924 7925 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7926 auto BaseStmt = AStmt; 7927 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7928 BaseStmt = CS->getCapturedStmt(); 7929 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7930 auto S = C->children(); 7931 if (S.begin() == S.end()) 7932 return StmtError(); 7933 // All associated statements must be '#pragma omp section' except for 7934 // the first one. 7935 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7936 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7937 if (SectionStmt) 7938 Diag(SectionStmt->getBeginLoc(), 7939 diag::err_omp_parallel_sections_substmt_not_section); 7940 return StmtError(); 7941 } 7942 cast<OMPSectionDirective>(SectionStmt) 7943 ->setHasCancel(DSAStack->isCancelRegion()); 7944 } 7945 } else { 7946 Diag(AStmt->getBeginLoc(), 7947 diag::err_omp_parallel_sections_not_compound_stmt); 7948 return StmtError(); 7949 } 7950 7951 setFunctionHasBranchProtectedScope(); 7952 7953 return OMPParallelSectionsDirective::Create( 7954 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7955 } 7956 7957 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7958 Stmt *AStmt, SourceLocation StartLoc, 7959 SourceLocation EndLoc) { 7960 if (!AStmt) 7961 return StmtError(); 7962 7963 auto *CS = cast<CapturedStmt>(AStmt); 7964 // 1.2.2 OpenMP Language Terminology 7965 // Structured block - An executable statement with a single entry at the 7966 // top and a single exit at the bottom. 7967 // The point of exit cannot be a branch out of the structured block. 7968 // longjmp() and throw() must not violate the entry/exit criteria. 7969 CS->getCapturedDecl()->setNothrow(); 7970 7971 setFunctionHasBranchProtectedScope(); 7972 7973 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7974 DSAStack->isCancelRegion()); 7975 } 7976 7977 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7978 SourceLocation EndLoc) { 7979 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7980 } 7981 7982 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7983 SourceLocation EndLoc) { 7984 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7985 } 7986 7987 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7988 SourceLocation EndLoc) { 7989 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7990 } 7991 7992 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7993 Stmt *AStmt, 7994 SourceLocation StartLoc, 7995 SourceLocation EndLoc) { 7996 if (!AStmt) 7997 return StmtError(); 7998 7999 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8000 8001 setFunctionHasBranchProtectedScope(); 8002 8003 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8004 AStmt, 8005 DSAStack->getTaskgroupReductionRef()); 8006 } 8007 8008 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8009 SourceLocation StartLoc, 8010 SourceLocation EndLoc) { 8011 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8012 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8013 } 8014 8015 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8016 Stmt *AStmt, 8017 SourceLocation StartLoc, 8018 SourceLocation EndLoc) { 8019 const OMPClause *DependFound = nullptr; 8020 const OMPClause *DependSourceClause = nullptr; 8021 const OMPClause *DependSinkClause = nullptr; 8022 bool ErrorFound = false; 8023 const OMPThreadsClause *TC = nullptr; 8024 const OMPSIMDClause *SC = nullptr; 8025 for (const OMPClause *C : Clauses) { 8026 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8027 DependFound = C; 8028 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8029 if (DependSourceClause) { 8030 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8031 << getOpenMPDirectiveName(OMPD_ordered) 8032 << getOpenMPClauseName(OMPC_depend) << 2; 8033 ErrorFound = true; 8034 } else { 8035 DependSourceClause = C; 8036 } 8037 if (DependSinkClause) { 8038 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8039 << 0; 8040 ErrorFound = true; 8041 } 8042 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8043 if (DependSourceClause) { 8044 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8045 << 1; 8046 ErrorFound = true; 8047 } 8048 DependSinkClause = C; 8049 } 8050 } else if (C->getClauseKind() == OMPC_threads) { 8051 TC = cast<OMPThreadsClause>(C); 8052 } else if (C->getClauseKind() == OMPC_simd) { 8053 SC = cast<OMPSIMDClause>(C); 8054 } 8055 } 8056 if (!ErrorFound && !SC && 8057 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8058 // OpenMP [2.8.1,simd Construct, Restrictions] 8059 // An ordered construct with the simd clause is the only OpenMP construct 8060 // that can appear in the simd region. 8061 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 8062 ErrorFound = true; 8063 } else if (DependFound && (TC || SC)) { 8064 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8065 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8066 ErrorFound = true; 8067 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8068 Diag(DependFound->getBeginLoc(), 8069 diag::err_omp_ordered_directive_without_param); 8070 ErrorFound = true; 8071 } else if (TC || Clauses.empty()) { 8072 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8073 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8074 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8075 << (TC != nullptr); 8076 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8077 ErrorFound = true; 8078 } 8079 } 8080 if ((!AStmt && !DependFound) || ErrorFound) 8081 return StmtError(); 8082 8083 if (AStmt) { 8084 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8085 8086 setFunctionHasBranchProtectedScope(); 8087 } 8088 8089 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8090 } 8091 8092 namespace { 8093 /// Helper class for checking expression in 'omp atomic [update]' 8094 /// construct. 8095 class OpenMPAtomicUpdateChecker { 8096 /// Error results for atomic update expressions. 8097 enum ExprAnalysisErrorCode { 8098 /// A statement is not an expression statement. 8099 NotAnExpression, 8100 /// Expression is not builtin binary or unary operation. 8101 NotABinaryOrUnaryExpression, 8102 /// Unary operation is not post-/pre- increment/decrement operation. 8103 NotAnUnaryIncDecExpression, 8104 /// An expression is not of scalar type. 8105 NotAScalarType, 8106 /// A binary operation is not an assignment operation. 8107 NotAnAssignmentOp, 8108 /// RHS part of the binary operation is not a binary expression. 8109 NotABinaryExpression, 8110 /// RHS part is not additive/multiplicative/shift/biwise binary 8111 /// expression. 8112 NotABinaryOperator, 8113 /// RHS binary operation does not have reference to the updated LHS 8114 /// part. 8115 NotAnUpdateExpression, 8116 /// No errors is found. 8117 NoError 8118 }; 8119 /// Reference to Sema. 8120 Sema &SemaRef; 8121 /// A location for note diagnostics (when error is found). 8122 SourceLocation NoteLoc; 8123 /// 'x' lvalue part of the source atomic expression. 8124 Expr *X; 8125 /// 'expr' rvalue part of the source atomic expression. 8126 Expr *E; 8127 /// Helper expression of the form 8128 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8129 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8130 Expr *UpdateExpr; 8131 /// Is 'x' a LHS in a RHS part of full update expression. It is 8132 /// important for non-associative operations. 8133 bool IsXLHSInRHSPart; 8134 BinaryOperatorKind Op; 8135 SourceLocation OpLoc; 8136 /// true if the source expression is a postfix unary operation, false 8137 /// if it is a prefix unary operation. 8138 bool IsPostfixUpdate; 8139 8140 public: 8141 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8142 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8143 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8144 /// Check specified statement that it is suitable for 'atomic update' 8145 /// constructs and extract 'x', 'expr' and Operation from the original 8146 /// expression. If DiagId and NoteId == 0, then only check is performed 8147 /// without error notification. 8148 /// \param DiagId Diagnostic which should be emitted if error is found. 8149 /// \param NoteId Diagnostic note for the main error message. 8150 /// \return true if statement is not an update expression, false otherwise. 8151 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8152 /// Return the 'x' lvalue part of the source atomic expression. 8153 Expr *getX() const { return X; } 8154 /// Return the 'expr' rvalue part of the source atomic expression. 8155 Expr *getExpr() const { return E; } 8156 /// Return the update expression used in calculation of the updated 8157 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8158 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8159 Expr *getUpdateExpr() const { return UpdateExpr; } 8160 /// Return true if 'x' is LHS in RHS part of full update expression, 8161 /// false otherwise. 8162 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8163 8164 /// true if the source expression is a postfix unary operation, false 8165 /// if it is a prefix unary operation. 8166 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8167 8168 private: 8169 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8170 unsigned NoteId = 0); 8171 }; 8172 } // namespace 8173 8174 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8175 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8176 ExprAnalysisErrorCode ErrorFound = NoError; 8177 SourceLocation ErrorLoc, NoteLoc; 8178 SourceRange ErrorRange, NoteRange; 8179 // Allowed constructs are: 8180 // x = x binop expr; 8181 // x = expr binop x; 8182 if (AtomicBinOp->getOpcode() == BO_Assign) { 8183 X = AtomicBinOp->getLHS(); 8184 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8185 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8186 if (AtomicInnerBinOp->isMultiplicativeOp() || 8187 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8188 AtomicInnerBinOp->isBitwiseOp()) { 8189 Op = AtomicInnerBinOp->getOpcode(); 8190 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8191 Expr *LHS = AtomicInnerBinOp->getLHS(); 8192 Expr *RHS = AtomicInnerBinOp->getRHS(); 8193 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8194 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8195 /*Canonical=*/true); 8196 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8197 /*Canonical=*/true); 8198 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8199 /*Canonical=*/true); 8200 if (XId == LHSId) { 8201 E = RHS; 8202 IsXLHSInRHSPart = true; 8203 } else if (XId == RHSId) { 8204 E = LHS; 8205 IsXLHSInRHSPart = false; 8206 } else { 8207 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8208 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8209 NoteLoc = X->getExprLoc(); 8210 NoteRange = X->getSourceRange(); 8211 ErrorFound = NotAnUpdateExpression; 8212 } 8213 } else { 8214 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8215 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8216 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8217 NoteRange = SourceRange(NoteLoc, NoteLoc); 8218 ErrorFound = NotABinaryOperator; 8219 } 8220 } else { 8221 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8222 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8223 ErrorFound = NotABinaryExpression; 8224 } 8225 } else { 8226 ErrorLoc = AtomicBinOp->getExprLoc(); 8227 ErrorRange = AtomicBinOp->getSourceRange(); 8228 NoteLoc = AtomicBinOp->getOperatorLoc(); 8229 NoteRange = SourceRange(NoteLoc, NoteLoc); 8230 ErrorFound = NotAnAssignmentOp; 8231 } 8232 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8233 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8234 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8235 return true; 8236 } 8237 if (SemaRef.CurContext->isDependentContext()) 8238 E = X = UpdateExpr = nullptr; 8239 return ErrorFound != NoError; 8240 } 8241 8242 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8243 unsigned NoteId) { 8244 ExprAnalysisErrorCode ErrorFound = NoError; 8245 SourceLocation ErrorLoc, NoteLoc; 8246 SourceRange ErrorRange, NoteRange; 8247 // Allowed constructs are: 8248 // x++; 8249 // x--; 8250 // ++x; 8251 // --x; 8252 // x binop= expr; 8253 // x = x binop expr; 8254 // x = expr binop x; 8255 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8256 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8257 if (AtomicBody->getType()->isScalarType() || 8258 AtomicBody->isInstantiationDependent()) { 8259 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8260 AtomicBody->IgnoreParenImpCasts())) { 8261 // Check for Compound Assignment Operation 8262 Op = BinaryOperator::getOpForCompoundAssignment( 8263 AtomicCompAssignOp->getOpcode()); 8264 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8265 E = AtomicCompAssignOp->getRHS(); 8266 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8267 IsXLHSInRHSPart = true; 8268 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8269 AtomicBody->IgnoreParenImpCasts())) { 8270 // Check for Binary Operation 8271 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8272 return true; 8273 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8274 AtomicBody->IgnoreParenImpCasts())) { 8275 // Check for Unary Operation 8276 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8277 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8278 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8279 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8280 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8281 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8282 IsXLHSInRHSPart = true; 8283 } else { 8284 ErrorFound = NotAnUnaryIncDecExpression; 8285 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8286 ErrorRange = AtomicUnaryOp->getSourceRange(); 8287 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8288 NoteRange = SourceRange(NoteLoc, NoteLoc); 8289 } 8290 } else if (!AtomicBody->isInstantiationDependent()) { 8291 ErrorFound = NotABinaryOrUnaryExpression; 8292 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8293 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8294 } 8295 } else { 8296 ErrorFound = NotAScalarType; 8297 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8298 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8299 } 8300 } else { 8301 ErrorFound = NotAnExpression; 8302 NoteLoc = ErrorLoc = S->getBeginLoc(); 8303 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8304 } 8305 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8306 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8307 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8308 return true; 8309 } 8310 if (SemaRef.CurContext->isDependentContext()) 8311 E = X = UpdateExpr = nullptr; 8312 if (ErrorFound == NoError && E && X) { 8313 // Build an update expression of form 'OpaqueValueExpr(x) binop 8314 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8315 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8316 auto *OVEX = new (SemaRef.getASTContext()) 8317 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8318 auto *OVEExpr = new (SemaRef.getASTContext()) 8319 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8320 ExprResult Update = 8321 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8322 IsXLHSInRHSPart ? OVEExpr : OVEX); 8323 if (Update.isInvalid()) 8324 return true; 8325 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8326 Sema::AA_Casting); 8327 if (Update.isInvalid()) 8328 return true; 8329 UpdateExpr = Update.get(); 8330 } 8331 return ErrorFound != NoError; 8332 } 8333 8334 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8335 Stmt *AStmt, 8336 SourceLocation StartLoc, 8337 SourceLocation EndLoc) { 8338 if (!AStmt) 8339 return StmtError(); 8340 8341 auto *CS = cast<CapturedStmt>(AStmt); 8342 // 1.2.2 OpenMP Language Terminology 8343 // Structured block - An executable statement with a single entry at the 8344 // top and a single exit at the bottom. 8345 // The point of exit cannot be a branch out of the structured block. 8346 // longjmp() and throw() must not violate the entry/exit criteria. 8347 OpenMPClauseKind AtomicKind = OMPC_unknown; 8348 SourceLocation AtomicKindLoc; 8349 for (const OMPClause *C : Clauses) { 8350 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8351 C->getClauseKind() == OMPC_update || 8352 C->getClauseKind() == OMPC_capture) { 8353 if (AtomicKind != OMPC_unknown) { 8354 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8355 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8356 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8357 << getOpenMPClauseName(AtomicKind); 8358 } else { 8359 AtomicKind = C->getClauseKind(); 8360 AtomicKindLoc = C->getBeginLoc(); 8361 } 8362 } 8363 } 8364 8365 Stmt *Body = CS->getCapturedStmt(); 8366 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8367 Body = EWC->getSubExpr(); 8368 8369 Expr *X = nullptr; 8370 Expr *V = nullptr; 8371 Expr *E = nullptr; 8372 Expr *UE = nullptr; 8373 bool IsXLHSInRHSPart = false; 8374 bool IsPostfixUpdate = false; 8375 // OpenMP [2.12.6, atomic Construct] 8376 // In the next expressions: 8377 // * x and v (as applicable) are both l-value expressions with scalar type. 8378 // * During the execution of an atomic region, multiple syntactic 8379 // occurrences of x must designate the same storage location. 8380 // * Neither of v and expr (as applicable) may access the storage location 8381 // designated by x. 8382 // * Neither of x and expr (as applicable) may access the storage location 8383 // designated by v. 8384 // * expr is an expression with scalar type. 8385 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8386 // * binop, binop=, ++, and -- are not overloaded operators. 8387 // * The expression x binop expr must be numerically equivalent to x binop 8388 // (expr). This requirement is satisfied if the operators in expr have 8389 // precedence greater than binop, or by using parentheses around expr or 8390 // subexpressions of expr. 8391 // * The expression expr binop x must be numerically equivalent to (expr) 8392 // binop x. This requirement is satisfied if the operators in expr have 8393 // precedence equal to or greater than binop, or by using parentheses around 8394 // expr or subexpressions of expr. 8395 // * For forms that allow multiple occurrences of x, the number of times 8396 // that x is evaluated is unspecified. 8397 if (AtomicKind == OMPC_read) { 8398 enum { 8399 NotAnExpression, 8400 NotAnAssignmentOp, 8401 NotAScalarType, 8402 NotAnLValue, 8403 NoError 8404 } ErrorFound = NoError; 8405 SourceLocation ErrorLoc, NoteLoc; 8406 SourceRange ErrorRange, NoteRange; 8407 // If clause is read: 8408 // v = x; 8409 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8410 const auto *AtomicBinOp = 8411 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8412 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8413 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8414 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8415 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8416 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8417 if (!X->isLValue() || !V->isLValue()) { 8418 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8419 ErrorFound = NotAnLValue; 8420 ErrorLoc = AtomicBinOp->getExprLoc(); 8421 ErrorRange = AtomicBinOp->getSourceRange(); 8422 NoteLoc = NotLValueExpr->getExprLoc(); 8423 NoteRange = NotLValueExpr->getSourceRange(); 8424 } 8425 } else if (!X->isInstantiationDependent() || 8426 !V->isInstantiationDependent()) { 8427 const Expr *NotScalarExpr = 8428 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8429 ? V 8430 : X; 8431 ErrorFound = NotAScalarType; 8432 ErrorLoc = AtomicBinOp->getExprLoc(); 8433 ErrorRange = AtomicBinOp->getSourceRange(); 8434 NoteLoc = NotScalarExpr->getExprLoc(); 8435 NoteRange = NotScalarExpr->getSourceRange(); 8436 } 8437 } else if (!AtomicBody->isInstantiationDependent()) { 8438 ErrorFound = NotAnAssignmentOp; 8439 ErrorLoc = AtomicBody->getExprLoc(); 8440 ErrorRange = AtomicBody->getSourceRange(); 8441 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8442 : AtomicBody->getExprLoc(); 8443 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8444 : AtomicBody->getSourceRange(); 8445 } 8446 } else { 8447 ErrorFound = NotAnExpression; 8448 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8449 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8450 } 8451 if (ErrorFound != NoError) { 8452 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8453 << ErrorRange; 8454 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8455 << NoteRange; 8456 return StmtError(); 8457 } 8458 if (CurContext->isDependentContext()) 8459 V = X = nullptr; 8460 } else if (AtomicKind == OMPC_write) { 8461 enum { 8462 NotAnExpression, 8463 NotAnAssignmentOp, 8464 NotAScalarType, 8465 NotAnLValue, 8466 NoError 8467 } ErrorFound = NoError; 8468 SourceLocation ErrorLoc, NoteLoc; 8469 SourceRange ErrorRange, NoteRange; 8470 // If clause is write: 8471 // x = expr; 8472 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8473 const auto *AtomicBinOp = 8474 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8475 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8476 X = AtomicBinOp->getLHS(); 8477 E = AtomicBinOp->getRHS(); 8478 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8479 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8480 if (!X->isLValue()) { 8481 ErrorFound = NotAnLValue; 8482 ErrorLoc = AtomicBinOp->getExprLoc(); 8483 ErrorRange = AtomicBinOp->getSourceRange(); 8484 NoteLoc = X->getExprLoc(); 8485 NoteRange = X->getSourceRange(); 8486 } 8487 } else if (!X->isInstantiationDependent() || 8488 !E->isInstantiationDependent()) { 8489 const Expr *NotScalarExpr = 8490 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8491 ? E 8492 : X; 8493 ErrorFound = NotAScalarType; 8494 ErrorLoc = AtomicBinOp->getExprLoc(); 8495 ErrorRange = AtomicBinOp->getSourceRange(); 8496 NoteLoc = NotScalarExpr->getExprLoc(); 8497 NoteRange = NotScalarExpr->getSourceRange(); 8498 } 8499 } else if (!AtomicBody->isInstantiationDependent()) { 8500 ErrorFound = NotAnAssignmentOp; 8501 ErrorLoc = AtomicBody->getExprLoc(); 8502 ErrorRange = AtomicBody->getSourceRange(); 8503 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8504 : AtomicBody->getExprLoc(); 8505 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8506 : AtomicBody->getSourceRange(); 8507 } 8508 } else { 8509 ErrorFound = NotAnExpression; 8510 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8511 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8512 } 8513 if (ErrorFound != NoError) { 8514 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8515 << ErrorRange; 8516 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8517 << NoteRange; 8518 return StmtError(); 8519 } 8520 if (CurContext->isDependentContext()) 8521 E = X = nullptr; 8522 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8523 // If clause is update: 8524 // x++; 8525 // x--; 8526 // ++x; 8527 // --x; 8528 // x binop= expr; 8529 // x = x binop expr; 8530 // x = expr binop x; 8531 OpenMPAtomicUpdateChecker Checker(*this); 8532 if (Checker.checkStatement( 8533 Body, (AtomicKind == OMPC_update) 8534 ? diag::err_omp_atomic_update_not_expression_statement 8535 : diag::err_omp_atomic_not_expression_statement, 8536 diag::note_omp_atomic_update)) 8537 return StmtError(); 8538 if (!CurContext->isDependentContext()) { 8539 E = Checker.getExpr(); 8540 X = Checker.getX(); 8541 UE = Checker.getUpdateExpr(); 8542 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8543 } 8544 } else if (AtomicKind == OMPC_capture) { 8545 enum { 8546 NotAnAssignmentOp, 8547 NotACompoundStatement, 8548 NotTwoSubstatements, 8549 NotASpecificExpression, 8550 NoError 8551 } ErrorFound = NoError; 8552 SourceLocation ErrorLoc, NoteLoc; 8553 SourceRange ErrorRange, NoteRange; 8554 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8555 // If clause is a capture: 8556 // v = x++; 8557 // v = x--; 8558 // v = ++x; 8559 // v = --x; 8560 // v = x binop= expr; 8561 // v = x = x binop expr; 8562 // v = x = expr binop x; 8563 const auto *AtomicBinOp = 8564 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8565 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8566 V = AtomicBinOp->getLHS(); 8567 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8568 OpenMPAtomicUpdateChecker Checker(*this); 8569 if (Checker.checkStatement( 8570 Body, diag::err_omp_atomic_capture_not_expression_statement, 8571 diag::note_omp_atomic_update)) 8572 return StmtError(); 8573 E = Checker.getExpr(); 8574 X = Checker.getX(); 8575 UE = Checker.getUpdateExpr(); 8576 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8577 IsPostfixUpdate = Checker.isPostfixUpdate(); 8578 } else if (!AtomicBody->isInstantiationDependent()) { 8579 ErrorLoc = AtomicBody->getExprLoc(); 8580 ErrorRange = AtomicBody->getSourceRange(); 8581 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8582 : AtomicBody->getExprLoc(); 8583 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8584 : AtomicBody->getSourceRange(); 8585 ErrorFound = NotAnAssignmentOp; 8586 } 8587 if (ErrorFound != NoError) { 8588 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8589 << ErrorRange; 8590 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8591 return StmtError(); 8592 } 8593 if (CurContext->isDependentContext()) 8594 UE = V = E = X = nullptr; 8595 } else { 8596 // If clause is a capture: 8597 // { v = x; x = expr; } 8598 // { v = x; x++; } 8599 // { v = x; x--; } 8600 // { v = x; ++x; } 8601 // { v = x; --x; } 8602 // { v = x; x binop= expr; } 8603 // { v = x; x = x binop expr; } 8604 // { v = x; x = expr binop x; } 8605 // { x++; v = x; } 8606 // { x--; v = x; } 8607 // { ++x; v = x; } 8608 // { --x; v = x; } 8609 // { x binop= expr; v = x; } 8610 // { x = x binop expr; v = x; } 8611 // { x = expr binop x; v = x; } 8612 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8613 // Check that this is { expr1; expr2; } 8614 if (CS->size() == 2) { 8615 Stmt *First = CS->body_front(); 8616 Stmt *Second = CS->body_back(); 8617 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8618 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8619 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8620 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8621 // Need to find what subexpression is 'v' and what is 'x'. 8622 OpenMPAtomicUpdateChecker Checker(*this); 8623 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8624 BinaryOperator *BinOp = nullptr; 8625 if (IsUpdateExprFound) { 8626 BinOp = dyn_cast<BinaryOperator>(First); 8627 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8628 } 8629 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8630 // { v = x; x++; } 8631 // { v = x; x--; } 8632 // { v = x; ++x; } 8633 // { v = x; --x; } 8634 // { v = x; x binop= expr; } 8635 // { v = x; x = x binop expr; } 8636 // { v = x; x = expr binop x; } 8637 // Check that the first expression has form v = x. 8638 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8639 llvm::FoldingSetNodeID XId, PossibleXId; 8640 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8641 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8642 IsUpdateExprFound = XId == PossibleXId; 8643 if (IsUpdateExprFound) { 8644 V = BinOp->getLHS(); 8645 X = Checker.getX(); 8646 E = Checker.getExpr(); 8647 UE = Checker.getUpdateExpr(); 8648 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8649 IsPostfixUpdate = true; 8650 } 8651 } 8652 if (!IsUpdateExprFound) { 8653 IsUpdateExprFound = !Checker.checkStatement(First); 8654 BinOp = nullptr; 8655 if (IsUpdateExprFound) { 8656 BinOp = dyn_cast<BinaryOperator>(Second); 8657 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8658 } 8659 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8660 // { x++; v = x; } 8661 // { x--; v = x; } 8662 // { ++x; v = x; } 8663 // { --x; v = x; } 8664 // { x binop= expr; v = x; } 8665 // { x = x binop expr; v = x; } 8666 // { x = expr binop x; v = x; } 8667 // Check that the second expression has form v = x. 8668 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8669 llvm::FoldingSetNodeID XId, PossibleXId; 8670 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8671 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8672 IsUpdateExprFound = XId == PossibleXId; 8673 if (IsUpdateExprFound) { 8674 V = BinOp->getLHS(); 8675 X = Checker.getX(); 8676 E = Checker.getExpr(); 8677 UE = Checker.getUpdateExpr(); 8678 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8679 IsPostfixUpdate = false; 8680 } 8681 } 8682 } 8683 if (!IsUpdateExprFound) { 8684 // { v = x; x = expr; } 8685 auto *FirstExpr = dyn_cast<Expr>(First); 8686 auto *SecondExpr = dyn_cast<Expr>(Second); 8687 if (!FirstExpr || !SecondExpr || 8688 !(FirstExpr->isInstantiationDependent() || 8689 SecondExpr->isInstantiationDependent())) { 8690 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8691 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8692 ErrorFound = NotAnAssignmentOp; 8693 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8694 : First->getBeginLoc(); 8695 NoteRange = ErrorRange = FirstBinOp 8696 ? FirstBinOp->getSourceRange() 8697 : SourceRange(ErrorLoc, ErrorLoc); 8698 } else { 8699 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8700 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8701 ErrorFound = NotAnAssignmentOp; 8702 NoteLoc = ErrorLoc = SecondBinOp 8703 ? SecondBinOp->getOperatorLoc() 8704 : Second->getBeginLoc(); 8705 NoteRange = ErrorRange = 8706 SecondBinOp ? SecondBinOp->getSourceRange() 8707 : SourceRange(ErrorLoc, ErrorLoc); 8708 } else { 8709 Expr *PossibleXRHSInFirst = 8710 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8711 Expr *PossibleXLHSInSecond = 8712 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8713 llvm::FoldingSetNodeID X1Id, X2Id; 8714 PossibleXRHSInFirst->Profile(X1Id, Context, 8715 /*Canonical=*/true); 8716 PossibleXLHSInSecond->Profile(X2Id, Context, 8717 /*Canonical=*/true); 8718 IsUpdateExprFound = X1Id == X2Id; 8719 if (IsUpdateExprFound) { 8720 V = FirstBinOp->getLHS(); 8721 X = SecondBinOp->getLHS(); 8722 E = SecondBinOp->getRHS(); 8723 UE = nullptr; 8724 IsXLHSInRHSPart = false; 8725 IsPostfixUpdate = true; 8726 } else { 8727 ErrorFound = NotASpecificExpression; 8728 ErrorLoc = FirstBinOp->getExprLoc(); 8729 ErrorRange = FirstBinOp->getSourceRange(); 8730 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8731 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8732 } 8733 } 8734 } 8735 } 8736 } 8737 } else { 8738 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8739 NoteRange = ErrorRange = 8740 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8741 ErrorFound = NotTwoSubstatements; 8742 } 8743 } else { 8744 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8745 NoteRange = ErrorRange = 8746 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8747 ErrorFound = NotACompoundStatement; 8748 } 8749 if (ErrorFound != NoError) { 8750 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8751 << ErrorRange; 8752 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8753 return StmtError(); 8754 } 8755 if (CurContext->isDependentContext()) 8756 UE = V = E = X = nullptr; 8757 } 8758 } 8759 8760 setFunctionHasBranchProtectedScope(); 8761 8762 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8763 X, V, E, UE, IsXLHSInRHSPart, 8764 IsPostfixUpdate); 8765 } 8766 8767 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8768 Stmt *AStmt, 8769 SourceLocation StartLoc, 8770 SourceLocation EndLoc) { 8771 if (!AStmt) 8772 return StmtError(); 8773 8774 auto *CS = cast<CapturedStmt>(AStmt); 8775 // 1.2.2 OpenMP Language Terminology 8776 // Structured block - An executable statement with a single entry at the 8777 // top and a single exit at the bottom. 8778 // The point of exit cannot be a branch out of the structured block. 8779 // longjmp() and throw() must not violate the entry/exit criteria. 8780 CS->getCapturedDecl()->setNothrow(); 8781 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8782 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8783 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8784 // 1.2.2 OpenMP Language Terminology 8785 // Structured block - An executable statement with a single entry at the 8786 // top and a single exit at the bottom. 8787 // The point of exit cannot be a branch out of the structured block. 8788 // longjmp() and throw() must not violate the entry/exit criteria. 8789 CS->getCapturedDecl()->setNothrow(); 8790 } 8791 8792 // OpenMP [2.16, Nesting of Regions] 8793 // If specified, a teams construct must be contained within a target 8794 // construct. That target construct must contain no statements or directives 8795 // outside of the teams construct. 8796 if (DSAStack->hasInnerTeamsRegion()) { 8797 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8798 bool OMPTeamsFound = true; 8799 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8800 auto I = CS->body_begin(); 8801 while (I != CS->body_end()) { 8802 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8803 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8804 OMPTeamsFound) { 8805 8806 OMPTeamsFound = false; 8807 break; 8808 } 8809 ++I; 8810 } 8811 assert(I != CS->body_end() && "Not found statement"); 8812 S = *I; 8813 } else { 8814 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8815 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8816 } 8817 if (!OMPTeamsFound) { 8818 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8819 Diag(DSAStack->getInnerTeamsRegionLoc(), 8820 diag::note_omp_nested_teams_construct_here); 8821 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8822 << isa<OMPExecutableDirective>(S); 8823 return StmtError(); 8824 } 8825 } 8826 8827 setFunctionHasBranchProtectedScope(); 8828 8829 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8830 } 8831 8832 StmtResult 8833 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8834 Stmt *AStmt, SourceLocation StartLoc, 8835 SourceLocation EndLoc) { 8836 if (!AStmt) 8837 return StmtError(); 8838 8839 auto *CS = cast<CapturedStmt>(AStmt); 8840 // 1.2.2 OpenMP Language Terminology 8841 // Structured block - An executable statement with a single entry at the 8842 // top and a single exit at the bottom. 8843 // The point of exit cannot be a branch out of the structured block. 8844 // longjmp() and throw() must not violate the entry/exit criteria. 8845 CS->getCapturedDecl()->setNothrow(); 8846 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8847 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8848 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8849 // 1.2.2 OpenMP Language Terminology 8850 // Structured block - An executable statement with a single entry at the 8851 // top and a single exit at the bottom. 8852 // The point of exit cannot be a branch out of the structured block. 8853 // longjmp() and throw() must not violate the entry/exit criteria. 8854 CS->getCapturedDecl()->setNothrow(); 8855 } 8856 8857 setFunctionHasBranchProtectedScope(); 8858 8859 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8860 AStmt); 8861 } 8862 8863 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8864 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8865 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8866 if (!AStmt) 8867 return StmtError(); 8868 8869 auto *CS = cast<CapturedStmt>(AStmt); 8870 // 1.2.2 OpenMP Language Terminology 8871 // Structured block - An executable statement with a single entry at the 8872 // top and a single exit at the bottom. 8873 // The point of exit cannot be a branch out of the structured block. 8874 // longjmp() and throw() must not violate the entry/exit criteria. 8875 CS->getCapturedDecl()->setNothrow(); 8876 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8877 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8878 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8879 // 1.2.2 OpenMP Language Terminology 8880 // Structured block - An executable statement with a single entry at the 8881 // top and a single exit at the bottom. 8882 // The point of exit cannot be a branch out of the structured block. 8883 // longjmp() and throw() must not violate the entry/exit criteria. 8884 CS->getCapturedDecl()->setNothrow(); 8885 } 8886 8887 OMPLoopDirective::HelperExprs B; 8888 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8889 // define the nested loops number. 8890 unsigned NestedLoopCount = 8891 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8892 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8893 VarsWithImplicitDSA, B); 8894 if (NestedLoopCount == 0) 8895 return StmtError(); 8896 8897 assert((CurContext->isDependentContext() || B.builtAll()) && 8898 "omp target parallel for loop exprs were not built"); 8899 8900 if (!CurContext->isDependentContext()) { 8901 // Finalize the clauses that need pre-built expressions for CodeGen. 8902 for (OMPClause *C : Clauses) { 8903 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8904 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8905 B.NumIterations, *this, CurScope, 8906 DSAStack)) 8907 return StmtError(); 8908 } 8909 } 8910 8911 setFunctionHasBranchProtectedScope(); 8912 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8913 NestedLoopCount, Clauses, AStmt, 8914 B, DSAStack->isCancelRegion()); 8915 } 8916 8917 /// Check for existence of a map clause in the list of clauses. 8918 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8919 const OpenMPClauseKind K) { 8920 return llvm::any_of( 8921 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8922 } 8923 8924 template <typename... Params> 8925 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8926 const Params... ClauseTypes) { 8927 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8928 } 8929 8930 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8931 Stmt *AStmt, 8932 SourceLocation StartLoc, 8933 SourceLocation EndLoc) { 8934 if (!AStmt) 8935 return StmtError(); 8936 8937 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8938 8939 // OpenMP [2.10.1, Restrictions, p. 97] 8940 // At least one map clause must appear on the directive. 8941 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8942 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8943 << "'map' or 'use_device_ptr'" 8944 << getOpenMPDirectiveName(OMPD_target_data); 8945 return StmtError(); 8946 } 8947 8948 setFunctionHasBranchProtectedScope(); 8949 8950 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8951 AStmt); 8952 } 8953 8954 StmtResult 8955 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8956 SourceLocation StartLoc, 8957 SourceLocation EndLoc, Stmt *AStmt) { 8958 if (!AStmt) 8959 return StmtError(); 8960 8961 auto *CS = cast<CapturedStmt>(AStmt); 8962 // 1.2.2 OpenMP Language Terminology 8963 // Structured block - An executable statement with a single entry at the 8964 // top and a single exit at the bottom. 8965 // The point of exit cannot be a branch out of the structured block. 8966 // longjmp() and throw() must not violate the entry/exit criteria. 8967 CS->getCapturedDecl()->setNothrow(); 8968 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8969 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8970 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8971 // 1.2.2 OpenMP Language Terminology 8972 // Structured block - An executable statement with a single entry at the 8973 // top and a single exit at the bottom. 8974 // The point of exit cannot be a branch out of the structured block. 8975 // longjmp() and throw() must not violate the entry/exit criteria. 8976 CS->getCapturedDecl()->setNothrow(); 8977 } 8978 8979 // OpenMP [2.10.2, Restrictions, p. 99] 8980 // At least one map clause must appear on the directive. 8981 if (!hasClauses(Clauses, OMPC_map)) { 8982 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8983 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8984 return StmtError(); 8985 } 8986 8987 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8988 AStmt); 8989 } 8990 8991 StmtResult 8992 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8993 SourceLocation StartLoc, 8994 SourceLocation EndLoc, Stmt *AStmt) { 8995 if (!AStmt) 8996 return StmtError(); 8997 8998 auto *CS = cast<CapturedStmt>(AStmt); 8999 // 1.2.2 OpenMP Language Terminology 9000 // Structured block - An executable statement with a single entry at the 9001 // top and a single exit at the bottom. 9002 // The point of exit cannot be a branch out of the structured block. 9003 // longjmp() and throw() must not violate the entry/exit criteria. 9004 CS->getCapturedDecl()->setNothrow(); 9005 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9006 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9007 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9008 // 1.2.2 OpenMP Language Terminology 9009 // Structured block - An executable statement with a single entry at the 9010 // top and a single exit at the bottom. 9011 // The point of exit cannot be a branch out of the structured block. 9012 // longjmp() and throw() must not violate the entry/exit criteria. 9013 CS->getCapturedDecl()->setNothrow(); 9014 } 9015 9016 // OpenMP [2.10.3, Restrictions, p. 102] 9017 // At least one map clause must appear on the directive. 9018 if (!hasClauses(Clauses, OMPC_map)) { 9019 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9020 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9021 return StmtError(); 9022 } 9023 9024 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9025 AStmt); 9026 } 9027 9028 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9029 SourceLocation StartLoc, 9030 SourceLocation EndLoc, 9031 Stmt *AStmt) { 9032 if (!AStmt) 9033 return StmtError(); 9034 9035 auto *CS = cast<CapturedStmt>(AStmt); 9036 // 1.2.2 OpenMP Language Terminology 9037 // Structured block - An executable statement with a single entry at the 9038 // top and a single exit at the bottom. 9039 // The point of exit cannot be a branch out of the structured block. 9040 // longjmp() and throw() must not violate the entry/exit criteria. 9041 CS->getCapturedDecl()->setNothrow(); 9042 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9043 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9044 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 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 9053 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9054 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9055 return StmtError(); 9056 } 9057 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9058 AStmt); 9059 } 9060 9061 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9062 Stmt *AStmt, SourceLocation StartLoc, 9063 SourceLocation EndLoc) { 9064 if (!AStmt) 9065 return StmtError(); 9066 9067 auto *CS = cast<CapturedStmt>(AStmt); 9068 // 1.2.2 OpenMP Language Terminology 9069 // Structured block - An executable statement with a single entry at the 9070 // top and a single exit at the bottom. 9071 // The point of exit cannot be a branch out of the structured block. 9072 // longjmp() and throw() must not violate the entry/exit criteria. 9073 CS->getCapturedDecl()->setNothrow(); 9074 9075 setFunctionHasBranchProtectedScope(); 9076 9077 DSAStack->setParentTeamsRegionLoc(StartLoc); 9078 9079 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9080 } 9081 9082 StmtResult 9083 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9084 SourceLocation EndLoc, 9085 OpenMPDirectiveKind CancelRegion) { 9086 if (DSAStack->isParentNowaitRegion()) { 9087 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9088 return StmtError(); 9089 } 9090 if (DSAStack->isParentOrderedRegion()) { 9091 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9092 return StmtError(); 9093 } 9094 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9095 CancelRegion); 9096 } 9097 9098 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9099 SourceLocation StartLoc, 9100 SourceLocation EndLoc, 9101 OpenMPDirectiveKind CancelRegion) { 9102 if (DSAStack->isParentNowaitRegion()) { 9103 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9104 return StmtError(); 9105 } 9106 if (DSAStack->isParentOrderedRegion()) { 9107 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9108 return StmtError(); 9109 } 9110 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9111 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9112 CancelRegion); 9113 } 9114 9115 static bool checkGrainsizeNumTasksClauses(Sema &S, 9116 ArrayRef<OMPClause *> Clauses) { 9117 const OMPClause *PrevClause = nullptr; 9118 bool ErrorFound = false; 9119 for (const OMPClause *C : Clauses) { 9120 if (C->getClauseKind() == OMPC_grainsize || 9121 C->getClauseKind() == OMPC_num_tasks) { 9122 if (!PrevClause) 9123 PrevClause = C; 9124 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9125 S.Diag(C->getBeginLoc(), 9126 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9127 << getOpenMPClauseName(C->getClauseKind()) 9128 << getOpenMPClauseName(PrevClause->getClauseKind()); 9129 S.Diag(PrevClause->getBeginLoc(), 9130 diag::note_omp_previous_grainsize_num_tasks) 9131 << getOpenMPClauseName(PrevClause->getClauseKind()); 9132 ErrorFound = true; 9133 } 9134 } 9135 } 9136 return ErrorFound; 9137 } 9138 9139 static bool checkReductionClauseWithNogroup(Sema &S, 9140 ArrayRef<OMPClause *> Clauses) { 9141 const OMPClause *ReductionClause = nullptr; 9142 const OMPClause *NogroupClause = nullptr; 9143 for (const OMPClause *C : Clauses) { 9144 if (C->getClauseKind() == OMPC_reduction) { 9145 ReductionClause = C; 9146 if (NogroupClause) 9147 break; 9148 continue; 9149 } 9150 if (C->getClauseKind() == OMPC_nogroup) { 9151 NogroupClause = C; 9152 if (ReductionClause) 9153 break; 9154 continue; 9155 } 9156 } 9157 if (ReductionClause && NogroupClause) { 9158 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9159 << SourceRange(NogroupClause->getBeginLoc(), 9160 NogroupClause->getEndLoc()); 9161 return true; 9162 } 9163 return false; 9164 } 9165 9166 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9167 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9168 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9169 if (!AStmt) 9170 return StmtError(); 9171 9172 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9173 OMPLoopDirective::HelperExprs B; 9174 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9175 // define the nested loops number. 9176 unsigned NestedLoopCount = 9177 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9178 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9179 VarsWithImplicitDSA, B); 9180 if (NestedLoopCount == 0) 9181 return StmtError(); 9182 9183 assert((CurContext->isDependentContext() || B.builtAll()) && 9184 "omp for loop exprs were not built"); 9185 9186 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9187 // The grainsize clause and num_tasks clause are mutually exclusive and may 9188 // not appear on the same taskloop directive. 9189 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9190 return StmtError(); 9191 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9192 // If a reduction clause is present on the taskloop directive, the nogroup 9193 // clause must not be specified. 9194 if (checkReductionClauseWithNogroup(*this, Clauses)) 9195 return StmtError(); 9196 9197 setFunctionHasBranchProtectedScope(); 9198 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9199 NestedLoopCount, Clauses, AStmt, B); 9200 } 9201 9202 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9203 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9204 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9205 if (!AStmt) 9206 return StmtError(); 9207 9208 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9209 OMPLoopDirective::HelperExprs B; 9210 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9211 // define the nested loops number. 9212 unsigned NestedLoopCount = 9213 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9214 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9215 VarsWithImplicitDSA, B); 9216 if (NestedLoopCount == 0) 9217 return StmtError(); 9218 9219 assert((CurContext->isDependentContext() || B.builtAll()) && 9220 "omp for loop exprs were not built"); 9221 9222 if (!CurContext->isDependentContext()) { 9223 // Finalize the clauses that need pre-built expressions for CodeGen. 9224 for (OMPClause *C : Clauses) { 9225 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9226 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9227 B.NumIterations, *this, CurScope, 9228 DSAStack)) 9229 return StmtError(); 9230 } 9231 } 9232 9233 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9234 // The grainsize clause and num_tasks clause are mutually exclusive and may 9235 // not appear on the same taskloop directive. 9236 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9237 return StmtError(); 9238 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9239 // If a reduction clause is present on the taskloop directive, the nogroup 9240 // clause must not be specified. 9241 if (checkReductionClauseWithNogroup(*this, Clauses)) 9242 return StmtError(); 9243 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9244 return StmtError(); 9245 9246 setFunctionHasBranchProtectedScope(); 9247 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9248 NestedLoopCount, Clauses, AStmt, B); 9249 } 9250 9251 StmtResult Sema::ActOnOpenMPDistributeDirective( 9252 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9253 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9254 if (!AStmt) 9255 return StmtError(); 9256 9257 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9258 OMPLoopDirective::HelperExprs B; 9259 // In presence of clause 'collapse' with number of loops, it will 9260 // define the nested loops number. 9261 unsigned NestedLoopCount = 9262 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9263 nullptr /*ordered not a clause on distribute*/, AStmt, 9264 *this, *DSAStack, VarsWithImplicitDSA, B); 9265 if (NestedLoopCount == 0) 9266 return StmtError(); 9267 9268 assert((CurContext->isDependentContext() || B.builtAll()) && 9269 "omp for loop exprs were not built"); 9270 9271 setFunctionHasBranchProtectedScope(); 9272 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9273 NestedLoopCount, Clauses, AStmt, B); 9274 } 9275 9276 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9277 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9278 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9279 if (!AStmt) 9280 return StmtError(); 9281 9282 auto *CS = cast<CapturedStmt>(AStmt); 9283 // 1.2.2 OpenMP Language Terminology 9284 // Structured block - An executable statement with a single entry at the 9285 // top and a single exit at the bottom. 9286 // The point of exit cannot be a branch out of the structured block. 9287 // longjmp() and throw() must not violate the entry/exit criteria. 9288 CS->getCapturedDecl()->setNothrow(); 9289 for (int ThisCaptureLevel = 9290 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9291 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9292 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9293 // 1.2.2 OpenMP Language Terminology 9294 // Structured block - An executable statement with a single entry at the 9295 // top and a single exit at the bottom. 9296 // The point of exit cannot be a branch out of the structured block. 9297 // longjmp() and throw() must not violate the entry/exit criteria. 9298 CS->getCapturedDecl()->setNothrow(); 9299 } 9300 9301 OMPLoopDirective::HelperExprs B; 9302 // In presence of clause 'collapse' with number of loops, it will 9303 // define the nested loops number. 9304 unsigned NestedLoopCount = checkOpenMPLoop( 9305 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9306 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9307 VarsWithImplicitDSA, B); 9308 if (NestedLoopCount == 0) 9309 return StmtError(); 9310 9311 assert((CurContext->isDependentContext() || B.builtAll()) && 9312 "omp for loop exprs were not built"); 9313 9314 setFunctionHasBranchProtectedScope(); 9315 return OMPDistributeParallelForDirective::Create( 9316 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9317 DSAStack->isCancelRegion()); 9318 } 9319 9320 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9321 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9322 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9323 if (!AStmt) 9324 return StmtError(); 9325 9326 auto *CS = cast<CapturedStmt>(AStmt); 9327 // 1.2.2 OpenMP Language Terminology 9328 // Structured block - An executable statement with a single entry at the 9329 // top and a single exit at the bottom. 9330 // The point of exit cannot be a branch out of the structured block. 9331 // longjmp() and throw() must not violate the entry/exit criteria. 9332 CS->getCapturedDecl()->setNothrow(); 9333 for (int ThisCaptureLevel = 9334 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9335 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9336 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9337 // 1.2.2 OpenMP Language Terminology 9338 // Structured block - An executable statement with a single entry at the 9339 // top and a single exit at the bottom. 9340 // The point of exit cannot be a branch out of the structured block. 9341 // longjmp() and throw() must not violate the entry/exit criteria. 9342 CS->getCapturedDecl()->setNothrow(); 9343 } 9344 9345 OMPLoopDirective::HelperExprs B; 9346 // In presence of clause 'collapse' with number of loops, it will 9347 // define the nested loops number. 9348 unsigned NestedLoopCount = checkOpenMPLoop( 9349 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9350 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9351 VarsWithImplicitDSA, B); 9352 if (NestedLoopCount == 0) 9353 return StmtError(); 9354 9355 assert((CurContext->isDependentContext() || B.builtAll()) && 9356 "omp for loop exprs were not built"); 9357 9358 if (!CurContext->isDependentContext()) { 9359 // Finalize the clauses that need pre-built expressions for CodeGen. 9360 for (OMPClause *C : Clauses) { 9361 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9362 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9363 B.NumIterations, *this, CurScope, 9364 DSAStack)) 9365 return StmtError(); 9366 } 9367 } 9368 9369 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9370 return StmtError(); 9371 9372 setFunctionHasBranchProtectedScope(); 9373 return OMPDistributeParallelForSimdDirective::Create( 9374 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9375 } 9376 9377 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9378 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9379 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9380 if (!AStmt) 9381 return StmtError(); 9382 9383 auto *CS = cast<CapturedStmt>(AStmt); 9384 // 1.2.2 OpenMP Language Terminology 9385 // Structured block - An executable statement with a single entry at the 9386 // top and a single exit at the bottom. 9387 // The point of exit cannot be a branch out of the structured block. 9388 // longjmp() and throw() must not violate the entry/exit criteria. 9389 CS->getCapturedDecl()->setNothrow(); 9390 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9391 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9392 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9393 // 1.2.2 OpenMP Language Terminology 9394 // Structured block - An executable statement with a single entry at the 9395 // top and a single exit at the bottom. 9396 // The point of exit cannot be a branch out of the structured block. 9397 // longjmp() and throw() must not violate the entry/exit criteria. 9398 CS->getCapturedDecl()->setNothrow(); 9399 } 9400 9401 OMPLoopDirective::HelperExprs B; 9402 // In presence of clause 'collapse' with number of loops, it will 9403 // define the nested loops number. 9404 unsigned NestedLoopCount = 9405 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9406 nullptr /*ordered not a clause on distribute*/, CS, *this, 9407 *DSAStack, VarsWithImplicitDSA, B); 9408 if (NestedLoopCount == 0) 9409 return StmtError(); 9410 9411 assert((CurContext->isDependentContext() || B.builtAll()) && 9412 "omp for loop exprs were not built"); 9413 9414 if (!CurContext->isDependentContext()) { 9415 // Finalize the clauses that need pre-built expressions for CodeGen. 9416 for (OMPClause *C : Clauses) { 9417 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9418 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9419 B.NumIterations, *this, CurScope, 9420 DSAStack)) 9421 return StmtError(); 9422 } 9423 } 9424 9425 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9426 return StmtError(); 9427 9428 setFunctionHasBranchProtectedScope(); 9429 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9430 NestedLoopCount, Clauses, AStmt, B); 9431 } 9432 9433 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9434 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9435 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9436 if (!AStmt) 9437 return StmtError(); 9438 9439 auto *CS = cast<CapturedStmt>(AStmt); 9440 // 1.2.2 OpenMP Language Terminology 9441 // Structured block - An executable statement with a single entry at the 9442 // top and a single exit at the bottom. 9443 // The point of exit cannot be a branch out of the structured block. 9444 // longjmp() and throw() must not violate the entry/exit criteria. 9445 CS->getCapturedDecl()->setNothrow(); 9446 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9447 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9448 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9449 // 1.2.2 OpenMP Language Terminology 9450 // Structured block - An executable statement with a single entry at the 9451 // top and a single exit at the bottom. 9452 // The point of exit cannot be a branch out of the structured block. 9453 // longjmp() and throw() must not violate the entry/exit criteria. 9454 CS->getCapturedDecl()->setNothrow(); 9455 } 9456 9457 OMPLoopDirective::HelperExprs B; 9458 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9459 // define the nested loops number. 9460 unsigned NestedLoopCount = checkOpenMPLoop( 9461 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9462 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9463 VarsWithImplicitDSA, B); 9464 if (NestedLoopCount == 0) 9465 return StmtError(); 9466 9467 assert((CurContext->isDependentContext() || B.builtAll()) && 9468 "omp target parallel for simd loop exprs were not built"); 9469 9470 if (!CurContext->isDependentContext()) { 9471 // Finalize the clauses that need pre-built expressions for CodeGen. 9472 for (OMPClause *C : Clauses) { 9473 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9474 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9475 B.NumIterations, *this, CurScope, 9476 DSAStack)) 9477 return StmtError(); 9478 } 9479 } 9480 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9481 return StmtError(); 9482 9483 setFunctionHasBranchProtectedScope(); 9484 return OMPTargetParallelForSimdDirective::Create( 9485 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9486 } 9487 9488 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9489 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9490 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9491 if (!AStmt) 9492 return StmtError(); 9493 9494 auto *CS = cast<CapturedStmt>(AStmt); 9495 // 1.2.2 OpenMP Language Terminology 9496 // Structured block - An executable statement with a single entry at the 9497 // top and a single exit at the bottom. 9498 // The point of exit cannot be a branch out of the structured block. 9499 // longjmp() and throw() must not violate the entry/exit criteria. 9500 CS->getCapturedDecl()->setNothrow(); 9501 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9502 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9503 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9504 // 1.2.2 OpenMP Language Terminology 9505 // Structured block - An executable statement with a single entry at the 9506 // top and a single exit at the bottom. 9507 // The point of exit cannot be a branch out of the structured block. 9508 // longjmp() and throw() must not violate the entry/exit criteria. 9509 CS->getCapturedDecl()->setNothrow(); 9510 } 9511 9512 OMPLoopDirective::HelperExprs B; 9513 // In presence of clause 'collapse' with number of loops, it will define the 9514 // nested loops number. 9515 unsigned NestedLoopCount = 9516 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9517 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9518 VarsWithImplicitDSA, B); 9519 if (NestedLoopCount == 0) 9520 return StmtError(); 9521 9522 assert((CurContext->isDependentContext() || B.builtAll()) && 9523 "omp target simd loop exprs were not built"); 9524 9525 if (!CurContext->isDependentContext()) { 9526 // Finalize the clauses that need pre-built expressions for CodeGen. 9527 for (OMPClause *C : Clauses) { 9528 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9529 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9530 B.NumIterations, *this, CurScope, 9531 DSAStack)) 9532 return StmtError(); 9533 } 9534 } 9535 9536 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9537 return StmtError(); 9538 9539 setFunctionHasBranchProtectedScope(); 9540 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9541 NestedLoopCount, Clauses, AStmt, B); 9542 } 9543 9544 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9545 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9546 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9547 if (!AStmt) 9548 return StmtError(); 9549 9550 auto *CS = cast<CapturedStmt>(AStmt); 9551 // 1.2.2 OpenMP Language Terminology 9552 // Structured block - An executable statement with a single entry at the 9553 // top and a single exit at the bottom. 9554 // The point of exit cannot be a branch out of the structured block. 9555 // longjmp() and throw() must not violate the entry/exit criteria. 9556 CS->getCapturedDecl()->setNothrow(); 9557 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9558 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9559 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9560 // 1.2.2 OpenMP Language Terminology 9561 // Structured block - An executable statement with a single entry at the 9562 // top and a single exit at the bottom. 9563 // The point of exit cannot be a branch out of the structured block. 9564 // longjmp() and throw() must not violate the entry/exit criteria. 9565 CS->getCapturedDecl()->setNothrow(); 9566 } 9567 9568 OMPLoopDirective::HelperExprs B; 9569 // In presence of clause 'collapse' with number of loops, it will 9570 // define the nested loops number. 9571 unsigned NestedLoopCount = 9572 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9573 nullptr /*ordered not a clause on distribute*/, CS, *this, 9574 *DSAStack, VarsWithImplicitDSA, B); 9575 if (NestedLoopCount == 0) 9576 return StmtError(); 9577 9578 assert((CurContext->isDependentContext() || B.builtAll()) && 9579 "omp teams distribute loop exprs were not built"); 9580 9581 setFunctionHasBranchProtectedScope(); 9582 9583 DSAStack->setParentTeamsRegionLoc(StartLoc); 9584 9585 return OMPTeamsDistributeDirective::Create( 9586 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9587 } 9588 9589 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9590 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9591 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9592 if (!AStmt) 9593 return StmtError(); 9594 9595 auto *CS = cast<CapturedStmt>(AStmt); 9596 // 1.2.2 OpenMP Language Terminology 9597 // Structured block - An executable statement with a single entry at the 9598 // top and a single exit at the bottom. 9599 // The point of exit cannot be a branch out of the structured block. 9600 // longjmp() and throw() must not violate the entry/exit criteria. 9601 CS->getCapturedDecl()->setNothrow(); 9602 for (int ThisCaptureLevel = 9603 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9604 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9605 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9606 // 1.2.2 OpenMP Language Terminology 9607 // Structured block - An executable statement with a single entry at the 9608 // top and a single exit at the bottom. 9609 // The point of exit cannot be a branch out of the structured block. 9610 // longjmp() and throw() must not violate the entry/exit criteria. 9611 CS->getCapturedDecl()->setNothrow(); 9612 } 9613 9614 9615 OMPLoopDirective::HelperExprs B; 9616 // In presence of clause 'collapse' with number of loops, it will 9617 // define the nested loops number. 9618 unsigned NestedLoopCount = checkOpenMPLoop( 9619 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9620 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9621 VarsWithImplicitDSA, B); 9622 9623 if (NestedLoopCount == 0) 9624 return StmtError(); 9625 9626 assert((CurContext->isDependentContext() || B.builtAll()) && 9627 "omp teams distribute simd loop exprs were not built"); 9628 9629 if (!CurContext->isDependentContext()) { 9630 // Finalize the clauses that need pre-built expressions for CodeGen. 9631 for (OMPClause *C : Clauses) { 9632 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9633 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9634 B.NumIterations, *this, CurScope, 9635 DSAStack)) 9636 return StmtError(); 9637 } 9638 } 9639 9640 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9641 return StmtError(); 9642 9643 setFunctionHasBranchProtectedScope(); 9644 9645 DSAStack->setParentTeamsRegionLoc(StartLoc); 9646 9647 return OMPTeamsDistributeSimdDirective::Create( 9648 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9649 } 9650 9651 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9652 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9653 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9654 if (!AStmt) 9655 return StmtError(); 9656 9657 auto *CS = cast<CapturedStmt>(AStmt); 9658 // 1.2.2 OpenMP Language Terminology 9659 // Structured block - An executable statement with a single entry at the 9660 // top and a single exit at the bottom. 9661 // The point of exit cannot be a branch out of the structured block. 9662 // longjmp() and throw() must not violate the entry/exit criteria. 9663 CS->getCapturedDecl()->setNothrow(); 9664 9665 for (int ThisCaptureLevel = 9666 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9667 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9668 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9669 // 1.2.2 OpenMP Language Terminology 9670 // Structured block - An executable statement with a single entry at the 9671 // top and a single exit at the bottom. 9672 // The point of exit cannot be a branch out of the structured block. 9673 // longjmp() and throw() must not violate the entry/exit criteria. 9674 CS->getCapturedDecl()->setNothrow(); 9675 } 9676 9677 OMPLoopDirective::HelperExprs B; 9678 // In presence of clause 'collapse' with number of loops, it will 9679 // define the nested loops number. 9680 unsigned NestedLoopCount = checkOpenMPLoop( 9681 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9682 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9683 VarsWithImplicitDSA, B); 9684 9685 if (NestedLoopCount == 0) 9686 return StmtError(); 9687 9688 assert((CurContext->isDependentContext() || B.builtAll()) && 9689 "omp for loop exprs were not built"); 9690 9691 if (!CurContext->isDependentContext()) { 9692 // Finalize the clauses that need pre-built expressions for CodeGen. 9693 for (OMPClause *C : Clauses) { 9694 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9695 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9696 B.NumIterations, *this, CurScope, 9697 DSAStack)) 9698 return StmtError(); 9699 } 9700 } 9701 9702 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9703 return StmtError(); 9704 9705 setFunctionHasBranchProtectedScope(); 9706 9707 DSAStack->setParentTeamsRegionLoc(StartLoc); 9708 9709 return OMPTeamsDistributeParallelForSimdDirective::Create( 9710 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9711 } 9712 9713 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9714 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9715 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9716 if (!AStmt) 9717 return StmtError(); 9718 9719 auto *CS = cast<CapturedStmt>(AStmt); 9720 // 1.2.2 OpenMP Language Terminology 9721 // Structured block - An executable statement with a single entry at the 9722 // top and a single exit at the bottom. 9723 // The point of exit cannot be a branch out of the structured block. 9724 // longjmp() and throw() must not violate the entry/exit criteria. 9725 CS->getCapturedDecl()->setNothrow(); 9726 9727 for (int ThisCaptureLevel = 9728 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9729 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9730 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9731 // 1.2.2 OpenMP Language Terminology 9732 // Structured block - An executable statement with a single entry at the 9733 // top and a single exit at the bottom. 9734 // The point of exit cannot be a branch out of the structured block. 9735 // longjmp() and throw() must not violate the entry/exit criteria. 9736 CS->getCapturedDecl()->setNothrow(); 9737 } 9738 9739 OMPLoopDirective::HelperExprs B; 9740 // In presence of clause 'collapse' with number of loops, it will 9741 // define the nested loops number. 9742 unsigned NestedLoopCount = checkOpenMPLoop( 9743 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9744 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9745 VarsWithImplicitDSA, B); 9746 9747 if (NestedLoopCount == 0) 9748 return StmtError(); 9749 9750 assert((CurContext->isDependentContext() || B.builtAll()) && 9751 "omp for loop exprs were not built"); 9752 9753 setFunctionHasBranchProtectedScope(); 9754 9755 DSAStack->setParentTeamsRegionLoc(StartLoc); 9756 9757 return OMPTeamsDistributeParallelForDirective::Create( 9758 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9759 DSAStack->isCancelRegion()); 9760 } 9761 9762 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9763 Stmt *AStmt, 9764 SourceLocation StartLoc, 9765 SourceLocation EndLoc) { 9766 if (!AStmt) 9767 return StmtError(); 9768 9769 auto *CS = cast<CapturedStmt>(AStmt); 9770 // 1.2.2 OpenMP Language Terminology 9771 // Structured block - An executable statement with a single entry at the 9772 // top and a single exit at the bottom. 9773 // The point of exit cannot be a branch out of the structured block. 9774 // longjmp() and throw() must not violate the entry/exit criteria. 9775 CS->getCapturedDecl()->setNothrow(); 9776 9777 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9778 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9779 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9780 // 1.2.2 OpenMP Language Terminology 9781 // Structured block - An executable statement with a single entry at the 9782 // top and a single exit at the bottom. 9783 // The point of exit cannot be a branch out of the structured block. 9784 // longjmp() and throw() must not violate the entry/exit criteria. 9785 CS->getCapturedDecl()->setNothrow(); 9786 } 9787 setFunctionHasBranchProtectedScope(); 9788 9789 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9790 AStmt); 9791 } 9792 9793 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9794 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9795 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9796 if (!AStmt) 9797 return StmtError(); 9798 9799 auto *CS = cast<CapturedStmt>(AStmt); 9800 // 1.2.2 OpenMP Language Terminology 9801 // Structured block - An executable statement with a single entry at the 9802 // top and a single exit at the bottom. 9803 // The point of exit cannot be a branch out of the structured block. 9804 // longjmp() and throw() must not violate the entry/exit criteria. 9805 CS->getCapturedDecl()->setNothrow(); 9806 for (int ThisCaptureLevel = 9807 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9808 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9809 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9810 // 1.2.2 OpenMP Language Terminology 9811 // Structured block - An executable statement with a single entry at the 9812 // top and a single exit at the bottom. 9813 // The point of exit cannot be a branch out of the structured block. 9814 // longjmp() and throw() must not violate the entry/exit criteria. 9815 CS->getCapturedDecl()->setNothrow(); 9816 } 9817 9818 OMPLoopDirective::HelperExprs B; 9819 // In presence of clause 'collapse' with number of loops, it will 9820 // define the nested loops number. 9821 unsigned NestedLoopCount = checkOpenMPLoop( 9822 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9823 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9824 VarsWithImplicitDSA, B); 9825 if (NestedLoopCount == 0) 9826 return StmtError(); 9827 9828 assert((CurContext->isDependentContext() || B.builtAll()) && 9829 "omp target teams distribute loop exprs were not built"); 9830 9831 setFunctionHasBranchProtectedScope(); 9832 return OMPTargetTeamsDistributeDirective::Create( 9833 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9834 } 9835 9836 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 9837 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9838 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9839 if (!AStmt) 9840 return StmtError(); 9841 9842 auto *CS = cast<CapturedStmt>(AStmt); 9843 // 1.2.2 OpenMP Language Terminology 9844 // Structured block - An executable statement with a single entry at the 9845 // top and a single exit at the bottom. 9846 // The point of exit cannot be a branch out of the structured block. 9847 // longjmp() and throw() must not violate the entry/exit criteria. 9848 CS->getCapturedDecl()->setNothrow(); 9849 for (int ThisCaptureLevel = 9850 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 9851 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9852 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9853 // 1.2.2 OpenMP Language Terminology 9854 // Structured block - An executable statement with a single entry at the 9855 // top and a single exit at the bottom. 9856 // The point of exit cannot be a branch out of the structured block. 9857 // longjmp() and throw() must not violate the entry/exit criteria. 9858 CS->getCapturedDecl()->setNothrow(); 9859 } 9860 9861 OMPLoopDirective::HelperExprs B; 9862 // In presence of clause 'collapse' with number of loops, it will 9863 // define the nested loops number. 9864 unsigned NestedLoopCount = checkOpenMPLoop( 9865 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9866 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9867 VarsWithImplicitDSA, B); 9868 if (NestedLoopCount == 0) 9869 return StmtError(); 9870 9871 assert((CurContext->isDependentContext() || B.builtAll()) && 9872 "omp target teams distribute parallel for loop exprs were not built"); 9873 9874 if (!CurContext->isDependentContext()) { 9875 // Finalize the clauses that need pre-built expressions for CodeGen. 9876 for (OMPClause *C : Clauses) { 9877 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9878 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9879 B.NumIterations, *this, CurScope, 9880 DSAStack)) 9881 return StmtError(); 9882 } 9883 } 9884 9885 setFunctionHasBranchProtectedScope(); 9886 return OMPTargetTeamsDistributeParallelForDirective::Create( 9887 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9888 DSAStack->isCancelRegion()); 9889 } 9890 9891 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9892 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9893 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9894 if (!AStmt) 9895 return StmtError(); 9896 9897 auto *CS = cast<CapturedStmt>(AStmt); 9898 // 1.2.2 OpenMP Language Terminology 9899 // Structured block - An executable statement with a single entry at the 9900 // top and a single exit at the bottom. 9901 // The point of exit cannot be a branch out of the structured block. 9902 // longjmp() and throw() must not violate the entry/exit criteria. 9903 CS->getCapturedDecl()->setNothrow(); 9904 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9905 OMPD_target_teams_distribute_parallel_for_simd); 9906 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9907 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9908 // 1.2.2 OpenMP Language Terminology 9909 // Structured block - An executable statement with a single entry at the 9910 // top and a single exit at the bottom. 9911 // The point of exit cannot be a branch out of the structured block. 9912 // longjmp() and throw() must not violate the entry/exit criteria. 9913 CS->getCapturedDecl()->setNothrow(); 9914 } 9915 9916 OMPLoopDirective::HelperExprs B; 9917 // In presence of clause 'collapse' with number of loops, it will 9918 // define the nested loops number. 9919 unsigned NestedLoopCount = 9920 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9921 getCollapseNumberExpr(Clauses), 9922 nullptr /*ordered not a clause on distribute*/, CS, *this, 9923 *DSAStack, VarsWithImplicitDSA, B); 9924 if (NestedLoopCount == 0) 9925 return StmtError(); 9926 9927 assert((CurContext->isDependentContext() || B.builtAll()) && 9928 "omp target teams distribute parallel for simd loop exprs were not " 9929 "built"); 9930 9931 if (!CurContext->isDependentContext()) { 9932 // Finalize the clauses that need pre-built expressions for CodeGen. 9933 for (OMPClause *C : Clauses) { 9934 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9935 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9936 B.NumIterations, *this, CurScope, 9937 DSAStack)) 9938 return StmtError(); 9939 } 9940 } 9941 9942 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9943 return StmtError(); 9944 9945 setFunctionHasBranchProtectedScope(); 9946 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9947 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9948 } 9949 9950 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9951 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9952 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9953 if (!AStmt) 9954 return StmtError(); 9955 9956 auto *CS = cast<CapturedStmt>(AStmt); 9957 // 1.2.2 OpenMP Language Terminology 9958 // Structured block - An executable statement with a single entry at the 9959 // top and a single exit at the bottom. 9960 // The point of exit cannot be a branch out of the structured block. 9961 // longjmp() and throw() must not violate the entry/exit criteria. 9962 CS->getCapturedDecl()->setNothrow(); 9963 for (int ThisCaptureLevel = 9964 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9965 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9966 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9967 // 1.2.2 OpenMP Language Terminology 9968 // Structured block - An executable statement with a single entry at the 9969 // top and a single exit at the bottom. 9970 // The point of exit cannot be a branch out of the structured block. 9971 // longjmp() and throw() must not violate the entry/exit criteria. 9972 CS->getCapturedDecl()->setNothrow(); 9973 } 9974 9975 OMPLoopDirective::HelperExprs B; 9976 // In presence of clause 'collapse' with number of loops, it will 9977 // define the nested loops number. 9978 unsigned NestedLoopCount = checkOpenMPLoop( 9979 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9980 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9981 VarsWithImplicitDSA, B); 9982 if (NestedLoopCount == 0) 9983 return StmtError(); 9984 9985 assert((CurContext->isDependentContext() || B.builtAll()) && 9986 "omp target teams distribute simd loop exprs were not built"); 9987 9988 if (!CurContext->isDependentContext()) { 9989 // Finalize the clauses that need pre-built expressions for CodeGen. 9990 for (OMPClause *C : Clauses) { 9991 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9992 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9993 B.NumIterations, *this, CurScope, 9994 DSAStack)) 9995 return StmtError(); 9996 } 9997 } 9998 9999 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10000 return StmtError(); 10001 10002 setFunctionHasBranchProtectedScope(); 10003 return OMPTargetTeamsDistributeSimdDirective::Create( 10004 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10005 } 10006 10007 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10008 SourceLocation StartLoc, 10009 SourceLocation LParenLoc, 10010 SourceLocation EndLoc) { 10011 OMPClause *Res = nullptr; 10012 switch (Kind) { 10013 case OMPC_final: 10014 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10015 break; 10016 case OMPC_num_threads: 10017 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10018 break; 10019 case OMPC_safelen: 10020 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10021 break; 10022 case OMPC_simdlen: 10023 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10024 break; 10025 case OMPC_allocator: 10026 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10027 break; 10028 case OMPC_collapse: 10029 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10030 break; 10031 case OMPC_ordered: 10032 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10033 break; 10034 case OMPC_device: 10035 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10036 break; 10037 case OMPC_num_teams: 10038 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10039 break; 10040 case OMPC_thread_limit: 10041 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10042 break; 10043 case OMPC_priority: 10044 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10045 break; 10046 case OMPC_grainsize: 10047 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10048 break; 10049 case OMPC_num_tasks: 10050 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10051 break; 10052 case OMPC_hint: 10053 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10054 break; 10055 case OMPC_if: 10056 case OMPC_default: 10057 case OMPC_proc_bind: 10058 case OMPC_schedule: 10059 case OMPC_private: 10060 case OMPC_firstprivate: 10061 case OMPC_lastprivate: 10062 case OMPC_shared: 10063 case OMPC_reduction: 10064 case OMPC_task_reduction: 10065 case OMPC_in_reduction: 10066 case OMPC_linear: 10067 case OMPC_aligned: 10068 case OMPC_copyin: 10069 case OMPC_copyprivate: 10070 case OMPC_nowait: 10071 case OMPC_untied: 10072 case OMPC_mergeable: 10073 case OMPC_threadprivate: 10074 case OMPC_allocate: 10075 case OMPC_flush: 10076 case OMPC_read: 10077 case OMPC_write: 10078 case OMPC_update: 10079 case OMPC_capture: 10080 case OMPC_seq_cst: 10081 case OMPC_depend: 10082 case OMPC_threads: 10083 case OMPC_simd: 10084 case OMPC_map: 10085 case OMPC_nogroup: 10086 case OMPC_dist_schedule: 10087 case OMPC_defaultmap: 10088 case OMPC_unknown: 10089 case OMPC_uniform: 10090 case OMPC_to: 10091 case OMPC_from: 10092 case OMPC_use_device_ptr: 10093 case OMPC_is_device_ptr: 10094 case OMPC_unified_address: 10095 case OMPC_unified_shared_memory: 10096 case OMPC_reverse_offload: 10097 case OMPC_dynamic_allocators: 10098 case OMPC_atomic_default_mem_order: 10099 case OMPC_device_type: 10100 case OMPC_match: 10101 llvm_unreachable("Clause is not allowed."); 10102 } 10103 return Res; 10104 } 10105 10106 // An OpenMP directive such as 'target parallel' has two captured regions: 10107 // for the 'target' and 'parallel' respectively. This function returns 10108 // the region in which to capture expressions associated with a clause. 10109 // A return value of OMPD_unknown signifies that the expression should not 10110 // be captured. 10111 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10112 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10113 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10114 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10115 switch (CKind) { 10116 case OMPC_if: 10117 switch (DKind) { 10118 case OMPD_target_parallel: 10119 case OMPD_target_parallel_for: 10120 case OMPD_target_parallel_for_simd: 10121 // If this clause applies to the nested 'parallel' region, capture within 10122 // the 'target' region, otherwise do not capture. 10123 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10124 CaptureRegion = OMPD_target; 10125 break; 10126 case OMPD_target_teams_distribute_parallel_for: 10127 case OMPD_target_teams_distribute_parallel_for_simd: 10128 // If this clause applies to the nested 'parallel' region, capture within 10129 // the 'teams' region, otherwise do not capture. 10130 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10131 CaptureRegion = OMPD_teams; 10132 break; 10133 case OMPD_teams_distribute_parallel_for: 10134 case OMPD_teams_distribute_parallel_for_simd: 10135 CaptureRegion = OMPD_teams; 10136 break; 10137 case OMPD_target_update: 10138 case OMPD_target_enter_data: 10139 case OMPD_target_exit_data: 10140 CaptureRegion = OMPD_task; 10141 break; 10142 case OMPD_cancel: 10143 case OMPD_parallel: 10144 case OMPD_parallel_sections: 10145 case OMPD_parallel_for: 10146 case OMPD_parallel_for_simd: 10147 case OMPD_target: 10148 case OMPD_target_simd: 10149 case OMPD_target_teams: 10150 case OMPD_target_teams_distribute: 10151 case OMPD_target_teams_distribute_simd: 10152 case OMPD_distribute_parallel_for: 10153 case OMPD_distribute_parallel_for_simd: 10154 case OMPD_task: 10155 case OMPD_taskloop: 10156 case OMPD_taskloop_simd: 10157 case OMPD_target_data: 10158 // Do not capture if-clause expressions. 10159 break; 10160 case OMPD_threadprivate: 10161 case OMPD_allocate: 10162 case OMPD_taskyield: 10163 case OMPD_barrier: 10164 case OMPD_taskwait: 10165 case OMPD_cancellation_point: 10166 case OMPD_flush: 10167 case OMPD_declare_reduction: 10168 case OMPD_declare_mapper: 10169 case OMPD_declare_simd: 10170 case OMPD_declare_variant: 10171 case OMPD_declare_target: 10172 case OMPD_end_declare_target: 10173 case OMPD_teams: 10174 case OMPD_simd: 10175 case OMPD_for: 10176 case OMPD_for_simd: 10177 case OMPD_sections: 10178 case OMPD_section: 10179 case OMPD_single: 10180 case OMPD_master: 10181 case OMPD_critical: 10182 case OMPD_taskgroup: 10183 case OMPD_distribute: 10184 case OMPD_ordered: 10185 case OMPD_atomic: 10186 case OMPD_distribute_simd: 10187 case OMPD_teams_distribute: 10188 case OMPD_teams_distribute_simd: 10189 case OMPD_requires: 10190 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10191 case OMPD_unknown: 10192 llvm_unreachable("Unknown OpenMP directive"); 10193 } 10194 break; 10195 case OMPC_num_threads: 10196 switch (DKind) { 10197 case OMPD_target_parallel: 10198 case OMPD_target_parallel_for: 10199 case OMPD_target_parallel_for_simd: 10200 CaptureRegion = OMPD_target; 10201 break; 10202 case OMPD_teams_distribute_parallel_for: 10203 case OMPD_teams_distribute_parallel_for_simd: 10204 case OMPD_target_teams_distribute_parallel_for: 10205 case OMPD_target_teams_distribute_parallel_for_simd: 10206 CaptureRegion = OMPD_teams; 10207 break; 10208 case OMPD_parallel: 10209 case OMPD_parallel_sections: 10210 case OMPD_parallel_for: 10211 case OMPD_parallel_for_simd: 10212 case OMPD_distribute_parallel_for: 10213 case OMPD_distribute_parallel_for_simd: 10214 // Do not capture num_threads-clause expressions. 10215 break; 10216 case OMPD_target_data: 10217 case OMPD_target_enter_data: 10218 case OMPD_target_exit_data: 10219 case OMPD_target_update: 10220 case OMPD_target: 10221 case OMPD_target_simd: 10222 case OMPD_target_teams: 10223 case OMPD_target_teams_distribute: 10224 case OMPD_target_teams_distribute_simd: 10225 case OMPD_cancel: 10226 case OMPD_task: 10227 case OMPD_taskloop: 10228 case OMPD_taskloop_simd: 10229 case OMPD_threadprivate: 10230 case OMPD_allocate: 10231 case OMPD_taskyield: 10232 case OMPD_barrier: 10233 case OMPD_taskwait: 10234 case OMPD_cancellation_point: 10235 case OMPD_flush: 10236 case OMPD_declare_reduction: 10237 case OMPD_declare_mapper: 10238 case OMPD_declare_simd: 10239 case OMPD_declare_variant: 10240 case OMPD_declare_target: 10241 case OMPD_end_declare_target: 10242 case OMPD_teams: 10243 case OMPD_simd: 10244 case OMPD_for: 10245 case OMPD_for_simd: 10246 case OMPD_sections: 10247 case OMPD_section: 10248 case OMPD_single: 10249 case OMPD_master: 10250 case OMPD_critical: 10251 case OMPD_taskgroup: 10252 case OMPD_distribute: 10253 case OMPD_ordered: 10254 case OMPD_atomic: 10255 case OMPD_distribute_simd: 10256 case OMPD_teams_distribute: 10257 case OMPD_teams_distribute_simd: 10258 case OMPD_requires: 10259 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10260 case OMPD_unknown: 10261 llvm_unreachable("Unknown OpenMP directive"); 10262 } 10263 break; 10264 case OMPC_num_teams: 10265 switch (DKind) { 10266 case OMPD_target_teams: 10267 case OMPD_target_teams_distribute: 10268 case OMPD_target_teams_distribute_simd: 10269 case OMPD_target_teams_distribute_parallel_for: 10270 case OMPD_target_teams_distribute_parallel_for_simd: 10271 CaptureRegion = OMPD_target; 10272 break; 10273 case OMPD_teams_distribute_parallel_for: 10274 case OMPD_teams_distribute_parallel_for_simd: 10275 case OMPD_teams: 10276 case OMPD_teams_distribute: 10277 case OMPD_teams_distribute_simd: 10278 // Do not capture num_teams-clause expressions. 10279 break; 10280 case OMPD_distribute_parallel_for: 10281 case OMPD_distribute_parallel_for_simd: 10282 case OMPD_task: 10283 case OMPD_taskloop: 10284 case OMPD_taskloop_simd: 10285 case OMPD_target_data: 10286 case OMPD_target_enter_data: 10287 case OMPD_target_exit_data: 10288 case OMPD_target_update: 10289 case OMPD_cancel: 10290 case OMPD_parallel: 10291 case OMPD_parallel_sections: 10292 case OMPD_parallel_for: 10293 case OMPD_parallel_for_simd: 10294 case OMPD_target: 10295 case OMPD_target_simd: 10296 case OMPD_target_parallel: 10297 case OMPD_target_parallel_for: 10298 case OMPD_target_parallel_for_simd: 10299 case OMPD_threadprivate: 10300 case OMPD_allocate: 10301 case OMPD_taskyield: 10302 case OMPD_barrier: 10303 case OMPD_taskwait: 10304 case OMPD_cancellation_point: 10305 case OMPD_flush: 10306 case OMPD_declare_reduction: 10307 case OMPD_declare_mapper: 10308 case OMPD_declare_simd: 10309 case OMPD_declare_variant: 10310 case OMPD_declare_target: 10311 case OMPD_end_declare_target: 10312 case OMPD_simd: 10313 case OMPD_for: 10314 case OMPD_for_simd: 10315 case OMPD_sections: 10316 case OMPD_section: 10317 case OMPD_single: 10318 case OMPD_master: 10319 case OMPD_critical: 10320 case OMPD_taskgroup: 10321 case OMPD_distribute: 10322 case OMPD_ordered: 10323 case OMPD_atomic: 10324 case OMPD_distribute_simd: 10325 case OMPD_requires: 10326 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10327 case OMPD_unknown: 10328 llvm_unreachable("Unknown OpenMP directive"); 10329 } 10330 break; 10331 case OMPC_thread_limit: 10332 switch (DKind) { 10333 case OMPD_target_teams: 10334 case OMPD_target_teams_distribute: 10335 case OMPD_target_teams_distribute_simd: 10336 case OMPD_target_teams_distribute_parallel_for: 10337 case OMPD_target_teams_distribute_parallel_for_simd: 10338 CaptureRegion = OMPD_target; 10339 break; 10340 case OMPD_teams_distribute_parallel_for: 10341 case OMPD_teams_distribute_parallel_for_simd: 10342 case OMPD_teams: 10343 case OMPD_teams_distribute: 10344 case OMPD_teams_distribute_simd: 10345 // Do not capture thread_limit-clause expressions. 10346 break; 10347 case OMPD_distribute_parallel_for: 10348 case OMPD_distribute_parallel_for_simd: 10349 case OMPD_task: 10350 case OMPD_taskloop: 10351 case OMPD_taskloop_simd: 10352 case OMPD_target_data: 10353 case OMPD_target_enter_data: 10354 case OMPD_target_exit_data: 10355 case OMPD_target_update: 10356 case OMPD_cancel: 10357 case OMPD_parallel: 10358 case OMPD_parallel_sections: 10359 case OMPD_parallel_for: 10360 case OMPD_parallel_for_simd: 10361 case OMPD_target: 10362 case OMPD_target_simd: 10363 case OMPD_target_parallel: 10364 case OMPD_target_parallel_for: 10365 case OMPD_target_parallel_for_simd: 10366 case OMPD_threadprivate: 10367 case OMPD_allocate: 10368 case OMPD_taskyield: 10369 case OMPD_barrier: 10370 case OMPD_taskwait: 10371 case OMPD_cancellation_point: 10372 case OMPD_flush: 10373 case OMPD_declare_reduction: 10374 case OMPD_declare_mapper: 10375 case OMPD_declare_simd: 10376 case OMPD_declare_variant: 10377 case OMPD_declare_target: 10378 case OMPD_end_declare_target: 10379 case OMPD_simd: 10380 case OMPD_for: 10381 case OMPD_for_simd: 10382 case OMPD_sections: 10383 case OMPD_section: 10384 case OMPD_single: 10385 case OMPD_master: 10386 case OMPD_critical: 10387 case OMPD_taskgroup: 10388 case OMPD_distribute: 10389 case OMPD_ordered: 10390 case OMPD_atomic: 10391 case OMPD_distribute_simd: 10392 case OMPD_requires: 10393 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10394 case OMPD_unknown: 10395 llvm_unreachable("Unknown OpenMP directive"); 10396 } 10397 break; 10398 case OMPC_schedule: 10399 switch (DKind) { 10400 case OMPD_parallel_for: 10401 case OMPD_parallel_for_simd: 10402 case OMPD_distribute_parallel_for: 10403 case OMPD_distribute_parallel_for_simd: 10404 case OMPD_teams_distribute_parallel_for: 10405 case OMPD_teams_distribute_parallel_for_simd: 10406 case OMPD_target_parallel_for: 10407 case OMPD_target_parallel_for_simd: 10408 case OMPD_target_teams_distribute_parallel_for: 10409 case OMPD_target_teams_distribute_parallel_for_simd: 10410 CaptureRegion = OMPD_parallel; 10411 break; 10412 case OMPD_for: 10413 case OMPD_for_simd: 10414 // Do not capture schedule-clause expressions. 10415 break; 10416 case OMPD_task: 10417 case OMPD_taskloop: 10418 case OMPD_taskloop_simd: 10419 case OMPD_target_data: 10420 case OMPD_target_enter_data: 10421 case OMPD_target_exit_data: 10422 case OMPD_target_update: 10423 case OMPD_teams: 10424 case OMPD_teams_distribute: 10425 case OMPD_teams_distribute_simd: 10426 case OMPD_target_teams_distribute: 10427 case OMPD_target_teams_distribute_simd: 10428 case OMPD_target: 10429 case OMPD_target_simd: 10430 case OMPD_target_parallel: 10431 case OMPD_cancel: 10432 case OMPD_parallel: 10433 case OMPD_parallel_sections: 10434 case OMPD_threadprivate: 10435 case OMPD_allocate: 10436 case OMPD_taskyield: 10437 case OMPD_barrier: 10438 case OMPD_taskwait: 10439 case OMPD_cancellation_point: 10440 case OMPD_flush: 10441 case OMPD_declare_reduction: 10442 case OMPD_declare_mapper: 10443 case OMPD_declare_simd: 10444 case OMPD_declare_variant: 10445 case OMPD_declare_target: 10446 case OMPD_end_declare_target: 10447 case OMPD_simd: 10448 case OMPD_sections: 10449 case OMPD_section: 10450 case OMPD_single: 10451 case OMPD_master: 10452 case OMPD_critical: 10453 case OMPD_taskgroup: 10454 case OMPD_distribute: 10455 case OMPD_ordered: 10456 case OMPD_atomic: 10457 case OMPD_distribute_simd: 10458 case OMPD_target_teams: 10459 case OMPD_requires: 10460 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10461 case OMPD_unknown: 10462 llvm_unreachable("Unknown OpenMP directive"); 10463 } 10464 break; 10465 case OMPC_dist_schedule: 10466 switch (DKind) { 10467 case OMPD_teams_distribute_parallel_for: 10468 case OMPD_teams_distribute_parallel_for_simd: 10469 case OMPD_teams_distribute: 10470 case OMPD_teams_distribute_simd: 10471 case OMPD_target_teams_distribute_parallel_for: 10472 case OMPD_target_teams_distribute_parallel_for_simd: 10473 case OMPD_target_teams_distribute: 10474 case OMPD_target_teams_distribute_simd: 10475 CaptureRegion = OMPD_teams; 10476 break; 10477 case OMPD_distribute_parallel_for: 10478 case OMPD_distribute_parallel_for_simd: 10479 case OMPD_distribute: 10480 case OMPD_distribute_simd: 10481 // Do not capture thread_limit-clause expressions. 10482 break; 10483 case OMPD_parallel_for: 10484 case OMPD_parallel_for_simd: 10485 case OMPD_target_parallel_for_simd: 10486 case OMPD_target_parallel_for: 10487 case OMPD_task: 10488 case OMPD_taskloop: 10489 case OMPD_taskloop_simd: 10490 case OMPD_target_data: 10491 case OMPD_target_enter_data: 10492 case OMPD_target_exit_data: 10493 case OMPD_target_update: 10494 case OMPD_teams: 10495 case OMPD_target: 10496 case OMPD_target_simd: 10497 case OMPD_target_parallel: 10498 case OMPD_cancel: 10499 case OMPD_parallel: 10500 case OMPD_parallel_sections: 10501 case OMPD_threadprivate: 10502 case OMPD_allocate: 10503 case OMPD_taskyield: 10504 case OMPD_barrier: 10505 case OMPD_taskwait: 10506 case OMPD_cancellation_point: 10507 case OMPD_flush: 10508 case OMPD_declare_reduction: 10509 case OMPD_declare_mapper: 10510 case OMPD_declare_simd: 10511 case OMPD_declare_variant: 10512 case OMPD_declare_target: 10513 case OMPD_end_declare_target: 10514 case OMPD_simd: 10515 case OMPD_for: 10516 case OMPD_for_simd: 10517 case OMPD_sections: 10518 case OMPD_section: 10519 case OMPD_single: 10520 case OMPD_master: 10521 case OMPD_critical: 10522 case OMPD_taskgroup: 10523 case OMPD_ordered: 10524 case OMPD_atomic: 10525 case OMPD_target_teams: 10526 case OMPD_requires: 10527 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10528 case OMPD_unknown: 10529 llvm_unreachable("Unknown OpenMP directive"); 10530 } 10531 break; 10532 case OMPC_device: 10533 switch (DKind) { 10534 case OMPD_target_update: 10535 case OMPD_target_enter_data: 10536 case OMPD_target_exit_data: 10537 case OMPD_target: 10538 case OMPD_target_simd: 10539 case OMPD_target_teams: 10540 case OMPD_target_parallel: 10541 case OMPD_target_teams_distribute: 10542 case OMPD_target_teams_distribute_simd: 10543 case OMPD_target_parallel_for: 10544 case OMPD_target_parallel_for_simd: 10545 case OMPD_target_teams_distribute_parallel_for: 10546 case OMPD_target_teams_distribute_parallel_for_simd: 10547 CaptureRegion = OMPD_task; 10548 break; 10549 case OMPD_target_data: 10550 // Do not capture device-clause expressions. 10551 break; 10552 case OMPD_teams_distribute_parallel_for: 10553 case OMPD_teams_distribute_parallel_for_simd: 10554 case OMPD_teams: 10555 case OMPD_teams_distribute: 10556 case OMPD_teams_distribute_simd: 10557 case OMPD_distribute_parallel_for: 10558 case OMPD_distribute_parallel_for_simd: 10559 case OMPD_task: 10560 case OMPD_taskloop: 10561 case OMPD_taskloop_simd: 10562 case OMPD_cancel: 10563 case OMPD_parallel: 10564 case OMPD_parallel_sections: 10565 case OMPD_parallel_for: 10566 case OMPD_parallel_for_simd: 10567 case OMPD_threadprivate: 10568 case OMPD_allocate: 10569 case OMPD_taskyield: 10570 case OMPD_barrier: 10571 case OMPD_taskwait: 10572 case OMPD_cancellation_point: 10573 case OMPD_flush: 10574 case OMPD_declare_reduction: 10575 case OMPD_declare_mapper: 10576 case OMPD_declare_simd: 10577 case OMPD_declare_variant: 10578 case OMPD_declare_target: 10579 case OMPD_end_declare_target: 10580 case OMPD_simd: 10581 case OMPD_for: 10582 case OMPD_for_simd: 10583 case OMPD_sections: 10584 case OMPD_section: 10585 case OMPD_single: 10586 case OMPD_master: 10587 case OMPD_critical: 10588 case OMPD_taskgroup: 10589 case OMPD_distribute: 10590 case OMPD_ordered: 10591 case OMPD_atomic: 10592 case OMPD_distribute_simd: 10593 case OMPD_requires: 10594 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10595 case OMPD_unknown: 10596 llvm_unreachable("Unknown OpenMP directive"); 10597 } 10598 break; 10599 case OMPC_firstprivate: 10600 case OMPC_lastprivate: 10601 case OMPC_reduction: 10602 case OMPC_task_reduction: 10603 case OMPC_in_reduction: 10604 case OMPC_linear: 10605 case OMPC_default: 10606 case OMPC_proc_bind: 10607 case OMPC_final: 10608 case OMPC_safelen: 10609 case OMPC_simdlen: 10610 case OMPC_allocator: 10611 case OMPC_collapse: 10612 case OMPC_private: 10613 case OMPC_shared: 10614 case OMPC_aligned: 10615 case OMPC_copyin: 10616 case OMPC_copyprivate: 10617 case OMPC_ordered: 10618 case OMPC_nowait: 10619 case OMPC_untied: 10620 case OMPC_mergeable: 10621 case OMPC_threadprivate: 10622 case OMPC_allocate: 10623 case OMPC_flush: 10624 case OMPC_read: 10625 case OMPC_write: 10626 case OMPC_update: 10627 case OMPC_capture: 10628 case OMPC_seq_cst: 10629 case OMPC_depend: 10630 case OMPC_threads: 10631 case OMPC_simd: 10632 case OMPC_map: 10633 case OMPC_priority: 10634 case OMPC_grainsize: 10635 case OMPC_nogroup: 10636 case OMPC_num_tasks: 10637 case OMPC_hint: 10638 case OMPC_defaultmap: 10639 case OMPC_unknown: 10640 case OMPC_uniform: 10641 case OMPC_to: 10642 case OMPC_from: 10643 case OMPC_use_device_ptr: 10644 case OMPC_is_device_ptr: 10645 case OMPC_unified_address: 10646 case OMPC_unified_shared_memory: 10647 case OMPC_reverse_offload: 10648 case OMPC_dynamic_allocators: 10649 case OMPC_atomic_default_mem_order: 10650 case OMPC_device_type: 10651 case OMPC_match: 10652 llvm_unreachable("Unexpected OpenMP clause."); 10653 } 10654 return CaptureRegion; 10655 } 10656 10657 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10658 Expr *Condition, SourceLocation StartLoc, 10659 SourceLocation LParenLoc, 10660 SourceLocation NameModifierLoc, 10661 SourceLocation ColonLoc, 10662 SourceLocation EndLoc) { 10663 Expr *ValExpr = Condition; 10664 Stmt *HelperValStmt = nullptr; 10665 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10666 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10667 !Condition->isInstantiationDependent() && 10668 !Condition->containsUnexpandedParameterPack()) { 10669 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10670 if (Val.isInvalid()) 10671 return nullptr; 10672 10673 ValExpr = Val.get(); 10674 10675 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10676 CaptureRegion = 10677 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10678 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10679 ValExpr = MakeFullExpr(ValExpr).get(); 10680 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10681 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10682 HelperValStmt = buildPreInits(Context, Captures); 10683 } 10684 } 10685 10686 return new (Context) 10687 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10688 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10689 } 10690 10691 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10692 SourceLocation StartLoc, 10693 SourceLocation LParenLoc, 10694 SourceLocation EndLoc) { 10695 Expr *ValExpr = Condition; 10696 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10697 !Condition->isInstantiationDependent() && 10698 !Condition->containsUnexpandedParameterPack()) { 10699 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10700 if (Val.isInvalid()) 10701 return nullptr; 10702 10703 ValExpr = MakeFullExpr(Val.get()).get(); 10704 } 10705 10706 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10707 } 10708 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10709 Expr *Op) { 10710 if (!Op) 10711 return ExprError(); 10712 10713 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10714 public: 10715 IntConvertDiagnoser() 10716 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10717 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10718 QualType T) override { 10719 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10720 } 10721 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10722 QualType T) override { 10723 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10724 } 10725 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10726 QualType T, 10727 QualType ConvTy) override { 10728 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10729 } 10730 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 10731 QualType ConvTy) override { 10732 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10733 << ConvTy->isEnumeralType() << ConvTy; 10734 } 10735 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 10736 QualType T) override { 10737 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 10738 } 10739 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 10740 QualType ConvTy) override { 10741 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10742 << ConvTy->isEnumeralType() << ConvTy; 10743 } 10744 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 10745 QualType) override { 10746 llvm_unreachable("conversion functions are permitted"); 10747 } 10748 } ConvertDiagnoser; 10749 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 10750 } 10751 10752 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 10753 OpenMPClauseKind CKind, 10754 bool StrictlyPositive) { 10755 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 10756 !ValExpr->isInstantiationDependent()) { 10757 SourceLocation Loc = ValExpr->getExprLoc(); 10758 ExprResult Value = 10759 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 10760 if (Value.isInvalid()) 10761 return false; 10762 10763 ValExpr = Value.get(); 10764 // The expression must evaluate to a non-negative integer value. 10765 llvm::APSInt Result; 10766 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 10767 Result.isSigned() && 10768 !((!StrictlyPositive && Result.isNonNegative()) || 10769 (StrictlyPositive && Result.isStrictlyPositive()))) { 10770 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 10771 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10772 << ValExpr->getSourceRange(); 10773 return false; 10774 } 10775 } 10776 return true; 10777 } 10778 10779 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 10780 SourceLocation StartLoc, 10781 SourceLocation LParenLoc, 10782 SourceLocation EndLoc) { 10783 Expr *ValExpr = NumThreads; 10784 Stmt *HelperValStmt = nullptr; 10785 10786 // OpenMP [2.5, Restrictions] 10787 // The num_threads expression must evaluate to a positive integer value. 10788 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 10789 /*StrictlyPositive=*/true)) 10790 return nullptr; 10791 10792 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10793 OpenMPDirectiveKind CaptureRegion = 10794 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 10795 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10796 ValExpr = MakeFullExpr(ValExpr).get(); 10797 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10798 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10799 HelperValStmt = buildPreInits(Context, Captures); 10800 } 10801 10802 return new (Context) OMPNumThreadsClause( 10803 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 10804 } 10805 10806 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 10807 OpenMPClauseKind CKind, 10808 bool StrictlyPositive) { 10809 if (!E) 10810 return ExprError(); 10811 if (E->isValueDependent() || E->isTypeDependent() || 10812 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 10813 return E; 10814 llvm::APSInt Result; 10815 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 10816 if (ICE.isInvalid()) 10817 return ExprError(); 10818 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 10819 (!StrictlyPositive && !Result.isNonNegative())) { 10820 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 10821 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10822 << E->getSourceRange(); 10823 return ExprError(); 10824 } 10825 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 10826 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 10827 << E->getSourceRange(); 10828 return ExprError(); 10829 } 10830 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 10831 DSAStack->setAssociatedLoops(Result.getExtValue()); 10832 else if (CKind == OMPC_ordered) 10833 DSAStack->setAssociatedLoops(Result.getExtValue()); 10834 return ICE; 10835 } 10836 10837 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 10838 SourceLocation LParenLoc, 10839 SourceLocation EndLoc) { 10840 // OpenMP [2.8.1, simd construct, Description] 10841 // The parameter of the safelen clause must be a constant 10842 // positive integer expression. 10843 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 10844 if (Safelen.isInvalid()) 10845 return nullptr; 10846 return new (Context) 10847 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 10848 } 10849 10850 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 10851 SourceLocation LParenLoc, 10852 SourceLocation EndLoc) { 10853 // OpenMP [2.8.1, simd construct, Description] 10854 // The parameter of the simdlen clause must be a constant 10855 // positive integer expression. 10856 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 10857 if (Simdlen.isInvalid()) 10858 return nullptr; 10859 return new (Context) 10860 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 10861 } 10862 10863 /// Tries to find omp_allocator_handle_t type. 10864 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 10865 DSAStackTy *Stack) { 10866 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 10867 if (!OMPAllocatorHandleT.isNull()) 10868 return true; 10869 // Build the predefined allocator expressions. 10870 bool ErrorFound = false; 10871 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 10872 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 10873 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 10874 StringRef Allocator = 10875 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 10876 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 10877 auto *VD = dyn_cast_or_null<ValueDecl>( 10878 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 10879 if (!VD) { 10880 ErrorFound = true; 10881 break; 10882 } 10883 QualType AllocatorType = 10884 VD->getType().getNonLValueExprType(S.getASTContext()); 10885 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10886 if (!Res.isUsable()) { 10887 ErrorFound = true; 10888 break; 10889 } 10890 if (OMPAllocatorHandleT.isNull()) 10891 OMPAllocatorHandleT = AllocatorType; 10892 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10893 ErrorFound = true; 10894 break; 10895 } 10896 Stack->setAllocator(AllocatorKind, Res.get()); 10897 } 10898 if (ErrorFound) { 10899 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10900 return false; 10901 } 10902 OMPAllocatorHandleT.addConst(); 10903 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10904 return true; 10905 } 10906 10907 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10908 SourceLocation LParenLoc, 10909 SourceLocation EndLoc) { 10910 // OpenMP [2.11.3, allocate Directive, Description] 10911 // allocator is an expression of omp_allocator_handle_t type. 10912 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10913 return nullptr; 10914 10915 ExprResult Allocator = DefaultLvalueConversion(A); 10916 if (Allocator.isInvalid()) 10917 return nullptr; 10918 Allocator = PerformImplicitConversion(Allocator.get(), 10919 DSAStack->getOMPAllocatorHandleT(), 10920 Sema::AA_Initializing, 10921 /*AllowExplicit=*/true); 10922 if (Allocator.isInvalid()) 10923 return nullptr; 10924 return new (Context) 10925 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10926 } 10927 10928 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10929 SourceLocation StartLoc, 10930 SourceLocation LParenLoc, 10931 SourceLocation EndLoc) { 10932 // OpenMP [2.7.1, loop construct, Description] 10933 // OpenMP [2.8.1, simd construct, Description] 10934 // OpenMP [2.9.6, distribute construct, Description] 10935 // The parameter of the collapse clause must be a constant 10936 // positive integer expression. 10937 ExprResult NumForLoopsResult = 10938 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10939 if (NumForLoopsResult.isInvalid()) 10940 return nullptr; 10941 return new (Context) 10942 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10943 } 10944 10945 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10946 SourceLocation EndLoc, 10947 SourceLocation LParenLoc, 10948 Expr *NumForLoops) { 10949 // OpenMP [2.7.1, loop construct, Description] 10950 // OpenMP [2.8.1, simd construct, Description] 10951 // OpenMP [2.9.6, distribute construct, Description] 10952 // The parameter of the ordered clause must be a constant 10953 // positive integer expression if any. 10954 if (NumForLoops && LParenLoc.isValid()) { 10955 ExprResult NumForLoopsResult = 10956 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10957 if (NumForLoopsResult.isInvalid()) 10958 return nullptr; 10959 NumForLoops = NumForLoopsResult.get(); 10960 } else { 10961 NumForLoops = nullptr; 10962 } 10963 auto *Clause = OMPOrderedClause::Create( 10964 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10965 StartLoc, LParenLoc, EndLoc); 10966 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10967 return Clause; 10968 } 10969 10970 OMPClause *Sema::ActOnOpenMPSimpleClause( 10971 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10972 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10973 OMPClause *Res = nullptr; 10974 switch (Kind) { 10975 case OMPC_default: 10976 Res = 10977 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10978 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10979 break; 10980 case OMPC_proc_bind: 10981 Res = ActOnOpenMPProcBindClause( 10982 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10983 LParenLoc, EndLoc); 10984 break; 10985 case OMPC_atomic_default_mem_order: 10986 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10987 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10988 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10989 break; 10990 case OMPC_if: 10991 case OMPC_final: 10992 case OMPC_num_threads: 10993 case OMPC_safelen: 10994 case OMPC_simdlen: 10995 case OMPC_allocator: 10996 case OMPC_collapse: 10997 case OMPC_schedule: 10998 case OMPC_private: 10999 case OMPC_firstprivate: 11000 case OMPC_lastprivate: 11001 case OMPC_shared: 11002 case OMPC_reduction: 11003 case OMPC_task_reduction: 11004 case OMPC_in_reduction: 11005 case OMPC_linear: 11006 case OMPC_aligned: 11007 case OMPC_copyin: 11008 case OMPC_copyprivate: 11009 case OMPC_ordered: 11010 case OMPC_nowait: 11011 case OMPC_untied: 11012 case OMPC_mergeable: 11013 case OMPC_threadprivate: 11014 case OMPC_allocate: 11015 case OMPC_flush: 11016 case OMPC_read: 11017 case OMPC_write: 11018 case OMPC_update: 11019 case OMPC_capture: 11020 case OMPC_seq_cst: 11021 case OMPC_depend: 11022 case OMPC_device: 11023 case OMPC_threads: 11024 case OMPC_simd: 11025 case OMPC_map: 11026 case OMPC_num_teams: 11027 case OMPC_thread_limit: 11028 case OMPC_priority: 11029 case OMPC_grainsize: 11030 case OMPC_nogroup: 11031 case OMPC_num_tasks: 11032 case OMPC_hint: 11033 case OMPC_dist_schedule: 11034 case OMPC_defaultmap: 11035 case OMPC_unknown: 11036 case OMPC_uniform: 11037 case OMPC_to: 11038 case OMPC_from: 11039 case OMPC_use_device_ptr: 11040 case OMPC_is_device_ptr: 11041 case OMPC_unified_address: 11042 case OMPC_unified_shared_memory: 11043 case OMPC_reverse_offload: 11044 case OMPC_dynamic_allocators: 11045 case OMPC_device_type: 11046 case OMPC_match: 11047 llvm_unreachable("Clause is not allowed."); 11048 } 11049 return Res; 11050 } 11051 11052 static std::string 11053 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11054 ArrayRef<unsigned> Exclude = llvm::None) { 11055 SmallString<256> Buffer; 11056 llvm::raw_svector_ostream Out(Buffer); 11057 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11058 unsigned Skipped = Exclude.size(); 11059 auto S = Exclude.begin(), E = Exclude.end(); 11060 for (unsigned I = First; I < Last; ++I) { 11061 if (std::find(S, E, I) != E) { 11062 --Skipped; 11063 continue; 11064 } 11065 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11066 if (I == Bound - Skipped) 11067 Out << " or "; 11068 else if (I != Bound + 1 - Skipped) 11069 Out << ", "; 11070 } 11071 return Out.str(); 11072 } 11073 11074 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11075 SourceLocation KindKwLoc, 11076 SourceLocation StartLoc, 11077 SourceLocation LParenLoc, 11078 SourceLocation EndLoc) { 11079 if (Kind == OMPC_DEFAULT_unknown) { 11080 static_assert(OMPC_DEFAULT_unknown > 0, 11081 "OMPC_DEFAULT_unknown not greater than 0"); 11082 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11083 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11084 /*Last=*/OMPC_DEFAULT_unknown) 11085 << getOpenMPClauseName(OMPC_default); 11086 return nullptr; 11087 } 11088 switch (Kind) { 11089 case OMPC_DEFAULT_none: 11090 DSAStack->setDefaultDSANone(KindKwLoc); 11091 break; 11092 case OMPC_DEFAULT_shared: 11093 DSAStack->setDefaultDSAShared(KindKwLoc); 11094 break; 11095 case OMPC_DEFAULT_unknown: 11096 llvm_unreachable("Clause kind is not allowed."); 11097 break; 11098 } 11099 return new (Context) 11100 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11101 } 11102 11103 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11104 SourceLocation KindKwLoc, 11105 SourceLocation StartLoc, 11106 SourceLocation LParenLoc, 11107 SourceLocation EndLoc) { 11108 if (Kind == OMPC_PROC_BIND_unknown) { 11109 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11110 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11111 /*Last=*/OMPC_PROC_BIND_unknown) 11112 << getOpenMPClauseName(OMPC_proc_bind); 11113 return nullptr; 11114 } 11115 return new (Context) 11116 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11117 } 11118 11119 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11120 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11121 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11122 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11123 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11124 << getListOfPossibleValues( 11125 OMPC_atomic_default_mem_order, /*First=*/0, 11126 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11127 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11128 return nullptr; 11129 } 11130 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11131 LParenLoc, EndLoc); 11132 } 11133 11134 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11135 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11136 SourceLocation StartLoc, SourceLocation LParenLoc, 11137 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11138 SourceLocation EndLoc) { 11139 OMPClause *Res = nullptr; 11140 switch (Kind) { 11141 case OMPC_schedule: 11142 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11143 assert(Argument.size() == NumberOfElements && 11144 ArgumentLoc.size() == NumberOfElements); 11145 Res = ActOnOpenMPScheduleClause( 11146 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11147 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11148 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11149 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11150 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11151 break; 11152 case OMPC_if: 11153 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11154 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11155 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11156 DelimLoc, EndLoc); 11157 break; 11158 case OMPC_dist_schedule: 11159 Res = ActOnOpenMPDistScheduleClause( 11160 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11161 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11162 break; 11163 case OMPC_defaultmap: 11164 enum { Modifier, DefaultmapKind }; 11165 Res = ActOnOpenMPDefaultmapClause( 11166 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11167 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11168 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11169 EndLoc); 11170 break; 11171 case OMPC_final: 11172 case OMPC_num_threads: 11173 case OMPC_safelen: 11174 case OMPC_simdlen: 11175 case OMPC_allocator: 11176 case OMPC_collapse: 11177 case OMPC_default: 11178 case OMPC_proc_bind: 11179 case OMPC_private: 11180 case OMPC_firstprivate: 11181 case OMPC_lastprivate: 11182 case OMPC_shared: 11183 case OMPC_reduction: 11184 case OMPC_task_reduction: 11185 case OMPC_in_reduction: 11186 case OMPC_linear: 11187 case OMPC_aligned: 11188 case OMPC_copyin: 11189 case OMPC_copyprivate: 11190 case OMPC_ordered: 11191 case OMPC_nowait: 11192 case OMPC_untied: 11193 case OMPC_mergeable: 11194 case OMPC_threadprivate: 11195 case OMPC_allocate: 11196 case OMPC_flush: 11197 case OMPC_read: 11198 case OMPC_write: 11199 case OMPC_update: 11200 case OMPC_capture: 11201 case OMPC_seq_cst: 11202 case OMPC_depend: 11203 case OMPC_device: 11204 case OMPC_threads: 11205 case OMPC_simd: 11206 case OMPC_map: 11207 case OMPC_num_teams: 11208 case OMPC_thread_limit: 11209 case OMPC_priority: 11210 case OMPC_grainsize: 11211 case OMPC_nogroup: 11212 case OMPC_num_tasks: 11213 case OMPC_hint: 11214 case OMPC_unknown: 11215 case OMPC_uniform: 11216 case OMPC_to: 11217 case OMPC_from: 11218 case OMPC_use_device_ptr: 11219 case OMPC_is_device_ptr: 11220 case OMPC_unified_address: 11221 case OMPC_unified_shared_memory: 11222 case OMPC_reverse_offload: 11223 case OMPC_dynamic_allocators: 11224 case OMPC_atomic_default_mem_order: 11225 case OMPC_device_type: 11226 case OMPC_match: 11227 llvm_unreachable("Clause is not allowed."); 11228 } 11229 return Res; 11230 } 11231 11232 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11233 OpenMPScheduleClauseModifier M2, 11234 SourceLocation M1Loc, SourceLocation M2Loc) { 11235 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11236 SmallVector<unsigned, 2> Excluded; 11237 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11238 Excluded.push_back(M2); 11239 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11240 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11241 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11242 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11243 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11244 << getListOfPossibleValues(OMPC_schedule, 11245 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11246 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11247 Excluded) 11248 << getOpenMPClauseName(OMPC_schedule); 11249 return true; 11250 } 11251 return false; 11252 } 11253 11254 OMPClause *Sema::ActOnOpenMPScheduleClause( 11255 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11256 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11257 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11258 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11259 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11260 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11261 return nullptr; 11262 // OpenMP, 2.7.1, Loop Construct, Restrictions 11263 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11264 // but not both. 11265 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11266 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11267 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11268 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11269 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11270 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11271 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11272 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11273 return nullptr; 11274 } 11275 if (Kind == OMPC_SCHEDULE_unknown) { 11276 std::string Values; 11277 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11278 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11279 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11280 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11281 Exclude); 11282 } else { 11283 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11284 /*Last=*/OMPC_SCHEDULE_unknown); 11285 } 11286 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11287 << Values << getOpenMPClauseName(OMPC_schedule); 11288 return nullptr; 11289 } 11290 // OpenMP, 2.7.1, Loop Construct, Restrictions 11291 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11292 // schedule(guided). 11293 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11294 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11295 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11296 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11297 diag::err_omp_schedule_nonmonotonic_static); 11298 return nullptr; 11299 } 11300 Expr *ValExpr = ChunkSize; 11301 Stmt *HelperValStmt = nullptr; 11302 if (ChunkSize) { 11303 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11304 !ChunkSize->isInstantiationDependent() && 11305 !ChunkSize->containsUnexpandedParameterPack()) { 11306 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11307 ExprResult Val = 11308 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11309 if (Val.isInvalid()) 11310 return nullptr; 11311 11312 ValExpr = Val.get(); 11313 11314 // OpenMP [2.7.1, Restrictions] 11315 // chunk_size must be a loop invariant integer expression with a positive 11316 // value. 11317 llvm::APSInt Result; 11318 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11319 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11320 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11321 << "schedule" << 1 << ChunkSize->getSourceRange(); 11322 return nullptr; 11323 } 11324 } else if (getOpenMPCaptureRegionForClause( 11325 DSAStack->getCurrentDirective(), OMPC_schedule) != 11326 OMPD_unknown && 11327 !CurContext->isDependentContext()) { 11328 ValExpr = MakeFullExpr(ValExpr).get(); 11329 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11330 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11331 HelperValStmt = buildPreInits(Context, Captures); 11332 } 11333 } 11334 } 11335 11336 return new (Context) 11337 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11338 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11339 } 11340 11341 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11342 SourceLocation StartLoc, 11343 SourceLocation EndLoc) { 11344 OMPClause *Res = nullptr; 11345 switch (Kind) { 11346 case OMPC_ordered: 11347 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11348 break; 11349 case OMPC_nowait: 11350 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11351 break; 11352 case OMPC_untied: 11353 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11354 break; 11355 case OMPC_mergeable: 11356 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11357 break; 11358 case OMPC_read: 11359 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11360 break; 11361 case OMPC_write: 11362 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11363 break; 11364 case OMPC_update: 11365 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11366 break; 11367 case OMPC_capture: 11368 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11369 break; 11370 case OMPC_seq_cst: 11371 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11372 break; 11373 case OMPC_threads: 11374 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11375 break; 11376 case OMPC_simd: 11377 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11378 break; 11379 case OMPC_nogroup: 11380 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11381 break; 11382 case OMPC_unified_address: 11383 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11384 break; 11385 case OMPC_unified_shared_memory: 11386 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11387 break; 11388 case OMPC_reverse_offload: 11389 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11390 break; 11391 case OMPC_dynamic_allocators: 11392 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11393 break; 11394 case OMPC_if: 11395 case OMPC_final: 11396 case OMPC_num_threads: 11397 case OMPC_safelen: 11398 case OMPC_simdlen: 11399 case OMPC_allocator: 11400 case OMPC_collapse: 11401 case OMPC_schedule: 11402 case OMPC_private: 11403 case OMPC_firstprivate: 11404 case OMPC_lastprivate: 11405 case OMPC_shared: 11406 case OMPC_reduction: 11407 case OMPC_task_reduction: 11408 case OMPC_in_reduction: 11409 case OMPC_linear: 11410 case OMPC_aligned: 11411 case OMPC_copyin: 11412 case OMPC_copyprivate: 11413 case OMPC_default: 11414 case OMPC_proc_bind: 11415 case OMPC_threadprivate: 11416 case OMPC_allocate: 11417 case OMPC_flush: 11418 case OMPC_depend: 11419 case OMPC_device: 11420 case OMPC_map: 11421 case OMPC_num_teams: 11422 case OMPC_thread_limit: 11423 case OMPC_priority: 11424 case OMPC_grainsize: 11425 case OMPC_num_tasks: 11426 case OMPC_hint: 11427 case OMPC_dist_schedule: 11428 case OMPC_defaultmap: 11429 case OMPC_unknown: 11430 case OMPC_uniform: 11431 case OMPC_to: 11432 case OMPC_from: 11433 case OMPC_use_device_ptr: 11434 case OMPC_is_device_ptr: 11435 case OMPC_atomic_default_mem_order: 11436 case OMPC_device_type: 11437 case OMPC_match: 11438 llvm_unreachable("Clause is not allowed."); 11439 } 11440 return Res; 11441 } 11442 11443 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11444 SourceLocation EndLoc) { 11445 DSAStack->setNowaitRegion(); 11446 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11447 } 11448 11449 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11450 SourceLocation EndLoc) { 11451 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11452 } 11453 11454 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11455 SourceLocation EndLoc) { 11456 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11457 } 11458 11459 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11460 SourceLocation EndLoc) { 11461 return new (Context) OMPReadClause(StartLoc, EndLoc); 11462 } 11463 11464 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11465 SourceLocation EndLoc) { 11466 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11467 } 11468 11469 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11470 SourceLocation EndLoc) { 11471 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11472 } 11473 11474 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11475 SourceLocation EndLoc) { 11476 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11477 } 11478 11479 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11480 SourceLocation EndLoc) { 11481 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11482 } 11483 11484 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11485 SourceLocation EndLoc) { 11486 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11487 } 11488 11489 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11490 SourceLocation EndLoc) { 11491 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11492 } 11493 11494 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11495 SourceLocation EndLoc) { 11496 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11497 } 11498 11499 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11500 SourceLocation EndLoc) { 11501 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11502 } 11503 11504 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11505 SourceLocation EndLoc) { 11506 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11507 } 11508 11509 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11510 SourceLocation EndLoc) { 11511 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11512 } 11513 11514 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11515 SourceLocation EndLoc) { 11516 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11517 } 11518 11519 OMPClause *Sema::ActOnOpenMPVarListClause( 11520 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11521 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11522 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11523 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11524 OpenMPLinearClauseKind LinKind, 11525 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11526 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11527 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11528 SourceLocation StartLoc = Locs.StartLoc; 11529 SourceLocation LParenLoc = Locs.LParenLoc; 11530 SourceLocation EndLoc = Locs.EndLoc; 11531 OMPClause *Res = nullptr; 11532 switch (Kind) { 11533 case OMPC_private: 11534 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11535 break; 11536 case OMPC_firstprivate: 11537 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11538 break; 11539 case OMPC_lastprivate: 11540 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11541 break; 11542 case OMPC_shared: 11543 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11544 break; 11545 case OMPC_reduction: 11546 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11547 EndLoc, ReductionOrMapperIdScopeSpec, 11548 ReductionOrMapperId); 11549 break; 11550 case OMPC_task_reduction: 11551 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11552 EndLoc, ReductionOrMapperIdScopeSpec, 11553 ReductionOrMapperId); 11554 break; 11555 case OMPC_in_reduction: 11556 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11557 EndLoc, ReductionOrMapperIdScopeSpec, 11558 ReductionOrMapperId); 11559 break; 11560 case OMPC_linear: 11561 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11562 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11563 break; 11564 case OMPC_aligned: 11565 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11566 ColonLoc, EndLoc); 11567 break; 11568 case OMPC_copyin: 11569 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11570 break; 11571 case OMPC_copyprivate: 11572 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11573 break; 11574 case OMPC_flush: 11575 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11576 break; 11577 case OMPC_depend: 11578 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11579 StartLoc, LParenLoc, EndLoc); 11580 break; 11581 case OMPC_map: 11582 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11583 ReductionOrMapperIdScopeSpec, 11584 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11585 DepLinMapLoc, ColonLoc, VarList, Locs); 11586 break; 11587 case OMPC_to: 11588 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11589 ReductionOrMapperId, Locs); 11590 break; 11591 case OMPC_from: 11592 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11593 ReductionOrMapperId, Locs); 11594 break; 11595 case OMPC_use_device_ptr: 11596 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11597 break; 11598 case OMPC_is_device_ptr: 11599 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11600 break; 11601 case OMPC_allocate: 11602 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11603 ColonLoc, EndLoc); 11604 break; 11605 case OMPC_if: 11606 case OMPC_final: 11607 case OMPC_num_threads: 11608 case OMPC_safelen: 11609 case OMPC_simdlen: 11610 case OMPC_allocator: 11611 case OMPC_collapse: 11612 case OMPC_default: 11613 case OMPC_proc_bind: 11614 case OMPC_schedule: 11615 case OMPC_ordered: 11616 case OMPC_nowait: 11617 case OMPC_untied: 11618 case OMPC_mergeable: 11619 case OMPC_threadprivate: 11620 case OMPC_read: 11621 case OMPC_write: 11622 case OMPC_update: 11623 case OMPC_capture: 11624 case OMPC_seq_cst: 11625 case OMPC_device: 11626 case OMPC_threads: 11627 case OMPC_simd: 11628 case OMPC_num_teams: 11629 case OMPC_thread_limit: 11630 case OMPC_priority: 11631 case OMPC_grainsize: 11632 case OMPC_nogroup: 11633 case OMPC_num_tasks: 11634 case OMPC_hint: 11635 case OMPC_dist_schedule: 11636 case OMPC_defaultmap: 11637 case OMPC_unknown: 11638 case OMPC_uniform: 11639 case OMPC_unified_address: 11640 case OMPC_unified_shared_memory: 11641 case OMPC_reverse_offload: 11642 case OMPC_dynamic_allocators: 11643 case OMPC_atomic_default_mem_order: 11644 case OMPC_device_type: 11645 case OMPC_match: 11646 llvm_unreachable("Clause is not allowed."); 11647 } 11648 return Res; 11649 } 11650 11651 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11652 ExprObjectKind OK, SourceLocation Loc) { 11653 ExprResult Res = BuildDeclRefExpr( 11654 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11655 if (!Res.isUsable()) 11656 return ExprError(); 11657 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11658 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11659 if (!Res.isUsable()) 11660 return ExprError(); 11661 } 11662 if (VK != VK_LValue && Res.get()->isGLValue()) { 11663 Res = DefaultLvalueConversion(Res.get()); 11664 if (!Res.isUsable()) 11665 return ExprError(); 11666 } 11667 return Res; 11668 } 11669 11670 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11671 SourceLocation StartLoc, 11672 SourceLocation LParenLoc, 11673 SourceLocation EndLoc) { 11674 SmallVector<Expr *, 8> Vars; 11675 SmallVector<Expr *, 8> PrivateCopies; 11676 for (Expr *RefExpr : VarList) { 11677 assert(RefExpr && "NULL expr in OpenMP private clause."); 11678 SourceLocation ELoc; 11679 SourceRange ERange; 11680 Expr *SimpleRefExpr = RefExpr; 11681 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11682 if (Res.second) { 11683 // It will be analyzed later. 11684 Vars.push_back(RefExpr); 11685 PrivateCopies.push_back(nullptr); 11686 } 11687 ValueDecl *D = Res.first; 11688 if (!D) 11689 continue; 11690 11691 QualType Type = D->getType(); 11692 auto *VD = dyn_cast<VarDecl>(D); 11693 11694 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11695 // A variable that appears in a private clause must not have an incomplete 11696 // type or a reference type. 11697 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11698 continue; 11699 Type = Type.getNonReferenceType(); 11700 11701 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11702 // A variable that is privatized must not have a const-qualified type 11703 // unless it is of class type with a mutable member. This restriction does 11704 // not apply to the firstprivate clause. 11705 // 11706 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11707 // A variable that appears in a private clause must not have a 11708 // const-qualified type unless it is of class type with a mutable member. 11709 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11710 continue; 11711 11712 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11713 // in a Construct] 11714 // Variables with the predetermined data-sharing attributes may not be 11715 // listed in data-sharing attributes clauses, except for the cases 11716 // listed below. For these exceptions only, listing a predetermined 11717 // variable in a data-sharing attribute clause is allowed and overrides 11718 // the variable's predetermined data-sharing attributes. 11719 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11720 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 11721 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11722 << getOpenMPClauseName(OMPC_private); 11723 reportOriginalDsa(*this, DSAStack, D, DVar); 11724 continue; 11725 } 11726 11727 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11728 // Variably modified types are not supported for tasks. 11729 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11730 isOpenMPTaskingDirective(CurrDir)) { 11731 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11732 << getOpenMPClauseName(OMPC_private) << Type 11733 << getOpenMPDirectiveName(CurrDir); 11734 bool IsDecl = 11735 !VD || 11736 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11737 Diag(D->getLocation(), 11738 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11739 << D; 11740 continue; 11741 } 11742 11743 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11744 // A list item cannot appear in both a map clause and a data-sharing 11745 // attribute clause on the same construct 11746 // 11747 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11748 // A list item cannot appear in both a map clause and a data-sharing 11749 // attribute clause on the same construct unless the construct is a 11750 // combined construct. 11751 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 11752 CurrDir == OMPD_target) { 11753 OpenMPClauseKind ConflictKind; 11754 if (DSAStack->checkMappableExprComponentListsForDecl( 11755 VD, /*CurrentRegionOnly=*/true, 11756 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 11757 OpenMPClauseKind WhereFoundClauseKind) -> bool { 11758 ConflictKind = WhereFoundClauseKind; 11759 return true; 11760 })) { 11761 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11762 << getOpenMPClauseName(OMPC_private) 11763 << getOpenMPClauseName(ConflictKind) 11764 << getOpenMPDirectiveName(CurrDir); 11765 reportOriginalDsa(*this, DSAStack, D, DVar); 11766 continue; 11767 } 11768 } 11769 11770 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 11771 // A variable of class type (or array thereof) that appears in a private 11772 // clause requires an accessible, unambiguous default constructor for the 11773 // class type. 11774 // Generate helper private variable and initialize it with the default 11775 // value. The address of the original variable is replaced by the address of 11776 // the new private variable in CodeGen. This new variable is not added to 11777 // IdResolver, so the code in the OpenMP region uses original variable for 11778 // proper diagnostics. 11779 Type = Type.getUnqualifiedType(); 11780 VarDecl *VDPrivate = 11781 buildVarDecl(*this, ELoc, Type, D->getName(), 11782 D->hasAttrs() ? &D->getAttrs() : nullptr, 11783 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11784 ActOnUninitializedDecl(VDPrivate); 11785 if (VDPrivate->isInvalidDecl()) 11786 continue; 11787 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11788 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 11789 11790 DeclRefExpr *Ref = nullptr; 11791 if (!VD && !CurContext->isDependentContext()) 11792 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11793 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 11794 Vars.push_back((VD || CurContext->isDependentContext()) 11795 ? RefExpr->IgnoreParens() 11796 : Ref); 11797 PrivateCopies.push_back(VDPrivateRefExpr); 11798 } 11799 11800 if (Vars.empty()) 11801 return nullptr; 11802 11803 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11804 PrivateCopies); 11805 } 11806 11807 namespace { 11808 class DiagsUninitializedSeveretyRAII { 11809 private: 11810 DiagnosticsEngine &Diags; 11811 SourceLocation SavedLoc; 11812 bool IsIgnored = false; 11813 11814 public: 11815 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 11816 bool IsIgnored) 11817 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 11818 if (!IsIgnored) { 11819 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 11820 /*Map*/ diag::Severity::Ignored, Loc); 11821 } 11822 } 11823 ~DiagsUninitializedSeveretyRAII() { 11824 if (!IsIgnored) 11825 Diags.popMappings(SavedLoc); 11826 } 11827 }; 11828 } 11829 11830 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 11831 SourceLocation StartLoc, 11832 SourceLocation LParenLoc, 11833 SourceLocation EndLoc) { 11834 SmallVector<Expr *, 8> Vars; 11835 SmallVector<Expr *, 8> PrivateCopies; 11836 SmallVector<Expr *, 8> Inits; 11837 SmallVector<Decl *, 4> ExprCaptures; 11838 bool IsImplicitClause = 11839 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 11840 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 11841 11842 for (Expr *RefExpr : VarList) { 11843 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 11844 SourceLocation ELoc; 11845 SourceRange ERange; 11846 Expr *SimpleRefExpr = RefExpr; 11847 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11848 if (Res.second) { 11849 // It will be analyzed later. 11850 Vars.push_back(RefExpr); 11851 PrivateCopies.push_back(nullptr); 11852 Inits.push_back(nullptr); 11853 } 11854 ValueDecl *D = Res.first; 11855 if (!D) 11856 continue; 11857 11858 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 11859 QualType Type = D->getType(); 11860 auto *VD = dyn_cast<VarDecl>(D); 11861 11862 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11863 // A variable that appears in a private clause must not have an incomplete 11864 // type or a reference type. 11865 if (RequireCompleteType(ELoc, Type, 11866 diag::err_omp_firstprivate_incomplete_type)) 11867 continue; 11868 Type = Type.getNonReferenceType(); 11869 11870 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 11871 // A variable of class type (or array thereof) that appears in a private 11872 // clause requires an accessible, unambiguous copy constructor for the 11873 // class type. 11874 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11875 11876 // If an implicit firstprivate variable found it was checked already. 11877 DSAStackTy::DSAVarData TopDVar; 11878 if (!IsImplicitClause) { 11879 DSAStackTy::DSAVarData DVar = 11880 DSAStack->getTopDSA(D, /*FromParent=*/false); 11881 TopDVar = DVar; 11882 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11883 bool IsConstant = ElemType.isConstant(Context); 11884 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 11885 // A list item that specifies a given variable may not appear in more 11886 // than one clause on the same directive, except that a variable may be 11887 // specified in both firstprivate and lastprivate clauses. 11888 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11889 // A list item may appear in a firstprivate or lastprivate clause but not 11890 // both. 11891 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 11892 (isOpenMPDistributeDirective(CurrDir) || 11893 DVar.CKind != OMPC_lastprivate) && 11894 DVar.RefExpr) { 11895 Diag(ELoc, diag::err_omp_wrong_dsa) 11896 << getOpenMPClauseName(DVar.CKind) 11897 << getOpenMPClauseName(OMPC_firstprivate); 11898 reportOriginalDsa(*this, DSAStack, D, DVar); 11899 continue; 11900 } 11901 11902 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11903 // in a Construct] 11904 // Variables with the predetermined data-sharing attributes may not be 11905 // listed in data-sharing attributes clauses, except for the cases 11906 // listed below. For these exceptions only, listing a predetermined 11907 // variable in a data-sharing attribute clause is allowed and overrides 11908 // the variable's predetermined data-sharing attributes. 11909 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11910 // in a Construct, C/C++, p.2] 11911 // Variables with const-qualified type having no mutable member may be 11912 // listed in a firstprivate clause, even if they are static data members. 11913 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11914 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11915 Diag(ELoc, diag::err_omp_wrong_dsa) 11916 << getOpenMPClauseName(DVar.CKind) 11917 << getOpenMPClauseName(OMPC_firstprivate); 11918 reportOriginalDsa(*this, DSAStack, D, DVar); 11919 continue; 11920 } 11921 11922 // OpenMP [2.9.3.4, Restrictions, p.2] 11923 // A list item that is private within a parallel region must not appear 11924 // in a firstprivate clause on a worksharing construct if any of the 11925 // worksharing regions arising from the worksharing construct ever bind 11926 // to any of the parallel regions arising from the parallel construct. 11927 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11928 // A list item that is private within a teams region must not appear in a 11929 // firstprivate clause on a distribute construct if any of the distribute 11930 // regions arising from the distribute construct ever bind to any of the 11931 // teams regions arising from the teams construct. 11932 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11933 // A list item that appears in a reduction clause of a teams construct 11934 // must not appear in a firstprivate clause on a distribute construct if 11935 // any of the distribute regions arising from the distribute construct 11936 // ever bind to any of the teams regions arising from the teams construct. 11937 if ((isOpenMPWorksharingDirective(CurrDir) || 11938 isOpenMPDistributeDirective(CurrDir)) && 11939 !isOpenMPParallelDirective(CurrDir) && 11940 !isOpenMPTeamsDirective(CurrDir)) { 11941 DVar = DSAStack->getImplicitDSA(D, true); 11942 if (DVar.CKind != OMPC_shared && 11943 (isOpenMPParallelDirective(DVar.DKind) || 11944 isOpenMPTeamsDirective(DVar.DKind) || 11945 DVar.DKind == OMPD_unknown)) { 11946 Diag(ELoc, diag::err_omp_required_access) 11947 << getOpenMPClauseName(OMPC_firstprivate) 11948 << getOpenMPClauseName(OMPC_shared); 11949 reportOriginalDsa(*this, DSAStack, D, DVar); 11950 continue; 11951 } 11952 } 11953 // OpenMP [2.9.3.4, Restrictions, p.3] 11954 // A list item that appears in a reduction clause of a parallel construct 11955 // must not appear in a firstprivate clause on a worksharing or task 11956 // construct if any of the worksharing or task regions arising from the 11957 // worksharing or task construct ever bind to any of the parallel regions 11958 // arising from the parallel construct. 11959 // OpenMP [2.9.3.4, Restrictions, p.4] 11960 // A list item that appears in a reduction clause in worksharing 11961 // construct must not appear in a firstprivate clause in a task construct 11962 // encountered during execution of any of the worksharing regions arising 11963 // from the worksharing construct. 11964 if (isOpenMPTaskingDirective(CurrDir)) { 11965 DVar = DSAStack->hasInnermostDSA( 11966 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11967 [](OpenMPDirectiveKind K) { 11968 return isOpenMPParallelDirective(K) || 11969 isOpenMPWorksharingDirective(K) || 11970 isOpenMPTeamsDirective(K); 11971 }, 11972 /*FromParent=*/true); 11973 if (DVar.CKind == OMPC_reduction && 11974 (isOpenMPParallelDirective(DVar.DKind) || 11975 isOpenMPWorksharingDirective(DVar.DKind) || 11976 isOpenMPTeamsDirective(DVar.DKind))) { 11977 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11978 << getOpenMPDirectiveName(DVar.DKind); 11979 reportOriginalDsa(*this, DSAStack, D, DVar); 11980 continue; 11981 } 11982 } 11983 11984 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11985 // A list item cannot appear in both a map clause and a data-sharing 11986 // attribute clause on the same construct 11987 // 11988 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11989 // A list item cannot appear in both a map clause and a data-sharing 11990 // attribute clause on the same construct unless the construct is a 11991 // combined construct. 11992 if ((LangOpts.OpenMP <= 45 && 11993 isOpenMPTargetExecutionDirective(CurrDir)) || 11994 CurrDir == OMPD_target) { 11995 OpenMPClauseKind ConflictKind; 11996 if (DSAStack->checkMappableExprComponentListsForDecl( 11997 VD, /*CurrentRegionOnly=*/true, 11998 [&ConflictKind]( 11999 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12000 OpenMPClauseKind WhereFoundClauseKind) { 12001 ConflictKind = WhereFoundClauseKind; 12002 return true; 12003 })) { 12004 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12005 << getOpenMPClauseName(OMPC_firstprivate) 12006 << getOpenMPClauseName(ConflictKind) 12007 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12008 reportOriginalDsa(*this, DSAStack, D, DVar); 12009 continue; 12010 } 12011 } 12012 } 12013 12014 // Variably modified types are not supported for tasks. 12015 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12016 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12017 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12018 << getOpenMPClauseName(OMPC_firstprivate) << Type 12019 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12020 bool IsDecl = 12021 !VD || 12022 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12023 Diag(D->getLocation(), 12024 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12025 << D; 12026 continue; 12027 } 12028 12029 Type = Type.getUnqualifiedType(); 12030 VarDecl *VDPrivate = 12031 buildVarDecl(*this, ELoc, Type, D->getName(), 12032 D->hasAttrs() ? &D->getAttrs() : nullptr, 12033 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12034 // Generate helper private variable and initialize it with the value of the 12035 // original variable. The address of the original variable is replaced by 12036 // the address of the new private variable in the CodeGen. This new variable 12037 // is not added to IdResolver, so the code in the OpenMP region uses 12038 // original variable for proper diagnostics and variable capturing. 12039 Expr *VDInitRefExpr = nullptr; 12040 // For arrays generate initializer for single element and replace it by the 12041 // original array element in CodeGen. 12042 if (Type->isArrayType()) { 12043 VarDecl *VDInit = 12044 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12045 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12046 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12047 ElemType = ElemType.getUnqualifiedType(); 12048 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12049 ".firstprivate.temp"); 12050 InitializedEntity Entity = 12051 InitializedEntity::InitializeVariable(VDInitTemp); 12052 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12053 12054 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12055 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12056 if (Result.isInvalid()) 12057 VDPrivate->setInvalidDecl(); 12058 else 12059 VDPrivate->setInit(Result.getAs<Expr>()); 12060 // Remove temp variable declaration. 12061 Context.Deallocate(VDInitTemp); 12062 } else { 12063 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12064 ".firstprivate.temp"); 12065 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12066 RefExpr->getExprLoc()); 12067 AddInitializerToDecl(VDPrivate, 12068 DefaultLvalueConversion(VDInitRefExpr).get(), 12069 /*DirectInit=*/false); 12070 } 12071 if (VDPrivate->isInvalidDecl()) { 12072 if (IsImplicitClause) { 12073 Diag(RefExpr->getExprLoc(), 12074 diag::note_omp_task_predetermined_firstprivate_here); 12075 } 12076 continue; 12077 } 12078 CurContext->addDecl(VDPrivate); 12079 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12080 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12081 RefExpr->getExprLoc()); 12082 DeclRefExpr *Ref = nullptr; 12083 if (!VD && !CurContext->isDependentContext()) { 12084 if (TopDVar.CKind == OMPC_lastprivate) { 12085 Ref = TopDVar.PrivateCopy; 12086 } else { 12087 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12088 if (!isOpenMPCapturedDecl(D)) 12089 ExprCaptures.push_back(Ref->getDecl()); 12090 } 12091 } 12092 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12093 Vars.push_back((VD || CurContext->isDependentContext()) 12094 ? RefExpr->IgnoreParens() 12095 : Ref); 12096 PrivateCopies.push_back(VDPrivateRefExpr); 12097 Inits.push_back(VDInitRefExpr); 12098 } 12099 12100 if (Vars.empty()) 12101 return nullptr; 12102 12103 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12104 Vars, PrivateCopies, Inits, 12105 buildPreInits(Context, ExprCaptures)); 12106 } 12107 12108 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12109 SourceLocation StartLoc, 12110 SourceLocation LParenLoc, 12111 SourceLocation EndLoc) { 12112 SmallVector<Expr *, 8> Vars; 12113 SmallVector<Expr *, 8> SrcExprs; 12114 SmallVector<Expr *, 8> DstExprs; 12115 SmallVector<Expr *, 8> AssignmentOps; 12116 SmallVector<Decl *, 4> ExprCaptures; 12117 SmallVector<Expr *, 4> ExprPostUpdates; 12118 for (Expr *RefExpr : VarList) { 12119 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12120 SourceLocation ELoc; 12121 SourceRange ERange; 12122 Expr *SimpleRefExpr = RefExpr; 12123 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12124 if (Res.second) { 12125 // It will be analyzed later. 12126 Vars.push_back(RefExpr); 12127 SrcExprs.push_back(nullptr); 12128 DstExprs.push_back(nullptr); 12129 AssignmentOps.push_back(nullptr); 12130 } 12131 ValueDecl *D = Res.first; 12132 if (!D) 12133 continue; 12134 12135 QualType Type = D->getType(); 12136 auto *VD = dyn_cast<VarDecl>(D); 12137 12138 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12139 // A variable that appears in a lastprivate clause must not have an 12140 // incomplete type or a reference type. 12141 if (RequireCompleteType(ELoc, Type, 12142 diag::err_omp_lastprivate_incomplete_type)) 12143 continue; 12144 Type = Type.getNonReferenceType(); 12145 12146 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12147 // A variable that is privatized must not have a const-qualified type 12148 // unless it is of class type with a mutable member. This restriction does 12149 // not apply to the firstprivate clause. 12150 // 12151 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12152 // A variable that appears in a lastprivate clause must not have a 12153 // const-qualified type unless it is of class type with a mutable member. 12154 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12155 continue; 12156 12157 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12158 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12159 // in a Construct] 12160 // Variables with the predetermined data-sharing attributes may not be 12161 // listed in data-sharing attributes clauses, except for the cases 12162 // listed below. 12163 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12164 // A list item may appear in a firstprivate or lastprivate clause but not 12165 // both. 12166 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12167 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12168 (isOpenMPDistributeDirective(CurrDir) || 12169 DVar.CKind != OMPC_firstprivate) && 12170 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12171 Diag(ELoc, diag::err_omp_wrong_dsa) 12172 << getOpenMPClauseName(DVar.CKind) 12173 << getOpenMPClauseName(OMPC_lastprivate); 12174 reportOriginalDsa(*this, DSAStack, D, DVar); 12175 continue; 12176 } 12177 12178 // OpenMP [2.14.3.5, Restrictions, p.2] 12179 // A list item that is private within a parallel region, or that appears in 12180 // the reduction clause of a parallel construct, must not appear in a 12181 // lastprivate clause on a worksharing construct if any of the corresponding 12182 // worksharing regions ever binds to any of the corresponding parallel 12183 // regions. 12184 DSAStackTy::DSAVarData TopDVar = DVar; 12185 if (isOpenMPWorksharingDirective(CurrDir) && 12186 !isOpenMPParallelDirective(CurrDir) && 12187 !isOpenMPTeamsDirective(CurrDir)) { 12188 DVar = DSAStack->getImplicitDSA(D, true); 12189 if (DVar.CKind != OMPC_shared) { 12190 Diag(ELoc, diag::err_omp_required_access) 12191 << getOpenMPClauseName(OMPC_lastprivate) 12192 << getOpenMPClauseName(OMPC_shared); 12193 reportOriginalDsa(*this, DSAStack, D, DVar); 12194 continue; 12195 } 12196 } 12197 12198 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12199 // A variable of class type (or array thereof) that appears in a 12200 // lastprivate clause requires an accessible, unambiguous default 12201 // constructor for the class type, unless the list item is also specified 12202 // in a firstprivate clause. 12203 // A variable of class type (or array thereof) that appears in a 12204 // lastprivate clause requires an accessible, unambiguous copy assignment 12205 // operator for the class type. 12206 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12207 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12208 Type.getUnqualifiedType(), ".lastprivate.src", 12209 D->hasAttrs() ? &D->getAttrs() : nullptr); 12210 DeclRefExpr *PseudoSrcExpr = 12211 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12212 VarDecl *DstVD = 12213 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12214 D->hasAttrs() ? &D->getAttrs() : nullptr); 12215 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12216 // For arrays generate assignment operation for single element and replace 12217 // it by the original array element in CodeGen. 12218 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12219 PseudoDstExpr, PseudoSrcExpr); 12220 if (AssignmentOp.isInvalid()) 12221 continue; 12222 AssignmentOp = 12223 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12224 if (AssignmentOp.isInvalid()) 12225 continue; 12226 12227 DeclRefExpr *Ref = nullptr; 12228 if (!VD && !CurContext->isDependentContext()) { 12229 if (TopDVar.CKind == OMPC_firstprivate) { 12230 Ref = TopDVar.PrivateCopy; 12231 } else { 12232 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12233 if (!isOpenMPCapturedDecl(D)) 12234 ExprCaptures.push_back(Ref->getDecl()); 12235 } 12236 if (TopDVar.CKind == OMPC_firstprivate || 12237 (!isOpenMPCapturedDecl(D) && 12238 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12239 ExprResult RefRes = DefaultLvalueConversion(Ref); 12240 if (!RefRes.isUsable()) 12241 continue; 12242 ExprResult PostUpdateRes = 12243 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12244 RefRes.get()); 12245 if (!PostUpdateRes.isUsable()) 12246 continue; 12247 ExprPostUpdates.push_back( 12248 IgnoredValueConversions(PostUpdateRes.get()).get()); 12249 } 12250 } 12251 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12252 Vars.push_back((VD || CurContext->isDependentContext()) 12253 ? RefExpr->IgnoreParens() 12254 : Ref); 12255 SrcExprs.push_back(PseudoSrcExpr); 12256 DstExprs.push_back(PseudoDstExpr); 12257 AssignmentOps.push_back(AssignmentOp.get()); 12258 } 12259 12260 if (Vars.empty()) 12261 return nullptr; 12262 12263 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12264 Vars, SrcExprs, DstExprs, AssignmentOps, 12265 buildPreInits(Context, ExprCaptures), 12266 buildPostUpdate(*this, ExprPostUpdates)); 12267 } 12268 12269 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12270 SourceLocation StartLoc, 12271 SourceLocation LParenLoc, 12272 SourceLocation EndLoc) { 12273 SmallVector<Expr *, 8> Vars; 12274 for (Expr *RefExpr : VarList) { 12275 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12276 SourceLocation ELoc; 12277 SourceRange ERange; 12278 Expr *SimpleRefExpr = RefExpr; 12279 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12280 if (Res.second) { 12281 // It will be analyzed later. 12282 Vars.push_back(RefExpr); 12283 } 12284 ValueDecl *D = Res.first; 12285 if (!D) 12286 continue; 12287 12288 auto *VD = dyn_cast<VarDecl>(D); 12289 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12290 // in a Construct] 12291 // Variables with the predetermined data-sharing attributes may not be 12292 // listed in data-sharing attributes clauses, except for the cases 12293 // listed below. For these exceptions only, listing a predetermined 12294 // variable in a data-sharing attribute clause is allowed and overrides 12295 // the variable's predetermined data-sharing attributes. 12296 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12297 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12298 DVar.RefExpr) { 12299 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12300 << getOpenMPClauseName(OMPC_shared); 12301 reportOriginalDsa(*this, DSAStack, D, DVar); 12302 continue; 12303 } 12304 12305 DeclRefExpr *Ref = nullptr; 12306 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12307 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12308 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12309 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12310 ? RefExpr->IgnoreParens() 12311 : Ref); 12312 } 12313 12314 if (Vars.empty()) 12315 return nullptr; 12316 12317 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12318 } 12319 12320 namespace { 12321 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12322 DSAStackTy *Stack; 12323 12324 public: 12325 bool VisitDeclRefExpr(DeclRefExpr *E) { 12326 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12327 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12328 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12329 return false; 12330 if (DVar.CKind != OMPC_unknown) 12331 return true; 12332 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12333 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12334 /*FromParent=*/true); 12335 return DVarPrivate.CKind != OMPC_unknown; 12336 } 12337 return false; 12338 } 12339 bool VisitStmt(Stmt *S) { 12340 for (Stmt *Child : S->children()) { 12341 if (Child && Visit(Child)) 12342 return true; 12343 } 12344 return false; 12345 } 12346 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12347 }; 12348 } // namespace 12349 12350 namespace { 12351 // Transform MemberExpression for specified FieldDecl of current class to 12352 // DeclRefExpr to specified OMPCapturedExprDecl. 12353 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12354 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12355 ValueDecl *Field = nullptr; 12356 DeclRefExpr *CapturedExpr = nullptr; 12357 12358 public: 12359 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12360 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12361 12362 ExprResult TransformMemberExpr(MemberExpr *E) { 12363 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12364 E->getMemberDecl() == Field) { 12365 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12366 return CapturedExpr; 12367 } 12368 return BaseTransform::TransformMemberExpr(E); 12369 } 12370 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12371 }; 12372 } // namespace 12373 12374 template <typename T, typename U> 12375 static T filterLookupForUDReductionAndMapper( 12376 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12377 for (U &Set : Lookups) { 12378 for (auto *D : Set) { 12379 if (T Res = Gen(cast<ValueDecl>(D))) 12380 return Res; 12381 } 12382 } 12383 return T(); 12384 } 12385 12386 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12387 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12388 12389 for (auto RD : D->redecls()) { 12390 // Don't bother with extra checks if we already know this one isn't visible. 12391 if (RD == D) 12392 continue; 12393 12394 auto ND = cast<NamedDecl>(RD); 12395 if (LookupResult::isVisible(SemaRef, ND)) 12396 return ND; 12397 } 12398 12399 return nullptr; 12400 } 12401 12402 static void 12403 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12404 SourceLocation Loc, QualType Ty, 12405 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12406 // Find all of the associated namespaces and classes based on the 12407 // arguments we have. 12408 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12409 Sema::AssociatedClassSet AssociatedClasses; 12410 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12411 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12412 AssociatedClasses); 12413 12414 // C++ [basic.lookup.argdep]p3: 12415 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12416 // and let Y be the lookup set produced by argument dependent 12417 // lookup (defined as follows). If X contains [...] then Y is 12418 // empty. Otherwise Y is the set of declarations found in the 12419 // namespaces associated with the argument types as described 12420 // below. The set of declarations found by the lookup of the name 12421 // is the union of X and Y. 12422 // 12423 // Here, we compute Y and add its members to the overloaded 12424 // candidate set. 12425 for (auto *NS : AssociatedNamespaces) { 12426 // When considering an associated namespace, the lookup is the 12427 // same as the lookup performed when the associated namespace is 12428 // used as a qualifier (3.4.3.2) except that: 12429 // 12430 // -- Any using-directives in the associated namespace are 12431 // ignored. 12432 // 12433 // -- Any namespace-scope friend functions declared in 12434 // associated classes are visible within their respective 12435 // namespaces even if they are not visible during an ordinary 12436 // lookup (11.4). 12437 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12438 for (auto *D : R) { 12439 auto *Underlying = D; 12440 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12441 Underlying = USD->getTargetDecl(); 12442 12443 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12444 !isa<OMPDeclareMapperDecl>(Underlying)) 12445 continue; 12446 12447 if (!SemaRef.isVisible(D)) { 12448 D = findAcceptableDecl(SemaRef, D); 12449 if (!D) 12450 continue; 12451 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12452 Underlying = USD->getTargetDecl(); 12453 } 12454 Lookups.emplace_back(); 12455 Lookups.back().addDecl(Underlying); 12456 } 12457 } 12458 } 12459 12460 static ExprResult 12461 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12462 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12463 const DeclarationNameInfo &ReductionId, QualType Ty, 12464 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12465 if (ReductionIdScopeSpec.isInvalid()) 12466 return ExprError(); 12467 SmallVector<UnresolvedSet<8>, 4> Lookups; 12468 if (S) { 12469 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12470 Lookup.suppressDiagnostics(); 12471 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12472 NamedDecl *D = Lookup.getRepresentativeDecl(); 12473 do { 12474 S = S->getParent(); 12475 } while (S && !S->isDeclScope(D)); 12476 if (S) 12477 S = S->getParent(); 12478 Lookups.emplace_back(); 12479 Lookups.back().append(Lookup.begin(), Lookup.end()); 12480 Lookup.clear(); 12481 } 12482 } else if (auto *ULE = 12483 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12484 Lookups.push_back(UnresolvedSet<8>()); 12485 Decl *PrevD = nullptr; 12486 for (NamedDecl *D : ULE->decls()) { 12487 if (D == PrevD) 12488 Lookups.push_back(UnresolvedSet<8>()); 12489 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12490 Lookups.back().addDecl(DRD); 12491 PrevD = D; 12492 } 12493 } 12494 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12495 Ty->isInstantiationDependentType() || 12496 Ty->containsUnexpandedParameterPack() || 12497 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12498 return !D->isInvalidDecl() && 12499 (D->getType()->isDependentType() || 12500 D->getType()->isInstantiationDependentType() || 12501 D->getType()->containsUnexpandedParameterPack()); 12502 })) { 12503 UnresolvedSet<8> ResSet; 12504 for (const UnresolvedSet<8> &Set : Lookups) { 12505 if (Set.empty()) 12506 continue; 12507 ResSet.append(Set.begin(), Set.end()); 12508 // The last item marks the end of all declarations at the specified scope. 12509 ResSet.addDecl(Set[Set.size() - 1]); 12510 } 12511 return UnresolvedLookupExpr::Create( 12512 SemaRef.Context, /*NamingClass=*/nullptr, 12513 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12514 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12515 } 12516 // Lookup inside the classes. 12517 // C++ [over.match.oper]p3: 12518 // For a unary operator @ with an operand of a type whose 12519 // cv-unqualified version is T1, and for a binary operator @ with 12520 // a left operand of a type whose cv-unqualified version is T1 and 12521 // a right operand of a type whose cv-unqualified version is T2, 12522 // three sets of candidate functions, designated member 12523 // candidates, non-member candidates and built-in candidates, are 12524 // constructed as follows: 12525 // -- If T1 is a complete class type or a class currently being 12526 // defined, the set of member candidates is the result of the 12527 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12528 // the set of member candidates is empty. 12529 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12530 Lookup.suppressDiagnostics(); 12531 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12532 // Complete the type if it can be completed. 12533 // If the type is neither complete nor being defined, bail out now. 12534 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12535 TyRec->getDecl()->getDefinition()) { 12536 Lookup.clear(); 12537 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12538 if (Lookup.empty()) { 12539 Lookups.emplace_back(); 12540 Lookups.back().append(Lookup.begin(), Lookup.end()); 12541 } 12542 } 12543 } 12544 // Perform ADL. 12545 if (SemaRef.getLangOpts().CPlusPlus) 12546 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12547 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12548 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12549 if (!D->isInvalidDecl() && 12550 SemaRef.Context.hasSameType(D->getType(), Ty)) 12551 return D; 12552 return nullptr; 12553 })) 12554 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12555 VK_LValue, Loc); 12556 if (SemaRef.getLangOpts().CPlusPlus) { 12557 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12558 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12559 if (!D->isInvalidDecl() && 12560 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12561 !Ty.isMoreQualifiedThan(D->getType())) 12562 return D; 12563 return nullptr; 12564 })) { 12565 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12566 /*DetectVirtual=*/false); 12567 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12568 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12569 VD->getType().getUnqualifiedType()))) { 12570 if (SemaRef.CheckBaseClassAccess( 12571 Loc, VD->getType(), Ty, Paths.front(), 12572 /*DiagID=*/0) != Sema::AR_inaccessible) { 12573 SemaRef.BuildBasePathArray(Paths, BasePath); 12574 return SemaRef.BuildDeclRefExpr( 12575 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12576 } 12577 } 12578 } 12579 } 12580 } 12581 if (ReductionIdScopeSpec.isSet()) { 12582 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12583 return ExprError(); 12584 } 12585 return ExprEmpty(); 12586 } 12587 12588 namespace { 12589 /// Data for the reduction-based clauses. 12590 struct ReductionData { 12591 /// List of original reduction items. 12592 SmallVector<Expr *, 8> Vars; 12593 /// List of private copies of the reduction items. 12594 SmallVector<Expr *, 8> Privates; 12595 /// LHS expressions for the reduction_op expressions. 12596 SmallVector<Expr *, 8> LHSs; 12597 /// RHS expressions for the reduction_op expressions. 12598 SmallVector<Expr *, 8> RHSs; 12599 /// Reduction operation expression. 12600 SmallVector<Expr *, 8> ReductionOps; 12601 /// Taskgroup descriptors for the corresponding reduction items in 12602 /// in_reduction clauses. 12603 SmallVector<Expr *, 8> TaskgroupDescriptors; 12604 /// List of captures for clause. 12605 SmallVector<Decl *, 4> ExprCaptures; 12606 /// List of postupdate expressions. 12607 SmallVector<Expr *, 4> ExprPostUpdates; 12608 ReductionData() = delete; 12609 /// Reserves required memory for the reduction data. 12610 ReductionData(unsigned Size) { 12611 Vars.reserve(Size); 12612 Privates.reserve(Size); 12613 LHSs.reserve(Size); 12614 RHSs.reserve(Size); 12615 ReductionOps.reserve(Size); 12616 TaskgroupDescriptors.reserve(Size); 12617 ExprCaptures.reserve(Size); 12618 ExprPostUpdates.reserve(Size); 12619 } 12620 /// Stores reduction item and reduction operation only (required for dependent 12621 /// reduction item). 12622 void push(Expr *Item, Expr *ReductionOp) { 12623 Vars.emplace_back(Item); 12624 Privates.emplace_back(nullptr); 12625 LHSs.emplace_back(nullptr); 12626 RHSs.emplace_back(nullptr); 12627 ReductionOps.emplace_back(ReductionOp); 12628 TaskgroupDescriptors.emplace_back(nullptr); 12629 } 12630 /// Stores reduction data. 12631 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12632 Expr *TaskgroupDescriptor) { 12633 Vars.emplace_back(Item); 12634 Privates.emplace_back(Private); 12635 LHSs.emplace_back(LHS); 12636 RHSs.emplace_back(RHS); 12637 ReductionOps.emplace_back(ReductionOp); 12638 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12639 } 12640 }; 12641 } // namespace 12642 12643 static bool checkOMPArraySectionConstantForReduction( 12644 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12645 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12646 const Expr *Length = OASE->getLength(); 12647 if (Length == nullptr) { 12648 // For array sections of the form [1:] or [:], we would need to analyze 12649 // the lower bound... 12650 if (OASE->getColonLoc().isValid()) 12651 return false; 12652 12653 // This is an array subscript which has implicit length 1! 12654 SingleElement = true; 12655 ArraySizes.push_back(llvm::APSInt::get(1)); 12656 } else { 12657 Expr::EvalResult Result; 12658 if (!Length->EvaluateAsInt(Result, Context)) 12659 return false; 12660 12661 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12662 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12663 ArraySizes.push_back(ConstantLengthValue); 12664 } 12665 12666 // Get the base of this array section and walk up from there. 12667 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12668 12669 // We require length = 1 for all array sections except the right-most to 12670 // guarantee that the memory region is contiguous and has no holes in it. 12671 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12672 Length = TempOASE->getLength(); 12673 if (Length == nullptr) { 12674 // For array sections of the form [1:] or [:], we would need to analyze 12675 // the lower bound... 12676 if (OASE->getColonLoc().isValid()) 12677 return false; 12678 12679 // This is an array subscript which has implicit length 1! 12680 ArraySizes.push_back(llvm::APSInt::get(1)); 12681 } else { 12682 Expr::EvalResult Result; 12683 if (!Length->EvaluateAsInt(Result, Context)) 12684 return false; 12685 12686 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12687 if (ConstantLengthValue.getSExtValue() != 1) 12688 return false; 12689 12690 ArraySizes.push_back(ConstantLengthValue); 12691 } 12692 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12693 } 12694 12695 // If we have a single element, we don't need to add the implicit lengths. 12696 if (!SingleElement) { 12697 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12698 // Has implicit length 1! 12699 ArraySizes.push_back(llvm::APSInt::get(1)); 12700 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12701 } 12702 } 12703 12704 // This array section can be privatized as a single value or as a constant 12705 // sized array. 12706 return true; 12707 } 12708 12709 static bool actOnOMPReductionKindClause( 12710 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12711 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12712 SourceLocation ColonLoc, SourceLocation EndLoc, 12713 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12714 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12715 DeclarationName DN = ReductionId.getName(); 12716 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12717 BinaryOperatorKind BOK = BO_Comma; 12718 12719 ASTContext &Context = S.Context; 12720 // OpenMP [2.14.3.6, reduction clause] 12721 // C 12722 // reduction-identifier is either an identifier or one of the following 12723 // operators: +, -, *, &, |, ^, && and || 12724 // C++ 12725 // reduction-identifier is either an id-expression or one of the following 12726 // operators: +, -, *, &, |, ^, && and || 12727 switch (OOK) { 12728 case OO_Plus: 12729 case OO_Minus: 12730 BOK = BO_Add; 12731 break; 12732 case OO_Star: 12733 BOK = BO_Mul; 12734 break; 12735 case OO_Amp: 12736 BOK = BO_And; 12737 break; 12738 case OO_Pipe: 12739 BOK = BO_Or; 12740 break; 12741 case OO_Caret: 12742 BOK = BO_Xor; 12743 break; 12744 case OO_AmpAmp: 12745 BOK = BO_LAnd; 12746 break; 12747 case OO_PipePipe: 12748 BOK = BO_LOr; 12749 break; 12750 case OO_New: 12751 case OO_Delete: 12752 case OO_Array_New: 12753 case OO_Array_Delete: 12754 case OO_Slash: 12755 case OO_Percent: 12756 case OO_Tilde: 12757 case OO_Exclaim: 12758 case OO_Equal: 12759 case OO_Less: 12760 case OO_Greater: 12761 case OO_LessEqual: 12762 case OO_GreaterEqual: 12763 case OO_PlusEqual: 12764 case OO_MinusEqual: 12765 case OO_StarEqual: 12766 case OO_SlashEqual: 12767 case OO_PercentEqual: 12768 case OO_CaretEqual: 12769 case OO_AmpEqual: 12770 case OO_PipeEqual: 12771 case OO_LessLess: 12772 case OO_GreaterGreater: 12773 case OO_LessLessEqual: 12774 case OO_GreaterGreaterEqual: 12775 case OO_EqualEqual: 12776 case OO_ExclaimEqual: 12777 case OO_Spaceship: 12778 case OO_PlusPlus: 12779 case OO_MinusMinus: 12780 case OO_Comma: 12781 case OO_ArrowStar: 12782 case OO_Arrow: 12783 case OO_Call: 12784 case OO_Subscript: 12785 case OO_Conditional: 12786 case OO_Coawait: 12787 case NUM_OVERLOADED_OPERATORS: 12788 llvm_unreachable("Unexpected reduction identifier"); 12789 case OO_None: 12790 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 12791 if (II->isStr("max")) 12792 BOK = BO_GT; 12793 else if (II->isStr("min")) 12794 BOK = BO_LT; 12795 } 12796 break; 12797 } 12798 SourceRange ReductionIdRange; 12799 if (ReductionIdScopeSpec.isValid()) 12800 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 12801 else 12802 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 12803 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 12804 12805 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 12806 bool FirstIter = true; 12807 for (Expr *RefExpr : VarList) { 12808 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 12809 // OpenMP [2.1, C/C++] 12810 // A list item is a variable or array section, subject to the restrictions 12811 // specified in Section 2.4 on page 42 and in each of the sections 12812 // describing clauses and directives for which a list appears. 12813 // OpenMP [2.14.3.3, Restrictions, p.1] 12814 // A variable that is part of another variable (as an array or 12815 // structure element) cannot appear in a private clause. 12816 if (!FirstIter && IR != ER) 12817 ++IR; 12818 FirstIter = false; 12819 SourceLocation ELoc; 12820 SourceRange ERange; 12821 Expr *SimpleRefExpr = RefExpr; 12822 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 12823 /*AllowArraySection=*/true); 12824 if (Res.second) { 12825 // Try to find 'declare reduction' corresponding construct before using 12826 // builtin/overloaded operators. 12827 QualType Type = Context.DependentTy; 12828 CXXCastPath BasePath; 12829 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12830 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12831 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12832 Expr *ReductionOp = nullptr; 12833 if (S.CurContext->isDependentContext() && 12834 (DeclareReductionRef.isUnset() || 12835 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 12836 ReductionOp = DeclareReductionRef.get(); 12837 // It will be analyzed later. 12838 RD.push(RefExpr, ReductionOp); 12839 } 12840 ValueDecl *D = Res.first; 12841 if (!D) 12842 continue; 12843 12844 Expr *TaskgroupDescriptor = nullptr; 12845 QualType Type; 12846 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 12847 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 12848 if (ASE) { 12849 Type = ASE->getType().getNonReferenceType(); 12850 } else if (OASE) { 12851 QualType BaseType = 12852 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 12853 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 12854 Type = ATy->getElementType(); 12855 else 12856 Type = BaseType->getPointeeType(); 12857 Type = Type.getNonReferenceType(); 12858 } else { 12859 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 12860 } 12861 auto *VD = dyn_cast<VarDecl>(D); 12862 12863 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12864 // A variable that appears in a private clause must not have an incomplete 12865 // type or a reference type. 12866 if (S.RequireCompleteType(ELoc, D->getType(), 12867 diag::err_omp_reduction_incomplete_type)) 12868 continue; 12869 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12870 // A list item that appears in a reduction clause must not be 12871 // const-qualified. 12872 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 12873 /*AcceptIfMutable*/ false, ASE || OASE)) 12874 continue; 12875 12876 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 12877 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 12878 // If a list-item is a reference type then it must bind to the same object 12879 // for all threads of the team. 12880 if (!ASE && !OASE) { 12881 if (VD) { 12882 VarDecl *VDDef = VD->getDefinition(); 12883 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 12884 DSARefChecker Check(Stack); 12885 if (Check.Visit(VDDef->getInit())) { 12886 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 12887 << getOpenMPClauseName(ClauseKind) << ERange; 12888 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 12889 continue; 12890 } 12891 } 12892 } 12893 12894 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12895 // in a Construct] 12896 // Variables with the predetermined data-sharing attributes may not be 12897 // listed in data-sharing attributes clauses, except for the cases 12898 // listed below. For these exceptions only, listing a predetermined 12899 // variable in a data-sharing attribute clause is allowed and overrides 12900 // the variable's predetermined data-sharing attributes. 12901 // OpenMP [2.14.3.6, Restrictions, p.3] 12902 // Any number of reduction clauses can be specified on the directive, 12903 // but a list item can appear only once in the reduction clauses for that 12904 // directive. 12905 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 12906 if (DVar.CKind == OMPC_reduction) { 12907 S.Diag(ELoc, diag::err_omp_once_referenced) 12908 << getOpenMPClauseName(ClauseKind); 12909 if (DVar.RefExpr) 12910 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12911 continue; 12912 } 12913 if (DVar.CKind != OMPC_unknown) { 12914 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12915 << getOpenMPClauseName(DVar.CKind) 12916 << getOpenMPClauseName(OMPC_reduction); 12917 reportOriginalDsa(S, Stack, D, DVar); 12918 continue; 12919 } 12920 12921 // OpenMP [2.14.3.6, Restrictions, p.1] 12922 // A list item that appears in a reduction clause of a worksharing 12923 // construct must be shared in the parallel regions to which any of the 12924 // worksharing regions arising from the worksharing construct bind. 12925 if (isOpenMPWorksharingDirective(CurrDir) && 12926 !isOpenMPParallelDirective(CurrDir) && 12927 !isOpenMPTeamsDirective(CurrDir)) { 12928 DVar = Stack->getImplicitDSA(D, true); 12929 if (DVar.CKind != OMPC_shared) { 12930 S.Diag(ELoc, diag::err_omp_required_access) 12931 << getOpenMPClauseName(OMPC_reduction) 12932 << getOpenMPClauseName(OMPC_shared); 12933 reportOriginalDsa(S, Stack, D, DVar); 12934 continue; 12935 } 12936 } 12937 } 12938 12939 // Try to find 'declare reduction' corresponding construct before using 12940 // builtin/overloaded operators. 12941 CXXCastPath BasePath; 12942 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12943 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12944 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12945 if (DeclareReductionRef.isInvalid()) 12946 continue; 12947 if (S.CurContext->isDependentContext() && 12948 (DeclareReductionRef.isUnset() || 12949 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12950 RD.push(RefExpr, DeclareReductionRef.get()); 12951 continue; 12952 } 12953 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12954 // Not allowed reduction identifier is found. 12955 S.Diag(ReductionId.getBeginLoc(), 12956 diag::err_omp_unknown_reduction_identifier) 12957 << Type << ReductionIdRange; 12958 continue; 12959 } 12960 12961 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12962 // The type of a list item that appears in a reduction clause must be valid 12963 // for the reduction-identifier. For a max or min reduction in C, the type 12964 // of the list item must be an allowed arithmetic data type: char, int, 12965 // float, double, or _Bool, possibly modified with long, short, signed, or 12966 // unsigned. For a max or min reduction in C++, the type of the list item 12967 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12968 // double, or bool, possibly modified with long, short, signed, or unsigned. 12969 if (DeclareReductionRef.isUnset()) { 12970 if ((BOK == BO_GT || BOK == BO_LT) && 12971 !(Type->isScalarType() || 12972 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12973 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12974 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12975 if (!ASE && !OASE) { 12976 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12977 VarDecl::DeclarationOnly; 12978 S.Diag(D->getLocation(), 12979 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12980 << D; 12981 } 12982 continue; 12983 } 12984 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12985 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12986 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12987 << getOpenMPClauseName(ClauseKind); 12988 if (!ASE && !OASE) { 12989 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12990 VarDecl::DeclarationOnly; 12991 S.Diag(D->getLocation(), 12992 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12993 << D; 12994 } 12995 continue; 12996 } 12997 } 12998 12999 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13000 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13001 D->hasAttrs() ? &D->getAttrs() : nullptr); 13002 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13003 D->hasAttrs() ? &D->getAttrs() : nullptr); 13004 QualType PrivateTy = Type; 13005 13006 // Try if we can determine constant lengths for all array sections and avoid 13007 // the VLA. 13008 bool ConstantLengthOASE = false; 13009 if (OASE) { 13010 bool SingleElement; 13011 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13012 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13013 Context, OASE, SingleElement, ArraySizes); 13014 13015 // If we don't have a single element, we must emit a constant array type. 13016 if (ConstantLengthOASE && !SingleElement) { 13017 for (llvm::APSInt &Size : ArraySizes) 13018 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13019 ArrayType::Normal, 13020 /*IndexTypeQuals=*/0); 13021 } 13022 } 13023 13024 if ((OASE && !ConstantLengthOASE) || 13025 (!OASE && !ASE && 13026 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13027 if (!Context.getTargetInfo().isVLASupported()) { 13028 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13029 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13030 S.Diag(ELoc, diag::note_vla_unsupported); 13031 } else { 13032 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13033 S.targetDiag(ELoc, diag::note_vla_unsupported); 13034 } 13035 continue; 13036 } 13037 // For arrays/array sections only: 13038 // Create pseudo array type for private copy. The size for this array will 13039 // be generated during codegen. 13040 // For array subscripts or single variables Private Ty is the same as Type 13041 // (type of the variable or single array element). 13042 PrivateTy = Context.getVariableArrayType( 13043 Type, 13044 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13045 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13046 } else if (!ASE && !OASE && 13047 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13048 PrivateTy = D->getType().getNonReferenceType(); 13049 } 13050 // Private copy. 13051 VarDecl *PrivateVD = 13052 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13053 D->hasAttrs() ? &D->getAttrs() : nullptr, 13054 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13055 // Add initializer for private variable. 13056 Expr *Init = nullptr; 13057 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13058 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13059 if (DeclareReductionRef.isUsable()) { 13060 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13061 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13062 if (DRD->getInitializer()) { 13063 Init = DRDRef; 13064 RHSVD->setInit(DRDRef); 13065 RHSVD->setInitStyle(VarDecl::CallInit); 13066 } 13067 } else { 13068 switch (BOK) { 13069 case BO_Add: 13070 case BO_Xor: 13071 case BO_Or: 13072 case BO_LOr: 13073 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13074 if (Type->isScalarType() || Type->isAnyComplexType()) 13075 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13076 break; 13077 case BO_Mul: 13078 case BO_LAnd: 13079 if (Type->isScalarType() || Type->isAnyComplexType()) { 13080 // '*' and '&&' reduction ops - initializer is '1'. 13081 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13082 } 13083 break; 13084 case BO_And: { 13085 // '&' reduction op - initializer is '~0'. 13086 QualType OrigType = Type; 13087 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13088 Type = ComplexTy->getElementType(); 13089 if (Type->isRealFloatingType()) { 13090 llvm::APFloat InitValue = 13091 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13092 /*isIEEE=*/true); 13093 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13094 Type, ELoc); 13095 } else if (Type->isScalarType()) { 13096 uint64_t Size = Context.getTypeSize(Type); 13097 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13098 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13099 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13100 } 13101 if (Init && OrigType->isAnyComplexType()) { 13102 // Init = 0xFFFF + 0xFFFFi; 13103 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13104 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13105 } 13106 Type = OrigType; 13107 break; 13108 } 13109 case BO_LT: 13110 case BO_GT: { 13111 // 'min' reduction op - initializer is 'Largest representable number in 13112 // the reduction list item type'. 13113 // 'max' reduction op - initializer is 'Least representable number in 13114 // the reduction list item type'. 13115 if (Type->isIntegerType() || Type->isPointerType()) { 13116 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13117 uint64_t Size = Context.getTypeSize(Type); 13118 QualType IntTy = 13119 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13120 llvm::APInt InitValue = 13121 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13122 : llvm::APInt::getMinValue(Size) 13123 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13124 : llvm::APInt::getMaxValue(Size); 13125 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13126 if (Type->isPointerType()) { 13127 // Cast to pointer type. 13128 ExprResult CastExpr = S.BuildCStyleCastExpr( 13129 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13130 if (CastExpr.isInvalid()) 13131 continue; 13132 Init = CastExpr.get(); 13133 } 13134 } else if (Type->isRealFloatingType()) { 13135 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13136 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13137 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13138 Type, ELoc); 13139 } 13140 break; 13141 } 13142 case BO_PtrMemD: 13143 case BO_PtrMemI: 13144 case BO_MulAssign: 13145 case BO_Div: 13146 case BO_Rem: 13147 case BO_Sub: 13148 case BO_Shl: 13149 case BO_Shr: 13150 case BO_LE: 13151 case BO_GE: 13152 case BO_EQ: 13153 case BO_NE: 13154 case BO_Cmp: 13155 case BO_AndAssign: 13156 case BO_XorAssign: 13157 case BO_OrAssign: 13158 case BO_Assign: 13159 case BO_AddAssign: 13160 case BO_SubAssign: 13161 case BO_DivAssign: 13162 case BO_RemAssign: 13163 case BO_ShlAssign: 13164 case BO_ShrAssign: 13165 case BO_Comma: 13166 llvm_unreachable("Unexpected reduction operation"); 13167 } 13168 } 13169 if (Init && DeclareReductionRef.isUnset()) 13170 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13171 else if (!Init) 13172 S.ActOnUninitializedDecl(RHSVD); 13173 if (RHSVD->isInvalidDecl()) 13174 continue; 13175 if (!RHSVD->hasInit() && 13176 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13177 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13178 << Type << ReductionIdRange; 13179 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13180 VarDecl::DeclarationOnly; 13181 S.Diag(D->getLocation(), 13182 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13183 << D; 13184 continue; 13185 } 13186 // Store initializer for single element in private copy. Will be used during 13187 // codegen. 13188 PrivateVD->setInit(RHSVD->getInit()); 13189 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13190 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13191 ExprResult ReductionOp; 13192 if (DeclareReductionRef.isUsable()) { 13193 QualType RedTy = DeclareReductionRef.get()->getType(); 13194 QualType PtrRedTy = Context.getPointerType(RedTy); 13195 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13196 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13197 if (!BasePath.empty()) { 13198 LHS = S.DefaultLvalueConversion(LHS.get()); 13199 RHS = S.DefaultLvalueConversion(RHS.get()); 13200 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13201 CK_UncheckedDerivedToBase, LHS.get(), 13202 &BasePath, LHS.get()->getValueKind()); 13203 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13204 CK_UncheckedDerivedToBase, RHS.get(), 13205 &BasePath, RHS.get()->getValueKind()); 13206 } 13207 FunctionProtoType::ExtProtoInfo EPI; 13208 QualType Params[] = {PtrRedTy, PtrRedTy}; 13209 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13210 auto *OVE = new (Context) OpaqueValueExpr( 13211 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13212 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13213 Expr *Args[] = {LHS.get(), RHS.get()}; 13214 ReductionOp = 13215 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13216 } else { 13217 ReductionOp = S.BuildBinOp( 13218 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13219 if (ReductionOp.isUsable()) { 13220 if (BOK != BO_LT && BOK != BO_GT) { 13221 ReductionOp = 13222 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13223 BO_Assign, LHSDRE, ReductionOp.get()); 13224 } else { 13225 auto *ConditionalOp = new (Context) 13226 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13227 Type, VK_LValue, OK_Ordinary); 13228 ReductionOp = 13229 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13230 BO_Assign, LHSDRE, ConditionalOp); 13231 } 13232 if (ReductionOp.isUsable()) 13233 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13234 /*DiscardedValue*/ false); 13235 } 13236 if (!ReductionOp.isUsable()) 13237 continue; 13238 } 13239 13240 // OpenMP [2.15.4.6, Restrictions, p.2] 13241 // A list item that appears in an in_reduction clause of a task construct 13242 // must appear in a task_reduction clause of a construct associated with a 13243 // taskgroup region that includes the participating task in its taskgroup 13244 // set. The construct associated with the innermost region that meets this 13245 // condition must specify the same reduction-identifier as the in_reduction 13246 // clause. 13247 if (ClauseKind == OMPC_in_reduction) { 13248 SourceRange ParentSR; 13249 BinaryOperatorKind ParentBOK; 13250 const Expr *ParentReductionOp; 13251 Expr *ParentBOKTD, *ParentReductionOpTD; 13252 DSAStackTy::DSAVarData ParentBOKDSA = 13253 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13254 ParentBOKTD); 13255 DSAStackTy::DSAVarData ParentReductionOpDSA = 13256 Stack->getTopMostTaskgroupReductionData( 13257 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13258 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13259 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13260 if (!IsParentBOK && !IsParentReductionOp) { 13261 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13262 continue; 13263 } 13264 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13265 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13266 IsParentReductionOp) { 13267 bool EmitError = true; 13268 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13269 llvm::FoldingSetNodeID RedId, ParentRedId; 13270 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13271 DeclareReductionRef.get()->Profile(RedId, Context, 13272 /*Canonical=*/true); 13273 EmitError = RedId != ParentRedId; 13274 } 13275 if (EmitError) { 13276 S.Diag(ReductionId.getBeginLoc(), 13277 diag::err_omp_reduction_identifier_mismatch) 13278 << ReductionIdRange << RefExpr->getSourceRange(); 13279 S.Diag(ParentSR.getBegin(), 13280 diag::note_omp_previous_reduction_identifier) 13281 << ParentSR 13282 << (IsParentBOK ? ParentBOKDSA.RefExpr 13283 : ParentReductionOpDSA.RefExpr) 13284 ->getSourceRange(); 13285 continue; 13286 } 13287 } 13288 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13289 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13290 } 13291 13292 DeclRefExpr *Ref = nullptr; 13293 Expr *VarsExpr = RefExpr->IgnoreParens(); 13294 if (!VD && !S.CurContext->isDependentContext()) { 13295 if (ASE || OASE) { 13296 TransformExprToCaptures RebuildToCapture(S, D); 13297 VarsExpr = 13298 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13299 Ref = RebuildToCapture.getCapturedExpr(); 13300 } else { 13301 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13302 } 13303 if (!S.isOpenMPCapturedDecl(D)) { 13304 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13305 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13306 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13307 if (!RefRes.isUsable()) 13308 continue; 13309 ExprResult PostUpdateRes = 13310 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13311 RefRes.get()); 13312 if (!PostUpdateRes.isUsable()) 13313 continue; 13314 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13315 Stack->getCurrentDirective() == OMPD_taskgroup) { 13316 S.Diag(RefExpr->getExprLoc(), 13317 diag::err_omp_reduction_non_addressable_expression) 13318 << RefExpr->getSourceRange(); 13319 continue; 13320 } 13321 RD.ExprPostUpdates.emplace_back( 13322 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13323 } 13324 } 13325 } 13326 // All reduction items are still marked as reduction (to do not increase 13327 // code base size). 13328 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13329 if (CurrDir == OMPD_taskgroup) { 13330 if (DeclareReductionRef.isUsable()) 13331 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13332 DeclareReductionRef.get()); 13333 else 13334 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13335 } 13336 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13337 TaskgroupDescriptor); 13338 } 13339 return RD.Vars.empty(); 13340 } 13341 13342 OMPClause *Sema::ActOnOpenMPReductionClause( 13343 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13344 SourceLocation ColonLoc, SourceLocation EndLoc, 13345 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13346 ArrayRef<Expr *> UnresolvedReductions) { 13347 ReductionData RD(VarList.size()); 13348 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13349 StartLoc, LParenLoc, ColonLoc, EndLoc, 13350 ReductionIdScopeSpec, ReductionId, 13351 UnresolvedReductions, RD)) 13352 return nullptr; 13353 13354 return OMPReductionClause::Create( 13355 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13356 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13357 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13358 buildPreInits(Context, RD.ExprCaptures), 13359 buildPostUpdate(*this, RD.ExprPostUpdates)); 13360 } 13361 13362 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13363 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13364 SourceLocation ColonLoc, SourceLocation EndLoc, 13365 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13366 ArrayRef<Expr *> UnresolvedReductions) { 13367 ReductionData RD(VarList.size()); 13368 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13369 StartLoc, LParenLoc, ColonLoc, EndLoc, 13370 ReductionIdScopeSpec, ReductionId, 13371 UnresolvedReductions, RD)) 13372 return nullptr; 13373 13374 return OMPTaskReductionClause::Create( 13375 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13376 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13377 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13378 buildPreInits(Context, RD.ExprCaptures), 13379 buildPostUpdate(*this, RD.ExprPostUpdates)); 13380 } 13381 13382 OMPClause *Sema::ActOnOpenMPInReductionClause( 13383 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13384 SourceLocation ColonLoc, SourceLocation EndLoc, 13385 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13386 ArrayRef<Expr *> UnresolvedReductions) { 13387 ReductionData RD(VarList.size()); 13388 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13389 StartLoc, LParenLoc, ColonLoc, EndLoc, 13390 ReductionIdScopeSpec, ReductionId, 13391 UnresolvedReductions, RD)) 13392 return nullptr; 13393 13394 return OMPInReductionClause::Create( 13395 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13396 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13397 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13398 buildPreInits(Context, RD.ExprCaptures), 13399 buildPostUpdate(*this, RD.ExprPostUpdates)); 13400 } 13401 13402 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13403 SourceLocation LinLoc) { 13404 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13405 LinKind == OMPC_LINEAR_unknown) { 13406 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13407 return true; 13408 } 13409 return false; 13410 } 13411 13412 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13413 OpenMPLinearClauseKind LinKind, 13414 QualType Type) { 13415 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13416 // A variable must not have an incomplete type or a reference type. 13417 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13418 return true; 13419 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13420 !Type->isReferenceType()) { 13421 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13422 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13423 return true; 13424 } 13425 Type = Type.getNonReferenceType(); 13426 13427 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13428 // A variable that is privatized must not have a const-qualified type 13429 // unless it is of class type with a mutable member. This restriction does 13430 // not apply to the firstprivate clause. 13431 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13432 return true; 13433 13434 // A list item must be of integral or pointer type. 13435 Type = Type.getUnqualifiedType().getCanonicalType(); 13436 const auto *Ty = Type.getTypePtrOrNull(); 13437 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13438 !Ty->isPointerType())) { 13439 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13440 if (D) { 13441 bool IsDecl = 13442 !VD || 13443 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13444 Diag(D->getLocation(), 13445 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13446 << D; 13447 } 13448 return true; 13449 } 13450 return false; 13451 } 13452 13453 OMPClause *Sema::ActOnOpenMPLinearClause( 13454 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13455 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13456 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13457 SmallVector<Expr *, 8> Vars; 13458 SmallVector<Expr *, 8> Privates; 13459 SmallVector<Expr *, 8> Inits; 13460 SmallVector<Decl *, 4> ExprCaptures; 13461 SmallVector<Expr *, 4> ExprPostUpdates; 13462 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13463 LinKind = OMPC_LINEAR_val; 13464 for (Expr *RefExpr : VarList) { 13465 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13466 SourceLocation ELoc; 13467 SourceRange ERange; 13468 Expr *SimpleRefExpr = RefExpr; 13469 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13470 if (Res.second) { 13471 // It will be analyzed later. 13472 Vars.push_back(RefExpr); 13473 Privates.push_back(nullptr); 13474 Inits.push_back(nullptr); 13475 } 13476 ValueDecl *D = Res.first; 13477 if (!D) 13478 continue; 13479 13480 QualType Type = D->getType(); 13481 auto *VD = dyn_cast<VarDecl>(D); 13482 13483 // OpenMP [2.14.3.7, linear clause] 13484 // A list-item cannot appear in more than one linear clause. 13485 // A list-item that appears in a linear clause cannot appear in any 13486 // other data-sharing attribute clause. 13487 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13488 if (DVar.RefExpr) { 13489 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13490 << getOpenMPClauseName(OMPC_linear); 13491 reportOriginalDsa(*this, DSAStack, D, DVar); 13492 continue; 13493 } 13494 13495 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13496 continue; 13497 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13498 13499 // Build private copy of original var. 13500 VarDecl *Private = 13501 buildVarDecl(*this, ELoc, Type, D->getName(), 13502 D->hasAttrs() ? &D->getAttrs() : nullptr, 13503 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13504 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13505 // Build var to save initial value. 13506 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13507 Expr *InitExpr; 13508 DeclRefExpr *Ref = nullptr; 13509 if (!VD && !CurContext->isDependentContext()) { 13510 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13511 if (!isOpenMPCapturedDecl(D)) { 13512 ExprCaptures.push_back(Ref->getDecl()); 13513 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13514 ExprResult RefRes = DefaultLvalueConversion(Ref); 13515 if (!RefRes.isUsable()) 13516 continue; 13517 ExprResult PostUpdateRes = 13518 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13519 SimpleRefExpr, RefRes.get()); 13520 if (!PostUpdateRes.isUsable()) 13521 continue; 13522 ExprPostUpdates.push_back( 13523 IgnoredValueConversions(PostUpdateRes.get()).get()); 13524 } 13525 } 13526 } 13527 if (LinKind == OMPC_LINEAR_uval) 13528 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13529 else 13530 InitExpr = VD ? SimpleRefExpr : Ref; 13531 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13532 /*DirectInit=*/false); 13533 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13534 13535 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13536 Vars.push_back((VD || CurContext->isDependentContext()) 13537 ? RefExpr->IgnoreParens() 13538 : Ref); 13539 Privates.push_back(PrivateRef); 13540 Inits.push_back(InitRef); 13541 } 13542 13543 if (Vars.empty()) 13544 return nullptr; 13545 13546 Expr *StepExpr = Step; 13547 Expr *CalcStepExpr = nullptr; 13548 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13549 !Step->isInstantiationDependent() && 13550 !Step->containsUnexpandedParameterPack()) { 13551 SourceLocation StepLoc = Step->getBeginLoc(); 13552 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13553 if (Val.isInvalid()) 13554 return nullptr; 13555 StepExpr = Val.get(); 13556 13557 // Build var to save the step value. 13558 VarDecl *SaveVar = 13559 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13560 ExprResult SaveRef = 13561 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13562 ExprResult CalcStep = 13563 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13564 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13565 13566 // Warn about zero linear step (it would be probably better specified as 13567 // making corresponding variables 'const'). 13568 llvm::APSInt Result; 13569 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13570 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13571 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13572 << (Vars.size() > 1); 13573 if (!IsConstant && CalcStep.isUsable()) { 13574 // Calculate the step beforehand instead of doing this on each iteration. 13575 // (This is not used if the number of iterations may be kfold-ed). 13576 CalcStepExpr = CalcStep.get(); 13577 } 13578 } 13579 13580 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13581 ColonLoc, EndLoc, Vars, Privates, Inits, 13582 StepExpr, CalcStepExpr, 13583 buildPreInits(Context, ExprCaptures), 13584 buildPostUpdate(*this, ExprPostUpdates)); 13585 } 13586 13587 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13588 Expr *NumIterations, Sema &SemaRef, 13589 Scope *S, DSAStackTy *Stack) { 13590 // Walk the vars and build update/final expressions for the CodeGen. 13591 SmallVector<Expr *, 8> Updates; 13592 SmallVector<Expr *, 8> Finals; 13593 SmallVector<Expr *, 8> UsedExprs; 13594 Expr *Step = Clause.getStep(); 13595 Expr *CalcStep = Clause.getCalcStep(); 13596 // OpenMP [2.14.3.7, linear clause] 13597 // If linear-step is not specified it is assumed to be 1. 13598 if (!Step) 13599 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13600 else if (CalcStep) 13601 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13602 bool HasErrors = false; 13603 auto CurInit = Clause.inits().begin(); 13604 auto CurPrivate = Clause.privates().begin(); 13605 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13606 for (Expr *RefExpr : Clause.varlists()) { 13607 SourceLocation ELoc; 13608 SourceRange ERange; 13609 Expr *SimpleRefExpr = RefExpr; 13610 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13611 ValueDecl *D = Res.first; 13612 if (Res.second || !D) { 13613 Updates.push_back(nullptr); 13614 Finals.push_back(nullptr); 13615 HasErrors = true; 13616 continue; 13617 } 13618 auto &&Info = Stack->isLoopControlVariable(D); 13619 // OpenMP [2.15.11, distribute simd Construct] 13620 // A list item may not appear in a linear clause, unless it is the loop 13621 // iteration variable. 13622 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13623 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13624 SemaRef.Diag(ELoc, 13625 diag::err_omp_linear_distribute_var_non_loop_iteration); 13626 Updates.push_back(nullptr); 13627 Finals.push_back(nullptr); 13628 HasErrors = true; 13629 continue; 13630 } 13631 Expr *InitExpr = *CurInit; 13632 13633 // Build privatized reference to the current linear var. 13634 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13635 Expr *CapturedRef; 13636 if (LinKind == OMPC_LINEAR_uval) 13637 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13638 else 13639 CapturedRef = 13640 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13641 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13642 /*RefersToCapture=*/true); 13643 13644 // Build update: Var = InitExpr + IV * Step 13645 ExprResult Update; 13646 if (!Info.first) 13647 Update = buildCounterUpdate( 13648 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13649 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13650 else 13651 Update = *CurPrivate; 13652 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13653 /*DiscardedValue*/ false); 13654 13655 // Build final: Var = InitExpr + NumIterations * Step 13656 ExprResult Final; 13657 if (!Info.first) 13658 Final = 13659 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13660 InitExpr, NumIterations, Step, /*Subtract=*/false, 13661 /*IsNonRectangularLB=*/false); 13662 else 13663 Final = *CurPrivate; 13664 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13665 /*DiscardedValue*/ false); 13666 13667 if (!Update.isUsable() || !Final.isUsable()) { 13668 Updates.push_back(nullptr); 13669 Finals.push_back(nullptr); 13670 UsedExprs.push_back(nullptr); 13671 HasErrors = true; 13672 } else { 13673 Updates.push_back(Update.get()); 13674 Finals.push_back(Final.get()); 13675 if (!Info.first) 13676 UsedExprs.push_back(SimpleRefExpr); 13677 } 13678 ++CurInit; 13679 ++CurPrivate; 13680 } 13681 if (Expr *S = Clause.getStep()) 13682 UsedExprs.push_back(S); 13683 // Fill the remaining part with the nullptr. 13684 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13685 Clause.setUpdates(Updates); 13686 Clause.setFinals(Finals); 13687 Clause.setUsedExprs(UsedExprs); 13688 return HasErrors; 13689 } 13690 13691 OMPClause *Sema::ActOnOpenMPAlignedClause( 13692 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13693 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13694 SmallVector<Expr *, 8> Vars; 13695 for (Expr *RefExpr : VarList) { 13696 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13697 SourceLocation ELoc; 13698 SourceRange ERange; 13699 Expr *SimpleRefExpr = RefExpr; 13700 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13701 if (Res.second) { 13702 // It will be analyzed later. 13703 Vars.push_back(RefExpr); 13704 } 13705 ValueDecl *D = Res.first; 13706 if (!D) 13707 continue; 13708 13709 QualType QType = D->getType(); 13710 auto *VD = dyn_cast<VarDecl>(D); 13711 13712 // OpenMP [2.8.1, simd construct, Restrictions] 13713 // The type of list items appearing in the aligned clause must be 13714 // array, pointer, reference to array, or reference to pointer. 13715 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13716 const Type *Ty = QType.getTypePtrOrNull(); 13717 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 13718 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 13719 << QType << getLangOpts().CPlusPlus << ERange; 13720 bool IsDecl = 13721 !VD || 13722 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13723 Diag(D->getLocation(), 13724 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13725 << D; 13726 continue; 13727 } 13728 13729 // OpenMP [2.8.1, simd construct, Restrictions] 13730 // A list-item cannot appear in more than one aligned clause. 13731 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 13732 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 13733 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 13734 << getOpenMPClauseName(OMPC_aligned); 13735 continue; 13736 } 13737 13738 DeclRefExpr *Ref = nullptr; 13739 if (!VD && isOpenMPCapturedDecl(D)) 13740 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13741 Vars.push_back(DefaultFunctionArrayConversion( 13742 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 13743 .get()); 13744 } 13745 13746 // OpenMP [2.8.1, simd construct, Description] 13747 // The parameter of the aligned clause, alignment, must be a constant 13748 // positive integer expression. 13749 // If no optional parameter is specified, implementation-defined default 13750 // alignments for SIMD instructions on the target platforms are assumed. 13751 if (Alignment != nullptr) { 13752 ExprResult AlignResult = 13753 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 13754 if (AlignResult.isInvalid()) 13755 return nullptr; 13756 Alignment = AlignResult.get(); 13757 } 13758 if (Vars.empty()) 13759 return nullptr; 13760 13761 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 13762 EndLoc, Vars, Alignment); 13763 } 13764 13765 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 13766 SourceLocation StartLoc, 13767 SourceLocation LParenLoc, 13768 SourceLocation EndLoc) { 13769 SmallVector<Expr *, 8> Vars; 13770 SmallVector<Expr *, 8> SrcExprs; 13771 SmallVector<Expr *, 8> DstExprs; 13772 SmallVector<Expr *, 8> AssignmentOps; 13773 for (Expr *RefExpr : VarList) { 13774 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 13775 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13776 // It will be analyzed later. 13777 Vars.push_back(RefExpr); 13778 SrcExprs.push_back(nullptr); 13779 DstExprs.push_back(nullptr); 13780 AssignmentOps.push_back(nullptr); 13781 continue; 13782 } 13783 13784 SourceLocation ELoc = RefExpr->getExprLoc(); 13785 // OpenMP [2.1, C/C++] 13786 // A list item is a variable name. 13787 // OpenMP [2.14.4.1, Restrictions, p.1] 13788 // A list item that appears in a copyin clause must be threadprivate. 13789 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 13790 if (!DE || !isa<VarDecl>(DE->getDecl())) { 13791 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 13792 << 0 << RefExpr->getSourceRange(); 13793 continue; 13794 } 13795 13796 Decl *D = DE->getDecl(); 13797 auto *VD = cast<VarDecl>(D); 13798 13799 QualType Type = VD->getType(); 13800 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 13801 // It will be analyzed later. 13802 Vars.push_back(DE); 13803 SrcExprs.push_back(nullptr); 13804 DstExprs.push_back(nullptr); 13805 AssignmentOps.push_back(nullptr); 13806 continue; 13807 } 13808 13809 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 13810 // A list item that appears in a copyin clause must be threadprivate. 13811 if (!DSAStack->isThreadPrivate(VD)) { 13812 Diag(ELoc, diag::err_omp_required_access) 13813 << getOpenMPClauseName(OMPC_copyin) 13814 << getOpenMPDirectiveName(OMPD_threadprivate); 13815 continue; 13816 } 13817 13818 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13819 // A variable of class type (or array thereof) that appears in a 13820 // copyin clause requires an accessible, unambiguous copy assignment 13821 // operator for the class type. 13822 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13823 VarDecl *SrcVD = 13824 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 13825 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13826 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 13827 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 13828 VarDecl *DstVD = 13829 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 13830 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13831 DeclRefExpr *PseudoDstExpr = 13832 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 13833 // For arrays generate assignment operation for single element and replace 13834 // it by the original array element in CodeGen. 13835 ExprResult AssignmentOp = 13836 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 13837 PseudoSrcExpr); 13838 if (AssignmentOp.isInvalid()) 13839 continue; 13840 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 13841 /*DiscardedValue*/ false); 13842 if (AssignmentOp.isInvalid()) 13843 continue; 13844 13845 DSAStack->addDSA(VD, DE, OMPC_copyin); 13846 Vars.push_back(DE); 13847 SrcExprs.push_back(PseudoSrcExpr); 13848 DstExprs.push_back(PseudoDstExpr); 13849 AssignmentOps.push_back(AssignmentOp.get()); 13850 } 13851 13852 if (Vars.empty()) 13853 return nullptr; 13854 13855 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13856 SrcExprs, DstExprs, AssignmentOps); 13857 } 13858 13859 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 13860 SourceLocation StartLoc, 13861 SourceLocation LParenLoc, 13862 SourceLocation EndLoc) { 13863 SmallVector<Expr *, 8> Vars; 13864 SmallVector<Expr *, 8> SrcExprs; 13865 SmallVector<Expr *, 8> DstExprs; 13866 SmallVector<Expr *, 8> AssignmentOps; 13867 for (Expr *RefExpr : VarList) { 13868 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13869 SourceLocation ELoc; 13870 SourceRange ERange; 13871 Expr *SimpleRefExpr = RefExpr; 13872 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13873 if (Res.second) { 13874 // It will be analyzed later. 13875 Vars.push_back(RefExpr); 13876 SrcExprs.push_back(nullptr); 13877 DstExprs.push_back(nullptr); 13878 AssignmentOps.push_back(nullptr); 13879 } 13880 ValueDecl *D = Res.first; 13881 if (!D) 13882 continue; 13883 13884 QualType Type = D->getType(); 13885 auto *VD = dyn_cast<VarDecl>(D); 13886 13887 // OpenMP [2.14.4.2, Restrictions, p.2] 13888 // A list item that appears in a copyprivate clause may not appear in a 13889 // private or firstprivate clause on the single construct. 13890 if (!VD || !DSAStack->isThreadPrivate(VD)) { 13891 DSAStackTy::DSAVarData DVar = 13892 DSAStack->getTopDSA(D, /*FromParent=*/false); 13893 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 13894 DVar.RefExpr) { 13895 Diag(ELoc, diag::err_omp_wrong_dsa) 13896 << getOpenMPClauseName(DVar.CKind) 13897 << getOpenMPClauseName(OMPC_copyprivate); 13898 reportOriginalDsa(*this, DSAStack, D, DVar); 13899 continue; 13900 } 13901 13902 // OpenMP [2.11.4.2, Restrictions, p.1] 13903 // All list items that appear in a copyprivate clause must be either 13904 // threadprivate or private in the enclosing context. 13905 if (DVar.CKind == OMPC_unknown) { 13906 DVar = DSAStack->getImplicitDSA(D, false); 13907 if (DVar.CKind == OMPC_shared) { 13908 Diag(ELoc, diag::err_omp_required_access) 13909 << getOpenMPClauseName(OMPC_copyprivate) 13910 << "threadprivate or private in the enclosing context"; 13911 reportOriginalDsa(*this, DSAStack, D, DVar); 13912 continue; 13913 } 13914 } 13915 } 13916 13917 // Variably modified types are not supported. 13918 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 13919 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13920 << getOpenMPClauseName(OMPC_copyprivate) << Type 13921 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13922 bool IsDecl = 13923 !VD || 13924 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13925 Diag(D->getLocation(), 13926 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13927 << D; 13928 continue; 13929 } 13930 13931 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13932 // A variable of class type (or array thereof) that appears in a 13933 // copyin clause requires an accessible, unambiguous copy assignment 13934 // operator for the class type. 13935 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13936 .getUnqualifiedType(); 13937 VarDecl *SrcVD = 13938 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13939 D->hasAttrs() ? &D->getAttrs() : nullptr); 13940 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13941 VarDecl *DstVD = 13942 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13943 D->hasAttrs() ? &D->getAttrs() : nullptr); 13944 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13945 ExprResult AssignmentOp = BuildBinOp( 13946 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13947 if (AssignmentOp.isInvalid()) 13948 continue; 13949 AssignmentOp = 13950 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13951 if (AssignmentOp.isInvalid()) 13952 continue; 13953 13954 // No need to mark vars as copyprivate, they are already threadprivate or 13955 // implicitly private. 13956 assert(VD || isOpenMPCapturedDecl(D)); 13957 Vars.push_back( 13958 VD ? RefExpr->IgnoreParens() 13959 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13960 SrcExprs.push_back(PseudoSrcExpr); 13961 DstExprs.push_back(PseudoDstExpr); 13962 AssignmentOps.push_back(AssignmentOp.get()); 13963 } 13964 13965 if (Vars.empty()) 13966 return nullptr; 13967 13968 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13969 Vars, SrcExprs, DstExprs, AssignmentOps); 13970 } 13971 13972 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13973 SourceLocation StartLoc, 13974 SourceLocation LParenLoc, 13975 SourceLocation EndLoc) { 13976 if (VarList.empty()) 13977 return nullptr; 13978 13979 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13980 } 13981 13982 OMPClause * 13983 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13984 SourceLocation DepLoc, SourceLocation ColonLoc, 13985 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13986 SourceLocation LParenLoc, SourceLocation EndLoc) { 13987 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13988 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13989 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13990 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13991 return nullptr; 13992 } 13993 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13994 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13995 DepKind == OMPC_DEPEND_sink)) { 13996 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13997 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13998 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13999 /*Last=*/OMPC_DEPEND_unknown, Except) 14000 << getOpenMPClauseName(OMPC_depend); 14001 return nullptr; 14002 } 14003 SmallVector<Expr *, 8> Vars; 14004 DSAStackTy::OperatorOffsetTy OpsOffs; 14005 llvm::APSInt DepCounter(/*BitWidth=*/32); 14006 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14007 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14008 if (const Expr *OrderedCountExpr = 14009 DSAStack->getParentOrderedRegionParam().first) { 14010 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14011 TotalDepCount.setIsUnsigned(/*Val=*/true); 14012 } 14013 } 14014 for (Expr *RefExpr : VarList) { 14015 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14016 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14017 // It will be analyzed later. 14018 Vars.push_back(RefExpr); 14019 continue; 14020 } 14021 14022 SourceLocation ELoc = RefExpr->getExprLoc(); 14023 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14024 if (DepKind == OMPC_DEPEND_sink) { 14025 if (DSAStack->getParentOrderedRegionParam().first && 14026 DepCounter >= TotalDepCount) { 14027 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14028 continue; 14029 } 14030 ++DepCounter; 14031 // OpenMP [2.13.9, Summary] 14032 // depend(dependence-type : vec), where dependence-type is: 14033 // 'sink' and where vec is the iteration vector, which has the form: 14034 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14035 // where n is the value specified by the ordered clause in the loop 14036 // directive, xi denotes the loop iteration variable of the i-th nested 14037 // loop associated with the loop directive, and di is a constant 14038 // non-negative integer. 14039 if (CurContext->isDependentContext()) { 14040 // It will be analyzed later. 14041 Vars.push_back(RefExpr); 14042 continue; 14043 } 14044 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14045 OverloadedOperatorKind OOK = OO_None; 14046 SourceLocation OOLoc; 14047 Expr *LHS = SimpleExpr; 14048 Expr *RHS = nullptr; 14049 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14050 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14051 OOLoc = BO->getOperatorLoc(); 14052 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14053 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14054 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14055 OOK = OCE->getOperator(); 14056 OOLoc = OCE->getOperatorLoc(); 14057 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14058 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14059 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14060 OOK = MCE->getMethodDecl() 14061 ->getNameInfo() 14062 .getName() 14063 .getCXXOverloadedOperator(); 14064 OOLoc = MCE->getCallee()->getExprLoc(); 14065 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14066 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14067 } 14068 SourceLocation ELoc; 14069 SourceRange ERange; 14070 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14071 if (Res.second) { 14072 // It will be analyzed later. 14073 Vars.push_back(RefExpr); 14074 } 14075 ValueDecl *D = Res.first; 14076 if (!D) 14077 continue; 14078 14079 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14080 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14081 continue; 14082 } 14083 if (RHS) { 14084 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14085 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14086 if (RHSRes.isInvalid()) 14087 continue; 14088 } 14089 if (!CurContext->isDependentContext() && 14090 DSAStack->getParentOrderedRegionParam().first && 14091 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14092 const ValueDecl *VD = 14093 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14094 if (VD) 14095 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14096 << 1 << VD; 14097 else 14098 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14099 continue; 14100 } 14101 OpsOffs.emplace_back(RHS, OOK); 14102 } else { 14103 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14104 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14105 (ASE && 14106 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14107 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14108 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14109 << RefExpr->getSourceRange(); 14110 continue; 14111 } 14112 14113 ExprResult Res; 14114 { 14115 Sema::TentativeAnalysisScope Trap(*this); 14116 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14117 RefExpr->IgnoreParenImpCasts()); 14118 } 14119 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14120 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14121 << RefExpr->getSourceRange(); 14122 continue; 14123 } 14124 } 14125 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14126 } 14127 14128 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14129 TotalDepCount > VarList.size() && 14130 DSAStack->getParentOrderedRegionParam().first && 14131 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14132 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14133 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14134 } 14135 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14136 Vars.empty()) 14137 return nullptr; 14138 14139 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14140 DepKind, DepLoc, ColonLoc, Vars, 14141 TotalDepCount.getZExtValue()); 14142 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14143 DSAStack->isParentOrderedRegion()) 14144 DSAStack->addDoacrossDependClause(C, OpsOffs); 14145 return C; 14146 } 14147 14148 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14149 SourceLocation LParenLoc, 14150 SourceLocation EndLoc) { 14151 Expr *ValExpr = Device; 14152 Stmt *HelperValStmt = nullptr; 14153 14154 // OpenMP [2.9.1, Restrictions] 14155 // The device expression must evaluate to a non-negative integer value. 14156 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14157 /*StrictlyPositive=*/false)) 14158 return nullptr; 14159 14160 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14161 OpenMPDirectiveKind CaptureRegion = 14162 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14163 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14164 ValExpr = MakeFullExpr(ValExpr).get(); 14165 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14166 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14167 HelperValStmt = buildPreInits(Context, Captures); 14168 } 14169 14170 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14171 StartLoc, LParenLoc, EndLoc); 14172 } 14173 14174 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14175 DSAStackTy *Stack, QualType QTy, 14176 bool FullCheck = true) { 14177 NamedDecl *ND; 14178 if (QTy->isIncompleteType(&ND)) { 14179 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14180 return false; 14181 } 14182 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14183 !QTy.isTrivialType(SemaRef.Context)) 14184 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14185 return true; 14186 } 14187 14188 /// Return true if it can be proven that the provided array expression 14189 /// (array section or array subscript) does NOT specify the whole size of the 14190 /// array whose base type is \a BaseQTy. 14191 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14192 const Expr *E, 14193 QualType BaseQTy) { 14194 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14195 14196 // If this is an array subscript, it refers to the whole size if the size of 14197 // the dimension is constant and equals 1. Also, an array section assumes the 14198 // format of an array subscript if no colon is used. 14199 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14200 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14201 return ATy->getSize().getSExtValue() != 1; 14202 // Size can't be evaluated statically. 14203 return false; 14204 } 14205 14206 assert(OASE && "Expecting array section if not an array subscript."); 14207 const Expr *LowerBound = OASE->getLowerBound(); 14208 const Expr *Length = OASE->getLength(); 14209 14210 // If there is a lower bound that does not evaluates to zero, we are not 14211 // covering the whole dimension. 14212 if (LowerBound) { 14213 Expr::EvalResult Result; 14214 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14215 return false; // Can't get the integer value as a constant. 14216 14217 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14218 if (ConstLowerBound.getSExtValue()) 14219 return true; 14220 } 14221 14222 // If we don't have a length we covering the whole dimension. 14223 if (!Length) 14224 return false; 14225 14226 // If the base is a pointer, we don't have a way to get the size of the 14227 // pointee. 14228 if (BaseQTy->isPointerType()) 14229 return false; 14230 14231 // We can only check if the length is the same as the size of the dimension 14232 // if we have a constant array. 14233 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14234 if (!CATy) 14235 return false; 14236 14237 Expr::EvalResult Result; 14238 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14239 return false; // Can't get the integer value as a constant. 14240 14241 llvm::APSInt ConstLength = Result.Val.getInt(); 14242 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14243 } 14244 14245 // Return true if it can be proven that the provided array expression (array 14246 // section or array subscript) does NOT specify a single element of the array 14247 // whose base type is \a BaseQTy. 14248 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14249 const Expr *E, 14250 QualType BaseQTy) { 14251 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14252 14253 // An array subscript always refer to a single element. Also, an array section 14254 // assumes the format of an array subscript if no colon is used. 14255 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14256 return false; 14257 14258 assert(OASE && "Expecting array section if not an array subscript."); 14259 const Expr *Length = OASE->getLength(); 14260 14261 // If we don't have a length we have to check if the array has unitary size 14262 // for this dimension. Also, we should always expect a length if the base type 14263 // is pointer. 14264 if (!Length) { 14265 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14266 return ATy->getSize().getSExtValue() != 1; 14267 // We cannot assume anything. 14268 return false; 14269 } 14270 14271 // Check if the length evaluates to 1. 14272 Expr::EvalResult Result; 14273 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14274 return false; // Can't get the integer value as a constant. 14275 14276 llvm::APSInt ConstLength = Result.Val.getInt(); 14277 return ConstLength.getSExtValue() != 1; 14278 } 14279 14280 // Return the expression of the base of the mappable expression or null if it 14281 // cannot be determined and do all the necessary checks to see if the expression 14282 // is valid as a standalone mappable expression. In the process, record all the 14283 // components of the expression. 14284 static const Expr *checkMapClauseExpressionBase( 14285 Sema &SemaRef, Expr *E, 14286 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14287 OpenMPClauseKind CKind, bool NoDiagnose) { 14288 SourceLocation ELoc = E->getExprLoc(); 14289 SourceRange ERange = E->getSourceRange(); 14290 14291 // The base of elements of list in a map clause have to be either: 14292 // - a reference to variable or field. 14293 // - a member expression. 14294 // - an array expression. 14295 // 14296 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14297 // reference to 'r'. 14298 // 14299 // If we have: 14300 // 14301 // struct SS { 14302 // Bla S; 14303 // foo() { 14304 // #pragma omp target map (S.Arr[:12]); 14305 // } 14306 // } 14307 // 14308 // We want to retrieve the member expression 'this->S'; 14309 14310 const Expr *RelevantExpr = nullptr; 14311 14312 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14313 // If a list item is an array section, it must specify contiguous storage. 14314 // 14315 // For this restriction it is sufficient that we make sure only references 14316 // to variables or fields and array expressions, and that no array sections 14317 // exist except in the rightmost expression (unless they cover the whole 14318 // dimension of the array). E.g. these would be invalid: 14319 // 14320 // r.ArrS[3:5].Arr[6:7] 14321 // 14322 // r.ArrS[3:5].x 14323 // 14324 // but these would be valid: 14325 // r.ArrS[3].Arr[6:7] 14326 // 14327 // r.ArrS[3].x 14328 14329 bool AllowUnitySizeArraySection = true; 14330 bool AllowWholeSizeArraySection = true; 14331 14332 while (!RelevantExpr) { 14333 E = E->IgnoreParenImpCasts(); 14334 14335 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14336 if (!isa<VarDecl>(CurE->getDecl())) 14337 return nullptr; 14338 14339 RelevantExpr = CurE; 14340 14341 // If we got a reference to a declaration, we should not expect any array 14342 // section before that. 14343 AllowUnitySizeArraySection = false; 14344 AllowWholeSizeArraySection = false; 14345 14346 // Record the component. 14347 CurComponents.emplace_back(CurE, CurE->getDecl()); 14348 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14349 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14350 14351 if (isa<CXXThisExpr>(BaseE)) 14352 // We found a base expression: this->Val. 14353 RelevantExpr = CurE; 14354 else 14355 E = BaseE; 14356 14357 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14358 if (!NoDiagnose) { 14359 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14360 << CurE->getSourceRange(); 14361 return nullptr; 14362 } 14363 if (RelevantExpr) 14364 return nullptr; 14365 continue; 14366 } 14367 14368 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14369 14370 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14371 // A bit-field cannot appear in a map clause. 14372 // 14373 if (FD->isBitField()) { 14374 if (!NoDiagnose) { 14375 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14376 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14377 return nullptr; 14378 } 14379 if (RelevantExpr) 14380 return nullptr; 14381 continue; 14382 } 14383 14384 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14385 // If the type of a list item is a reference to a type T then the type 14386 // will be considered to be T for all purposes of this clause. 14387 QualType CurType = BaseE->getType().getNonReferenceType(); 14388 14389 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14390 // A list item cannot be a variable that is a member of a structure with 14391 // a union type. 14392 // 14393 if (CurType->isUnionType()) { 14394 if (!NoDiagnose) { 14395 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14396 << CurE->getSourceRange(); 14397 return nullptr; 14398 } 14399 continue; 14400 } 14401 14402 // If we got a member expression, we should not expect any array section 14403 // before that: 14404 // 14405 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14406 // If a list item is an element of a structure, only the rightmost symbol 14407 // of the variable reference can be an array section. 14408 // 14409 AllowUnitySizeArraySection = false; 14410 AllowWholeSizeArraySection = false; 14411 14412 // Record the component. 14413 CurComponents.emplace_back(CurE, FD); 14414 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14415 E = CurE->getBase()->IgnoreParenImpCasts(); 14416 14417 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14418 if (!NoDiagnose) { 14419 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14420 << 0 << CurE->getSourceRange(); 14421 return nullptr; 14422 } 14423 continue; 14424 } 14425 14426 // If we got an array subscript that express the whole dimension we 14427 // can have any array expressions before. If it only expressing part of 14428 // the dimension, we can only have unitary-size array expressions. 14429 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14430 E->getType())) 14431 AllowWholeSizeArraySection = false; 14432 14433 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14434 Expr::EvalResult Result; 14435 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14436 if (!Result.Val.getInt().isNullValue()) { 14437 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14438 diag::err_omp_invalid_map_this_expr); 14439 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14440 diag::note_omp_invalid_subscript_on_this_ptr_map); 14441 } 14442 } 14443 RelevantExpr = TE; 14444 } 14445 14446 // Record the component - we don't have any declaration associated. 14447 CurComponents.emplace_back(CurE, nullptr); 14448 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14449 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14450 E = CurE->getBase()->IgnoreParenImpCasts(); 14451 14452 QualType CurType = 14453 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14454 14455 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14456 // If the type of a list item is a reference to a type T then the type 14457 // will be considered to be T for all purposes of this clause. 14458 if (CurType->isReferenceType()) 14459 CurType = CurType->getPointeeType(); 14460 14461 bool IsPointer = CurType->isAnyPointerType(); 14462 14463 if (!IsPointer && !CurType->isArrayType()) { 14464 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14465 << 0 << CurE->getSourceRange(); 14466 return nullptr; 14467 } 14468 14469 bool NotWhole = 14470 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14471 bool NotUnity = 14472 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14473 14474 if (AllowWholeSizeArraySection) { 14475 // Any array section is currently allowed. Allowing a whole size array 14476 // section implies allowing a unity array section as well. 14477 // 14478 // If this array section refers to the whole dimension we can still 14479 // accept other array sections before this one, except if the base is a 14480 // pointer. Otherwise, only unitary sections are accepted. 14481 if (NotWhole || IsPointer) 14482 AllowWholeSizeArraySection = false; 14483 } else if (AllowUnitySizeArraySection && NotUnity) { 14484 // A unity or whole array section is not allowed and that is not 14485 // compatible with the properties of the current array section. 14486 SemaRef.Diag( 14487 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14488 << CurE->getSourceRange(); 14489 return nullptr; 14490 } 14491 14492 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14493 Expr::EvalResult ResultR; 14494 Expr::EvalResult ResultL; 14495 if (CurE->getLength()->EvaluateAsInt(ResultR, 14496 SemaRef.getASTContext())) { 14497 if (!ResultR.Val.getInt().isOneValue()) { 14498 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14499 diag::err_omp_invalid_map_this_expr); 14500 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14501 diag::note_omp_invalid_length_on_this_ptr_mapping); 14502 } 14503 } 14504 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14505 ResultL, SemaRef.getASTContext())) { 14506 if (!ResultL.Val.getInt().isNullValue()) { 14507 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14508 diag::err_omp_invalid_map_this_expr); 14509 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14510 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14511 } 14512 } 14513 RelevantExpr = TE; 14514 } 14515 14516 // Record the component - we don't have any declaration associated. 14517 CurComponents.emplace_back(CurE, nullptr); 14518 } else { 14519 if (!NoDiagnose) { 14520 // If nothing else worked, this is not a valid map clause expression. 14521 SemaRef.Diag( 14522 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14523 << ERange; 14524 } 14525 return nullptr; 14526 } 14527 } 14528 14529 return RelevantExpr; 14530 } 14531 14532 // Return true if expression E associated with value VD has conflicts with other 14533 // map information. 14534 static bool checkMapConflicts( 14535 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14536 bool CurrentRegionOnly, 14537 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14538 OpenMPClauseKind CKind) { 14539 assert(VD && E); 14540 SourceLocation ELoc = E->getExprLoc(); 14541 SourceRange ERange = E->getSourceRange(); 14542 14543 // In order to easily check the conflicts we need to match each component of 14544 // the expression under test with the components of the expressions that are 14545 // already in the stack. 14546 14547 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14548 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14549 "Map clause expression with unexpected base!"); 14550 14551 // Variables to help detecting enclosing problems in data environment nests. 14552 bool IsEnclosedByDataEnvironmentExpr = false; 14553 const Expr *EnclosingExpr = nullptr; 14554 14555 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14556 VD, CurrentRegionOnly, 14557 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14558 ERange, CKind, &EnclosingExpr, 14559 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14560 StackComponents, 14561 OpenMPClauseKind) { 14562 assert(!StackComponents.empty() && 14563 "Map clause expression with no components!"); 14564 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14565 "Map clause expression with unexpected base!"); 14566 (void)VD; 14567 14568 // The whole expression in the stack. 14569 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14570 14571 // Expressions must start from the same base. Here we detect at which 14572 // point both expressions diverge from each other and see if we can 14573 // detect if the memory referred to both expressions is contiguous and 14574 // do not overlap. 14575 auto CI = CurComponents.rbegin(); 14576 auto CE = CurComponents.rend(); 14577 auto SI = StackComponents.rbegin(); 14578 auto SE = StackComponents.rend(); 14579 for (; CI != CE && SI != SE; ++CI, ++SI) { 14580 14581 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14582 // At most one list item can be an array item derived from a given 14583 // variable in map clauses of the same construct. 14584 if (CurrentRegionOnly && 14585 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14586 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14587 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14588 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14589 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14590 diag::err_omp_multiple_array_items_in_map_clause) 14591 << CI->getAssociatedExpression()->getSourceRange(); 14592 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14593 diag::note_used_here) 14594 << SI->getAssociatedExpression()->getSourceRange(); 14595 return true; 14596 } 14597 14598 // Do both expressions have the same kind? 14599 if (CI->getAssociatedExpression()->getStmtClass() != 14600 SI->getAssociatedExpression()->getStmtClass()) 14601 break; 14602 14603 // Are we dealing with different variables/fields? 14604 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14605 break; 14606 } 14607 // Check if the extra components of the expressions in the enclosing 14608 // data environment are redundant for the current base declaration. 14609 // If they are, the maps completely overlap, which is legal. 14610 for (; SI != SE; ++SI) { 14611 QualType Type; 14612 if (const auto *ASE = 14613 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14614 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14615 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14616 SI->getAssociatedExpression())) { 14617 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14618 Type = 14619 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14620 } 14621 if (Type.isNull() || Type->isAnyPointerType() || 14622 checkArrayExpressionDoesNotReferToWholeSize( 14623 SemaRef, SI->getAssociatedExpression(), Type)) 14624 break; 14625 } 14626 14627 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14628 // List items of map clauses in the same construct must not share 14629 // original storage. 14630 // 14631 // If the expressions are exactly the same or one is a subset of the 14632 // other, it means they are sharing storage. 14633 if (CI == CE && SI == SE) { 14634 if (CurrentRegionOnly) { 14635 if (CKind == OMPC_map) { 14636 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14637 } else { 14638 assert(CKind == OMPC_to || CKind == OMPC_from); 14639 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14640 << ERange; 14641 } 14642 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14643 << RE->getSourceRange(); 14644 return true; 14645 } 14646 // If we find the same expression in the enclosing data environment, 14647 // that is legal. 14648 IsEnclosedByDataEnvironmentExpr = true; 14649 return false; 14650 } 14651 14652 QualType DerivedType = 14653 std::prev(CI)->getAssociatedDeclaration()->getType(); 14654 SourceLocation DerivedLoc = 14655 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14656 14657 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14658 // If the type of a list item is a reference to a type T then the type 14659 // will be considered to be T for all purposes of this clause. 14660 DerivedType = DerivedType.getNonReferenceType(); 14661 14662 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14663 // A variable for which the type is pointer and an array section 14664 // derived from that variable must not appear as list items of map 14665 // clauses of the same construct. 14666 // 14667 // Also, cover one of the cases in: 14668 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14669 // If any part of the original storage of a list item has corresponding 14670 // storage in the device data environment, all of the original storage 14671 // must have corresponding storage in the device data environment. 14672 // 14673 if (DerivedType->isAnyPointerType()) { 14674 if (CI == CE || SI == SE) { 14675 SemaRef.Diag( 14676 DerivedLoc, 14677 diag::err_omp_pointer_mapped_along_with_derived_section) 14678 << DerivedLoc; 14679 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14680 << RE->getSourceRange(); 14681 return true; 14682 } 14683 if (CI->getAssociatedExpression()->getStmtClass() != 14684 SI->getAssociatedExpression()->getStmtClass() || 14685 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14686 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14687 assert(CI != CE && SI != SE); 14688 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14689 << DerivedLoc; 14690 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14691 << RE->getSourceRange(); 14692 return true; 14693 } 14694 } 14695 14696 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14697 // List items of map clauses in the same construct must not share 14698 // original storage. 14699 // 14700 // An expression is a subset of the other. 14701 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14702 if (CKind == OMPC_map) { 14703 if (CI != CE || SI != SE) { 14704 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14705 // a pointer. 14706 auto Begin = 14707 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14708 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14709 auto It = Begin; 14710 while (It != End && !It->getAssociatedDeclaration()) 14711 std::advance(It, 1); 14712 assert(It != End && 14713 "Expected at least one component with the declaration."); 14714 if (It != Begin && It->getAssociatedDeclaration() 14715 ->getType() 14716 .getCanonicalType() 14717 ->isAnyPointerType()) { 14718 IsEnclosedByDataEnvironmentExpr = false; 14719 EnclosingExpr = nullptr; 14720 return false; 14721 } 14722 } 14723 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14724 } else { 14725 assert(CKind == OMPC_to || CKind == OMPC_from); 14726 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14727 << ERange; 14728 } 14729 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14730 << RE->getSourceRange(); 14731 return true; 14732 } 14733 14734 // The current expression uses the same base as other expression in the 14735 // data environment but does not contain it completely. 14736 if (!CurrentRegionOnly && SI != SE) 14737 EnclosingExpr = RE; 14738 14739 // The current expression is a subset of the expression in the data 14740 // environment. 14741 IsEnclosedByDataEnvironmentExpr |= 14742 (!CurrentRegionOnly && CI != CE && SI == SE); 14743 14744 return false; 14745 }); 14746 14747 if (CurrentRegionOnly) 14748 return FoundError; 14749 14750 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14751 // If any part of the original storage of a list item has corresponding 14752 // storage in the device data environment, all of the original storage must 14753 // have corresponding storage in the device data environment. 14754 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 14755 // If a list item is an element of a structure, and a different element of 14756 // the structure has a corresponding list item in the device data environment 14757 // prior to a task encountering the construct associated with the map clause, 14758 // then the list item must also have a corresponding list item in the device 14759 // data environment prior to the task encountering the construct. 14760 // 14761 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 14762 SemaRef.Diag(ELoc, 14763 diag::err_omp_original_storage_is_shared_and_does_not_contain) 14764 << ERange; 14765 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 14766 << EnclosingExpr->getSourceRange(); 14767 return true; 14768 } 14769 14770 return FoundError; 14771 } 14772 14773 // Look up the user-defined mapper given the mapper name and mapped type, and 14774 // build a reference to it. 14775 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 14776 CXXScopeSpec &MapperIdScopeSpec, 14777 const DeclarationNameInfo &MapperId, 14778 QualType Type, 14779 Expr *UnresolvedMapper) { 14780 if (MapperIdScopeSpec.isInvalid()) 14781 return ExprError(); 14782 // Get the actual type for the array type. 14783 if (Type->isArrayType()) { 14784 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 14785 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 14786 } 14787 // Find all user-defined mappers with the given MapperId. 14788 SmallVector<UnresolvedSet<8>, 4> Lookups; 14789 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 14790 Lookup.suppressDiagnostics(); 14791 if (S) { 14792 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 14793 NamedDecl *D = Lookup.getRepresentativeDecl(); 14794 while (S && !S->isDeclScope(D)) 14795 S = S->getParent(); 14796 if (S) 14797 S = S->getParent(); 14798 Lookups.emplace_back(); 14799 Lookups.back().append(Lookup.begin(), Lookup.end()); 14800 Lookup.clear(); 14801 } 14802 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 14803 // Extract the user-defined mappers with the given MapperId. 14804 Lookups.push_back(UnresolvedSet<8>()); 14805 for (NamedDecl *D : ULE->decls()) { 14806 auto *DMD = cast<OMPDeclareMapperDecl>(D); 14807 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 14808 Lookups.back().addDecl(DMD); 14809 } 14810 } 14811 // Defer the lookup for dependent types. The results will be passed through 14812 // UnresolvedMapper on instantiation. 14813 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 14814 Type->isInstantiationDependentType() || 14815 Type->containsUnexpandedParameterPack() || 14816 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14817 return !D->isInvalidDecl() && 14818 (D->getType()->isDependentType() || 14819 D->getType()->isInstantiationDependentType() || 14820 D->getType()->containsUnexpandedParameterPack()); 14821 })) { 14822 UnresolvedSet<8> URS; 14823 for (const UnresolvedSet<8> &Set : Lookups) { 14824 if (Set.empty()) 14825 continue; 14826 URS.append(Set.begin(), Set.end()); 14827 } 14828 return UnresolvedLookupExpr::Create( 14829 SemaRef.Context, /*NamingClass=*/nullptr, 14830 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 14831 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 14832 } 14833 SourceLocation Loc = MapperId.getLoc(); 14834 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14835 // The type must be of struct, union or class type in C and C++ 14836 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 14837 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 14838 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 14839 return ExprError(); 14840 } 14841 // Perform argument dependent lookup. 14842 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 14843 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 14844 // Return the first user-defined mapper with the desired type. 14845 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14846 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 14847 if (!D->isInvalidDecl() && 14848 SemaRef.Context.hasSameType(D->getType(), Type)) 14849 return D; 14850 return nullptr; 14851 })) 14852 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14853 // Find the first user-defined mapper with a type derived from the desired 14854 // type. 14855 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14856 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 14857 if (!D->isInvalidDecl() && 14858 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 14859 !Type.isMoreQualifiedThan(D->getType())) 14860 return D; 14861 return nullptr; 14862 })) { 14863 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14864 /*DetectVirtual=*/false); 14865 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 14866 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14867 VD->getType().getUnqualifiedType()))) { 14868 if (SemaRef.CheckBaseClassAccess( 14869 Loc, VD->getType(), Type, Paths.front(), 14870 /*DiagID=*/0) != Sema::AR_inaccessible) { 14871 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14872 } 14873 } 14874 } 14875 } 14876 // Report error if a mapper is specified, but cannot be found. 14877 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 14878 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 14879 << Type << MapperId.getName(); 14880 return ExprError(); 14881 } 14882 return ExprEmpty(); 14883 } 14884 14885 namespace { 14886 // Utility struct that gathers all the related lists associated with a mappable 14887 // expression. 14888 struct MappableVarListInfo { 14889 // The list of expressions. 14890 ArrayRef<Expr *> VarList; 14891 // The list of processed expressions. 14892 SmallVector<Expr *, 16> ProcessedVarList; 14893 // The mappble components for each expression. 14894 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 14895 // The base declaration of the variable. 14896 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 14897 // The reference to the user-defined mapper associated with every expression. 14898 SmallVector<Expr *, 16> UDMapperList; 14899 14900 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 14901 // We have a list of components and base declarations for each entry in the 14902 // variable list. 14903 VarComponents.reserve(VarList.size()); 14904 VarBaseDeclarations.reserve(VarList.size()); 14905 } 14906 }; 14907 } 14908 14909 // Check the validity of the provided variable list for the provided clause kind 14910 // \a CKind. In the check process the valid expressions, mappable expression 14911 // components, variables, and user-defined mappers are extracted and used to 14912 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 14913 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 14914 // and \a MapperId are expected to be valid if the clause kind is 'map'. 14915 static void checkMappableExpressionList( 14916 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 14917 MappableVarListInfo &MVLI, SourceLocation StartLoc, 14918 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 14919 ArrayRef<Expr *> UnresolvedMappers, 14920 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 14921 bool IsMapTypeImplicit = false) { 14922 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 14923 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 14924 "Unexpected clause kind with mappable expressions!"); 14925 14926 // If the identifier of user-defined mapper is not specified, it is "default". 14927 // We do not change the actual name in this clause to distinguish whether a 14928 // mapper is specified explicitly, i.e., it is not explicitly specified when 14929 // MapperId.getName() is empty. 14930 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 14931 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14932 MapperId.setName(DeclNames.getIdentifier( 14933 &SemaRef.getASTContext().Idents.get("default"))); 14934 } 14935 14936 // Iterators to find the current unresolved mapper expression. 14937 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14938 bool UpdateUMIt = false; 14939 Expr *UnresolvedMapper = nullptr; 14940 14941 // Keep track of the mappable components and base declarations in this clause. 14942 // Each entry in the list is going to have a list of components associated. We 14943 // record each set of the components so that we can build the clause later on. 14944 // In the end we should have the same amount of declarations and component 14945 // lists. 14946 14947 for (Expr *RE : MVLI.VarList) { 14948 assert(RE && "Null expr in omp to/from/map clause"); 14949 SourceLocation ELoc = RE->getExprLoc(); 14950 14951 // Find the current unresolved mapper expression. 14952 if (UpdateUMIt && UMIt != UMEnd) { 14953 UMIt++; 14954 assert( 14955 UMIt != UMEnd && 14956 "Expect the size of UnresolvedMappers to match with that of VarList"); 14957 } 14958 UpdateUMIt = true; 14959 if (UMIt != UMEnd) 14960 UnresolvedMapper = *UMIt; 14961 14962 const Expr *VE = RE->IgnoreParenLValueCasts(); 14963 14964 if (VE->isValueDependent() || VE->isTypeDependent() || 14965 VE->isInstantiationDependent() || 14966 VE->containsUnexpandedParameterPack()) { 14967 // Try to find the associated user-defined mapper. 14968 ExprResult ER = buildUserDefinedMapperRef( 14969 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14970 VE->getType().getCanonicalType(), UnresolvedMapper); 14971 if (ER.isInvalid()) 14972 continue; 14973 MVLI.UDMapperList.push_back(ER.get()); 14974 // We can only analyze this information once the missing information is 14975 // resolved. 14976 MVLI.ProcessedVarList.push_back(RE); 14977 continue; 14978 } 14979 14980 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14981 14982 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14983 SemaRef.Diag(ELoc, 14984 diag::err_omp_expected_named_var_member_or_array_expression) 14985 << RE->getSourceRange(); 14986 continue; 14987 } 14988 14989 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14990 ValueDecl *CurDeclaration = nullptr; 14991 14992 // Obtain the array or member expression bases if required. Also, fill the 14993 // components array with all the components identified in the process. 14994 const Expr *BE = checkMapClauseExpressionBase( 14995 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14996 if (!BE) 14997 continue; 14998 14999 assert(!CurComponents.empty() && 15000 "Invalid mappable expression information."); 15001 15002 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15003 // Add store "this" pointer to class in DSAStackTy for future checking 15004 DSAS->addMappedClassesQualTypes(TE->getType()); 15005 // Try to find the associated user-defined mapper. 15006 ExprResult ER = buildUserDefinedMapperRef( 15007 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15008 VE->getType().getCanonicalType(), UnresolvedMapper); 15009 if (ER.isInvalid()) 15010 continue; 15011 MVLI.UDMapperList.push_back(ER.get()); 15012 // Skip restriction checking for variable or field declarations 15013 MVLI.ProcessedVarList.push_back(RE); 15014 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15015 MVLI.VarComponents.back().append(CurComponents.begin(), 15016 CurComponents.end()); 15017 MVLI.VarBaseDeclarations.push_back(nullptr); 15018 continue; 15019 } 15020 15021 // For the following checks, we rely on the base declaration which is 15022 // expected to be associated with the last component. The declaration is 15023 // expected to be a variable or a field (if 'this' is being mapped). 15024 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15025 assert(CurDeclaration && "Null decl on map clause."); 15026 assert( 15027 CurDeclaration->isCanonicalDecl() && 15028 "Expecting components to have associated only canonical declarations."); 15029 15030 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15031 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15032 15033 assert((VD || FD) && "Only variables or fields are expected here!"); 15034 (void)FD; 15035 15036 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15037 // threadprivate variables cannot appear in a map clause. 15038 // OpenMP 4.5 [2.10.5, target update Construct] 15039 // threadprivate variables cannot appear in a from clause. 15040 if (VD && DSAS->isThreadPrivate(VD)) { 15041 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15042 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15043 << getOpenMPClauseName(CKind); 15044 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15045 continue; 15046 } 15047 15048 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15049 // A list item cannot appear in both a map clause and a data-sharing 15050 // attribute clause on the same construct. 15051 15052 // Check conflicts with other map clause expressions. We check the conflicts 15053 // with the current construct separately from the enclosing data 15054 // environment, because the restrictions are different. We only have to 15055 // check conflicts across regions for the map clauses. 15056 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15057 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15058 break; 15059 if (CKind == OMPC_map && 15060 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15061 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15062 break; 15063 15064 // OpenMP 4.5 [2.10.5, target update Construct] 15065 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15066 // If the type of a list item is a reference to a type T then the type will 15067 // be considered to be T for all purposes of this clause. 15068 auto I = llvm::find_if( 15069 CurComponents, 15070 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15071 return MC.getAssociatedDeclaration(); 15072 }); 15073 assert(I != CurComponents.end() && "Null decl on map clause."); 15074 QualType Type = 15075 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15076 15077 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15078 // A list item in a to or from clause must have a mappable type. 15079 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15080 // A list item must have a mappable type. 15081 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15082 DSAS, Type)) 15083 continue; 15084 15085 if (CKind == OMPC_map) { 15086 // target enter data 15087 // OpenMP [2.10.2, Restrictions, p. 99] 15088 // A map-type must be specified in all map clauses and must be either 15089 // to or alloc. 15090 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15091 if (DKind == OMPD_target_enter_data && 15092 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15093 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15094 << (IsMapTypeImplicit ? 1 : 0) 15095 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15096 << getOpenMPDirectiveName(DKind); 15097 continue; 15098 } 15099 15100 // target exit_data 15101 // OpenMP [2.10.3, Restrictions, p. 102] 15102 // A map-type must be specified in all map clauses and must be either 15103 // from, release, or delete. 15104 if (DKind == OMPD_target_exit_data && 15105 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15106 MapType == OMPC_MAP_delete)) { 15107 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15108 << (IsMapTypeImplicit ? 1 : 0) 15109 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15110 << getOpenMPDirectiveName(DKind); 15111 continue; 15112 } 15113 15114 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15115 // A list item cannot appear in both a map clause and a data-sharing 15116 // attribute clause on the same construct 15117 // 15118 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15119 // A list item cannot appear in both a map clause and a data-sharing 15120 // attribute clause on the same construct unless the construct is a 15121 // combined construct. 15122 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15123 isOpenMPTargetExecutionDirective(DKind)) || 15124 DKind == OMPD_target)) { 15125 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15126 if (isOpenMPPrivate(DVar.CKind)) { 15127 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15128 << getOpenMPClauseName(DVar.CKind) 15129 << getOpenMPClauseName(OMPC_map) 15130 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15131 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15132 continue; 15133 } 15134 } 15135 } 15136 15137 // Try to find the associated user-defined mapper. 15138 ExprResult ER = buildUserDefinedMapperRef( 15139 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15140 Type.getCanonicalType(), UnresolvedMapper); 15141 if (ER.isInvalid()) 15142 continue; 15143 MVLI.UDMapperList.push_back(ER.get()); 15144 15145 // Save the current expression. 15146 MVLI.ProcessedVarList.push_back(RE); 15147 15148 // Store the components in the stack so that they can be used to check 15149 // against other clauses later on. 15150 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15151 /*WhereFoundClauseKind=*/OMPC_map); 15152 15153 // Save the components and declaration to create the clause. For purposes of 15154 // the clause creation, any component list that has has base 'this' uses 15155 // null as base declaration. 15156 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15157 MVLI.VarComponents.back().append(CurComponents.begin(), 15158 CurComponents.end()); 15159 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15160 : CurDeclaration); 15161 } 15162 } 15163 15164 OMPClause *Sema::ActOnOpenMPMapClause( 15165 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15166 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15167 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15168 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15169 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15170 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15171 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15172 OMPC_MAP_MODIFIER_unknown, 15173 OMPC_MAP_MODIFIER_unknown}; 15174 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15175 15176 // Process map-type-modifiers, flag errors for duplicate modifiers. 15177 unsigned Count = 0; 15178 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15179 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15180 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15181 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15182 continue; 15183 } 15184 assert(Count < OMPMapClause::NumberOfModifiers && 15185 "Modifiers exceed the allowed number of map type modifiers"); 15186 Modifiers[Count] = MapTypeModifiers[I]; 15187 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15188 ++Count; 15189 } 15190 15191 MappableVarListInfo MVLI(VarList); 15192 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15193 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15194 MapType, IsMapTypeImplicit); 15195 15196 // We need to produce a map clause even if we don't have variables so that 15197 // other diagnostics related with non-existing map clauses are accurate. 15198 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15199 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15200 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15201 MapperIdScopeSpec.getWithLocInContext(Context), 15202 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15203 } 15204 15205 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15206 TypeResult ParsedType) { 15207 assert(ParsedType.isUsable()); 15208 15209 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15210 if (ReductionType.isNull()) 15211 return QualType(); 15212 15213 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15214 // A type name in a declare reduction directive cannot be a function type, an 15215 // array type, a reference type, or a type qualified with const, volatile or 15216 // restrict. 15217 if (ReductionType.hasQualifiers()) { 15218 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15219 return QualType(); 15220 } 15221 15222 if (ReductionType->isFunctionType()) { 15223 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15224 return QualType(); 15225 } 15226 if (ReductionType->isReferenceType()) { 15227 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15228 return QualType(); 15229 } 15230 if (ReductionType->isArrayType()) { 15231 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15232 return QualType(); 15233 } 15234 return ReductionType; 15235 } 15236 15237 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15238 Scope *S, DeclContext *DC, DeclarationName Name, 15239 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15240 AccessSpecifier AS, Decl *PrevDeclInScope) { 15241 SmallVector<Decl *, 8> Decls; 15242 Decls.reserve(ReductionTypes.size()); 15243 15244 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15245 forRedeclarationInCurContext()); 15246 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15247 // A reduction-identifier may not be re-declared in the current scope for the 15248 // same type or for a type that is compatible according to the base language 15249 // rules. 15250 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15251 OMPDeclareReductionDecl *PrevDRD = nullptr; 15252 bool InCompoundScope = true; 15253 if (S != nullptr) { 15254 // Find previous declaration with the same name not referenced in other 15255 // declarations. 15256 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15257 InCompoundScope = 15258 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15259 LookupName(Lookup, S); 15260 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15261 /*AllowInlineNamespace=*/false); 15262 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15263 LookupResult::Filter Filter = Lookup.makeFilter(); 15264 while (Filter.hasNext()) { 15265 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15266 if (InCompoundScope) { 15267 auto I = UsedAsPrevious.find(PrevDecl); 15268 if (I == UsedAsPrevious.end()) 15269 UsedAsPrevious[PrevDecl] = false; 15270 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15271 UsedAsPrevious[D] = true; 15272 } 15273 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15274 PrevDecl->getLocation(); 15275 } 15276 Filter.done(); 15277 if (InCompoundScope) { 15278 for (const auto &PrevData : UsedAsPrevious) { 15279 if (!PrevData.second) { 15280 PrevDRD = PrevData.first; 15281 break; 15282 } 15283 } 15284 } 15285 } else if (PrevDeclInScope != nullptr) { 15286 auto *PrevDRDInScope = PrevDRD = 15287 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15288 do { 15289 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15290 PrevDRDInScope->getLocation(); 15291 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15292 } while (PrevDRDInScope != nullptr); 15293 } 15294 for (const auto &TyData : ReductionTypes) { 15295 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15296 bool Invalid = false; 15297 if (I != PreviousRedeclTypes.end()) { 15298 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15299 << TyData.first; 15300 Diag(I->second, diag::note_previous_definition); 15301 Invalid = true; 15302 } 15303 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15304 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15305 Name, TyData.first, PrevDRD); 15306 DC->addDecl(DRD); 15307 DRD->setAccess(AS); 15308 Decls.push_back(DRD); 15309 if (Invalid) 15310 DRD->setInvalidDecl(); 15311 else 15312 PrevDRD = DRD; 15313 } 15314 15315 return DeclGroupPtrTy::make( 15316 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15317 } 15318 15319 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15320 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15321 15322 // Enter new function scope. 15323 PushFunctionScope(); 15324 setFunctionHasBranchProtectedScope(); 15325 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15326 15327 if (S != nullptr) 15328 PushDeclContext(S, DRD); 15329 else 15330 CurContext = DRD; 15331 15332 PushExpressionEvaluationContext( 15333 ExpressionEvaluationContext::PotentiallyEvaluated); 15334 15335 QualType ReductionType = DRD->getType(); 15336 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15337 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15338 // uses semantics of argument handles by value, but it should be passed by 15339 // reference. C lang does not support references, so pass all parameters as 15340 // pointers. 15341 // Create 'T omp_in;' variable. 15342 VarDecl *OmpInParm = 15343 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15344 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15345 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15346 // uses semantics of argument handles by value, but it should be passed by 15347 // reference. C lang does not support references, so pass all parameters as 15348 // pointers. 15349 // Create 'T omp_out;' variable. 15350 VarDecl *OmpOutParm = 15351 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15352 if (S != nullptr) { 15353 PushOnScopeChains(OmpInParm, S); 15354 PushOnScopeChains(OmpOutParm, S); 15355 } else { 15356 DRD->addDecl(OmpInParm); 15357 DRD->addDecl(OmpOutParm); 15358 } 15359 Expr *InE = 15360 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15361 Expr *OutE = 15362 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15363 DRD->setCombinerData(InE, OutE); 15364 } 15365 15366 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15367 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15368 DiscardCleanupsInEvaluationContext(); 15369 PopExpressionEvaluationContext(); 15370 15371 PopDeclContext(); 15372 PopFunctionScopeInfo(); 15373 15374 if (Combiner != nullptr) 15375 DRD->setCombiner(Combiner); 15376 else 15377 DRD->setInvalidDecl(); 15378 } 15379 15380 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15381 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15382 15383 // Enter new function scope. 15384 PushFunctionScope(); 15385 setFunctionHasBranchProtectedScope(); 15386 15387 if (S != nullptr) 15388 PushDeclContext(S, DRD); 15389 else 15390 CurContext = DRD; 15391 15392 PushExpressionEvaluationContext( 15393 ExpressionEvaluationContext::PotentiallyEvaluated); 15394 15395 QualType ReductionType = DRD->getType(); 15396 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15397 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15398 // uses semantics of argument handles by value, but it should be passed by 15399 // reference. C lang does not support references, so pass all parameters as 15400 // pointers. 15401 // Create 'T omp_priv;' variable. 15402 VarDecl *OmpPrivParm = 15403 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15404 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15405 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15406 // uses semantics of argument handles by value, but it should be passed by 15407 // reference. C lang does not support references, so pass all parameters as 15408 // pointers. 15409 // Create 'T omp_orig;' variable. 15410 VarDecl *OmpOrigParm = 15411 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15412 if (S != nullptr) { 15413 PushOnScopeChains(OmpPrivParm, S); 15414 PushOnScopeChains(OmpOrigParm, S); 15415 } else { 15416 DRD->addDecl(OmpPrivParm); 15417 DRD->addDecl(OmpOrigParm); 15418 } 15419 Expr *OrigE = 15420 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15421 Expr *PrivE = 15422 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15423 DRD->setInitializerData(OrigE, PrivE); 15424 return OmpPrivParm; 15425 } 15426 15427 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15428 VarDecl *OmpPrivParm) { 15429 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15430 DiscardCleanupsInEvaluationContext(); 15431 PopExpressionEvaluationContext(); 15432 15433 PopDeclContext(); 15434 PopFunctionScopeInfo(); 15435 15436 if (Initializer != nullptr) { 15437 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15438 } else if (OmpPrivParm->hasInit()) { 15439 DRD->setInitializer(OmpPrivParm->getInit(), 15440 OmpPrivParm->isDirectInit() 15441 ? OMPDeclareReductionDecl::DirectInit 15442 : OMPDeclareReductionDecl::CopyInit); 15443 } else { 15444 DRD->setInvalidDecl(); 15445 } 15446 } 15447 15448 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15449 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15450 for (Decl *D : DeclReductions.get()) { 15451 if (IsValid) { 15452 if (S) 15453 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15454 /*AddToContext=*/false); 15455 } else { 15456 D->setInvalidDecl(); 15457 } 15458 } 15459 return DeclReductions; 15460 } 15461 15462 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15463 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15464 QualType T = TInfo->getType(); 15465 if (D.isInvalidType()) 15466 return true; 15467 15468 if (getLangOpts().CPlusPlus) { 15469 // Check that there are no default arguments (C++ only). 15470 CheckExtraCXXDefaultArguments(D); 15471 } 15472 15473 return CreateParsedType(T, TInfo); 15474 } 15475 15476 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15477 TypeResult ParsedType) { 15478 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15479 15480 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15481 assert(!MapperType.isNull() && "Expect valid mapper type"); 15482 15483 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15484 // The type must be of struct, union or class type in C and C++ 15485 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15486 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15487 return QualType(); 15488 } 15489 return MapperType; 15490 } 15491 15492 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15493 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15494 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15495 Decl *PrevDeclInScope) { 15496 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15497 forRedeclarationInCurContext()); 15498 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15499 // A mapper-identifier may not be redeclared in the current scope for the 15500 // same type or for a type that is compatible according to the base language 15501 // rules. 15502 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15503 OMPDeclareMapperDecl *PrevDMD = nullptr; 15504 bool InCompoundScope = true; 15505 if (S != nullptr) { 15506 // Find previous declaration with the same name not referenced in other 15507 // declarations. 15508 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15509 InCompoundScope = 15510 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15511 LookupName(Lookup, S); 15512 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15513 /*AllowInlineNamespace=*/false); 15514 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15515 LookupResult::Filter Filter = Lookup.makeFilter(); 15516 while (Filter.hasNext()) { 15517 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15518 if (InCompoundScope) { 15519 auto I = UsedAsPrevious.find(PrevDecl); 15520 if (I == UsedAsPrevious.end()) 15521 UsedAsPrevious[PrevDecl] = false; 15522 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15523 UsedAsPrevious[D] = true; 15524 } 15525 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15526 PrevDecl->getLocation(); 15527 } 15528 Filter.done(); 15529 if (InCompoundScope) { 15530 for (const auto &PrevData : UsedAsPrevious) { 15531 if (!PrevData.second) { 15532 PrevDMD = PrevData.first; 15533 break; 15534 } 15535 } 15536 } 15537 } else if (PrevDeclInScope) { 15538 auto *PrevDMDInScope = PrevDMD = 15539 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15540 do { 15541 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15542 PrevDMDInScope->getLocation(); 15543 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15544 } while (PrevDMDInScope != nullptr); 15545 } 15546 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15547 bool Invalid = false; 15548 if (I != PreviousRedeclTypes.end()) { 15549 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15550 << MapperType << Name; 15551 Diag(I->second, diag::note_previous_definition); 15552 Invalid = true; 15553 } 15554 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15555 MapperType, VN, PrevDMD); 15556 DC->addDecl(DMD); 15557 DMD->setAccess(AS); 15558 if (Invalid) 15559 DMD->setInvalidDecl(); 15560 15561 // Enter new function scope. 15562 PushFunctionScope(); 15563 setFunctionHasBranchProtectedScope(); 15564 15565 CurContext = DMD; 15566 15567 return DMD; 15568 } 15569 15570 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15571 Scope *S, 15572 QualType MapperType, 15573 SourceLocation StartLoc, 15574 DeclarationName VN) { 15575 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15576 if (S) 15577 PushOnScopeChains(VD, S); 15578 else 15579 DMD->addDecl(VD); 15580 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15581 DMD->setMapperVarRef(MapperVarRefExpr); 15582 } 15583 15584 Sema::DeclGroupPtrTy 15585 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15586 ArrayRef<OMPClause *> ClauseList) { 15587 PopDeclContext(); 15588 PopFunctionScopeInfo(); 15589 15590 if (D) { 15591 if (S) 15592 PushOnScopeChains(D, S, /*AddToContext=*/false); 15593 D->CreateClauses(Context, ClauseList); 15594 } 15595 15596 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15597 } 15598 15599 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15600 SourceLocation StartLoc, 15601 SourceLocation LParenLoc, 15602 SourceLocation EndLoc) { 15603 Expr *ValExpr = NumTeams; 15604 Stmt *HelperValStmt = nullptr; 15605 15606 // OpenMP [teams Constrcut, Restrictions] 15607 // The num_teams expression must evaluate to a positive integer value. 15608 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15609 /*StrictlyPositive=*/true)) 15610 return nullptr; 15611 15612 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15613 OpenMPDirectiveKind CaptureRegion = 15614 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15615 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15616 ValExpr = MakeFullExpr(ValExpr).get(); 15617 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15618 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15619 HelperValStmt = buildPreInits(Context, Captures); 15620 } 15621 15622 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15623 StartLoc, LParenLoc, EndLoc); 15624 } 15625 15626 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15627 SourceLocation StartLoc, 15628 SourceLocation LParenLoc, 15629 SourceLocation EndLoc) { 15630 Expr *ValExpr = ThreadLimit; 15631 Stmt *HelperValStmt = nullptr; 15632 15633 // OpenMP [teams Constrcut, Restrictions] 15634 // The thread_limit expression must evaluate to a positive integer value. 15635 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15636 /*StrictlyPositive=*/true)) 15637 return nullptr; 15638 15639 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15640 OpenMPDirectiveKind CaptureRegion = 15641 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15642 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15643 ValExpr = MakeFullExpr(ValExpr).get(); 15644 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15645 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15646 HelperValStmt = buildPreInits(Context, Captures); 15647 } 15648 15649 return new (Context) OMPThreadLimitClause( 15650 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15651 } 15652 15653 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15654 SourceLocation StartLoc, 15655 SourceLocation LParenLoc, 15656 SourceLocation EndLoc) { 15657 Expr *ValExpr = Priority; 15658 15659 // OpenMP [2.9.1, task Constrcut] 15660 // The priority-value is a non-negative numerical scalar expression. 15661 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 15662 /*StrictlyPositive=*/false)) 15663 return nullptr; 15664 15665 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15666 } 15667 15668 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15669 SourceLocation StartLoc, 15670 SourceLocation LParenLoc, 15671 SourceLocation EndLoc) { 15672 Expr *ValExpr = Grainsize; 15673 15674 // OpenMP [2.9.2, taskloop Constrcut] 15675 // The parameter of the grainsize clause must be a positive integer 15676 // expression. 15677 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 15678 /*StrictlyPositive=*/true)) 15679 return nullptr; 15680 15681 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15682 } 15683 15684 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15685 SourceLocation StartLoc, 15686 SourceLocation LParenLoc, 15687 SourceLocation EndLoc) { 15688 Expr *ValExpr = NumTasks; 15689 15690 // OpenMP [2.9.2, taskloop Constrcut] 15691 // The parameter of the num_tasks clause must be a positive integer 15692 // expression. 15693 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 15694 /*StrictlyPositive=*/true)) 15695 return nullptr; 15696 15697 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15698 } 15699 15700 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15701 SourceLocation LParenLoc, 15702 SourceLocation EndLoc) { 15703 // OpenMP [2.13.2, critical construct, Description] 15704 // ... where hint-expression is an integer constant expression that evaluates 15705 // to a valid lock hint. 15706 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15707 if (HintExpr.isInvalid()) 15708 return nullptr; 15709 return new (Context) 15710 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 15711 } 15712 15713 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 15714 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 15715 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 15716 SourceLocation EndLoc) { 15717 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 15718 std::string Values; 15719 Values += "'"; 15720 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 15721 Values += "'"; 15722 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 15723 << Values << getOpenMPClauseName(OMPC_dist_schedule); 15724 return nullptr; 15725 } 15726 Expr *ValExpr = ChunkSize; 15727 Stmt *HelperValStmt = nullptr; 15728 if (ChunkSize) { 15729 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 15730 !ChunkSize->isInstantiationDependent() && 15731 !ChunkSize->containsUnexpandedParameterPack()) { 15732 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 15733 ExprResult Val = 15734 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 15735 if (Val.isInvalid()) 15736 return nullptr; 15737 15738 ValExpr = Val.get(); 15739 15740 // OpenMP [2.7.1, Restrictions] 15741 // chunk_size must be a loop invariant integer expression with a positive 15742 // value. 15743 llvm::APSInt Result; 15744 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 15745 if (Result.isSigned() && !Result.isStrictlyPositive()) { 15746 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 15747 << "dist_schedule" << ChunkSize->getSourceRange(); 15748 return nullptr; 15749 } 15750 } else if (getOpenMPCaptureRegionForClause( 15751 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 15752 OMPD_unknown && 15753 !CurContext->isDependentContext()) { 15754 ValExpr = MakeFullExpr(ValExpr).get(); 15755 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15756 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15757 HelperValStmt = buildPreInits(Context, Captures); 15758 } 15759 } 15760 } 15761 15762 return new (Context) 15763 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 15764 Kind, ValExpr, HelperValStmt); 15765 } 15766 15767 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 15768 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 15769 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 15770 SourceLocation KindLoc, SourceLocation EndLoc) { 15771 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 15772 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 15773 std::string Value; 15774 SourceLocation Loc; 15775 Value += "'"; 15776 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 15777 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15778 OMPC_DEFAULTMAP_MODIFIER_tofrom); 15779 Loc = MLoc; 15780 } else { 15781 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15782 OMPC_DEFAULTMAP_scalar); 15783 Loc = KindLoc; 15784 } 15785 Value += "'"; 15786 Diag(Loc, diag::err_omp_unexpected_clause_value) 15787 << Value << getOpenMPClauseName(OMPC_defaultmap); 15788 return nullptr; 15789 } 15790 DSAStack->setDefaultDMAToFromScalar(StartLoc); 15791 15792 return new (Context) 15793 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 15794 } 15795 15796 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 15797 DeclContext *CurLexicalContext = getCurLexicalContext(); 15798 if (!CurLexicalContext->isFileContext() && 15799 !CurLexicalContext->isExternCContext() && 15800 !CurLexicalContext->isExternCXXContext() && 15801 !isa<CXXRecordDecl>(CurLexicalContext) && 15802 !isa<ClassTemplateDecl>(CurLexicalContext) && 15803 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 15804 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 15805 Diag(Loc, diag::err_omp_region_not_file_context); 15806 return false; 15807 } 15808 ++DeclareTargetNestingLevel; 15809 return true; 15810 } 15811 15812 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 15813 assert(DeclareTargetNestingLevel > 0 && 15814 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 15815 --DeclareTargetNestingLevel; 15816 } 15817 15818 NamedDecl * 15819 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 15820 const DeclarationNameInfo &Id, 15821 NamedDeclSetType &SameDirectiveDecls) { 15822 LookupResult Lookup(*this, Id, LookupOrdinaryName); 15823 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 15824 15825 if (Lookup.isAmbiguous()) 15826 return nullptr; 15827 Lookup.suppressDiagnostics(); 15828 15829 if (!Lookup.isSingleResult()) { 15830 VarOrFuncDeclFilterCCC CCC(*this); 15831 if (TypoCorrection Corrected = 15832 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 15833 CTK_ErrorRecovery)) { 15834 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 15835 << Id.getName()); 15836 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 15837 return nullptr; 15838 } 15839 15840 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 15841 return nullptr; 15842 } 15843 15844 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 15845 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 15846 !isa<FunctionTemplateDecl>(ND)) { 15847 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 15848 return nullptr; 15849 } 15850 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 15851 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 15852 return ND; 15853 } 15854 15855 void Sema::ActOnOpenMPDeclareTargetName( 15856 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 15857 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 15858 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 15859 isa<FunctionTemplateDecl>(ND)) && 15860 "Expected variable, function or function template."); 15861 15862 // Diagnose marking after use as it may lead to incorrect diagnosis and 15863 // codegen. 15864 if (LangOpts.OpenMP >= 50 && 15865 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 15866 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 15867 15868 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15869 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 15870 if (DevTy.hasValue() && *DevTy != DT) { 15871 Diag(Loc, diag::err_omp_device_type_mismatch) 15872 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 15873 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 15874 return; 15875 } 15876 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15877 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 15878 if (!Res) { 15879 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 15880 SourceRange(Loc, Loc)); 15881 ND->addAttr(A); 15882 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15883 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 15884 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 15885 } else if (*Res != MT) { 15886 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 15887 } 15888 } 15889 15890 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 15891 Sema &SemaRef, Decl *D) { 15892 if (!D || !isa<VarDecl>(D)) 15893 return; 15894 auto *VD = cast<VarDecl>(D); 15895 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15896 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15897 if (SemaRef.LangOpts.OpenMP >= 50 && 15898 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 15899 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 15900 VD->hasGlobalStorage()) { 15901 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15902 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15903 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 15904 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 15905 // If a lambda declaration and definition appears between a 15906 // declare target directive and the matching end declare target 15907 // directive, all variables that are captured by the lambda 15908 // expression must also appear in a to clause. 15909 SemaRef.Diag(VD->getLocation(), 15910 diag::err_omp_lambda_capture_in_declare_target_not_to); 15911 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 15912 << VD << 0 << SR; 15913 return; 15914 } 15915 } 15916 if (MapTy.hasValue()) 15917 return; 15918 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 15919 SemaRef.Diag(SL, diag::note_used_here) << SR; 15920 } 15921 15922 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 15923 Sema &SemaRef, DSAStackTy *Stack, 15924 ValueDecl *VD) { 15925 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 15926 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 15927 /*FullCheck=*/false); 15928 } 15929 15930 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 15931 SourceLocation IdLoc) { 15932 if (!D || D->isInvalidDecl()) 15933 return; 15934 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 15935 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 15936 if (auto *VD = dyn_cast<VarDecl>(D)) { 15937 // Only global variables can be marked as declare target. 15938 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 15939 !VD->isStaticDataMember()) 15940 return; 15941 // 2.10.6: threadprivate variable cannot appear in a declare target 15942 // directive. 15943 if (DSAStack->isThreadPrivate(VD)) { 15944 Diag(SL, diag::err_omp_threadprivate_in_target); 15945 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 15946 return; 15947 } 15948 } 15949 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 15950 D = FTD->getTemplatedDecl(); 15951 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 15952 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15953 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 15954 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 15955 Diag(IdLoc, diag::err_omp_function_in_link_clause); 15956 Diag(FD->getLocation(), diag::note_defined_here) << FD; 15957 return; 15958 } 15959 // Mark the function as must be emitted for the device. 15960 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15961 OMPDeclareTargetDeclAttr::getDeviceType(FD); 15962 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 15963 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 15964 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 15965 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 15966 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 15967 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 15968 } 15969 if (auto *VD = dyn_cast<ValueDecl>(D)) { 15970 // Problem if any with var declared with incomplete type will be reported 15971 // as normal, so no need to check it here. 15972 if ((E || !VD->getType()->isIncompleteType()) && 15973 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 15974 return; 15975 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 15976 // Checking declaration inside declare target region. 15977 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 15978 isa<FunctionTemplateDecl>(D)) { 15979 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 15980 Context, OMPDeclareTargetDeclAttr::MT_To, 15981 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 15982 D->addAttr(A); 15983 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15984 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 15985 } 15986 return; 15987 } 15988 } 15989 if (!E) 15990 return; 15991 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 15992 } 15993 15994 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15995 CXXScopeSpec &MapperIdScopeSpec, 15996 DeclarationNameInfo &MapperId, 15997 const OMPVarListLocTy &Locs, 15998 ArrayRef<Expr *> UnresolvedMappers) { 15999 MappableVarListInfo MVLI(VarList); 16000 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16001 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16002 if (MVLI.ProcessedVarList.empty()) 16003 return nullptr; 16004 16005 return OMPToClause::Create( 16006 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16007 MVLI.VarComponents, MVLI.UDMapperList, 16008 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16009 } 16010 16011 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16012 CXXScopeSpec &MapperIdScopeSpec, 16013 DeclarationNameInfo &MapperId, 16014 const OMPVarListLocTy &Locs, 16015 ArrayRef<Expr *> UnresolvedMappers) { 16016 MappableVarListInfo MVLI(VarList); 16017 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16018 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16019 if (MVLI.ProcessedVarList.empty()) 16020 return nullptr; 16021 16022 return OMPFromClause::Create( 16023 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16024 MVLI.VarComponents, MVLI.UDMapperList, 16025 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16026 } 16027 16028 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16029 const OMPVarListLocTy &Locs) { 16030 MappableVarListInfo MVLI(VarList); 16031 SmallVector<Expr *, 8> PrivateCopies; 16032 SmallVector<Expr *, 8> Inits; 16033 16034 for (Expr *RefExpr : VarList) { 16035 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16036 SourceLocation ELoc; 16037 SourceRange ERange; 16038 Expr *SimpleRefExpr = RefExpr; 16039 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16040 if (Res.second) { 16041 // It will be analyzed later. 16042 MVLI.ProcessedVarList.push_back(RefExpr); 16043 PrivateCopies.push_back(nullptr); 16044 Inits.push_back(nullptr); 16045 } 16046 ValueDecl *D = Res.first; 16047 if (!D) 16048 continue; 16049 16050 QualType Type = D->getType(); 16051 Type = Type.getNonReferenceType().getUnqualifiedType(); 16052 16053 auto *VD = dyn_cast<VarDecl>(D); 16054 16055 // Item should be a pointer or reference to pointer. 16056 if (!Type->isPointerType()) { 16057 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16058 << 0 << RefExpr->getSourceRange(); 16059 continue; 16060 } 16061 16062 // Build the private variable and the expression that refers to it. 16063 auto VDPrivate = 16064 buildVarDecl(*this, ELoc, Type, D->getName(), 16065 D->hasAttrs() ? &D->getAttrs() : nullptr, 16066 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16067 if (VDPrivate->isInvalidDecl()) 16068 continue; 16069 16070 CurContext->addDecl(VDPrivate); 16071 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16072 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16073 16074 // Add temporary variable to initialize the private copy of the pointer. 16075 VarDecl *VDInit = 16076 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16077 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16078 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16079 AddInitializerToDecl(VDPrivate, 16080 DefaultLvalueConversion(VDInitRefExpr).get(), 16081 /*DirectInit=*/false); 16082 16083 // If required, build a capture to implement the privatization initialized 16084 // with the current list item value. 16085 DeclRefExpr *Ref = nullptr; 16086 if (!VD) 16087 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16088 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16089 PrivateCopies.push_back(VDPrivateRefExpr); 16090 Inits.push_back(VDInitRefExpr); 16091 16092 // We need to add a data sharing attribute for this variable to make sure it 16093 // is correctly captured. A variable that shows up in a use_device_ptr has 16094 // similar properties of a first private variable. 16095 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16096 16097 // Create a mappable component for the list item. List items in this clause 16098 // only need a component. 16099 MVLI.VarBaseDeclarations.push_back(D); 16100 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16101 MVLI.VarComponents.back().push_back( 16102 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16103 } 16104 16105 if (MVLI.ProcessedVarList.empty()) 16106 return nullptr; 16107 16108 return OMPUseDevicePtrClause::Create( 16109 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16110 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16111 } 16112 16113 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16114 const OMPVarListLocTy &Locs) { 16115 MappableVarListInfo MVLI(VarList); 16116 for (Expr *RefExpr : VarList) { 16117 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16118 SourceLocation ELoc; 16119 SourceRange ERange; 16120 Expr *SimpleRefExpr = RefExpr; 16121 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16122 if (Res.second) { 16123 // It will be analyzed later. 16124 MVLI.ProcessedVarList.push_back(RefExpr); 16125 } 16126 ValueDecl *D = Res.first; 16127 if (!D) 16128 continue; 16129 16130 QualType Type = D->getType(); 16131 // item should be a pointer or array or reference to pointer or array 16132 if (!Type.getNonReferenceType()->isPointerType() && 16133 !Type.getNonReferenceType()->isArrayType()) { 16134 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16135 << 0 << RefExpr->getSourceRange(); 16136 continue; 16137 } 16138 16139 // Check if the declaration in the clause does not show up in any data 16140 // sharing attribute. 16141 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16142 if (isOpenMPPrivate(DVar.CKind)) { 16143 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16144 << getOpenMPClauseName(DVar.CKind) 16145 << getOpenMPClauseName(OMPC_is_device_ptr) 16146 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16147 reportOriginalDsa(*this, DSAStack, D, DVar); 16148 continue; 16149 } 16150 16151 const Expr *ConflictExpr; 16152 if (DSAStack->checkMappableExprComponentListsForDecl( 16153 D, /*CurrentRegionOnly=*/true, 16154 [&ConflictExpr]( 16155 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16156 OpenMPClauseKind) -> bool { 16157 ConflictExpr = R.front().getAssociatedExpression(); 16158 return true; 16159 })) { 16160 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16161 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16162 << ConflictExpr->getSourceRange(); 16163 continue; 16164 } 16165 16166 // Store the components in the stack so that they can be used to check 16167 // against other clauses later on. 16168 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16169 DSAStack->addMappableExpressionComponents( 16170 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16171 16172 // Record the expression we've just processed. 16173 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16174 16175 // Create a mappable component for the list item. List items in this clause 16176 // only need a component. We use a null declaration to signal fields in 16177 // 'this'. 16178 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16179 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16180 "Unexpected device pointer expression!"); 16181 MVLI.VarBaseDeclarations.push_back( 16182 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16183 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16184 MVLI.VarComponents.back().push_back(MC); 16185 } 16186 16187 if (MVLI.ProcessedVarList.empty()) 16188 return nullptr; 16189 16190 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16191 MVLI.VarBaseDeclarations, 16192 MVLI.VarComponents); 16193 } 16194 16195 OMPClause *Sema::ActOnOpenMPAllocateClause( 16196 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16197 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16198 if (Allocator) { 16199 // OpenMP [2.11.4 allocate Clause, Description] 16200 // allocator is an expression of omp_allocator_handle_t type. 16201 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16202 return nullptr; 16203 16204 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16205 if (AllocatorRes.isInvalid()) 16206 return nullptr; 16207 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16208 DSAStack->getOMPAllocatorHandleT(), 16209 Sema::AA_Initializing, 16210 /*AllowExplicit=*/true); 16211 if (AllocatorRes.isInvalid()) 16212 return nullptr; 16213 Allocator = AllocatorRes.get(); 16214 } else { 16215 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16216 // allocate clauses that appear on a target construct or on constructs in a 16217 // target region must specify an allocator expression unless a requires 16218 // directive with the dynamic_allocators clause is present in the same 16219 // compilation unit. 16220 if (LangOpts.OpenMPIsDevice && 16221 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16222 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16223 } 16224 // Analyze and build list of variables. 16225 SmallVector<Expr *, 8> Vars; 16226 for (Expr *RefExpr : VarList) { 16227 assert(RefExpr && "NULL expr in OpenMP private clause."); 16228 SourceLocation ELoc; 16229 SourceRange ERange; 16230 Expr *SimpleRefExpr = RefExpr; 16231 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16232 if (Res.second) { 16233 // It will be analyzed later. 16234 Vars.push_back(RefExpr); 16235 } 16236 ValueDecl *D = Res.first; 16237 if (!D) 16238 continue; 16239 16240 auto *VD = dyn_cast<VarDecl>(D); 16241 DeclRefExpr *Ref = nullptr; 16242 if (!VD && !CurContext->isDependentContext()) 16243 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16244 Vars.push_back((VD || CurContext->isDependentContext()) 16245 ? RefExpr->IgnoreParens() 16246 : Ref); 16247 } 16248 16249 if (Vars.empty()) 16250 return nullptr; 16251 16252 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16253 ColonLoc, EndLoc, Vars); 16254 } 16255