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 vaiables 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 llvm_unreachable("Unexpected clause"); 4603 } 4604 for (Stmt *CC : C->children()) { 4605 if (CC) 4606 DSAChecker.Visit(CC); 4607 } 4608 } 4609 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4610 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4611 } 4612 for (const auto &P : VarsWithInheritedDSA) { 4613 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4614 continue; 4615 ErrorFound = true; 4616 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4617 << P.first << P.second->getSourceRange(); 4618 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4619 } 4620 4621 if (!AllowedNameModifiers.empty()) 4622 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4623 ErrorFound; 4624 4625 if (ErrorFound) 4626 return StmtError(); 4627 4628 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4629 Res.getAs<OMPExecutableDirective>() 4630 ->getStructuredBlock() 4631 ->setIsOMPStructuredBlock(true); 4632 } 4633 4634 if (!CurContext->isDependentContext() && 4635 isOpenMPTargetExecutionDirective(Kind) && 4636 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4637 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4638 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4639 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4640 // Register target to DSA Stack. 4641 DSAStack->addTargetDirLocation(StartLoc); 4642 } 4643 4644 return Res; 4645 } 4646 4647 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4648 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4649 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4650 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4651 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4652 assert(Aligneds.size() == Alignments.size()); 4653 assert(Linears.size() == LinModifiers.size()); 4654 assert(Linears.size() == Steps.size()); 4655 if (!DG || DG.get().isNull()) 4656 return DeclGroupPtrTy(); 4657 4658 const int SimdId = 0; 4659 if (!DG.get().isSingleDecl()) { 4660 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4661 << SimdId; 4662 return DG; 4663 } 4664 Decl *ADecl = DG.get().getSingleDecl(); 4665 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4666 ADecl = FTD->getTemplatedDecl(); 4667 4668 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4669 if (!FD) { 4670 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4671 return DeclGroupPtrTy(); 4672 } 4673 4674 // OpenMP [2.8.2, declare simd construct, Description] 4675 // The parameter of the simdlen clause must be a constant positive integer 4676 // expression. 4677 ExprResult SL; 4678 if (Simdlen) 4679 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4680 // OpenMP [2.8.2, declare simd construct, Description] 4681 // The special this pointer can be used as if was one of the arguments to the 4682 // function in any of the linear, aligned, or uniform clauses. 4683 // The uniform clause declares one or more arguments to have an invariant 4684 // value for all concurrent invocations of the function in the execution of a 4685 // single SIMD loop. 4686 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4687 const Expr *UniformedLinearThis = nullptr; 4688 for (const Expr *E : Uniforms) { 4689 E = E->IgnoreParenImpCasts(); 4690 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4691 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4692 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4693 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4694 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4695 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4696 continue; 4697 } 4698 if (isa<CXXThisExpr>(E)) { 4699 UniformedLinearThis = E; 4700 continue; 4701 } 4702 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4703 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4704 } 4705 // OpenMP [2.8.2, declare simd construct, Description] 4706 // The aligned clause declares that the object to which each list item points 4707 // is aligned to the number of bytes expressed in the optional parameter of 4708 // the aligned clause. 4709 // The special this pointer can be used as if was one of the arguments to the 4710 // function in any of the linear, aligned, or uniform clauses. 4711 // The type of list items appearing in the aligned clause must be array, 4712 // pointer, reference to array, or reference to pointer. 4713 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4714 const Expr *AlignedThis = nullptr; 4715 for (const Expr *E : Aligneds) { 4716 E = E->IgnoreParenImpCasts(); 4717 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4718 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4719 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4720 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4721 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4722 ->getCanonicalDecl() == CanonPVD) { 4723 // OpenMP [2.8.1, simd construct, Restrictions] 4724 // A list-item cannot appear in more than one aligned clause. 4725 if (AlignedArgs.count(CanonPVD) > 0) { 4726 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4727 << 1 << E->getSourceRange(); 4728 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4729 diag::note_omp_explicit_dsa) 4730 << getOpenMPClauseName(OMPC_aligned); 4731 continue; 4732 } 4733 AlignedArgs[CanonPVD] = E; 4734 QualType QTy = PVD->getType() 4735 .getNonReferenceType() 4736 .getUnqualifiedType() 4737 .getCanonicalType(); 4738 const Type *Ty = QTy.getTypePtrOrNull(); 4739 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4740 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4741 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4742 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4743 } 4744 continue; 4745 } 4746 } 4747 if (isa<CXXThisExpr>(E)) { 4748 if (AlignedThis) { 4749 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4750 << 2 << E->getSourceRange(); 4751 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4752 << getOpenMPClauseName(OMPC_aligned); 4753 } 4754 AlignedThis = E; 4755 continue; 4756 } 4757 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4758 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4759 } 4760 // The optional parameter of the aligned clause, alignment, must be a constant 4761 // positive integer expression. If no optional parameter is specified, 4762 // implementation-defined default alignments for SIMD instructions on the 4763 // target platforms are assumed. 4764 SmallVector<const Expr *, 4> NewAligns; 4765 for (Expr *E : Alignments) { 4766 ExprResult Align; 4767 if (E) 4768 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4769 NewAligns.push_back(Align.get()); 4770 } 4771 // OpenMP [2.8.2, declare simd construct, Description] 4772 // The linear clause declares one or more list items to be private to a SIMD 4773 // lane and to have a linear relationship with respect to the iteration space 4774 // of a loop. 4775 // The special this pointer can be used as if was one of the arguments to the 4776 // function in any of the linear, aligned, or uniform clauses. 4777 // When a linear-step expression is specified in a linear clause it must be 4778 // either a constant integer expression or an integer-typed parameter that is 4779 // specified in a uniform clause on the directive. 4780 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4781 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4782 auto MI = LinModifiers.begin(); 4783 for (const Expr *E : Linears) { 4784 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4785 ++MI; 4786 E = E->IgnoreParenImpCasts(); 4787 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4788 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4789 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4790 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4791 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4792 ->getCanonicalDecl() == CanonPVD) { 4793 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4794 // A list-item cannot appear in more than one linear clause. 4795 if (LinearArgs.count(CanonPVD) > 0) { 4796 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4797 << getOpenMPClauseName(OMPC_linear) 4798 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4799 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4800 diag::note_omp_explicit_dsa) 4801 << getOpenMPClauseName(OMPC_linear); 4802 continue; 4803 } 4804 // Each argument can appear in at most one uniform or linear clause. 4805 if (UniformedArgs.count(CanonPVD) > 0) { 4806 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4807 << getOpenMPClauseName(OMPC_linear) 4808 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4809 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4810 diag::note_omp_explicit_dsa) 4811 << getOpenMPClauseName(OMPC_uniform); 4812 continue; 4813 } 4814 LinearArgs[CanonPVD] = E; 4815 if (E->isValueDependent() || E->isTypeDependent() || 4816 E->isInstantiationDependent() || 4817 E->containsUnexpandedParameterPack()) 4818 continue; 4819 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4820 PVD->getOriginalType()); 4821 continue; 4822 } 4823 } 4824 if (isa<CXXThisExpr>(E)) { 4825 if (UniformedLinearThis) { 4826 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4827 << getOpenMPClauseName(OMPC_linear) 4828 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4829 << E->getSourceRange(); 4830 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4831 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4832 : OMPC_linear); 4833 continue; 4834 } 4835 UniformedLinearThis = E; 4836 if (E->isValueDependent() || E->isTypeDependent() || 4837 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4838 continue; 4839 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4840 E->getType()); 4841 continue; 4842 } 4843 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4844 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4845 } 4846 Expr *Step = nullptr; 4847 Expr *NewStep = nullptr; 4848 SmallVector<Expr *, 4> NewSteps; 4849 for (Expr *E : Steps) { 4850 // Skip the same step expression, it was checked already. 4851 if (Step == E || !E) { 4852 NewSteps.push_back(E ? NewStep : nullptr); 4853 continue; 4854 } 4855 Step = E; 4856 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4857 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4858 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4859 if (UniformedArgs.count(CanonPVD) == 0) { 4860 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4861 << Step->getSourceRange(); 4862 } else if (E->isValueDependent() || E->isTypeDependent() || 4863 E->isInstantiationDependent() || 4864 E->containsUnexpandedParameterPack() || 4865 CanonPVD->getType()->hasIntegerRepresentation()) { 4866 NewSteps.push_back(Step); 4867 } else { 4868 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4869 << Step->getSourceRange(); 4870 } 4871 continue; 4872 } 4873 NewStep = Step; 4874 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4875 !Step->isInstantiationDependent() && 4876 !Step->containsUnexpandedParameterPack()) { 4877 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4878 .get(); 4879 if (NewStep) 4880 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4881 } 4882 NewSteps.push_back(NewStep); 4883 } 4884 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4885 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4886 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4887 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4888 const_cast<Expr **>(Linears.data()), Linears.size(), 4889 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4890 NewSteps.data(), NewSteps.size(), SR); 4891 ADecl->addAttr(NewAttr); 4892 return DG; 4893 } 4894 4895 Sema::DeclGroupPtrTy 4896 Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG, 4897 Expr *VariantRef, SourceRange SR) { 4898 if (!DG || DG.get().isNull()) 4899 return DeclGroupPtrTy(); 4900 4901 const int VariantId = 1; 4902 // Must be applied only to single decl. 4903 if (!DG.get().isSingleDecl()) { 4904 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4905 << VariantId << SR; 4906 return DG; 4907 } 4908 Decl *ADecl = DG.get().getSingleDecl(); 4909 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4910 ADecl = FTD->getTemplatedDecl(); 4911 4912 // Decl must be a function. 4913 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4914 if (!FD) { 4915 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 4916 << VariantId << SR; 4917 return DeclGroupPtrTy(); 4918 } 4919 4920 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 4921 return FD->hasAttrs() && 4922 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 4923 FD->hasAttr<TargetAttr>()); 4924 }; 4925 // OpenMP is not compatible with CPU-specific attributes. 4926 if (HasMultiVersionAttributes(FD)) { 4927 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 4928 << SR; 4929 return DG; 4930 } 4931 4932 // Allow #pragma omp declare variant only if the function is not used. 4933 if (FD->isUsed(false)) { 4934 Diag(SR.getBegin(), diag::err_omp_declare_variant_after_used) 4935 << FD->getLocation(); 4936 return DG; 4937 } 4938 4939 // The VariantRef must point to function. 4940 if (!VariantRef) { 4941 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 4942 return DG; 4943 } 4944 4945 // Do not check templates, wait until instantiation. 4946 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 4947 VariantRef->containsUnexpandedParameterPack() || 4948 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 4949 return DG; 4950 4951 // Convert VariantRef expression to the type of the original function to 4952 // resolve possible conflicts. 4953 ExprResult VariantRefCast; 4954 if (LangOpts.CPlusPlus) { 4955 QualType FnPtrType; 4956 auto *Method = dyn_cast<CXXMethodDecl>(FD); 4957 if (Method && !Method->isStatic()) { 4958 const Type *ClassType = 4959 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 4960 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 4961 ExprResult ER; 4962 { 4963 // Build adrr_of unary op to correctly handle type checks for member 4964 // functions. 4965 Sema::TentativeAnalysisScope Trap(*this); 4966 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 4967 VariantRef); 4968 } 4969 if (!ER.isUsable()) { 4970 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 4971 << VariantId << VariantRef->getSourceRange(); 4972 return DG; 4973 } 4974 VariantRef = ER.get(); 4975 } else { 4976 FnPtrType = Context.getPointerType(FD->getType()); 4977 } 4978 ImplicitConversionSequence ICS = 4979 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 4980 /*SuppressUserConversions=*/false, 4981 /*AllowExplicit=*/false, 4982 /*InOverloadResolution=*/false, 4983 /*CStyle=*/false, 4984 /*AllowObjCWritebackConversion=*/false); 4985 if (ICS.isFailure()) { 4986 Diag(VariantRef->getExprLoc(), 4987 diag::err_omp_declare_variant_incompat_types) 4988 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 4989 return DG; 4990 } 4991 VariantRefCast = PerformImplicitConversion( 4992 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 4993 if (!VariantRefCast.isUsable()) 4994 return DG; 4995 // Drop previously built artificial addr_of unary op for member functions. 4996 if (Method && !Method->isStatic()) { 4997 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 4998 if (auto *UO = dyn_cast<UnaryOperator>( 4999 PossibleAddrOfVariantRef->IgnoreImplicit())) 5000 VariantRefCast = UO->getSubExpr(); 5001 } 5002 } else { 5003 VariantRefCast = VariantRef; 5004 } 5005 5006 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5007 if (!ER.isUsable() || 5008 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5009 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5010 << VariantId << VariantRef->getSourceRange(); 5011 return DG; 5012 } 5013 5014 // The VariantRef must point to function. 5015 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5016 if (!DRE) { 5017 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5018 << VariantId << VariantRef->getSourceRange(); 5019 return DG; 5020 } 5021 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5022 if (!NewFD) { 5023 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5024 << VariantId << VariantRef->getSourceRange(); 5025 return DG; 5026 } 5027 5028 enum DoesntSupport { 5029 VirtFuncs = 1, 5030 Constructors = 3, 5031 Destructors = 4, 5032 DeletedFuncs = 5, 5033 DefaultedFuncs = 6, 5034 ConstexprFuncs = 7, 5035 ConstevalFuncs = 8, 5036 }; 5037 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5038 if (CXXFD->isVirtual()) { 5039 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5040 << VirtFuncs; 5041 return DG; 5042 } 5043 5044 if (isa<CXXConstructorDecl>(FD)) { 5045 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5046 << Constructors; 5047 return DG; 5048 } 5049 5050 if (isa<CXXDestructorDecl>(FD)) { 5051 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5052 << Destructors; 5053 return DG; 5054 } 5055 } 5056 5057 if (FD->isDeleted()) { 5058 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5059 << DeletedFuncs; 5060 return DG; 5061 } 5062 5063 if (FD->isDefaulted()) { 5064 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5065 << DefaultedFuncs; 5066 return DG; 5067 } 5068 5069 if (FD->isConstexpr()) { 5070 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5071 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5072 return DG; 5073 } 5074 5075 // Check general compatibility. 5076 if (areMultiversionVariantFunctionsCompatible( 5077 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5078 PartialDiagnosticAt( 5079 SR.getBegin(), 5080 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5081 PartialDiagnosticAt( 5082 VariantRef->getExprLoc(), 5083 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5084 PartialDiagnosticAt(VariantRef->getExprLoc(), 5085 PDiag(diag::err_omp_declare_variant_diff) 5086 << FD->getLocation()), 5087 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false)) 5088 return DG; 5089 5090 return DG; 5091 } 5092 5093 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5094 Stmt *AStmt, 5095 SourceLocation StartLoc, 5096 SourceLocation EndLoc) { 5097 if (!AStmt) 5098 return StmtError(); 5099 5100 auto *CS = cast<CapturedStmt>(AStmt); 5101 // 1.2.2 OpenMP Language Terminology 5102 // Structured block - An executable statement with a single entry at the 5103 // top and a single exit at the bottom. 5104 // The point of exit cannot be a branch out of the structured block. 5105 // longjmp() and throw() must not violate the entry/exit criteria. 5106 CS->getCapturedDecl()->setNothrow(); 5107 5108 setFunctionHasBranchProtectedScope(); 5109 5110 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5111 DSAStack->isCancelRegion()); 5112 } 5113 5114 namespace { 5115 /// Iteration space of a single for loop. 5116 struct LoopIterationSpace final { 5117 /// True if the condition operator is the strict compare operator (<, > or 5118 /// !=). 5119 bool IsStrictCompare = false; 5120 /// Condition of the loop. 5121 Expr *PreCond = nullptr; 5122 /// This expression calculates the number of iterations in the loop. 5123 /// It is always possible to calculate it before starting the loop. 5124 Expr *NumIterations = nullptr; 5125 /// The loop counter variable. 5126 Expr *CounterVar = nullptr; 5127 /// Private loop counter variable. 5128 Expr *PrivateCounterVar = nullptr; 5129 /// This is initializer for the initial value of #CounterVar. 5130 Expr *CounterInit = nullptr; 5131 /// This is step for the #CounterVar used to generate its update: 5132 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5133 Expr *CounterStep = nullptr; 5134 /// Should step be subtracted? 5135 bool Subtract = false; 5136 /// Source range of the loop init. 5137 SourceRange InitSrcRange; 5138 /// Source range of the loop condition. 5139 SourceRange CondSrcRange; 5140 /// Source range of the loop increment. 5141 SourceRange IncSrcRange; 5142 /// Minimum value that can have the loop control variable. Used to support 5143 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5144 /// since only such variables can be used in non-loop invariant expressions. 5145 Expr *MinValue = nullptr; 5146 /// Maximum value that can have the loop control variable. Used to support 5147 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5148 /// since only such variables can be used in non-loop invariant expressions. 5149 Expr *MaxValue = nullptr; 5150 /// true, if the lower bound depends on the outer loop control var. 5151 bool IsNonRectangularLB = false; 5152 /// true, if the upper bound depends on the outer loop control var. 5153 bool IsNonRectangularUB = false; 5154 /// Index of the loop this loop depends on and forms non-rectangular loop 5155 /// nest. 5156 unsigned LoopDependentIdx = 0; 5157 /// Final condition for the non-rectangular loop nest support. It is used to 5158 /// check that the number of iterations for this particular counter must be 5159 /// finished. 5160 Expr *FinalCondition = nullptr; 5161 }; 5162 5163 /// Helper class for checking canonical form of the OpenMP loops and 5164 /// extracting iteration space of each loop in the loop nest, that will be used 5165 /// for IR generation. 5166 class OpenMPIterationSpaceChecker { 5167 /// Reference to Sema. 5168 Sema &SemaRef; 5169 /// Data-sharing stack. 5170 DSAStackTy &Stack; 5171 /// A location for diagnostics (when there is no some better location). 5172 SourceLocation DefaultLoc; 5173 /// A location for diagnostics (when increment is not compatible). 5174 SourceLocation ConditionLoc; 5175 /// A source location for referring to loop init later. 5176 SourceRange InitSrcRange; 5177 /// A source location for referring to condition later. 5178 SourceRange ConditionSrcRange; 5179 /// A source location for referring to increment later. 5180 SourceRange IncrementSrcRange; 5181 /// Loop variable. 5182 ValueDecl *LCDecl = nullptr; 5183 /// Reference to loop variable. 5184 Expr *LCRef = nullptr; 5185 /// Lower bound (initializer for the var). 5186 Expr *LB = nullptr; 5187 /// Upper bound. 5188 Expr *UB = nullptr; 5189 /// Loop step (increment). 5190 Expr *Step = nullptr; 5191 /// This flag is true when condition is one of: 5192 /// Var < UB 5193 /// Var <= UB 5194 /// UB > Var 5195 /// UB >= Var 5196 /// This will have no value when the condition is != 5197 llvm::Optional<bool> TestIsLessOp; 5198 /// This flag is true when condition is strict ( < or > ). 5199 bool TestIsStrictOp = false; 5200 /// This flag is true when step is subtracted on each iteration. 5201 bool SubtractStep = false; 5202 /// The outer loop counter this loop depends on (if any). 5203 const ValueDecl *DepDecl = nullptr; 5204 /// Contains number of loop (starts from 1) on which loop counter init 5205 /// expression of this loop depends on. 5206 Optional<unsigned> InitDependOnLC; 5207 /// Contains number of loop (starts from 1) on which loop counter condition 5208 /// expression of this loop depends on. 5209 Optional<unsigned> CondDependOnLC; 5210 /// Checks if the provide statement depends on the loop counter. 5211 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5212 /// Original condition required for checking of the exit condition for 5213 /// non-rectangular loop. 5214 Expr *Condition = nullptr; 5215 5216 public: 5217 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5218 SourceLocation DefaultLoc) 5219 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5220 ConditionLoc(DefaultLoc) {} 5221 /// Check init-expr for canonical loop form and save loop counter 5222 /// variable - #Var and its initialization value - #LB. 5223 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5224 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5225 /// for less/greater and for strict/non-strict comparison. 5226 bool checkAndSetCond(Expr *S); 5227 /// Check incr-expr for canonical loop form and return true if it 5228 /// does not conform, otherwise save loop step (#Step). 5229 bool checkAndSetInc(Expr *S); 5230 /// Return the loop counter variable. 5231 ValueDecl *getLoopDecl() const { return LCDecl; } 5232 /// Return the reference expression to loop counter variable. 5233 Expr *getLoopDeclRefExpr() const { return LCRef; } 5234 /// Source range of the loop init. 5235 SourceRange getInitSrcRange() const { return InitSrcRange; } 5236 /// Source range of the loop condition. 5237 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5238 /// Source range of the loop increment. 5239 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5240 /// True if the step should be subtracted. 5241 bool shouldSubtractStep() const { return SubtractStep; } 5242 /// True, if the compare operator is strict (<, > or !=). 5243 bool isStrictTestOp() const { return TestIsStrictOp; } 5244 /// Build the expression to calculate the number of iterations. 5245 Expr *buildNumIterations( 5246 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5247 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5248 /// Build the precondition expression for the loops. 5249 Expr * 5250 buildPreCond(Scope *S, Expr *Cond, 5251 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5252 /// Build reference expression to the counter be used for codegen. 5253 DeclRefExpr * 5254 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5255 DSAStackTy &DSA) const; 5256 /// Build reference expression to the private counter be used for 5257 /// codegen. 5258 Expr *buildPrivateCounterVar() const; 5259 /// Build initialization of the counter be used for codegen. 5260 Expr *buildCounterInit() const; 5261 /// Build step of the counter be used for codegen. 5262 Expr *buildCounterStep() const; 5263 /// Build loop data with counter value for depend clauses in ordered 5264 /// directives. 5265 Expr * 5266 buildOrderedLoopData(Scope *S, Expr *Counter, 5267 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5268 SourceLocation Loc, Expr *Inc = nullptr, 5269 OverloadedOperatorKind OOK = OO_Amp); 5270 /// Builds the minimum value for the loop counter. 5271 std::pair<Expr *, Expr *> buildMinMaxValues( 5272 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5273 /// Builds final condition for the non-rectangular loops. 5274 Expr *buildFinalCondition(Scope *S) const; 5275 /// Return true if any expression is dependent. 5276 bool dependent() const; 5277 /// Returns true if the initializer forms non-rectangular loop. 5278 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5279 /// Returns true if the condition forms non-rectangular loop. 5280 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5281 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5282 unsigned getLoopDependentIdx() const { 5283 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5284 } 5285 5286 private: 5287 /// Check the right-hand side of an assignment in the increment 5288 /// expression. 5289 bool checkAndSetIncRHS(Expr *RHS); 5290 /// Helper to set loop counter variable and its initializer. 5291 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5292 bool EmitDiags); 5293 /// Helper to set upper bound. 5294 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5295 SourceRange SR, SourceLocation SL); 5296 /// Helper to set loop increment. 5297 bool setStep(Expr *NewStep, bool Subtract); 5298 }; 5299 5300 bool OpenMPIterationSpaceChecker::dependent() const { 5301 if (!LCDecl) { 5302 assert(!LB && !UB && !Step); 5303 return false; 5304 } 5305 return LCDecl->getType()->isDependentType() || 5306 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5307 (Step && Step->isValueDependent()); 5308 } 5309 5310 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5311 Expr *NewLCRefExpr, 5312 Expr *NewLB, bool EmitDiags) { 5313 // State consistency checking to ensure correct usage. 5314 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5315 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5316 if (!NewLCDecl || !NewLB) 5317 return true; 5318 LCDecl = getCanonicalDecl(NewLCDecl); 5319 LCRef = NewLCRefExpr; 5320 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5321 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5322 if ((Ctor->isCopyOrMoveConstructor() || 5323 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5324 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5325 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5326 LB = NewLB; 5327 if (EmitDiags) 5328 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5329 return false; 5330 } 5331 5332 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5333 llvm::Optional<bool> LessOp, 5334 bool StrictOp, SourceRange SR, 5335 SourceLocation SL) { 5336 // State consistency checking to ensure correct usage. 5337 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5338 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5339 if (!NewUB) 5340 return true; 5341 UB = NewUB; 5342 if (LessOp) 5343 TestIsLessOp = LessOp; 5344 TestIsStrictOp = StrictOp; 5345 ConditionSrcRange = SR; 5346 ConditionLoc = SL; 5347 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5348 return false; 5349 } 5350 5351 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5352 // State consistency checking to ensure correct usage. 5353 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5354 if (!NewStep) 5355 return true; 5356 if (!NewStep->isValueDependent()) { 5357 // Check that the step is integer expression. 5358 SourceLocation StepLoc = NewStep->getBeginLoc(); 5359 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5360 StepLoc, getExprAsWritten(NewStep)); 5361 if (Val.isInvalid()) 5362 return true; 5363 NewStep = Val.get(); 5364 5365 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5366 // If test-expr is of form var relational-op b and relational-op is < or 5367 // <= then incr-expr must cause var to increase on each iteration of the 5368 // loop. If test-expr is of form var relational-op b and relational-op is 5369 // > or >= then incr-expr must cause var to decrease on each iteration of 5370 // the loop. 5371 // If test-expr is of form b relational-op var and relational-op is < or 5372 // <= then incr-expr must cause var to decrease on each iteration of the 5373 // loop. If test-expr is of form b relational-op var and relational-op is 5374 // > or >= then incr-expr must cause var to increase on each iteration of 5375 // the loop. 5376 llvm::APSInt Result; 5377 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5378 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5379 bool IsConstNeg = 5380 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5381 bool IsConstPos = 5382 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5383 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5384 5385 // != with increment is treated as <; != with decrement is treated as > 5386 if (!TestIsLessOp.hasValue()) 5387 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5388 if (UB && (IsConstZero || 5389 (TestIsLessOp.getValue() ? 5390 (IsConstNeg || (IsUnsigned && Subtract)) : 5391 (IsConstPos || (IsUnsigned && !Subtract))))) { 5392 SemaRef.Diag(NewStep->getExprLoc(), 5393 diag::err_omp_loop_incr_not_compatible) 5394 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5395 SemaRef.Diag(ConditionLoc, 5396 diag::note_omp_loop_cond_requres_compatible_incr) 5397 << TestIsLessOp.getValue() << ConditionSrcRange; 5398 return true; 5399 } 5400 if (TestIsLessOp.getValue() == Subtract) { 5401 NewStep = 5402 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5403 .get(); 5404 Subtract = !Subtract; 5405 } 5406 } 5407 5408 Step = NewStep; 5409 SubtractStep = Subtract; 5410 return false; 5411 } 5412 5413 namespace { 5414 /// Checker for the non-rectangular loops. Checks if the initializer or 5415 /// condition expression references loop counter variable. 5416 class LoopCounterRefChecker final 5417 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5418 Sema &SemaRef; 5419 DSAStackTy &Stack; 5420 const ValueDecl *CurLCDecl = nullptr; 5421 const ValueDecl *DepDecl = nullptr; 5422 const ValueDecl *PrevDepDecl = nullptr; 5423 bool IsInitializer = true; 5424 unsigned BaseLoopId = 0; 5425 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5426 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5427 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5428 << (IsInitializer ? 0 : 1); 5429 return false; 5430 } 5431 const auto &&Data = Stack.isLoopControlVariable(VD); 5432 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5433 // The type of the loop iterator on which we depend may not have a random 5434 // access iterator type. 5435 if (Data.first && VD->getType()->isRecordType()) { 5436 SmallString<128> Name; 5437 llvm::raw_svector_ostream OS(Name); 5438 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5439 /*Qualified=*/true); 5440 SemaRef.Diag(E->getExprLoc(), 5441 diag::err_omp_wrong_dependency_iterator_type) 5442 << OS.str(); 5443 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5444 return false; 5445 } 5446 if (Data.first && 5447 (DepDecl || (PrevDepDecl && 5448 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5449 if (!DepDecl && PrevDepDecl) 5450 DepDecl = PrevDepDecl; 5451 SmallString<128> Name; 5452 llvm::raw_svector_ostream OS(Name); 5453 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5454 /*Qualified=*/true); 5455 SemaRef.Diag(E->getExprLoc(), 5456 diag::err_omp_invariant_or_linear_dependency) 5457 << OS.str(); 5458 return false; 5459 } 5460 if (Data.first) { 5461 DepDecl = VD; 5462 BaseLoopId = Data.first; 5463 } 5464 return Data.first; 5465 } 5466 5467 public: 5468 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5469 const ValueDecl *VD = E->getDecl(); 5470 if (isa<VarDecl>(VD)) 5471 return checkDecl(E, VD); 5472 return false; 5473 } 5474 bool VisitMemberExpr(const MemberExpr *E) { 5475 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5476 const ValueDecl *VD = E->getMemberDecl(); 5477 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5478 return checkDecl(E, VD); 5479 } 5480 return false; 5481 } 5482 bool VisitStmt(const Stmt *S) { 5483 bool Res = false; 5484 for (const Stmt *Child : S->children()) 5485 Res = (Child && Visit(Child)) || Res; 5486 return Res; 5487 } 5488 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5489 const ValueDecl *CurLCDecl, bool IsInitializer, 5490 const ValueDecl *PrevDepDecl = nullptr) 5491 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5492 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5493 unsigned getBaseLoopId() const { 5494 assert(CurLCDecl && "Expected loop dependency."); 5495 return BaseLoopId; 5496 } 5497 const ValueDecl *getDepDecl() const { 5498 assert(CurLCDecl && "Expected loop dependency."); 5499 return DepDecl; 5500 } 5501 }; 5502 } // namespace 5503 5504 Optional<unsigned> 5505 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5506 bool IsInitializer) { 5507 // Check for the non-rectangular loops. 5508 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5509 DepDecl); 5510 if (LoopStmtChecker.Visit(S)) { 5511 DepDecl = LoopStmtChecker.getDepDecl(); 5512 return LoopStmtChecker.getBaseLoopId(); 5513 } 5514 return llvm::None; 5515 } 5516 5517 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5518 // Check init-expr for canonical loop form and save loop counter 5519 // variable - #Var and its initialization value - #LB. 5520 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5521 // var = lb 5522 // integer-type var = lb 5523 // random-access-iterator-type var = lb 5524 // pointer-type var = lb 5525 // 5526 if (!S) { 5527 if (EmitDiags) { 5528 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5529 } 5530 return true; 5531 } 5532 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5533 if (!ExprTemp->cleanupsHaveSideEffects()) 5534 S = ExprTemp->getSubExpr(); 5535 5536 InitSrcRange = S->getSourceRange(); 5537 if (Expr *E = dyn_cast<Expr>(S)) 5538 S = E->IgnoreParens(); 5539 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5540 if (BO->getOpcode() == BO_Assign) { 5541 Expr *LHS = BO->getLHS()->IgnoreParens(); 5542 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5543 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5544 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5545 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5546 EmitDiags); 5547 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5548 } 5549 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5550 if (ME->isArrow() && 5551 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5552 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5553 EmitDiags); 5554 } 5555 } 5556 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5557 if (DS->isSingleDecl()) { 5558 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5559 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5560 // Accept non-canonical init form here but emit ext. warning. 5561 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5562 SemaRef.Diag(S->getBeginLoc(), 5563 diag::ext_omp_loop_not_canonical_init) 5564 << S->getSourceRange(); 5565 return setLCDeclAndLB( 5566 Var, 5567 buildDeclRefExpr(SemaRef, Var, 5568 Var->getType().getNonReferenceType(), 5569 DS->getBeginLoc()), 5570 Var->getInit(), EmitDiags); 5571 } 5572 } 5573 } 5574 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5575 if (CE->getOperator() == OO_Equal) { 5576 Expr *LHS = CE->getArg(0); 5577 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5578 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5579 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5580 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5581 EmitDiags); 5582 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5583 } 5584 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5585 if (ME->isArrow() && 5586 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5587 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5588 EmitDiags); 5589 } 5590 } 5591 } 5592 5593 if (dependent() || SemaRef.CurContext->isDependentContext()) 5594 return false; 5595 if (EmitDiags) { 5596 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5597 << S->getSourceRange(); 5598 } 5599 return true; 5600 } 5601 5602 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5603 /// variable (which may be the loop variable) if possible. 5604 static const ValueDecl *getInitLCDecl(const Expr *E) { 5605 if (!E) 5606 return nullptr; 5607 E = getExprAsWritten(E); 5608 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5609 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5610 if ((Ctor->isCopyOrMoveConstructor() || 5611 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5612 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5613 E = CE->getArg(0)->IgnoreParenImpCasts(); 5614 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5615 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5616 return getCanonicalDecl(VD); 5617 } 5618 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5619 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5620 return getCanonicalDecl(ME->getMemberDecl()); 5621 return nullptr; 5622 } 5623 5624 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5625 // Check test-expr for canonical form, save upper-bound UB, flags for 5626 // less/greater and for strict/non-strict comparison. 5627 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5628 // var relational-op b 5629 // b relational-op var 5630 // 5631 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5632 if (!S) { 5633 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5634 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5635 return true; 5636 } 5637 Condition = S; 5638 S = getExprAsWritten(S); 5639 SourceLocation CondLoc = S->getBeginLoc(); 5640 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5641 if (BO->isRelationalOp()) { 5642 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5643 return setUB(BO->getRHS(), 5644 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5645 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5646 BO->getSourceRange(), BO->getOperatorLoc()); 5647 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5648 return setUB(BO->getLHS(), 5649 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5650 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5651 BO->getSourceRange(), BO->getOperatorLoc()); 5652 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5653 return setUB( 5654 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5655 /*LessOp=*/llvm::None, 5656 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5657 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5658 if (CE->getNumArgs() == 2) { 5659 auto Op = CE->getOperator(); 5660 switch (Op) { 5661 case OO_Greater: 5662 case OO_GreaterEqual: 5663 case OO_Less: 5664 case OO_LessEqual: 5665 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5666 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5667 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5668 CE->getOperatorLoc()); 5669 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5670 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5671 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5672 CE->getOperatorLoc()); 5673 break; 5674 case OO_ExclaimEqual: 5675 if (IneqCondIsCanonical) 5676 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5677 : CE->getArg(0), 5678 /*LessOp=*/llvm::None, 5679 /*StrictOp=*/true, CE->getSourceRange(), 5680 CE->getOperatorLoc()); 5681 break; 5682 default: 5683 break; 5684 } 5685 } 5686 } 5687 if (dependent() || SemaRef.CurContext->isDependentContext()) 5688 return false; 5689 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5690 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5691 return true; 5692 } 5693 5694 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5695 // RHS of canonical loop form increment can be: 5696 // var + incr 5697 // incr + var 5698 // var - incr 5699 // 5700 RHS = RHS->IgnoreParenImpCasts(); 5701 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5702 if (BO->isAdditiveOp()) { 5703 bool IsAdd = BO->getOpcode() == BO_Add; 5704 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5705 return setStep(BO->getRHS(), !IsAdd); 5706 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5707 return setStep(BO->getLHS(), /*Subtract=*/false); 5708 } 5709 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5710 bool IsAdd = CE->getOperator() == OO_Plus; 5711 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5712 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5713 return setStep(CE->getArg(1), !IsAdd); 5714 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5715 return setStep(CE->getArg(0), /*Subtract=*/false); 5716 } 5717 } 5718 if (dependent() || SemaRef.CurContext->isDependentContext()) 5719 return false; 5720 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5721 << RHS->getSourceRange() << LCDecl; 5722 return true; 5723 } 5724 5725 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5726 // Check incr-expr for canonical loop form and return true if it 5727 // does not conform. 5728 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5729 // ++var 5730 // var++ 5731 // --var 5732 // var-- 5733 // var += incr 5734 // var -= incr 5735 // var = var + incr 5736 // var = incr + var 5737 // var = var - incr 5738 // 5739 if (!S) { 5740 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5741 return true; 5742 } 5743 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5744 if (!ExprTemp->cleanupsHaveSideEffects()) 5745 S = ExprTemp->getSubExpr(); 5746 5747 IncrementSrcRange = S->getSourceRange(); 5748 S = S->IgnoreParens(); 5749 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5750 if (UO->isIncrementDecrementOp() && 5751 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5752 return setStep(SemaRef 5753 .ActOnIntegerConstant(UO->getBeginLoc(), 5754 (UO->isDecrementOp() ? -1 : 1)) 5755 .get(), 5756 /*Subtract=*/false); 5757 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5758 switch (BO->getOpcode()) { 5759 case BO_AddAssign: 5760 case BO_SubAssign: 5761 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5762 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5763 break; 5764 case BO_Assign: 5765 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5766 return checkAndSetIncRHS(BO->getRHS()); 5767 break; 5768 default: 5769 break; 5770 } 5771 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5772 switch (CE->getOperator()) { 5773 case OO_PlusPlus: 5774 case OO_MinusMinus: 5775 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5776 return setStep(SemaRef 5777 .ActOnIntegerConstant( 5778 CE->getBeginLoc(), 5779 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5780 .get(), 5781 /*Subtract=*/false); 5782 break; 5783 case OO_PlusEqual: 5784 case OO_MinusEqual: 5785 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5786 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5787 break; 5788 case OO_Equal: 5789 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5790 return checkAndSetIncRHS(CE->getArg(1)); 5791 break; 5792 default: 5793 break; 5794 } 5795 } 5796 if (dependent() || SemaRef.CurContext->isDependentContext()) 5797 return false; 5798 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5799 << S->getSourceRange() << LCDecl; 5800 return true; 5801 } 5802 5803 static ExprResult 5804 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5805 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5806 if (SemaRef.CurContext->isDependentContext()) 5807 return ExprResult(Capture); 5808 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5809 return SemaRef.PerformImplicitConversion( 5810 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5811 /*AllowExplicit=*/true); 5812 auto I = Captures.find(Capture); 5813 if (I != Captures.end()) 5814 return buildCapture(SemaRef, Capture, I->second); 5815 DeclRefExpr *Ref = nullptr; 5816 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5817 Captures[Capture] = Ref; 5818 return Res; 5819 } 5820 5821 /// Build the expression to calculate the number of iterations. 5822 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5823 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5824 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5825 ExprResult Diff; 5826 QualType VarType = LCDecl->getType().getNonReferenceType(); 5827 if (VarType->isIntegerType() || VarType->isPointerType() || 5828 SemaRef.getLangOpts().CPlusPlus) { 5829 Expr *LBVal = LB; 5830 Expr *UBVal = UB; 5831 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5832 // max(LB(MinVal), LB(MaxVal)) 5833 if (InitDependOnLC) { 5834 const LoopIterationSpace &IS = 5835 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5836 InitDependOnLC.getValueOr( 5837 CondDependOnLC.getValueOr(0))]; 5838 if (!IS.MinValue || !IS.MaxValue) 5839 return nullptr; 5840 // OuterVar = Min 5841 ExprResult MinValue = 5842 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5843 if (!MinValue.isUsable()) 5844 return nullptr; 5845 5846 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5847 IS.CounterVar, MinValue.get()); 5848 if (!LBMinVal.isUsable()) 5849 return nullptr; 5850 // OuterVar = Min, LBVal 5851 LBMinVal = 5852 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5853 if (!LBMinVal.isUsable()) 5854 return nullptr; 5855 // (OuterVar = Min, LBVal) 5856 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5857 if (!LBMinVal.isUsable()) 5858 return nullptr; 5859 5860 // OuterVar = Max 5861 ExprResult MaxValue = 5862 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5863 if (!MaxValue.isUsable()) 5864 return nullptr; 5865 5866 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5867 IS.CounterVar, MaxValue.get()); 5868 if (!LBMaxVal.isUsable()) 5869 return nullptr; 5870 // OuterVar = Max, LBVal 5871 LBMaxVal = 5872 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5873 if (!LBMaxVal.isUsable()) 5874 return nullptr; 5875 // (OuterVar = Max, LBVal) 5876 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5877 if (!LBMaxVal.isUsable()) 5878 return nullptr; 5879 5880 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 5881 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 5882 if (!LBMin || !LBMax) 5883 return nullptr; 5884 // LB(MinVal) < LB(MaxVal) 5885 ExprResult MinLessMaxRes = 5886 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 5887 if (!MinLessMaxRes.isUsable()) 5888 return nullptr; 5889 Expr *MinLessMax = 5890 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 5891 if (!MinLessMax) 5892 return nullptr; 5893 if (TestIsLessOp.getValue()) { 5894 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 5895 // LB(MaxVal)) 5896 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5897 MinLessMax, LBMin, LBMax); 5898 if (!MinLB.isUsable()) 5899 return nullptr; 5900 LBVal = MinLB.get(); 5901 } else { 5902 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 5903 // LB(MaxVal)) 5904 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5905 MinLessMax, LBMax, LBMin); 5906 if (!MaxLB.isUsable()) 5907 return nullptr; 5908 LBVal = MaxLB.get(); 5909 } 5910 } 5911 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 5912 // min(UB(MinVal), UB(MaxVal)) 5913 if (CondDependOnLC) { 5914 const LoopIterationSpace &IS = 5915 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5916 InitDependOnLC.getValueOr( 5917 CondDependOnLC.getValueOr(0))]; 5918 if (!IS.MinValue || !IS.MaxValue) 5919 return nullptr; 5920 // OuterVar = Min 5921 ExprResult MinValue = 5922 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5923 if (!MinValue.isUsable()) 5924 return nullptr; 5925 5926 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5927 IS.CounterVar, MinValue.get()); 5928 if (!UBMinVal.isUsable()) 5929 return nullptr; 5930 // OuterVar = Min, UBVal 5931 UBMinVal = 5932 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 5933 if (!UBMinVal.isUsable()) 5934 return nullptr; 5935 // (OuterVar = Min, UBVal) 5936 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 5937 if (!UBMinVal.isUsable()) 5938 return nullptr; 5939 5940 // OuterVar = Max 5941 ExprResult MaxValue = 5942 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5943 if (!MaxValue.isUsable()) 5944 return nullptr; 5945 5946 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5947 IS.CounterVar, MaxValue.get()); 5948 if (!UBMaxVal.isUsable()) 5949 return nullptr; 5950 // OuterVar = Max, UBVal 5951 UBMaxVal = 5952 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 5953 if (!UBMaxVal.isUsable()) 5954 return nullptr; 5955 // (OuterVar = Max, UBVal) 5956 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 5957 if (!UBMaxVal.isUsable()) 5958 return nullptr; 5959 5960 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 5961 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 5962 if (!UBMin || !UBMax) 5963 return nullptr; 5964 // UB(MinVal) > UB(MaxVal) 5965 ExprResult MinGreaterMaxRes = 5966 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 5967 if (!MinGreaterMaxRes.isUsable()) 5968 return nullptr; 5969 Expr *MinGreaterMax = 5970 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 5971 if (!MinGreaterMax) 5972 return nullptr; 5973 if (TestIsLessOp.getValue()) { 5974 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 5975 // UB(MaxVal)) 5976 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 5977 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 5978 if (!MaxUB.isUsable()) 5979 return nullptr; 5980 UBVal = MaxUB.get(); 5981 } else { 5982 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 5983 // UB(MaxVal)) 5984 ExprResult MinUB = SemaRef.ActOnConditionalOp( 5985 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 5986 if (!MinUB.isUsable()) 5987 return nullptr; 5988 UBVal = MinUB.get(); 5989 } 5990 } 5991 // Upper - Lower 5992 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 5993 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 5994 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5995 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5996 if (!Upper || !Lower) 5997 return nullptr; 5998 5999 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6000 6001 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6002 // BuildBinOp already emitted error, this one is to point user to upper 6003 // and lower bound, and to tell what is passed to 'operator-'. 6004 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6005 << Upper->getSourceRange() << Lower->getSourceRange(); 6006 return nullptr; 6007 } 6008 } 6009 6010 if (!Diff.isUsable()) 6011 return nullptr; 6012 6013 // Upper - Lower [- 1] 6014 if (TestIsStrictOp) 6015 Diff = SemaRef.BuildBinOp( 6016 S, DefaultLoc, BO_Sub, Diff.get(), 6017 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6018 if (!Diff.isUsable()) 6019 return nullptr; 6020 6021 // Upper - Lower [- 1] + Step 6022 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6023 if (!NewStep.isUsable()) 6024 return nullptr; 6025 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6026 if (!Diff.isUsable()) 6027 return nullptr; 6028 6029 // Parentheses (for dumping/debugging purposes only). 6030 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6031 if (!Diff.isUsable()) 6032 return nullptr; 6033 6034 // (Upper - Lower [- 1] + Step) / Step 6035 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6036 if (!Diff.isUsable()) 6037 return nullptr; 6038 6039 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6040 QualType Type = Diff.get()->getType(); 6041 ASTContext &C = SemaRef.Context; 6042 bool UseVarType = VarType->hasIntegerRepresentation() && 6043 C.getTypeSize(Type) > C.getTypeSize(VarType); 6044 if (!Type->isIntegerType() || UseVarType) { 6045 unsigned NewSize = 6046 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6047 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6048 : Type->hasSignedIntegerRepresentation(); 6049 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6050 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6051 Diff = SemaRef.PerformImplicitConversion( 6052 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6053 if (!Diff.isUsable()) 6054 return nullptr; 6055 } 6056 } 6057 if (LimitedType) { 6058 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6059 if (NewSize != C.getTypeSize(Type)) { 6060 if (NewSize < C.getTypeSize(Type)) { 6061 assert(NewSize == 64 && "incorrect loop var size"); 6062 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6063 << InitSrcRange << ConditionSrcRange; 6064 } 6065 QualType NewType = C.getIntTypeForBitwidth( 6066 NewSize, Type->hasSignedIntegerRepresentation() || 6067 C.getTypeSize(Type) < NewSize); 6068 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6069 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6070 Sema::AA_Converting, true); 6071 if (!Diff.isUsable()) 6072 return nullptr; 6073 } 6074 } 6075 } 6076 6077 return Diff.get(); 6078 } 6079 6080 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6081 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6082 // Do not build for iterators, they cannot be used in non-rectangular loop 6083 // nests. 6084 if (LCDecl->getType()->isRecordType()) 6085 return std::make_pair(nullptr, nullptr); 6086 // If we subtract, the min is in the condition, otherwise the min is in the 6087 // init value. 6088 Expr *MinExpr = nullptr; 6089 Expr *MaxExpr = nullptr; 6090 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6091 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6092 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6093 : CondDependOnLC.hasValue(); 6094 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6095 : InitDependOnLC.hasValue(); 6096 Expr *Lower = 6097 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6098 Expr *Upper = 6099 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6100 if (!Upper || !Lower) 6101 return std::make_pair(nullptr, nullptr); 6102 6103 if (TestIsLessOp.getValue()) 6104 MinExpr = Lower; 6105 else 6106 MaxExpr = Upper; 6107 6108 // Build minimum/maximum value based on number of iterations. 6109 ExprResult Diff; 6110 QualType VarType = LCDecl->getType().getNonReferenceType(); 6111 6112 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6113 if (!Diff.isUsable()) 6114 return std::make_pair(nullptr, nullptr); 6115 6116 // Upper - Lower [- 1] 6117 if (TestIsStrictOp) 6118 Diff = SemaRef.BuildBinOp( 6119 S, DefaultLoc, BO_Sub, Diff.get(), 6120 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6121 if (!Diff.isUsable()) 6122 return std::make_pair(nullptr, nullptr); 6123 6124 // Upper - Lower [- 1] + Step 6125 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6126 if (!NewStep.isUsable()) 6127 return std::make_pair(nullptr, nullptr); 6128 6129 // Parentheses (for dumping/debugging purposes only). 6130 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6131 if (!Diff.isUsable()) 6132 return std::make_pair(nullptr, nullptr); 6133 6134 // (Upper - Lower [- 1]) / Step 6135 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6136 if (!Diff.isUsable()) 6137 return std::make_pair(nullptr, nullptr); 6138 6139 // ((Upper - Lower [- 1]) / Step) * Step 6140 // Parentheses (for dumping/debugging purposes only). 6141 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6142 if (!Diff.isUsable()) 6143 return std::make_pair(nullptr, nullptr); 6144 6145 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6146 if (!Diff.isUsable()) 6147 return std::make_pair(nullptr, nullptr); 6148 6149 // Convert to the original type or ptrdiff_t, if original type is pointer. 6150 if (!VarType->isAnyPointerType() && 6151 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6152 Diff = SemaRef.PerformImplicitConversion( 6153 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6154 } else if (VarType->isAnyPointerType() && 6155 !SemaRef.Context.hasSameType( 6156 Diff.get()->getType(), 6157 SemaRef.Context.getUnsignedPointerDiffType())) { 6158 Diff = SemaRef.PerformImplicitConversion( 6159 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6160 Sema::AA_Converting, /*AllowExplicit=*/true); 6161 } 6162 if (!Diff.isUsable()) 6163 return std::make_pair(nullptr, nullptr); 6164 6165 // Parentheses (for dumping/debugging purposes only). 6166 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6167 if (!Diff.isUsable()) 6168 return std::make_pair(nullptr, nullptr); 6169 6170 if (TestIsLessOp.getValue()) { 6171 // MinExpr = Lower; 6172 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6173 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6174 if (!Diff.isUsable()) 6175 return std::make_pair(nullptr, nullptr); 6176 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6177 if (!Diff.isUsable()) 6178 return std::make_pair(nullptr, nullptr); 6179 MaxExpr = Diff.get(); 6180 } else { 6181 // MaxExpr = Upper; 6182 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6183 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6184 if (!Diff.isUsable()) 6185 return std::make_pair(nullptr, nullptr); 6186 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6187 if (!Diff.isUsable()) 6188 return std::make_pair(nullptr, nullptr); 6189 MinExpr = Diff.get(); 6190 } 6191 6192 return std::make_pair(MinExpr, MaxExpr); 6193 } 6194 6195 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6196 if (InitDependOnLC || CondDependOnLC) 6197 return Condition; 6198 return nullptr; 6199 } 6200 6201 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6202 Scope *S, Expr *Cond, 6203 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6204 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6205 Sema::TentativeAnalysisScope Trap(SemaRef); 6206 6207 ExprResult NewLB = 6208 InitDependOnLC ? LB : tryBuildCapture(SemaRef, LB, Captures); 6209 ExprResult NewUB = 6210 CondDependOnLC ? UB : tryBuildCapture(SemaRef, UB, Captures); 6211 if (!NewLB.isUsable() || !NewUB.isUsable()) 6212 return nullptr; 6213 6214 ExprResult CondExpr = 6215 SemaRef.BuildBinOp(S, DefaultLoc, 6216 TestIsLessOp.getValue() ? 6217 (TestIsStrictOp ? BO_LT : BO_LE) : 6218 (TestIsStrictOp ? BO_GT : BO_GE), 6219 NewLB.get(), NewUB.get()); 6220 if (CondExpr.isUsable()) { 6221 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6222 SemaRef.Context.BoolTy)) 6223 CondExpr = SemaRef.PerformImplicitConversion( 6224 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6225 /*AllowExplicit=*/true); 6226 } 6227 6228 // Otherwise use original loop condition and evaluate it in runtime. 6229 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6230 } 6231 6232 /// Build reference expression to the counter be used for codegen. 6233 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6234 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6235 DSAStackTy &DSA) const { 6236 auto *VD = dyn_cast<VarDecl>(LCDecl); 6237 if (!VD) { 6238 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6239 DeclRefExpr *Ref = buildDeclRefExpr( 6240 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6241 const DSAStackTy::DSAVarData Data = 6242 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6243 // If the loop control decl is explicitly marked as private, do not mark it 6244 // as captured again. 6245 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6246 Captures.insert(std::make_pair(LCRef, Ref)); 6247 return Ref; 6248 } 6249 return cast<DeclRefExpr>(LCRef); 6250 } 6251 6252 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6253 if (LCDecl && !LCDecl->isInvalidDecl()) { 6254 QualType Type = LCDecl->getType().getNonReferenceType(); 6255 VarDecl *PrivateVar = buildVarDecl( 6256 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6257 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6258 isa<VarDecl>(LCDecl) 6259 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6260 : nullptr); 6261 if (PrivateVar->isInvalidDecl()) 6262 return nullptr; 6263 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6264 } 6265 return nullptr; 6266 } 6267 6268 /// Build initialization of the counter to be used for codegen. 6269 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6270 6271 /// Build step of the counter be used for codegen. 6272 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6273 6274 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6275 Scope *S, Expr *Counter, 6276 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6277 Expr *Inc, OverloadedOperatorKind OOK) { 6278 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6279 if (!Cnt) 6280 return nullptr; 6281 if (Inc) { 6282 assert((OOK == OO_Plus || OOK == OO_Minus) && 6283 "Expected only + or - operations for depend clauses."); 6284 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6285 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6286 if (!Cnt) 6287 return nullptr; 6288 } 6289 ExprResult Diff; 6290 QualType VarType = LCDecl->getType().getNonReferenceType(); 6291 if (VarType->isIntegerType() || VarType->isPointerType() || 6292 SemaRef.getLangOpts().CPlusPlus) { 6293 // Upper - Lower 6294 Expr *Upper = TestIsLessOp.getValue() 6295 ? Cnt 6296 : tryBuildCapture(SemaRef, UB, Captures).get(); 6297 Expr *Lower = TestIsLessOp.getValue() 6298 ? tryBuildCapture(SemaRef, LB, Captures).get() 6299 : Cnt; 6300 if (!Upper || !Lower) 6301 return nullptr; 6302 6303 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6304 6305 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6306 // BuildBinOp already emitted error, this one is to point user to upper 6307 // and lower bound, and to tell what is passed to 'operator-'. 6308 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6309 << Upper->getSourceRange() << Lower->getSourceRange(); 6310 return nullptr; 6311 } 6312 } 6313 6314 if (!Diff.isUsable()) 6315 return nullptr; 6316 6317 // Parentheses (for dumping/debugging purposes only). 6318 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6319 if (!Diff.isUsable()) 6320 return nullptr; 6321 6322 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6323 if (!NewStep.isUsable()) 6324 return nullptr; 6325 // (Upper - Lower) / Step 6326 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6327 if (!Diff.isUsable()) 6328 return nullptr; 6329 6330 return Diff.get(); 6331 } 6332 } // namespace 6333 6334 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6335 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6336 assert(Init && "Expected loop in canonical form."); 6337 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6338 if (AssociatedLoops > 0 && 6339 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6340 DSAStack->loopStart(); 6341 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6342 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6343 if (ValueDecl *D = ISC.getLoopDecl()) { 6344 auto *VD = dyn_cast<VarDecl>(D); 6345 DeclRefExpr *PrivateRef = nullptr; 6346 if (!VD) { 6347 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6348 VD = Private; 6349 } else { 6350 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6351 /*WithInit=*/false); 6352 VD = cast<VarDecl>(PrivateRef->getDecl()); 6353 } 6354 } 6355 DSAStack->addLoopControlVariable(D, VD); 6356 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6357 if (LD != D->getCanonicalDecl()) { 6358 DSAStack->resetPossibleLoopCounter(); 6359 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6360 MarkDeclarationsReferencedInExpr( 6361 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6362 Var->getType().getNonLValueExprType(Context), 6363 ForLoc, /*RefersToCapture=*/true)); 6364 } 6365 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6366 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6367 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6368 // associated for-loop of a simd construct with just one associated 6369 // for-loop may be listed in a linear clause with a constant-linear-step 6370 // that is the increment of the associated for-loop. The loop iteration 6371 // variable(s) in the associated for-loop(s) of a for or parallel for 6372 // construct may be listed in a private or lastprivate clause. 6373 DSAStackTy::DSAVarData DVar = 6374 DSAStack->getTopDSA(D, /*FromParent=*/false); 6375 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6376 // is declared in the loop and it is predetermined as a private. 6377 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6378 OpenMPClauseKind PredeterminedCKind = 6379 isOpenMPSimdDirective(DKind) 6380 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6381 : OMPC_private; 6382 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6383 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6384 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6385 DVar.CKind != OMPC_private))) || 6386 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6387 isOpenMPDistributeDirective(DKind)) && 6388 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6389 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6390 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6391 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6392 << getOpenMPClauseName(DVar.CKind) 6393 << getOpenMPDirectiveName(DKind) 6394 << getOpenMPClauseName(PredeterminedCKind); 6395 if (DVar.RefExpr == nullptr) 6396 DVar.CKind = PredeterminedCKind; 6397 reportOriginalDsa(*this, DSAStack, D, DVar, 6398 /*IsLoopIterVar=*/true); 6399 } else if (LoopDeclRefExpr) { 6400 // Make the loop iteration variable private (for worksharing 6401 // constructs), linear (for simd directives with the only one 6402 // associated loop) or lastprivate (for simd directives with several 6403 // collapsed or ordered loops). 6404 if (DVar.CKind == OMPC_unknown) 6405 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6406 PrivateRef); 6407 } 6408 } 6409 } 6410 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6411 } 6412 } 6413 6414 /// Called on a for stmt to check and extract its iteration space 6415 /// for further processing (such as collapsing). 6416 static bool checkOpenMPIterationSpace( 6417 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6418 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6419 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6420 Expr *OrderedLoopCountExpr, 6421 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6422 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6423 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6424 // OpenMP [2.6, Canonical Loop Form] 6425 // for (init-expr; test-expr; incr-expr) structured-block 6426 auto *For = dyn_cast_or_null<ForStmt>(S); 6427 if (!For) { 6428 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6429 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6430 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6431 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6432 if (TotalNestedLoopCount > 1) { 6433 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6434 SemaRef.Diag(DSA.getConstructLoc(), 6435 diag::note_omp_collapse_ordered_expr) 6436 << 2 << CollapseLoopCountExpr->getSourceRange() 6437 << OrderedLoopCountExpr->getSourceRange(); 6438 else if (CollapseLoopCountExpr) 6439 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6440 diag::note_omp_collapse_ordered_expr) 6441 << 0 << CollapseLoopCountExpr->getSourceRange(); 6442 else 6443 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6444 diag::note_omp_collapse_ordered_expr) 6445 << 1 << OrderedLoopCountExpr->getSourceRange(); 6446 } 6447 return true; 6448 } 6449 assert(For->getBody()); 6450 6451 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 6452 6453 // Check init. 6454 Stmt *Init = For->getInit(); 6455 if (ISC.checkAndSetInit(Init)) 6456 return true; 6457 6458 bool HasErrors = false; 6459 6460 // Check loop variable's type. 6461 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6462 // OpenMP [2.6, Canonical Loop Form] 6463 // Var is one of the following: 6464 // A variable of signed or unsigned integer type. 6465 // For C++, a variable of a random access iterator type. 6466 // For C, a variable of a pointer type. 6467 QualType VarType = LCDecl->getType().getNonReferenceType(); 6468 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6469 !VarType->isPointerType() && 6470 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6471 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6472 << SemaRef.getLangOpts().CPlusPlus; 6473 HasErrors = true; 6474 } 6475 6476 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6477 // a Construct 6478 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6479 // parallel for construct is (are) private. 6480 // The loop iteration variable in the associated for-loop of a simd 6481 // construct with just one associated for-loop is linear with a 6482 // constant-linear-step that is the increment of the associated for-loop. 6483 // Exclude loop var from the list of variables with implicitly defined data 6484 // sharing attributes. 6485 VarsWithImplicitDSA.erase(LCDecl); 6486 6487 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6488 6489 // Check test-expr. 6490 HasErrors |= ISC.checkAndSetCond(For->getCond()); 6491 6492 // Check incr-expr. 6493 HasErrors |= ISC.checkAndSetInc(For->getInc()); 6494 } 6495 6496 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6497 return HasErrors; 6498 6499 // Build the loop's iteration space representation. 6500 ResultIterSpaces[CurrentNestedLoopCount].PreCond = 6501 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 6502 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6503 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6504 (isOpenMPWorksharingDirective(DKind) || 6505 isOpenMPTaskLoopDirective(DKind) || 6506 isOpenMPDistributeDirective(DKind)), 6507 Captures); 6508 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6509 ISC.buildCounterVar(Captures, DSA); 6510 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6511 ISC.buildPrivateCounterVar(); 6512 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6513 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6514 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6515 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6516 ISC.getConditionSrcRange(); 6517 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6518 ISC.getIncrementSrcRange(); 6519 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6520 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6521 ISC.isStrictTestOp(); 6522 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6523 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6524 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6525 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6526 ISC.buildFinalCondition(DSA.getCurScope()); 6527 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6528 ISC.doesInitDependOnLC(); 6529 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6530 ISC.doesCondDependOnLC(); 6531 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6532 ISC.getLoopDependentIdx(); 6533 6534 HasErrors |= 6535 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6536 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6537 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6538 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6539 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6540 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6541 if (!HasErrors && DSA.isOrderedRegion()) { 6542 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6543 if (CurrentNestedLoopCount < 6544 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6545 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6546 CurrentNestedLoopCount, 6547 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6548 DSA.getOrderedRegionParam().second->setLoopCounter( 6549 CurrentNestedLoopCount, 6550 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6551 } 6552 } 6553 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6554 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6555 // Erroneous case - clause has some problems. 6556 continue; 6557 } 6558 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6559 Pair.second.size() <= CurrentNestedLoopCount) { 6560 // Erroneous case - clause has some problems. 6561 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6562 continue; 6563 } 6564 Expr *CntValue; 6565 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6566 CntValue = ISC.buildOrderedLoopData( 6567 DSA.getCurScope(), 6568 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6569 Pair.first->getDependencyLoc()); 6570 else 6571 CntValue = ISC.buildOrderedLoopData( 6572 DSA.getCurScope(), 6573 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6574 Pair.first->getDependencyLoc(), 6575 Pair.second[CurrentNestedLoopCount].first, 6576 Pair.second[CurrentNestedLoopCount].second); 6577 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6578 } 6579 } 6580 6581 return HasErrors; 6582 } 6583 6584 /// Build 'VarRef = Start. 6585 static ExprResult 6586 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6587 ExprResult Start, bool IsNonRectangularLB, 6588 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6589 // Build 'VarRef = Start. 6590 ExprResult NewStart = IsNonRectangularLB 6591 ? Start.get() 6592 : tryBuildCapture(SemaRef, Start.get(), Captures); 6593 if (!NewStart.isUsable()) 6594 return ExprError(); 6595 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6596 VarRef.get()->getType())) { 6597 NewStart = SemaRef.PerformImplicitConversion( 6598 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6599 /*AllowExplicit=*/true); 6600 if (!NewStart.isUsable()) 6601 return ExprError(); 6602 } 6603 6604 ExprResult Init = 6605 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6606 return Init; 6607 } 6608 6609 /// Build 'VarRef = Start + Iter * Step'. 6610 static ExprResult buildCounterUpdate( 6611 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6612 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6613 bool IsNonRectangularLB, 6614 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6615 // Add parentheses (for debugging purposes only). 6616 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6617 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6618 !Step.isUsable()) 6619 return ExprError(); 6620 6621 ExprResult NewStep = Step; 6622 if (Captures) 6623 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6624 if (NewStep.isInvalid()) 6625 return ExprError(); 6626 ExprResult Update = 6627 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6628 if (!Update.isUsable()) 6629 return ExprError(); 6630 6631 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6632 // 'VarRef = Start (+|-) Iter * Step'. 6633 if (!Start.isUsable()) 6634 return ExprError(); 6635 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6636 if (!NewStart.isUsable()) 6637 return ExprError(); 6638 if (Captures && !IsNonRectangularLB) 6639 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6640 if (NewStart.isInvalid()) 6641 return ExprError(); 6642 6643 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6644 ExprResult SavedUpdate = Update; 6645 ExprResult UpdateVal; 6646 if (VarRef.get()->getType()->isOverloadableType() || 6647 NewStart.get()->getType()->isOverloadableType() || 6648 Update.get()->getType()->isOverloadableType()) { 6649 Sema::TentativeAnalysisScope Trap(SemaRef); 6650 6651 Update = 6652 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6653 if (Update.isUsable()) { 6654 UpdateVal = 6655 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6656 VarRef.get(), SavedUpdate.get()); 6657 if (UpdateVal.isUsable()) { 6658 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6659 UpdateVal.get()); 6660 } 6661 } 6662 } 6663 6664 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6665 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6666 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6667 NewStart.get(), SavedUpdate.get()); 6668 if (!Update.isUsable()) 6669 return ExprError(); 6670 6671 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6672 VarRef.get()->getType())) { 6673 Update = SemaRef.PerformImplicitConversion( 6674 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6675 if (!Update.isUsable()) 6676 return ExprError(); 6677 } 6678 6679 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6680 } 6681 return Update; 6682 } 6683 6684 /// Convert integer expression \a E to make it have at least \a Bits 6685 /// bits. 6686 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6687 if (E == nullptr) 6688 return ExprError(); 6689 ASTContext &C = SemaRef.Context; 6690 QualType OldType = E->getType(); 6691 unsigned HasBits = C.getTypeSize(OldType); 6692 if (HasBits >= Bits) 6693 return ExprResult(E); 6694 // OK to convert to signed, because new type has more bits than old. 6695 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6696 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6697 true); 6698 } 6699 6700 /// Check if the given expression \a E is a constant integer that fits 6701 /// into \a Bits bits. 6702 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6703 if (E == nullptr) 6704 return false; 6705 llvm::APSInt Result; 6706 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6707 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6708 return false; 6709 } 6710 6711 /// Build preinits statement for the given declarations. 6712 static Stmt *buildPreInits(ASTContext &Context, 6713 MutableArrayRef<Decl *> PreInits) { 6714 if (!PreInits.empty()) { 6715 return new (Context) DeclStmt( 6716 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6717 SourceLocation(), SourceLocation()); 6718 } 6719 return nullptr; 6720 } 6721 6722 /// Build preinits statement for the given declarations. 6723 static Stmt * 6724 buildPreInits(ASTContext &Context, 6725 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6726 if (!Captures.empty()) { 6727 SmallVector<Decl *, 16> PreInits; 6728 for (const auto &Pair : Captures) 6729 PreInits.push_back(Pair.second->getDecl()); 6730 return buildPreInits(Context, PreInits); 6731 } 6732 return nullptr; 6733 } 6734 6735 /// Build postupdate expression for the given list of postupdates expressions. 6736 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6737 Expr *PostUpdate = nullptr; 6738 if (!PostUpdates.empty()) { 6739 for (Expr *E : PostUpdates) { 6740 Expr *ConvE = S.BuildCStyleCastExpr( 6741 E->getExprLoc(), 6742 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6743 E->getExprLoc(), E) 6744 .get(); 6745 PostUpdate = PostUpdate 6746 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6747 PostUpdate, ConvE) 6748 .get() 6749 : ConvE; 6750 } 6751 } 6752 return PostUpdate; 6753 } 6754 6755 /// Called on a for stmt to check itself and nested loops (if any). 6756 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6757 /// number of collapsed loops otherwise. 6758 static unsigned 6759 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6760 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6761 DSAStackTy &DSA, 6762 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6763 OMPLoopDirective::HelperExprs &Built) { 6764 unsigned NestedLoopCount = 1; 6765 if (CollapseLoopCountExpr) { 6766 // Found 'collapse' clause - calculate collapse number. 6767 Expr::EvalResult Result; 6768 if (!CollapseLoopCountExpr->isValueDependent() && 6769 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6770 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6771 } else { 6772 Built.clear(/*Size=*/1); 6773 return 1; 6774 } 6775 } 6776 unsigned OrderedLoopCount = 1; 6777 if (OrderedLoopCountExpr) { 6778 // Found 'ordered' clause - calculate collapse number. 6779 Expr::EvalResult EVResult; 6780 if (!OrderedLoopCountExpr->isValueDependent() && 6781 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6782 SemaRef.getASTContext())) { 6783 llvm::APSInt Result = EVResult.Val.getInt(); 6784 if (Result.getLimitedValue() < NestedLoopCount) { 6785 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6786 diag::err_omp_wrong_ordered_loop_count) 6787 << OrderedLoopCountExpr->getSourceRange(); 6788 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6789 diag::note_collapse_loop_count) 6790 << CollapseLoopCountExpr->getSourceRange(); 6791 } 6792 OrderedLoopCount = Result.getLimitedValue(); 6793 } else { 6794 Built.clear(/*Size=*/1); 6795 return 1; 6796 } 6797 } 6798 // This is helper routine for loop directives (e.g., 'for', 'simd', 6799 // 'for simd', etc.). 6800 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6801 SmallVector<LoopIterationSpace, 4> IterSpaces( 6802 std::max(OrderedLoopCount, NestedLoopCount)); 6803 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6804 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6805 if (checkOpenMPIterationSpace( 6806 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6807 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6808 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6809 return 0; 6810 // Move on to the next nested for loop, or to the loop body. 6811 // OpenMP [2.8.1, simd construct, Restrictions] 6812 // All loops associated with the construct must be perfectly nested; that 6813 // is, there must be no intervening code nor any OpenMP directive between 6814 // any two loops. 6815 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6816 } 6817 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6818 if (checkOpenMPIterationSpace( 6819 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6820 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6821 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6822 return 0; 6823 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6824 // Handle initialization of captured loop iterator variables. 6825 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6826 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6827 Captures[DRE] = DRE; 6828 } 6829 } 6830 // Move on to the next nested for loop, or to the loop body. 6831 // OpenMP [2.8.1, simd construct, Restrictions] 6832 // All loops associated with the construct must be perfectly nested; that 6833 // is, there must be no intervening code nor any OpenMP directive between 6834 // any two loops. 6835 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6836 } 6837 6838 Built.clear(/* size */ NestedLoopCount); 6839 6840 if (SemaRef.CurContext->isDependentContext()) 6841 return NestedLoopCount; 6842 6843 // An example of what is generated for the following code: 6844 // 6845 // #pragma omp simd collapse(2) ordered(2) 6846 // for (i = 0; i < NI; ++i) 6847 // for (k = 0; k < NK; ++k) 6848 // for (j = J0; j < NJ; j+=2) { 6849 // <loop body> 6850 // } 6851 // 6852 // We generate the code below. 6853 // Note: the loop body may be outlined in CodeGen. 6854 // Note: some counters may be C++ classes, operator- is used to find number of 6855 // iterations and operator+= to calculate counter value. 6856 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6857 // or i64 is currently supported). 6858 // 6859 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6860 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6861 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6862 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6863 // // similar updates for vars in clauses (e.g. 'linear') 6864 // <loop body (using local i and j)> 6865 // } 6866 // i = NI; // assign final values of counters 6867 // j = NJ; 6868 // 6869 6870 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6871 // the iteration counts of the collapsed for loops. 6872 // Precondition tests if there is at least one iteration (all conditions are 6873 // true). 6874 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6875 Expr *N0 = IterSpaces[0].NumIterations; 6876 ExprResult LastIteration32 = 6877 widenIterationCount(/*Bits=*/32, 6878 SemaRef 6879 .PerformImplicitConversion( 6880 N0->IgnoreImpCasts(), N0->getType(), 6881 Sema::AA_Converting, /*AllowExplicit=*/true) 6882 .get(), 6883 SemaRef); 6884 ExprResult LastIteration64 = widenIterationCount( 6885 /*Bits=*/64, 6886 SemaRef 6887 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6888 Sema::AA_Converting, 6889 /*AllowExplicit=*/true) 6890 .get(), 6891 SemaRef); 6892 6893 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6894 return NestedLoopCount; 6895 6896 ASTContext &C = SemaRef.Context; 6897 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6898 6899 Scope *CurScope = DSA.getCurScope(); 6900 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6901 if (PreCond.isUsable()) { 6902 PreCond = 6903 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6904 PreCond.get(), IterSpaces[Cnt].PreCond); 6905 } 6906 Expr *N = IterSpaces[Cnt].NumIterations; 6907 SourceLocation Loc = N->getExprLoc(); 6908 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6909 if (LastIteration32.isUsable()) 6910 LastIteration32 = SemaRef.BuildBinOp( 6911 CurScope, Loc, BO_Mul, LastIteration32.get(), 6912 SemaRef 6913 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6914 Sema::AA_Converting, 6915 /*AllowExplicit=*/true) 6916 .get()); 6917 if (LastIteration64.isUsable()) 6918 LastIteration64 = SemaRef.BuildBinOp( 6919 CurScope, Loc, BO_Mul, LastIteration64.get(), 6920 SemaRef 6921 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6922 Sema::AA_Converting, 6923 /*AllowExplicit=*/true) 6924 .get()); 6925 } 6926 6927 // Choose either the 32-bit or 64-bit version. 6928 ExprResult LastIteration = LastIteration64; 6929 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6930 (LastIteration32.isUsable() && 6931 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6932 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6933 fitsInto( 6934 /*Bits=*/32, 6935 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6936 LastIteration64.get(), SemaRef)))) 6937 LastIteration = LastIteration32; 6938 QualType VType = LastIteration.get()->getType(); 6939 QualType RealVType = VType; 6940 QualType StrideVType = VType; 6941 if (isOpenMPTaskLoopDirective(DKind)) { 6942 VType = 6943 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6944 StrideVType = 6945 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6946 } 6947 6948 if (!LastIteration.isUsable()) 6949 return 0; 6950 6951 // Save the number of iterations. 6952 ExprResult NumIterations = LastIteration; 6953 { 6954 LastIteration = SemaRef.BuildBinOp( 6955 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6956 LastIteration.get(), 6957 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6958 if (!LastIteration.isUsable()) 6959 return 0; 6960 } 6961 6962 // Calculate the last iteration number beforehand instead of doing this on 6963 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6964 llvm::APSInt Result; 6965 bool IsConstant = 6966 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6967 ExprResult CalcLastIteration; 6968 if (!IsConstant) { 6969 ExprResult SaveRef = 6970 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6971 LastIteration = SaveRef; 6972 6973 // Prepare SaveRef + 1. 6974 NumIterations = SemaRef.BuildBinOp( 6975 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6976 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6977 if (!NumIterations.isUsable()) 6978 return 0; 6979 } 6980 6981 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6982 6983 // Build variables passed into runtime, necessary for worksharing directives. 6984 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6985 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6986 isOpenMPDistributeDirective(DKind)) { 6987 // Lower bound variable, initialized with zero. 6988 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6989 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6990 SemaRef.AddInitializerToDecl(LBDecl, 6991 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6992 /*DirectInit*/ false); 6993 6994 // Upper bound variable, initialized with last iteration number. 6995 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6996 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6997 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6998 /*DirectInit*/ false); 6999 7000 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7001 // This will be used to implement clause 'lastprivate'. 7002 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7003 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7004 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7005 SemaRef.AddInitializerToDecl(ILDecl, 7006 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7007 /*DirectInit*/ false); 7008 7009 // Stride variable returned by runtime (we initialize it to 1 by default). 7010 VarDecl *STDecl = 7011 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7012 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7013 SemaRef.AddInitializerToDecl(STDecl, 7014 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7015 /*DirectInit*/ false); 7016 7017 // Build expression: UB = min(UB, LastIteration) 7018 // It is necessary for CodeGen of directives with static scheduling. 7019 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7020 UB.get(), LastIteration.get()); 7021 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7022 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7023 LastIteration.get(), UB.get()); 7024 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7025 CondOp.get()); 7026 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7027 7028 // If we have a combined directive that combines 'distribute', 'for' or 7029 // 'simd' we need to be able to access the bounds of the schedule of the 7030 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7031 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7032 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7033 // Lower bound variable, initialized with zero. 7034 VarDecl *CombLBDecl = 7035 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7036 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7037 SemaRef.AddInitializerToDecl( 7038 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7039 /*DirectInit*/ false); 7040 7041 // Upper bound variable, initialized with last iteration number. 7042 VarDecl *CombUBDecl = 7043 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7044 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7045 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7046 /*DirectInit*/ false); 7047 7048 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7049 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7050 ExprResult CombCondOp = 7051 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7052 LastIteration.get(), CombUB.get()); 7053 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7054 CombCondOp.get()); 7055 CombEUB = 7056 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7057 7058 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7059 // We expect to have at least 2 more parameters than the 'parallel' 7060 // directive does - the lower and upper bounds of the previous schedule. 7061 assert(CD->getNumParams() >= 4 && 7062 "Unexpected number of parameters in loop combined directive"); 7063 7064 // Set the proper type for the bounds given what we learned from the 7065 // enclosed loops. 7066 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7067 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7068 7069 // Previous lower and upper bounds are obtained from the region 7070 // parameters. 7071 PrevLB = 7072 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7073 PrevUB = 7074 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7075 } 7076 } 7077 7078 // Build the iteration variable and its initialization before loop. 7079 ExprResult IV; 7080 ExprResult Init, CombInit; 7081 { 7082 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7083 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7084 Expr *RHS = 7085 (isOpenMPWorksharingDirective(DKind) || 7086 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7087 ? LB.get() 7088 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7089 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7090 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7091 7092 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7093 Expr *CombRHS = 7094 (isOpenMPWorksharingDirective(DKind) || 7095 isOpenMPTaskLoopDirective(DKind) || 7096 isOpenMPDistributeDirective(DKind)) 7097 ? CombLB.get() 7098 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7099 CombInit = 7100 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7101 CombInit = 7102 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7103 } 7104 } 7105 7106 bool UseStrictCompare = 7107 RealVType->hasUnsignedIntegerRepresentation() && 7108 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7109 return LIS.IsStrictCompare; 7110 }); 7111 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7112 // unsigned IV)) for worksharing loops. 7113 SourceLocation CondLoc = AStmt->getBeginLoc(); 7114 Expr *BoundUB = UB.get(); 7115 if (UseStrictCompare) { 7116 BoundUB = 7117 SemaRef 7118 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7119 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7120 .get(); 7121 BoundUB = 7122 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7123 } 7124 ExprResult Cond = 7125 (isOpenMPWorksharingDirective(DKind) || 7126 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7127 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7128 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7129 BoundUB) 7130 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7131 NumIterations.get()); 7132 ExprResult CombDistCond; 7133 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7134 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7135 NumIterations.get()); 7136 } 7137 7138 ExprResult CombCond; 7139 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7140 Expr *BoundCombUB = CombUB.get(); 7141 if (UseStrictCompare) { 7142 BoundCombUB = 7143 SemaRef 7144 .BuildBinOp( 7145 CurScope, CondLoc, BO_Add, BoundCombUB, 7146 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7147 .get(); 7148 BoundCombUB = 7149 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7150 .get(); 7151 } 7152 CombCond = 7153 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7154 IV.get(), BoundCombUB); 7155 } 7156 // Loop increment (IV = IV + 1) 7157 SourceLocation IncLoc = AStmt->getBeginLoc(); 7158 ExprResult Inc = 7159 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7160 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7161 if (!Inc.isUsable()) 7162 return 0; 7163 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7164 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7165 if (!Inc.isUsable()) 7166 return 0; 7167 7168 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7169 // Used for directives with static scheduling. 7170 // In combined construct, add combined version that use CombLB and CombUB 7171 // base variables for the update 7172 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7173 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7174 isOpenMPDistributeDirective(DKind)) { 7175 // LB + ST 7176 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7177 if (!NextLB.isUsable()) 7178 return 0; 7179 // LB = LB + ST 7180 NextLB = 7181 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7182 NextLB = 7183 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7184 if (!NextLB.isUsable()) 7185 return 0; 7186 // UB + ST 7187 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7188 if (!NextUB.isUsable()) 7189 return 0; 7190 // UB = UB + ST 7191 NextUB = 7192 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7193 NextUB = 7194 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7195 if (!NextUB.isUsable()) 7196 return 0; 7197 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7198 CombNextLB = 7199 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7200 if (!NextLB.isUsable()) 7201 return 0; 7202 // LB = LB + ST 7203 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7204 CombNextLB.get()); 7205 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7206 /*DiscardedValue*/ false); 7207 if (!CombNextLB.isUsable()) 7208 return 0; 7209 // UB + ST 7210 CombNextUB = 7211 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7212 if (!CombNextUB.isUsable()) 7213 return 0; 7214 // UB = UB + ST 7215 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7216 CombNextUB.get()); 7217 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7218 /*DiscardedValue*/ false); 7219 if (!CombNextUB.isUsable()) 7220 return 0; 7221 } 7222 } 7223 7224 // Create increment expression for distribute loop when combined in a same 7225 // directive with for as IV = IV + ST; ensure upper bound expression based 7226 // on PrevUB instead of NumIterations - used to implement 'for' when found 7227 // in combination with 'distribute', like in 'distribute parallel for' 7228 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7229 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7230 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7231 DistCond = SemaRef.BuildBinOp( 7232 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7233 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7234 7235 DistInc = 7236 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7237 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7238 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7239 DistInc.get()); 7240 DistInc = 7241 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7242 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7243 7244 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7245 // construct 7246 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7247 ExprResult IsUBGreater = 7248 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7249 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7250 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7251 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7252 CondOp.get()); 7253 PrevEUB = 7254 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7255 7256 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7257 // parallel for is in combination with a distribute directive with 7258 // schedule(static, 1) 7259 Expr *BoundPrevUB = PrevUB.get(); 7260 if (UseStrictCompare) { 7261 BoundPrevUB = 7262 SemaRef 7263 .BuildBinOp( 7264 CurScope, CondLoc, BO_Add, BoundPrevUB, 7265 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7266 .get(); 7267 BoundPrevUB = 7268 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7269 .get(); 7270 } 7271 ParForInDistCond = 7272 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7273 IV.get(), BoundPrevUB); 7274 } 7275 7276 // Build updates and final values of the loop counters. 7277 bool HasErrors = false; 7278 Built.Counters.resize(NestedLoopCount); 7279 Built.Inits.resize(NestedLoopCount); 7280 Built.Updates.resize(NestedLoopCount); 7281 Built.Finals.resize(NestedLoopCount); 7282 Built.DependentCounters.resize(NestedLoopCount); 7283 Built.DependentInits.resize(NestedLoopCount); 7284 Built.FinalsConditions.resize(NestedLoopCount); 7285 { 7286 // We implement the following algorithm for obtaining the 7287 // original loop iteration variable values based on the 7288 // value of the collapsed loop iteration variable IV. 7289 // 7290 // Let n+1 be the number of collapsed loops in the nest. 7291 // Iteration variables (I0, I1, .... In) 7292 // Iteration counts (N0, N1, ... Nn) 7293 // 7294 // Acc = IV; 7295 // 7296 // To compute Ik for loop k, 0 <= k <= n, generate: 7297 // Prod = N(k+1) * N(k+2) * ... * Nn; 7298 // Ik = Acc / Prod; 7299 // Acc -= Ik * Prod; 7300 // 7301 ExprResult Acc = IV; 7302 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7303 LoopIterationSpace &IS = IterSpaces[Cnt]; 7304 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7305 ExprResult Iter; 7306 7307 // Compute prod 7308 ExprResult Prod = 7309 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7310 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7311 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7312 IterSpaces[K].NumIterations); 7313 7314 // Iter = Acc / Prod 7315 // If there is at least one more inner loop to avoid 7316 // multiplication by 1. 7317 if (Cnt + 1 < NestedLoopCount) 7318 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7319 Acc.get(), Prod.get()); 7320 else 7321 Iter = Acc; 7322 if (!Iter.isUsable()) { 7323 HasErrors = true; 7324 break; 7325 } 7326 7327 // Update Acc: 7328 // Acc -= Iter * Prod 7329 // Check if there is at least one more inner loop to avoid 7330 // multiplication by 1. 7331 if (Cnt + 1 < NestedLoopCount) 7332 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7333 Iter.get(), Prod.get()); 7334 else 7335 Prod = Iter; 7336 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7337 Acc.get(), Prod.get()); 7338 7339 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7340 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7341 DeclRefExpr *CounterVar = buildDeclRefExpr( 7342 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7343 /*RefersToCapture=*/true); 7344 ExprResult Init = 7345 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7346 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7347 if (!Init.isUsable()) { 7348 HasErrors = true; 7349 break; 7350 } 7351 ExprResult Update = buildCounterUpdate( 7352 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7353 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7354 if (!Update.isUsable()) { 7355 HasErrors = true; 7356 break; 7357 } 7358 7359 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7360 ExprResult Final = 7361 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7362 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7363 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7364 if (!Final.isUsable()) { 7365 HasErrors = true; 7366 break; 7367 } 7368 7369 if (!Update.isUsable() || !Final.isUsable()) { 7370 HasErrors = true; 7371 break; 7372 } 7373 // Save results 7374 Built.Counters[Cnt] = IS.CounterVar; 7375 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7376 Built.Inits[Cnt] = Init.get(); 7377 Built.Updates[Cnt] = Update.get(); 7378 Built.Finals[Cnt] = Final.get(); 7379 Built.DependentCounters[Cnt] = nullptr; 7380 Built.DependentInits[Cnt] = nullptr; 7381 Built.FinalsConditions[Cnt] = nullptr; 7382 if (IS.IsNonRectangularLB) { 7383 Built.DependentCounters[Cnt] = 7384 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7385 Built.DependentInits[Cnt] = 7386 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7387 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7388 } 7389 } 7390 } 7391 7392 if (HasErrors) 7393 return 0; 7394 7395 // Save results 7396 Built.IterationVarRef = IV.get(); 7397 Built.LastIteration = LastIteration.get(); 7398 Built.NumIterations = NumIterations.get(); 7399 Built.CalcLastIteration = SemaRef 7400 .ActOnFinishFullExpr(CalcLastIteration.get(), 7401 /*DiscardedValue=*/false) 7402 .get(); 7403 Built.PreCond = PreCond.get(); 7404 Built.PreInits = buildPreInits(C, Captures); 7405 Built.Cond = Cond.get(); 7406 Built.Init = Init.get(); 7407 Built.Inc = Inc.get(); 7408 Built.LB = LB.get(); 7409 Built.UB = UB.get(); 7410 Built.IL = IL.get(); 7411 Built.ST = ST.get(); 7412 Built.EUB = EUB.get(); 7413 Built.NLB = NextLB.get(); 7414 Built.NUB = NextUB.get(); 7415 Built.PrevLB = PrevLB.get(); 7416 Built.PrevUB = PrevUB.get(); 7417 Built.DistInc = DistInc.get(); 7418 Built.PrevEUB = PrevEUB.get(); 7419 Built.DistCombinedFields.LB = CombLB.get(); 7420 Built.DistCombinedFields.UB = CombUB.get(); 7421 Built.DistCombinedFields.EUB = CombEUB.get(); 7422 Built.DistCombinedFields.Init = CombInit.get(); 7423 Built.DistCombinedFields.Cond = CombCond.get(); 7424 Built.DistCombinedFields.NLB = CombNextLB.get(); 7425 Built.DistCombinedFields.NUB = CombNextUB.get(); 7426 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7427 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7428 7429 return NestedLoopCount; 7430 } 7431 7432 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7433 auto CollapseClauses = 7434 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7435 if (CollapseClauses.begin() != CollapseClauses.end()) 7436 return (*CollapseClauses.begin())->getNumForLoops(); 7437 return nullptr; 7438 } 7439 7440 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7441 auto OrderedClauses = 7442 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7443 if (OrderedClauses.begin() != OrderedClauses.end()) 7444 return (*OrderedClauses.begin())->getNumForLoops(); 7445 return nullptr; 7446 } 7447 7448 static bool checkSimdlenSafelenSpecified(Sema &S, 7449 const ArrayRef<OMPClause *> Clauses) { 7450 const OMPSafelenClause *Safelen = nullptr; 7451 const OMPSimdlenClause *Simdlen = nullptr; 7452 7453 for (const OMPClause *Clause : Clauses) { 7454 if (Clause->getClauseKind() == OMPC_safelen) 7455 Safelen = cast<OMPSafelenClause>(Clause); 7456 else if (Clause->getClauseKind() == OMPC_simdlen) 7457 Simdlen = cast<OMPSimdlenClause>(Clause); 7458 if (Safelen && Simdlen) 7459 break; 7460 } 7461 7462 if (Simdlen && Safelen) { 7463 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7464 const Expr *SafelenLength = Safelen->getSafelen(); 7465 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7466 SimdlenLength->isInstantiationDependent() || 7467 SimdlenLength->containsUnexpandedParameterPack()) 7468 return false; 7469 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7470 SafelenLength->isInstantiationDependent() || 7471 SafelenLength->containsUnexpandedParameterPack()) 7472 return false; 7473 Expr::EvalResult SimdlenResult, SafelenResult; 7474 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7475 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7476 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7477 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7478 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7479 // If both simdlen and safelen clauses are specified, the value of the 7480 // simdlen parameter must be less than or equal to the value of the safelen 7481 // parameter. 7482 if (SimdlenRes > SafelenRes) { 7483 S.Diag(SimdlenLength->getExprLoc(), 7484 diag::err_omp_wrong_simdlen_safelen_values) 7485 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7486 return true; 7487 } 7488 } 7489 return false; 7490 } 7491 7492 StmtResult 7493 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7494 SourceLocation StartLoc, SourceLocation EndLoc, 7495 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7496 if (!AStmt) 7497 return StmtError(); 7498 7499 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7500 OMPLoopDirective::HelperExprs B; 7501 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7502 // define the nested loops number. 7503 unsigned NestedLoopCount = checkOpenMPLoop( 7504 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7505 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7506 if (NestedLoopCount == 0) 7507 return StmtError(); 7508 7509 assert((CurContext->isDependentContext() || B.builtAll()) && 7510 "omp simd loop exprs were not built"); 7511 7512 if (!CurContext->isDependentContext()) { 7513 // Finalize the clauses that need pre-built expressions for CodeGen. 7514 for (OMPClause *C : Clauses) { 7515 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7516 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7517 B.NumIterations, *this, CurScope, 7518 DSAStack)) 7519 return StmtError(); 7520 } 7521 } 7522 7523 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7524 return StmtError(); 7525 7526 setFunctionHasBranchProtectedScope(); 7527 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7528 Clauses, AStmt, B); 7529 } 7530 7531 StmtResult 7532 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7533 SourceLocation StartLoc, SourceLocation EndLoc, 7534 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7535 if (!AStmt) 7536 return StmtError(); 7537 7538 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7539 OMPLoopDirective::HelperExprs B; 7540 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7541 // define the nested loops number. 7542 unsigned NestedLoopCount = checkOpenMPLoop( 7543 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7544 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7545 if (NestedLoopCount == 0) 7546 return StmtError(); 7547 7548 assert((CurContext->isDependentContext() || B.builtAll()) && 7549 "omp for loop exprs were not built"); 7550 7551 if (!CurContext->isDependentContext()) { 7552 // Finalize the clauses that need pre-built expressions for CodeGen. 7553 for (OMPClause *C : Clauses) { 7554 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7555 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7556 B.NumIterations, *this, CurScope, 7557 DSAStack)) 7558 return StmtError(); 7559 } 7560 } 7561 7562 setFunctionHasBranchProtectedScope(); 7563 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7564 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7565 } 7566 7567 StmtResult Sema::ActOnOpenMPForSimdDirective( 7568 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7569 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7570 if (!AStmt) 7571 return StmtError(); 7572 7573 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7574 OMPLoopDirective::HelperExprs B; 7575 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7576 // define the nested loops number. 7577 unsigned NestedLoopCount = 7578 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7579 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7580 VarsWithImplicitDSA, B); 7581 if (NestedLoopCount == 0) 7582 return StmtError(); 7583 7584 assert((CurContext->isDependentContext() || B.builtAll()) && 7585 "omp for simd loop exprs were not built"); 7586 7587 if (!CurContext->isDependentContext()) { 7588 // Finalize the clauses that need pre-built expressions for CodeGen. 7589 for (OMPClause *C : Clauses) { 7590 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7591 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7592 B.NumIterations, *this, CurScope, 7593 DSAStack)) 7594 return StmtError(); 7595 } 7596 } 7597 7598 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7599 return StmtError(); 7600 7601 setFunctionHasBranchProtectedScope(); 7602 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7603 Clauses, AStmt, B); 7604 } 7605 7606 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7607 Stmt *AStmt, 7608 SourceLocation StartLoc, 7609 SourceLocation EndLoc) { 7610 if (!AStmt) 7611 return StmtError(); 7612 7613 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7614 auto BaseStmt = AStmt; 7615 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7616 BaseStmt = CS->getCapturedStmt(); 7617 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7618 auto S = C->children(); 7619 if (S.begin() == S.end()) 7620 return StmtError(); 7621 // All associated statements must be '#pragma omp section' except for 7622 // the first one. 7623 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7624 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7625 if (SectionStmt) 7626 Diag(SectionStmt->getBeginLoc(), 7627 diag::err_omp_sections_substmt_not_section); 7628 return StmtError(); 7629 } 7630 cast<OMPSectionDirective>(SectionStmt) 7631 ->setHasCancel(DSAStack->isCancelRegion()); 7632 } 7633 } else { 7634 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7635 return StmtError(); 7636 } 7637 7638 setFunctionHasBranchProtectedScope(); 7639 7640 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7641 DSAStack->isCancelRegion()); 7642 } 7643 7644 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7645 SourceLocation StartLoc, 7646 SourceLocation EndLoc) { 7647 if (!AStmt) 7648 return StmtError(); 7649 7650 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7651 7652 setFunctionHasBranchProtectedScope(); 7653 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7654 7655 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7656 DSAStack->isCancelRegion()); 7657 } 7658 7659 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7660 Stmt *AStmt, 7661 SourceLocation StartLoc, 7662 SourceLocation EndLoc) { 7663 if (!AStmt) 7664 return StmtError(); 7665 7666 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7667 7668 setFunctionHasBranchProtectedScope(); 7669 7670 // OpenMP [2.7.3, single Construct, Restrictions] 7671 // The copyprivate clause must not be used with the nowait clause. 7672 const OMPClause *Nowait = nullptr; 7673 const OMPClause *Copyprivate = nullptr; 7674 for (const OMPClause *Clause : Clauses) { 7675 if (Clause->getClauseKind() == OMPC_nowait) 7676 Nowait = Clause; 7677 else if (Clause->getClauseKind() == OMPC_copyprivate) 7678 Copyprivate = Clause; 7679 if (Copyprivate && Nowait) { 7680 Diag(Copyprivate->getBeginLoc(), 7681 diag::err_omp_single_copyprivate_with_nowait); 7682 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7683 return StmtError(); 7684 } 7685 } 7686 7687 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7688 } 7689 7690 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7691 SourceLocation StartLoc, 7692 SourceLocation EndLoc) { 7693 if (!AStmt) 7694 return StmtError(); 7695 7696 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7697 7698 setFunctionHasBranchProtectedScope(); 7699 7700 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7701 } 7702 7703 StmtResult Sema::ActOnOpenMPCriticalDirective( 7704 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7705 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7706 if (!AStmt) 7707 return StmtError(); 7708 7709 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7710 7711 bool ErrorFound = false; 7712 llvm::APSInt Hint; 7713 SourceLocation HintLoc; 7714 bool DependentHint = false; 7715 for (const OMPClause *C : Clauses) { 7716 if (C->getClauseKind() == OMPC_hint) { 7717 if (!DirName.getName()) { 7718 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7719 ErrorFound = true; 7720 } 7721 Expr *E = cast<OMPHintClause>(C)->getHint(); 7722 if (E->isTypeDependent() || E->isValueDependent() || 7723 E->isInstantiationDependent()) { 7724 DependentHint = true; 7725 } else { 7726 Hint = E->EvaluateKnownConstInt(Context); 7727 HintLoc = C->getBeginLoc(); 7728 } 7729 } 7730 } 7731 if (ErrorFound) 7732 return StmtError(); 7733 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7734 if (Pair.first && DirName.getName() && !DependentHint) { 7735 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7736 Diag(StartLoc, diag::err_omp_critical_with_hint); 7737 if (HintLoc.isValid()) 7738 Diag(HintLoc, diag::note_omp_critical_hint_here) 7739 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7740 else 7741 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7742 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7743 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7744 << 1 7745 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7746 /*Radix=*/10, /*Signed=*/false); 7747 } else { 7748 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7749 } 7750 } 7751 } 7752 7753 setFunctionHasBranchProtectedScope(); 7754 7755 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7756 Clauses, AStmt); 7757 if (!Pair.first && DirName.getName() && !DependentHint) 7758 DSAStack->addCriticalWithHint(Dir, Hint); 7759 return Dir; 7760 } 7761 7762 StmtResult Sema::ActOnOpenMPParallelForDirective( 7763 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7764 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7765 if (!AStmt) 7766 return StmtError(); 7767 7768 auto *CS = cast<CapturedStmt>(AStmt); 7769 // 1.2.2 OpenMP Language Terminology 7770 // Structured block - An executable statement with a single entry at the 7771 // top and a single exit at the bottom. 7772 // The point of exit cannot be a branch out of the structured block. 7773 // longjmp() and throw() must not violate the entry/exit criteria. 7774 CS->getCapturedDecl()->setNothrow(); 7775 7776 OMPLoopDirective::HelperExprs B; 7777 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7778 // define the nested loops number. 7779 unsigned NestedLoopCount = 7780 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7781 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7782 VarsWithImplicitDSA, B); 7783 if (NestedLoopCount == 0) 7784 return StmtError(); 7785 7786 assert((CurContext->isDependentContext() || B.builtAll()) && 7787 "omp parallel for loop exprs were not built"); 7788 7789 if (!CurContext->isDependentContext()) { 7790 // Finalize the clauses that need pre-built expressions for CodeGen. 7791 for (OMPClause *C : Clauses) { 7792 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7793 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7794 B.NumIterations, *this, CurScope, 7795 DSAStack)) 7796 return StmtError(); 7797 } 7798 } 7799 7800 setFunctionHasBranchProtectedScope(); 7801 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7802 NestedLoopCount, Clauses, AStmt, B, 7803 DSAStack->isCancelRegion()); 7804 } 7805 7806 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7807 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7808 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7809 if (!AStmt) 7810 return StmtError(); 7811 7812 auto *CS = cast<CapturedStmt>(AStmt); 7813 // 1.2.2 OpenMP Language Terminology 7814 // Structured block - An executable statement with a single entry at the 7815 // top and a single exit at the bottom. 7816 // The point of exit cannot be a branch out of the structured block. 7817 // longjmp() and throw() must not violate the entry/exit criteria. 7818 CS->getCapturedDecl()->setNothrow(); 7819 7820 OMPLoopDirective::HelperExprs B; 7821 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7822 // define the nested loops number. 7823 unsigned NestedLoopCount = 7824 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7825 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7826 VarsWithImplicitDSA, B); 7827 if (NestedLoopCount == 0) 7828 return StmtError(); 7829 7830 if (!CurContext->isDependentContext()) { 7831 // Finalize the clauses that need pre-built expressions for CodeGen. 7832 for (OMPClause *C : Clauses) { 7833 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7834 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7835 B.NumIterations, *this, CurScope, 7836 DSAStack)) 7837 return StmtError(); 7838 } 7839 } 7840 7841 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7842 return StmtError(); 7843 7844 setFunctionHasBranchProtectedScope(); 7845 return OMPParallelForSimdDirective::Create( 7846 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7847 } 7848 7849 StmtResult 7850 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7851 Stmt *AStmt, SourceLocation StartLoc, 7852 SourceLocation EndLoc) { 7853 if (!AStmt) 7854 return StmtError(); 7855 7856 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7857 auto BaseStmt = AStmt; 7858 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7859 BaseStmt = CS->getCapturedStmt(); 7860 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7861 auto S = C->children(); 7862 if (S.begin() == S.end()) 7863 return StmtError(); 7864 // All associated statements must be '#pragma omp section' except for 7865 // the first one. 7866 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7867 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7868 if (SectionStmt) 7869 Diag(SectionStmt->getBeginLoc(), 7870 diag::err_omp_parallel_sections_substmt_not_section); 7871 return StmtError(); 7872 } 7873 cast<OMPSectionDirective>(SectionStmt) 7874 ->setHasCancel(DSAStack->isCancelRegion()); 7875 } 7876 } else { 7877 Diag(AStmt->getBeginLoc(), 7878 diag::err_omp_parallel_sections_not_compound_stmt); 7879 return StmtError(); 7880 } 7881 7882 setFunctionHasBranchProtectedScope(); 7883 7884 return OMPParallelSectionsDirective::Create( 7885 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7886 } 7887 7888 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7889 Stmt *AStmt, SourceLocation StartLoc, 7890 SourceLocation EndLoc) { 7891 if (!AStmt) 7892 return StmtError(); 7893 7894 auto *CS = cast<CapturedStmt>(AStmt); 7895 // 1.2.2 OpenMP Language Terminology 7896 // Structured block - An executable statement with a single entry at the 7897 // top and a single exit at the bottom. 7898 // The point of exit cannot be a branch out of the structured block. 7899 // longjmp() and throw() must not violate the entry/exit criteria. 7900 CS->getCapturedDecl()->setNothrow(); 7901 7902 setFunctionHasBranchProtectedScope(); 7903 7904 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7905 DSAStack->isCancelRegion()); 7906 } 7907 7908 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7909 SourceLocation EndLoc) { 7910 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7911 } 7912 7913 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7914 SourceLocation EndLoc) { 7915 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7916 } 7917 7918 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7919 SourceLocation EndLoc) { 7920 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7921 } 7922 7923 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7924 Stmt *AStmt, 7925 SourceLocation StartLoc, 7926 SourceLocation EndLoc) { 7927 if (!AStmt) 7928 return StmtError(); 7929 7930 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7931 7932 setFunctionHasBranchProtectedScope(); 7933 7934 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7935 AStmt, 7936 DSAStack->getTaskgroupReductionRef()); 7937 } 7938 7939 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7940 SourceLocation StartLoc, 7941 SourceLocation EndLoc) { 7942 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7943 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7944 } 7945 7946 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7947 Stmt *AStmt, 7948 SourceLocation StartLoc, 7949 SourceLocation EndLoc) { 7950 const OMPClause *DependFound = nullptr; 7951 const OMPClause *DependSourceClause = nullptr; 7952 const OMPClause *DependSinkClause = nullptr; 7953 bool ErrorFound = false; 7954 const OMPThreadsClause *TC = nullptr; 7955 const OMPSIMDClause *SC = nullptr; 7956 for (const OMPClause *C : Clauses) { 7957 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7958 DependFound = C; 7959 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7960 if (DependSourceClause) { 7961 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7962 << getOpenMPDirectiveName(OMPD_ordered) 7963 << getOpenMPClauseName(OMPC_depend) << 2; 7964 ErrorFound = true; 7965 } else { 7966 DependSourceClause = C; 7967 } 7968 if (DependSinkClause) { 7969 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7970 << 0; 7971 ErrorFound = true; 7972 } 7973 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7974 if (DependSourceClause) { 7975 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7976 << 1; 7977 ErrorFound = true; 7978 } 7979 DependSinkClause = C; 7980 } 7981 } else if (C->getClauseKind() == OMPC_threads) { 7982 TC = cast<OMPThreadsClause>(C); 7983 } else if (C->getClauseKind() == OMPC_simd) { 7984 SC = cast<OMPSIMDClause>(C); 7985 } 7986 } 7987 if (!ErrorFound && !SC && 7988 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7989 // OpenMP [2.8.1,simd Construct, Restrictions] 7990 // An ordered construct with the simd clause is the only OpenMP construct 7991 // that can appear in the simd region. 7992 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7993 ErrorFound = true; 7994 } else if (DependFound && (TC || SC)) { 7995 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7996 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7997 ErrorFound = true; 7998 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7999 Diag(DependFound->getBeginLoc(), 8000 diag::err_omp_ordered_directive_without_param); 8001 ErrorFound = true; 8002 } else if (TC || Clauses.empty()) { 8003 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8004 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8005 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8006 << (TC != nullptr); 8007 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8008 ErrorFound = true; 8009 } 8010 } 8011 if ((!AStmt && !DependFound) || ErrorFound) 8012 return StmtError(); 8013 8014 if (AStmt) { 8015 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8016 8017 setFunctionHasBranchProtectedScope(); 8018 } 8019 8020 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8021 } 8022 8023 namespace { 8024 /// Helper class for checking expression in 'omp atomic [update]' 8025 /// construct. 8026 class OpenMPAtomicUpdateChecker { 8027 /// Error results for atomic update expressions. 8028 enum ExprAnalysisErrorCode { 8029 /// A statement is not an expression statement. 8030 NotAnExpression, 8031 /// Expression is not builtin binary or unary operation. 8032 NotABinaryOrUnaryExpression, 8033 /// Unary operation is not post-/pre- increment/decrement operation. 8034 NotAnUnaryIncDecExpression, 8035 /// An expression is not of scalar type. 8036 NotAScalarType, 8037 /// A binary operation is not an assignment operation. 8038 NotAnAssignmentOp, 8039 /// RHS part of the binary operation is not a binary expression. 8040 NotABinaryExpression, 8041 /// RHS part is not additive/multiplicative/shift/biwise binary 8042 /// expression. 8043 NotABinaryOperator, 8044 /// RHS binary operation does not have reference to the updated LHS 8045 /// part. 8046 NotAnUpdateExpression, 8047 /// No errors is found. 8048 NoError 8049 }; 8050 /// Reference to Sema. 8051 Sema &SemaRef; 8052 /// A location for note diagnostics (when error is found). 8053 SourceLocation NoteLoc; 8054 /// 'x' lvalue part of the source atomic expression. 8055 Expr *X; 8056 /// 'expr' rvalue part of the source atomic expression. 8057 Expr *E; 8058 /// Helper expression of the form 8059 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8060 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8061 Expr *UpdateExpr; 8062 /// Is 'x' a LHS in a RHS part of full update expression. It is 8063 /// important for non-associative operations. 8064 bool IsXLHSInRHSPart; 8065 BinaryOperatorKind Op; 8066 SourceLocation OpLoc; 8067 /// true if the source expression is a postfix unary operation, false 8068 /// if it is a prefix unary operation. 8069 bool IsPostfixUpdate; 8070 8071 public: 8072 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8073 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8074 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8075 /// Check specified statement that it is suitable for 'atomic update' 8076 /// constructs and extract 'x', 'expr' and Operation from the original 8077 /// expression. If DiagId and NoteId == 0, then only check is performed 8078 /// without error notification. 8079 /// \param DiagId Diagnostic which should be emitted if error is found. 8080 /// \param NoteId Diagnostic note for the main error message. 8081 /// \return true if statement is not an update expression, false otherwise. 8082 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8083 /// Return the 'x' lvalue part of the source atomic expression. 8084 Expr *getX() const { return X; } 8085 /// Return the 'expr' rvalue part of the source atomic expression. 8086 Expr *getExpr() const { return E; } 8087 /// Return the update expression used in calculation of the updated 8088 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8089 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8090 Expr *getUpdateExpr() const { return UpdateExpr; } 8091 /// Return true if 'x' is LHS in RHS part of full update expression, 8092 /// false otherwise. 8093 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8094 8095 /// true if the source expression is a postfix unary operation, false 8096 /// if it is a prefix unary operation. 8097 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8098 8099 private: 8100 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8101 unsigned NoteId = 0); 8102 }; 8103 } // namespace 8104 8105 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8106 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8107 ExprAnalysisErrorCode ErrorFound = NoError; 8108 SourceLocation ErrorLoc, NoteLoc; 8109 SourceRange ErrorRange, NoteRange; 8110 // Allowed constructs are: 8111 // x = x binop expr; 8112 // x = expr binop x; 8113 if (AtomicBinOp->getOpcode() == BO_Assign) { 8114 X = AtomicBinOp->getLHS(); 8115 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8116 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8117 if (AtomicInnerBinOp->isMultiplicativeOp() || 8118 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8119 AtomicInnerBinOp->isBitwiseOp()) { 8120 Op = AtomicInnerBinOp->getOpcode(); 8121 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8122 Expr *LHS = AtomicInnerBinOp->getLHS(); 8123 Expr *RHS = AtomicInnerBinOp->getRHS(); 8124 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8125 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8126 /*Canonical=*/true); 8127 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8128 /*Canonical=*/true); 8129 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8130 /*Canonical=*/true); 8131 if (XId == LHSId) { 8132 E = RHS; 8133 IsXLHSInRHSPart = true; 8134 } else if (XId == RHSId) { 8135 E = LHS; 8136 IsXLHSInRHSPart = false; 8137 } else { 8138 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8139 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8140 NoteLoc = X->getExprLoc(); 8141 NoteRange = X->getSourceRange(); 8142 ErrorFound = NotAnUpdateExpression; 8143 } 8144 } else { 8145 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8146 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8147 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8148 NoteRange = SourceRange(NoteLoc, NoteLoc); 8149 ErrorFound = NotABinaryOperator; 8150 } 8151 } else { 8152 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8153 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8154 ErrorFound = NotABinaryExpression; 8155 } 8156 } else { 8157 ErrorLoc = AtomicBinOp->getExprLoc(); 8158 ErrorRange = AtomicBinOp->getSourceRange(); 8159 NoteLoc = AtomicBinOp->getOperatorLoc(); 8160 NoteRange = SourceRange(NoteLoc, NoteLoc); 8161 ErrorFound = NotAnAssignmentOp; 8162 } 8163 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8164 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8165 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8166 return true; 8167 } 8168 if (SemaRef.CurContext->isDependentContext()) 8169 E = X = UpdateExpr = nullptr; 8170 return ErrorFound != NoError; 8171 } 8172 8173 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8174 unsigned NoteId) { 8175 ExprAnalysisErrorCode ErrorFound = NoError; 8176 SourceLocation ErrorLoc, NoteLoc; 8177 SourceRange ErrorRange, NoteRange; 8178 // Allowed constructs are: 8179 // x++; 8180 // x--; 8181 // ++x; 8182 // --x; 8183 // x binop= expr; 8184 // x = x binop expr; 8185 // x = expr binop x; 8186 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8187 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8188 if (AtomicBody->getType()->isScalarType() || 8189 AtomicBody->isInstantiationDependent()) { 8190 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8191 AtomicBody->IgnoreParenImpCasts())) { 8192 // Check for Compound Assignment Operation 8193 Op = BinaryOperator::getOpForCompoundAssignment( 8194 AtomicCompAssignOp->getOpcode()); 8195 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8196 E = AtomicCompAssignOp->getRHS(); 8197 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8198 IsXLHSInRHSPart = true; 8199 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8200 AtomicBody->IgnoreParenImpCasts())) { 8201 // Check for Binary Operation 8202 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8203 return true; 8204 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8205 AtomicBody->IgnoreParenImpCasts())) { 8206 // Check for Unary Operation 8207 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8208 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8209 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8210 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8211 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8212 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8213 IsXLHSInRHSPart = true; 8214 } else { 8215 ErrorFound = NotAnUnaryIncDecExpression; 8216 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8217 ErrorRange = AtomicUnaryOp->getSourceRange(); 8218 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8219 NoteRange = SourceRange(NoteLoc, NoteLoc); 8220 } 8221 } else if (!AtomicBody->isInstantiationDependent()) { 8222 ErrorFound = NotABinaryOrUnaryExpression; 8223 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8224 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8225 } 8226 } else { 8227 ErrorFound = NotAScalarType; 8228 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8229 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8230 } 8231 } else { 8232 ErrorFound = NotAnExpression; 8233 NoteLoc = ErrorLoc = S->getBeginLoc(); 8234 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8235 } 8236 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8237 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8238 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8239 return true; 8240 } 8241 if (SemaRef.CurContext->isDependentContext()) 8242 E = X = UpdateExpr = nullptr; 8243 if (ErrorFound == NoError && E && X) { 8244 // Build an update expression of form 'OpaqueValueExpr(x) binop 8245 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8246 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8247 auto *OVEX = new (SemaRef.getASTContext()) 8248 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8249 auto *OVEExpr = new (SemaRef.getASTContext()) 8250 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8251 ExprResult Update = 8252 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8253 IsXLHSInRHSPart ? OVEExpr : OVEX); 8254 if (Update.isInvalid()) 8255 return true; 8256 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8257 Sema::AA_Casting); 8258 if (Update.isInvalid()) 8259 return true; 8260 UpdateExpr = Update.get(); 8261 } 8262 return ErrorFound != NoError; 8263 } 8264 8265 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8266 Stmt *AStmt, 8267 SourceLocation StartLoc, 8268 SourceLocation EndLoc) { 8269 if (!AStmt) 8270 return StmtError(); 8271 8272 auto *CS = cast<CapturedStmt>(AStmt); 8273 // 1.2.2 OpenMP Language Terminology 8274 // Structured block - An executable statement with a single entry at the 8275 // top and a single exit at the bottom. 8276 // The point of exit cannot be a branch out of the structured block. 8277 // longjmp() and throw() must not violate the entry/exit criteria. 8278 OpenMPClauseKind AtomicKind = OMPC_unknown; 8279 SourceLocation AtomicKindLoc; 8280 for (const OMPClause *C : Clauses) { 8281 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8282 C->getClauseKind() == OMPC_update || 8283 C->getClauseKind() == OMPC_capture) { 8284 if (AtomicKind != OMPC_unknown) { 8285 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8286 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8287 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8288 << getOpenMPClauseName(AtomicKind); 8289 } else { 8290 AtomicKind = C->getClauseKind(); 8291 AtomicKindLoc = C->getBeginLoc(); 8292 } 8293 } 8294 } 8295 8296 Stmt *Body = CS->getCapturedStmt(); 8297 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8298 Body = EWC->getSubExpr(); 8299 8300 Expr *X = nullptr; 8301 Expr *V = nullptr; 8302 Expr *E = nullptr; 8303 Expr *UE = nullptr; 8304 bool IsXLHSInRHSPart = false; 8305 bool IsPostfixUpdate = false; 8306 // OpenMP [2.12.6, atomic Construct] 8307 // In the next expressions: 8308 // * x and v (as applicable) are both l-value expressions with scalar type. 8309 // * During the execution of an atomic region, multiple syntactic 8310 // occurrences of x must designate the same storage location. 8311 // * Neither of v and expr (as applicable) may access the storage location 8312 // designated by x. 8313 // * Neither of x and expr (as applicable) may access the storage location 8314 // designated by v. 8315 // * expr is an expression with scalar type. 8316 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8317 // * binop, binop=, ++, and -- are not overloaded operators. 8318 // * The expression x binop expr must be numerically equivalent to x binop 8319 // (expr). This requirement is satisfied if the operators in expr have 8320 // precedence greater than binop, or by using parentheses around expr or 8321 // subexpressions of expr. 8322 // * The expression expr binop x must be numerically equivalent to (expr) 8323 // binop x. This requirement is satisfied if the operators in expr have 8324 // precedence equal to or greater than binop, or by using parentheses around 8325 // expr or subexpressions of expr. 8326 // * For forms that allow multiple occurrences of x, the number of times 8327 // that x is evaluated is unspecified. 8328 if (AtomicKind == OMPC_read) { 8329 enum { 8330 NotAnExpression, 8331 NotAnAssignmentOp, 8332 NotAScalarType, 8333 NotAnLValue, 8334 NoError 8335 } ErrorFound = NoError; 8336 SourceLocation ErrorLoc, NoteLoc; 8337 SourceRange ErrorRange, NoteRange; 8338 // If clause is read: 8339 // v = x; 8340 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8341 const auto *AtomicBinOp = 8342 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8343 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8344 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8345 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8346 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8347 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8348 if (!X->isLValue() || !V->isLValue()) { 8349 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8350 ErrorFound = NotAnLValue; 8351 ErrorLoc = AtomicBinOp->getExprLoc(); 8352 ErrorRange = AtomicBinOp->getSourceRange(); 8353 NoteLoc = NotLValueExpr->getExprLoc(); 8354 NoteRange = NotLValueExpr->getSourceRange(); 8355 } 8356 } else if (!X->isInstantiationDependent() || 8357 !V->isInstantiationDependent()) { 8358 const Expr *NotScalarExpr = 8359 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8360 ? V 8361 : X; 8362 ErrorFound = NotAScalarType; 8363 ErrorLoc = AtomicBinOp->getExprLoc(); 8364 ErrorRange = AtomicBinOp->getSourceRange(); 8365 NoteLoc = NotScalarExpr->getExprLoc(); 8366 NoteRange = NotScalarExpr->getSourceRange(); 8367 } 8368 } else if (!AtomicBody->isInstantiationDependent()) { 8369 ErrorFound = NotAnAssignmentOp; 8370 ErrorLoc = AtomicBody->getExprLoc(); 8371 ErrorRange = AtomicBody->getSourceRange(); 8372 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8373 : AtomicBody->getExprLoc(); 8374 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8375 : AtomicBody->getSourceRange(); 8376 } 8377 } else { 8378 ErrorFound = NotAnExpression; 8379 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8380 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8381 } 8382 if (ErrorFound != NoError) { 8383 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8384 << ErrorRange; 8385 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8386 << NoteRange; 8387 return StmtError(); 8388 } 8389 if (CurContext->isDependentContext()) 8390 V = X = nullptr; 8391 } else if (AtomicKind == OMPC_write) { 8392 enum { 8393 NotAnExpression, 8394 NotAnAssignmentOp, 8395 NotAScalarType, 8396 NotAnLValue, 8397 NoError 8398 } ErrorFound = NoError; 8399 SourceLocation ErrorLoc, NoteLoc; 8400 SourceRange ErrorRange, NoteRange; 8401 // If clause is write: 8402 // x = expr; 8403 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8404 const auto *AtomicBinOp = 8405 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8406 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8407 X = AtomicBinOp->getLHS(); 8408 E = AtomicBinOp->getRHS(); 8409 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8410 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8411 if (!X->isLValue()) { 8412 ErrorFound = NotAnLValue; 8413 ErrorLoc = AtomicBinOp->getExprLoc(); 8414 ErrorRange = AtomicBinOp->getSourceRange(); 8415 NoteLoc = X->getExprLoc(); 8416 NoteRange = X->getSourceRange(); 8417 } 8418 } else if (!X->isInstantiationDependent() || 8419 !E->isInstantiationDependent()) { 8420 const Expr *NotScalarExpr = 8421 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8422 ? E 8423 : X; 8424 ErrorFound = NotAScalarType; 8425 ErrorLoc = AtomicBinOp->getExprLoc(); 8426 ErrorRange = AtomicBinOp->getSourceRange(); 8427 NoteLoc = NotScalarExpr->getExprLoc(); 8428 NoteRange = NotScalarExpr->getSourceRange(); 8429 } 8430 } else if (!AtomicBody->isInstantiationDependent()) { 8431 ErrorFound = NotAnAssignmentOp; 8432 ErrorLoc = AtomicBody->getExprLoc(); 8433 ErrorRange = AtomicBody->getSourceRange(); 8434 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8435 : AtomicBody->getExprLoc(); 8436 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8437 : AtomicBody->getSourceRange(); 8438 } 8439 } else { 8440 ErrorFound = NotAnExpression; 8441 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8442 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8443 } 8444 if (ErrorFound != NoError) { 8445 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8446 << ErrorRange; 8447 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8448 << NoteRange; 8449 return StmtError(); 8450 } 8451 if (CurContext->isDependentContext()) 8452 E = X = nullptr; 8453 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8454 // If clause is update: 8455 // x++; 8456 // x--; 8457 // ++x; 8458 // --x; 8459 // x binop= expr; 8460 // x = x binop expr; 8461 // x = expr binop x; 8462 OpenMPAtomicUpdateChecker Checker(*this); 8463 if (Checker.checkStatement( 8464 Body, (AtomicKind == OMPC_update) 8465 ? diag::err_omp_atomic_update_not_expression_statement 8466 : diag::err_omp_atomic_not_expression_statement, 8467 diag::note_omp_atomic_update)) 8468 return StmtError(); 8469 if (!CurContext->isDependentContext()) { 8470 E = Checker.getExpr(); 8471 X = Checker.getX(); 8472 UE = Checker.getUpdateExpr(); 8473 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8474 } 8475 } else if (AtomicKind == OMPC_capture) { 8476 enum { 8477 NotAnAssignmentOp, 8478 NotACompoundStatement, 8479 NotTwoSubstatements, 8480 NotASpecificExpression, 8481 NoError 8482 } ErrorFound = NoError; 8483 SourceLocation ErrorLoc, NoteLoc; 8484 SourceRange ErrorRange, NoteRange; 8485 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8486 // If clause is a capture: 8487 // v = x++; 8488 // v = x--; 8489 // v = ++x; 8490 // v = --x; 8491 // v = x binop= expr; 8492 // v = x = x binop expr; 8493 // v = x = expr binop x; 8494 const auto *AtomicBinOp = 8495 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8496 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8497 V = AtomicBinOp->getLHS(); 8498 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8499 OpenMPAtomicUpdateChecker Checker(*this); 8500 if (Checker.checkStatement( 8501 Body, diag::err_omp_atomic_capture_not_expression_statement, 8502 diag::note_omp_atomic_update)) 8503 return StmtError(); 8504 E = Checker.getExpr(); 8505 X = Checker.getX(); 8506 UE = Checker.getUpdateExpr(); 8507 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8508 IsPostfixUpdate = Checker.isPostfixUpdate(); 8509 } else if (!AtomicBody->isInstantiationDependent()) { 8510 ErrorLoc = AtomicBody->getExprLoc(); 8511 ErrorRange = AtomicBody->getSourceRange(); 8512 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8513 : AtomicBody->getExprLoc(); 8514 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8515 : AtomicBody->getSourceRange(); 8516 ErrorFound = NotAnAssignmentOp; 8517 } 8518 if (ErrorFound != NoError) { 8519 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8520 << ErrorRange; 8521 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8522 return StmtError(); 8523 } 8524 if (CurContext->isDependentContext()) 8525 UE = V = E = X = nullptr; 8526 } else { 8527 // If clause is a capture: 8528 // { v = x; x = expr; } 8529 // { v = x; x++; } 8530 // { v = x; x--; } 8531 // { v = x; ++x; } 8532 // { v = x; --x; } 8533 // { v = x; x binop= expr; } 8534 // { v = x; x = x binop expr; } 8535 // { v = x; x = expr binop x; } 8536 // { x++; v = x; } 8537 // { x--; v = x; } 8538 // { ++x; v = x; } 8539 // { --x; v = x; } 8540 // { x binop= expr; v = x; } 8541 // { x = x binop expr; v = x; } 8542 // { x = expr binop x; v = x; } 8543 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8544 // Check that this is { expr1; expr2; } 8545 if (CS->size() == 2) { 8546 Stmt *First = CS->body_front(); 8547 Stmt *Second = CS->body_back(); 8548 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8549 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8550 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8551 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8552 // Need to find what subexpression is 'v' and what is 'x'. 8553 OpenMPAtomicUpdateChecker Checker(*this); 8554 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8555 BinaryOperator *BinOp = nullptr; 8556 if (IsUpdateExprFound) { 8557 BinOp = dyn_cast<BinaryOperator>(First); 8558 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8559 } 8560 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8561 // { v = x; x++; } 8562 // { v = x; x--; } 8563 // { v = x; ++x; } 8564 // { v = x; --x; } 8565 // { v = x; x binop= expr; } 8566 // { v = x; x = x binop expr; } 8567 // { v = x; x = expr binop x; } 8568 // Check that the first expression has form v = x. 8569 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8570 llvm::FoldingSetNodeID XId, PossibleXId; 8571 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8572 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8573 IsUpdateExprFound = XId == PossibleXId; 8574 if (IsUpdateExprFound) { 8575 V = BinOp->getLHS(); 8576 X = Checker.getX(); 8577 E = Checker.getExpr(); 8578 UE = Checker.getUpdateExpr(); 8579 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8580 IsPostfixUpdate = true; 8581 } 8582 } 8583 if (!IsUpdateExprFound) { 8584 IsUpdateExprFound = !Checker.checkStatement(First); 8585 BinOp = nullptr; 8586 if (IsUpdateExprFound) { 8587 BinOp = dyn_cast<BinaryOperator>(Second); 8588 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8589 } 8590 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8591 // { x++; v = x; } 8592 // { x--; v = x; } 8593 // { ++x; v = x; } 8594 // { --x; v = x; } 8595 // { x binop= expr; v = x; } 8596 // { x = x binop expr; v = x; } 8597 // { x = expr binop x; v = x; } 8598 // Check that the second expression has form v = x. 8599 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8600 llvm::FoldingSetNodeID XId, PossibleXId; 8601 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8602 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8603 IsUpdateExprFound = XId == PossibleXId; 8604 if (IsUpdateExprFound) { 8605 V = BinOp->getLHS(); 8606 X = Checker.getX(); 8607 E = Checker.getExpr(); 8608 UE = Checker.getUpdateExpr(); 8609 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8610 IsPostfixUpdate = false; 8611 } 8612 } 8613 } 8614 if (!IsUpdateExprFound) { 8615 // { v = x; x = expr; } 8616 auto *FirstExpr = dyn_cast<Expr>(First); 8617 auto *SecondExpr = dyn_cast<Expr>(Second); 8618 if (!FirstExpr || !SecondExpr || 8619 !(FirstExpr->isInstantiationDependent() || 8620 SecondExpr->isInstantiationDependent())) { 8621 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8622 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8623 ErrorFound = NotAnAssignmentOp; 8624 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8625 : First->getBeginLoc(); 8626 NoteRange = ErrorRange = FirstBinOp 8627 ? FirstBinOp->getSourceRange() 8628 : SourceRange(ErrorLoc, ErrorLoc); 8629 } else { 8630 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8631 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8632 ErrorFound = NotAnAssignmentOp; 8633 NoteLoc = ErrorLoc = SecondBinOp 8634 ? SecondBinOp->getOperatorLoc() 8635 : Second->getBeginLoc(); 8636 NoteRange = ErrorRange = 8637 SecondBinOp ? SecondBinOp->getSourceRange() 8638 : SourceRange(ErrorLoc, ErrorLoc); 8639 } else { 8640 Expr *PossibleXRHSInFirst = 8641 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8642 Expr *PossibleXLHSInSecond = 8643 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8644 llvm::FoldingSetNodeID X1Id, X2Id; 8645 PossibleXRHSInFirst->Profile(X1Id, Context, 8646 /*Canonical=*/true); 8647 PossibleXLHSInSecond->Profile(X2Id, Context, 8648 /*Canonical=*/true); 8649 IsUpdateExprFound = X1Id == X2Id; 8650 if (IsUpdateExprFound) { 8651 V = FirstBinOp->getLHS(); 8652 X = SecondBinOp->getLHS(); 8653 E = SecondBinOp->getRHS(); 8654 UE = nullptr; 8655 IsXLHSInRHSPart = false; 8656 IsPostfixUpdate = true; 8657 } else { 8658 ErrorFound = NotASpecificExpression; 8659 ErrorLoc = FirstBinOp->getExprLoc(); 8660 ErrorRange = FirstBinOp->getSourceRange(); 8661 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8662 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8663 } 8664 } 8665 } 8666 } 8667 } 8668 } else { 8669 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8670 NoteRange = ErrorRange = 8671 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8672 ErrorFound = NotTwoSubstatements; 8673 } 8674 } else { 8675 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8676 NoteRange = ErrorRange = 8677 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8678 ErrorFound = NotACompoundStatement; 8679 } 8680 if (ErrorFound != NoError) { 8681 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8682 << ErrorRange; 8683 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8684 return StmtError(); 8685 } 8686 if (CurContext->isDependentContext()) 8687 UE = V = E = X = nullptr; 8688 } 8689 } 8690 8691 setFunctionHasBranchProtectedScope(); 8692 8693 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8694 X, V, E, UE, IsXLHSInRHSPart, 8695 IsPostfixUpdate); 8696 } 8697 8698 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8699 Stmt *AStmt, 8700 SourceLocation StartLoc, 8701 SourceLocation EndLoc) { 8702 if (!AStmt) 8703 return StmtError(); 8704 8705 auto *CS = cast<CapturedStmt>(AStmt); 8706 // 1.2.2 OpenMP Language Terminology 8707 // Structured block - An executable statement with a single entry at the 8708 // top and a single exit at the bottom. 8709 // The point of exit cannot be a branch out of the structured block. 8710 // longjmp() and throw() must not violate the entry/exit criteria. 8711 CS->getCapturedDecl()->setNothrow(); 8712 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8713 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8714 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8715 // 1.2.2 OpenMP Language Terminology 8716 // Structured block - An executable statement with a single entry at the 8717 // top and a single exit at the bottom. 8718 // The point of exit cannot be a branch out of the structured block. 8719 // longjmp() and throw() must not violate the entry/exit criteria. 8720 CS->getCapturedDecl()->setNothrow(); 8721 } 8722 8723 // OpenMP [2.16, Nesting of Regions] 8724 // If specified, a teams construct must be contained within a target 8725 // construct. That target construct must contain no statements or directives 8726 // outside of the teams construct. 8727 if (DSAStack->hasInnerTeamsRegion()) { 8728 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8729 bool OMPTeamsFound = true; 8730 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8731 auto I = CS->body_begin(); 8732 while (I != CS->body_end()) { 8733 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8734 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8735 OMPTeamsFound) { 8736 8737 OMPTeamsFound = false; 8738 break; 8739 } 8740 ++I; 8741 } 8742 assert(I != CS->body_end() && "Not found statement"); 8743 S = *I; 8744 } else { 8745 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8746 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8747 } 8748 if (!OMPTeamsFound) { 8749 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8750 Diag(DSAStack->getInnerTeamsRegionLoc(), 8751 diag::note_omp_nested_teams_construct_here); 8752 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8753 << isa<OMPExecutableDirective>(S); 8754 return StmtError(); 8755 } 8756 } 8757 8758 setFunctionHasBranchProtectedScope(); 8759 8760 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8761 } 8762 8763 StmtResult 8764 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8765 Stmt *AStmt, SourceLocation StartLoc, 8766 SourceLocation EndLoc) { 8767 if (!AStmt) 8768 return StmtError(); 8769 8770 auto *CS = cast<CapturedStmt>(AStmt); 8771 // 1.2.2 OpenMP Language Terminology 8772 // Structured block - An executable statement with a single entry at the 8773 // top and a single exit at the bottom. 8774 // The point of exit cannot be a branch out of the structured block. 8775 // longjmp() and throw() must not violate the entry/exit criteria. 8776 CS->getCapturedDecl()->setNothrow(); 8777 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8778 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8779 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8780 // 1.2.2 OpenMP Language Terminology 8781 // Structured block - An executable statement with a single entry at the 8782 // top and a single exit at the bottom. 8783 // The point of exit cannot be a branch out of the structured block. 8784 // longjmp() and throw() must not violate the entry/exit criteria. 8785 CS->getCapturedDecl()->setNothrow(); 8786 } 8787 8788 setFunctionHasBranchProtectedScope(); 8789 8790 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8791 AStmt); 8792 } 8793 8794 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8795 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8796 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8797 if (!AStmt) 8798 return StmtError(); 8799 8800 auto *CS = cast<CapturedStmt>(AStmt); 8801 // 1.2.2 OpenMP Language Terminology 8802 // Structured block - An executable statement with a single entry at the 8803 // top and a single exit at the bottom. 8804 // The point of exit cannot be a branch out of the structured block. 8805 // longjmp() and throw() must not violate the entry/exit criteria. 8806 CS->getCapturedDecl()->setNothrow(); 8807 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8808 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8809 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8810 // 1.2.2 OpenMP Language Terminology 8811 // Structured block - An executable statement with a single entry at the 8812 // top and a single exit at the bottom. 8813 // The point of exit cannot be a branch out of the structured block. 8814 // longjmp() and throw() must not violate the entry/exit criteria. 8815 CS->getCapturedDecl()->setNothrow(); 8816 } 8817 8818 OMPLoopDirective::HelperExprs B; 8819 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8820 // define the nested loops number. 8821 unsigned NestedLoopCount = 8822 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8823 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8824 VarsWithImplicitDSA, B); 8825 if (NestedLoopCount == 0) 8826 return StmtError(); 8827 8828 assert((CurContext->isDependentContext() || B.builtAll()) && 8829 "omp target parallel for loop exprs were not built"); 8830 8831 if (!CurContext->isDependentContext()) { 8832 // Finalize the clauses that need pre-built expressions for CodeGen. 8833 for (OMPClause *C : Clauses) { 8834 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8835 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8836 B.NumIterations, *this, CurScope, 8837 DSAStack)) 8838 return StmtError(); 8839 } 8840 } 8841 8842 setFunctionHasBranchProtectedScope(); 8843 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8844 NestedLoopCount, Clauses, AStmt, 8845 B, DSAStack->isCancelRegion()); 8846 } 8847 8848 /// Check for existence of a map clause in the list of clauses. 8849 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8850 const OpenMPClauseKind K) { 8851 return llvm::any_of( 8852 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8853 } 8854 8855 template <typename... Params> 8856 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8857 const Params... ClauseTypes) { 8858 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8859 } 8860 8861 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8862 Stmt *AStmt, 8863 SourceLocation StartLoc, 8864 SourceLocation EndLoc) { 8865 if (!AStmt) 8866 return StmtError(); 8867 8868 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8869 8870 // OpenMP [2.10.1, Restrictions, p. 97] 8871 // At least one map clause must appear on the directive. 8872 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8873 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8874 << "'map' or 'use_device_ptr'" 8875 << getOpenMPDirectiveName(OMPD_target_data); 8876 return StmtError(); 8877 } 8878 8879 setFunctionHasBranchProtectedScope(); 8880 8881 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8882 AStmt); 8883 } 8884 8885 StmtResult 8886 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8887 SourceLocation StartLoc, 8888 SourceLocation EndLoc, Stmt *AStmt) { 8889 if (!AStmt) 8890 return StmtError(); 8891 8892 auto *CS = cast<CapturedStmt>(AStmt); 8893 // 1.2.2 OpenMP Language Terminology 8894 // Structured block - An executable statement with a single entry at the 8895 // top and a single exit at the bottom. 8896 // The point of exit cannot be a branch out of the structured block. 8897 // longjmp() and throw() must not violate the entry/exit criteria. 8898 CS->getCapturedDecl()->setNothrow(); 8899 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8900 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8901 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8902 // 1.2.2 OpenMP Language Terminology 8903 // Structured block - An executable statement with a single entry at the 8904 // top and a single exit at the bottom. 8905 // The point of exit cannot be a branch out of the structured block. 8906 // longjmp() and throw() must not violate the entry/exit criteria. 8907 CS->getCapturedDecl()->setNothrow(); 8908 } 8909 8910 // OpenMP [2.10.2, Restrictions, p. 99] 8911 // At least one map clause must appear on the directive. 8912 if (!hasClauses(Clauses, OMPC_map)) { 8913 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8914 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8915 return StmtError(); 8916 } 8917 8918 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8919 AStmt); 8920 } 8921 8922 StmtResult 8923 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8924 SourceLocation StartLoc, 8925 SourceLocation EndLoc, Stmt *AStmt) { 8926 if (!AStmt) 8927 return StmtError(); 8928 8929 auto *CS = cast<CapturedStmt>(AStmt); 8930 // 1.2.2 OpenMP Language Terminology 8931 // Structured block - An executable statement with a single entry at the 8932 // top and a single exit at the bottom. 8933 // The point of exit cannot be a branch out of the structured block. 8934 // longjmp() and throw() must not violate the entry/exit criteria. 8935 CS->getCapturedDecl()->setNothrow(); 8936 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8937 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8938 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8939 // 1.2.2 OpenMP Language Terminology 8940 // Structured block - An executable statement with a single entry at the 8941 // top and a single exit at the bottom. 8942 // The point of exit cannot be a branch out of the structured block. 8943 // longjmp() and throw() must not violate the entry/exit criteria. 8944 CS->getCapturedDecl()->setNothrow(); 8945 } 8946 8947 // OpenMP [2.10.3, Restrictions, p. 102] 8948 // At least one map clause must appear on the directive. 8949 if (!hasClauses(Clauses, OMPC_map)) { 8950 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8951 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8952 return StmtError(); 8953 } 8954 8955 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8956 AStmt); 8957 } 8958 8959 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8960 SourceLocation StartLoc, 8961 SourceLocation EndLoc, 8962 Stmt *AStmt) { 8963 if (!AStmt) 8964 return StmtError(); 8965 8966 auto *CS = cast<CapturedStmt>(AStmt); 8967 // 1.2.2 OpenMP Language Terminology 8968 // Structured block - An executable statement with a single entry at the 8969 // top and a single exit at the bottom. 8970 // The point of exit cannot be a branch out of the structured block. 8971 // longjmp() and throw() must not violate the entry/exit criteria. 8972 CS->getCapturedDecl()->setNothrow(); 8973 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8974 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8975 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8976 // 1.2.2 OpenMP Language Terminology 8977 // Structured block - An executable statement with a single entry at the 8978 // top and a single exit at the bottom. 8979 // The point of exit cannot be a branch out of the structured block. 8980 // longjmp() and throw() must not violate the entry/exit criteria. 8981 CS->getCapturedDecl()->setNothrow(); 8982 } 8983 8984 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8985 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8986 return StmtError(); 8987 } 8988 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8989 AStmt); 8990 } 8991 8992 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8993 Stmt *AStmt, SourceLocation StartLoc, 8994 SourceLocation EndLoc) { 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 9006 setFunctionHasBranchProtectedScope(); 9007 9008 DSAStack->setParentTeamsRegionLoc(StartLoc); 9009 9010 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9011 } 9012 9013 StmtResult 9014 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9015 SourceLocation EndLoc, 9016 OpenMPDirectiveKind CancelRegion) { 9017 if (DSAStack->isParentNowaitRegion()) { 9018 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9019 return StmtError(); 9020 } 9021 if (DSAStack->isParentOrderedRegion()) { 9022 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9023 return StmtError(); 9024 } 9025 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9026 CancelRegion); 9027 } 9028 9029 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9030 SourceLocation StartLoc, 9031 SourceLocation EndLoc, 9032 OpenMPDirectiveKind CancelRegion) { 9033 if (DSAStack->isParentNowaitRegion()) { 9034 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9035 return StmtError(); 9036 } 9037 if (DSAStack->isParentOrderedRegion()) { 9038 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9039 return StmtError(); 9040 } 9041 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9042 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9043 CancelRegion); 9044 } 9045 9046 static bool checkGrainsizeNumTasksClauses(Sema &S, 9047 ArrayRef<OMPClause *> Clauses) { 9048 const OMPClause *PrevClause = nullptr; 9049 bool ErrorFound = false; 9050 for (const OMPClause *C : Clauses) { 9051 if (C->getClauseKind() == OMPC_grainsize || 9052 C->getClauseKind() == OMPC_num_tasks) { 9053 if (!PrevClause) 9054 PrevClause = C; 9055 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9056 S.Diag(C->getBeginLoc(), 9057 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9058 << getOpenMPClauseName(C->getClauseKind()) 9059 << getOpenMPClauseName(PrevClause->getClauseKind()); 9060 S.Diag(PrevClause->getBeginLoc(), 9061 diag::note_omp_previous_grainsize_num_tasks) 9062 << getOpenMPClauseName(PrevClause->getClauseKind()); 9063 ErrorFound = true; 9064 } 9065 } 9066 } 9067 return ErrorFound; 9068 } 9069 9070 static bool checkReductionClauseWithNogroup(Sema &S, 9071 ArrayRef<OMPClause *> Clauses) { 9072 const OMPClause *ReductionClause = nullptr; 9073 const OMPClause *NogroupClause = nullptr; 9074 for (const OMPClause *C : Clauses) { 9075 if (C->getClauseKind() == OMPC_reduction) { 9076 ReductionClause = C; 9077 if (NogroupClause) 9078 break; 9079 continue; 9080 } 9081 if (C->getClauseKind() == OMPC_nogroup) { 9082 NogroupClause = C; 9083 if (ReductionClause) 9084 break; 9085 continue; 9086 } 9087 } 9088 if (ReductionClause && NogroupClause) { 9089 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9090 << SourceRange(NogroupClause->getBeginLoc(), 9091 NogroupClause->getEndLoc()); 9092 return true; 9093 } 9094 return false; 9095 } 9096 9097 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9098 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9099 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9100 if (!AStmt) 9101 return StmtError(); 9102 9103 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9104 OMPLoopDirective::HelperExprs B; 9105 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9106 // define the nested loops number. 9107 unsigned NestedLoopCount = 9108 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9109 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9110 VarsWithImplicitDSA, B); 9111 if (NestedLoopCount == 0) 9112 return StmtError(); 9113 9114 assert((CurContext->isDependentContext() || B.builtAll()) && 9115 "omp for loop exprs were not built"); 9116 9117 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9118 // The grainsize clause and num_tasks clause are mutually exclusive and may 9119 // not appear on the same taskloop directive. 9120 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9121 return StmtError(); 9122 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9123 // If a reduction clause is present on the taskloop directive, the nogroup 9124 // clause must not be specified. 9125 if (checkReductionClauseWithNogroup(*this, Clauses)) 9126 return StmtError(); 9127 9128 setFunctionHasBranchProtectedScope(); 9129 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9130 NestedLoopCount, Clauses, AStmt, B); 9131 } 9132 9133 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9134 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9135 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9136 if (!AStmt) 9137 return StmtError(); 9138 9139 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9140 OMPLoopDirective::HelperExprs B; 9141 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9142 // define the nested loops number. 9143 unsigned NestedLoopCount = 9144 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9145 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9146 VarsWithImplicitDSA, B); 9147 if (NestedLoopCount == 0) 9148 return StmtError(); 9149 9150 assert((CurContext->isDependentContext() || B.builtAll()) && 9151 "omp for loop exprs were not built"); 9152 9153 if (!CurContext->isDependentContext()) { 9154 // Finalize the clauses that need pre-built expressions for CodeGen. 9155 for (OMPClause *C : Clauses) { 9156 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9157 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9158 B.NumIterations, *this, CurScope, 9159 DSAStack)) 9160 return StmtError(); 9161 } 9162 } 9163 9164 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9165 // The grainsize clause and num_tasks clause are mutually exclusive and may 9166 // not appear on the same taskloop directive. 9167 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9168 return StmtError(); 9169 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9170 // If a reduction clause is present on the taskloop directive, the nogroup 9171 // clause must not be specified. 9172 if (checkReductionClauseWithNogroup(*this, Clauses)) 9173 return StmtError(); 9174 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9175 return StmtError(); 9176 9177 setFunctionHasBranchProtectedScope(); 9178 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9179 NestedLoopCount, Clauses, AStmt, B); 9180 } 9181 9182 StmtResult Sema::ActOnOpenMPDistributeDirective( 9183 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9184 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9185 if (!AStmt) 9186 return StmtError(); 9187 9188 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9189 OMPLoopDirective::HelperExprs B; 9190 // In presence of clause 'collapse' with number of loops, it will 9191 // define the nested loops number. 9192 unsigned NestedLoopCount = 9193 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9194 nullptr /*ordered not a clause on distribute*/, AStmt, 9195 *this, *DSAStack, VarsWithImplicitDSA, B); 9196 if (NestedLoopCount == 0) 9197 return StmtError(); 9198 9199 assert((CurContext->isDependentContext() || B.builtAll()) && 9200 "omp for loop exprs were not built"); 9201 9202 setFunctionHasBranchProtectedScope(); 9203 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9204 NestedLoopCount, Clauses, AStmt, B); 9205 } 9206 9207 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9208 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9209 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9210 if (!AStmt) 9211 return StmtError(); 9212 9213 auto *CS = cast<CapturedStmt>(AStmt); 9214 // 1.2.2 OpenMP Language Terminology 9215 // Structured block - An executable statement with a single entry at the 9216 // top and a single exit at the bottom. 9217 // The point of exit cannot be a branch out of the structured block. 9218 // longjmp() and throw() must not violate the entry/exit criteria. 9219 CS->getCapturedDecl()->setNothrow(); 9220 for (int ThisCaptureLevel = 9221 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9222 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9223 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9224 // 1.2.2 OpenMP Language Terminology 9225 // Structured block - An executable statement with a single entry at the 9226 // top and a single exit at the bottom. 9227 // The point of exit cannot be a branch out of the structured block. 9228 // longjmp() and throw() must not violate the entry/exit criteria. 9229 CS->getCapturedDecl()->setNothrow(); 9230 } 9231 9232 OMPLoopDirective::HelperExprs B; 9233 // In presence of clause 'collapse' with number of loops, it will 9234 // define the nested loops number. 9235 unsigned NestedLoopCount = checkOpenMPLoop( 9236 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9237 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9238 VarsWithImplicitDSA, B); 9239 if (NestedLoopCount == 0) 9240 return StmtError(); 9241 9242 assert((CurContext->isDependentContext() || B.builtAll()) && 9243 "omp for loop exprs were not built"); 9244 9245 setFunctionHasBranchProtectedScope(); 9246 return OMPDistributeParallelForDirective::Create( 9247 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9248 DSAStack->isCancelRegion()); 9249 } 9250 9251 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9252 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9253 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9254 if (!AStmt) 9255 return StmtError(); 9256 9257 auto *CS = cast<CapturedStmt>(AStmt); 9258 // 1.2.2 OpenMP Language Terminology 9259 // Structured block - An executable statement with a single entry at the 9260 // top and a single exit at the bottom. 9261 // The point of exit cannot be a branch out of the structured block. 9262 // longjmp() and throw() must not violate the entry/exit criteria. 9263 CS->getCapturedDecl()->setNothrow(); 9264 for (int ThisCaptureLevel = 9265 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9266 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9267 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9268 // 1.2.2 OpenMP Language Terminology 9269 // Structured block - An executable statement with a single entry at the 9270 // top and a single exit at the bottom. 9271 // The point of exit cannot be a branch out of the structured block. 9272 // longjmp() and throw() must not violate the entry/exit criteria. 9273 CS->getCapturedDecl()->setNothrow(); 9274 } 9275 9276 OMPLoopDirective::HelperExprs B; 9277 // In presence of clause 'collapse' with number of loops, it will 9278 // define the nested loops number. 9279 unsigned NestedLoopCount = checkOpenMPLoop( 9280 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9281 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9282 VarsWithImplicitDSA, B); 9283 if (NestedLoopCount == 0) 9284 return StmtError(); 9285 9286 assert((CurContext->isDependentContext() || B.builtAll()) && 9287 "omp for loop exprs were not built"); 9288 9289 if (!CurContext->isDependentContext()) { 9290 // Finalize the clauses that need pre-built expressions for CodeGen. 9291 for (OMPClause *C : Clauses) { 9292 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9293 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9294 B.NumIterations, *this, CurScope, 9295 DSAStack)) 9296 return StmtError(); 9297 } 9298 } 9299 9300 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9301 return StmtError(); 9302 9303 setFunctionHasBranchProtectedScope(); 9304 return OMPDistributeParallelForSimdDirective::Create( 9305 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9306 } 9307 9308 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9309 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9310 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9311 if (!AStmt) 9312 return StmtError(); 9313 9314 auto *CS = cast<CapturedStmt>(AStmt); 9315 // 1.2.2 OpenMP Language Terminology 9316 // Structured block - An executable statement with a single entry at the 9317 // top and a single exit at the bottom. 9318 // The point of exit cannot be a branch out of the structured block. 9319 // longjmp() and throw() must not violate the entry/exit criteria. 9320 CS->getCapturedDecl()->setNothrow(); 9321 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9322 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9323 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9324 // 1.2.2 OpenMP Language Terminology 9325 // Structured block - An executable statement with a single entry at the 9326 // top and a single exit at the bottom. 9327 // The point of exit cannot be a branch out of the structured block. 9328 // longjmp() and throw() must not violate the entry/exit criteria. 9329 CS->getCapturedDecl()->setNothrow(); 9330 } 9331 9332 OMPLoopDirective::HelperExprs B; 9333 // In presence of clause 'collapse' with number of loops, it will 9334 // define the nested loops number. 9335 unsigned NestedLoopCount = 9336 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9337 nullptr /*ordered not a clause on distribute*/, CS, *this, 9338 *DSAStack, VarsWithImplicitDSA, B); 9339 if (NestedLoopCount == 0) 9340 return StmtError(); 9341 9342 assert((CurContext->isDependentContext() || B.builtAll()) && 9343 "omp for loop exprs were not built"); 9344 9345 if (!CurContext->isDependentContext()) { 9346 // Finalize the clauses that need pre-built expressions for CodeGen. 9347 for (OMPClause *C : Clauses) { 9348 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9349 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9350 B.NumIterations, *this, CurScope, 9351 DSAStack)) 9352 return StmtError(); 9353 } 9354 } 9355 9356 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9357 return StmtError(); 9358 9359 setFunctionHasBranchProtectedScope(); 9360 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9361 NestedLoopCount, Clauses, AStmt, B); 9362 } 9363 9364 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9365 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9366 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9367 if (!AStmt) 9368 return StmtError(); 9369 9370 auto *CS = cast<CapturedStmt>(AStmt); 9371 // 1.2.2 OpenMP Language Terminology 9372 // Structured block - An executable statement with a single entry at the 9373 // top and a single exit at the bottom. 9374 // The point of exit cannot be a branch out of the structured block. 9375 // longjmp() and throw() must not violate the entry/exit criteria. 9376 CS->getCapturedDecl()->setNothrow(); 9377 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9378 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9379 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9380 // 1.2.2 OpenMP Language Terminology 9381 // Structured block - An executable statement with a single entry at the 9382 // top and a single exit at the bottom. 9383 // The point of exit cannot be a branch out of the structured block. 9384 // longjmp() and throw() must not violate the entry/exit criteria. 9385 CS->getCapturedDecl()->setNothrow(); 9386 } 9387 9388 OMPLoopDirective::HelperExprs B; 9389 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9390 // define the nested loops number. 9391 unsigned NestedLoopCount = checkOpenMPLoop( 9392 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9393 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9394 VarsWithImplicitDSA, B); 9395 if (NestedLoopCount == 0) 9396 return StmtError(); 9397 9398 assert((CurContext->isDependentContext() || B.builtAll()) && 9399 "omp target parallel for simd loop exprs were not built"); 9400 9401 if (!CurContext->isDependentContext()) { 9402 // Finalize the clauses that need pre-built expressions for CodeGen. 9403 for (OMPClause *C : Clauses) { 9404 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9405 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9406 B.NumIterations, *this, CurScope, 9407 DSAStack)) 9408 return StmtError(); 9409 } 9410 } 9411 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9412 return StmtError(); 9413 9414 setFunctionHasBranchProtectedScope(); 9415 return OMPTargetParallelForSimdDirective::Create( 9416 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9417 } 9418 9419 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9420 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9421 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9422 if (!AStmt) 9423 return StmtError(); 9424 9425 auto *CS = cast<CapturedStmt>(AStmt); 9426 // 1.2.2 OpenMP Language Terminology 9427 // Structured block - An executable statement with a single entry at the 9428 // top and a single exit at the bottom. 9429 // The point of exit cannot be a branch out of the structured block. 9430 // longjmp() and throw() must not violate the entry/exit criteria. 9431 CS->getCapturedDecl()->setNothrow(); 9432 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9433 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9434 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9435 // 1.2.2 OpenMP Language Terminology 9436 // Structured block - An executable statement with a single entry at the 9437 // top and a single exit at the bottom. 9438 // The point of exit cannot be a branch out of the structured block. 9439 // longjmp() and throw() must not violate the entry/exit criteria. 9440 CS->getCapturedDecl()->setNothrow(); 9441 } 9442 9443 OMPLoopDirective::HelperExprs B; 9444 // In presence of clause 'collapse' with number of loops, it will define the 9445 // nested loops number. 9446 unsigned NestedLoopCount = 9447 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9448 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9449 VarsWithImplicitDSA, B); 9450 if (NestedLoopCount == 0) 9451 return StmtError(); 9452 9453 assert((CurContext->isDependentContext() || B.builtAll()) && 9454 "omp target simd loop exprs were not built"); 9455 9456 if (!CurContext->isDependentContext()) { 9457 // Finalize the clauses that need pre-built expressions for CodeGen. 9458 for (OMPClause *C : Clauses) { 9459 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9460 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9461 B.NumIterations, *this, CurScope, 9462 DSAStack)) 9463 return StmtError(); 9464 } 9465 } 9466 9467 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9468 return StmtError(); 9469 9470 setFunctionHasBranchProtectedScope(); 9471 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9472 NestedLoopCount, Clauses, AStmt, B); 9473 } 9474 9475 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9476 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9477 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9478 if (!AStmt) 9479 return StmtError(); 9480 9481 auto *CS = cast<CapturedStmt>(AStmt); 9482 // 1.2.2 OpenMP Language Terminology 9483 // Structured block - An executable statement with a single entry at the 9484 // top and a single exit at the bottom. 9485 // The point of exit cannot be a branch out of the structured block. 9486 // longjmp() and throw() must not violate the entry/exit criteria. 9487 CS->getCapturedDecl()->setNothrow(); 9488 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9489 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9490 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9491 // 1.2.2 OpenMP Language Terminology 9492 // Structured block - An executable statement with a single entry at the 9493 // top and a single exit at the bottom. 9494 // The point of exit cannot be a branch out of the structured block. 9495 // longjmp() and throw() must not violate the entry/exit criteria. 9496 CS->getCapturedDecl()->setNothrow(); 9497 } 9498 9499 OMPLoopDirective::HelperExprs B; 9500 // In presence of clause 'collapse' with number of loops, it will 9501 // define the nested loops number. 9502 unsigned NestedLoopCount = 9503 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9504 nullptr /*ordered not a clause on distribute*/, CS, *this, 9505 *DSAStack, VarsWithImplicitDSA, B); 9506 if (NestedLoopCount == 0) 9507 return StmtError(); 9508 9509 assert((CurContext->isDependentContext() || B.builtAll()) && 9510 "omp teams distribute loop exprs were not built"); 9511 9512 setFunctionHasBranchProtectedScope(); 9513 9514 DSAStack->setParentTeamsRegionLoc(StartLoc); 9515 9516 return OMPTeamsDistributeDirective::Create( 9517 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9518 } 9519 9520 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9521 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9522 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9523 if (!AStmt) 9524 return StmtError(); 9525 9526 auto *CS = cast<CapturedStmt>(AStmt); 9527 // 1.2.2 OpenMP Language Terminology 9528 // Structured block - An executable statement with a single entry at the 9529 // top and a single exit at the bottom. 9530 // The point of exit cannot be a branch out of the structured block. 9531 // longjmp() and throw() must not violate the entry/exit criteria. 9532 CS->getCapturedDecl()->setNothrow(); 9533 for (int ThisCaptureLevel = 9534 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9535 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9536 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9537 // 1.2.2 OpenMP Language Terminology 9538 // Structured block - An executable statement with a single entry at the 9539 // top and a single exit at the bottom. 9540 // The point of exit cannot be a branch out of the structured block. 9541 // longjmp() and throw() must not violate the entry/exit criteria. 9542 CS->getCapturedDecl()->setNothrow(); 9543 } 9544 9545 9546 OMPLoopDirective::HelperExprs B; 9547 // In presence of clause 'collapse' with number of loops, it will 9548 // define the nested loops number. 9549 unsigned NestedLoopCount = checkOpenMPLoop( 9550 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9551 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9552 VarsWithImplicitDSA, B); 9553 9554 if (NestedLoopCount == 0) 9555 return StmtError(); 9556 9557 assert((CurContext->isDependentContext() || B.builtAll()) && 9558 "omp teams distribute simd loop exprs were not built"); 9559 9560 if (!CurContext->isDependentContext()) { 9561 // Finalize the clauses that need pre-built expressions for CodeGen. 9562 for (OMPClause *C : Clauses) { 9563 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9564 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9565 B.NumIterations, *this, CurScope, 9566 DSAStack)) 9567 return StmtError(); 9568 } 9569 } 9570 9571 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9572 return StmtError(); 9573 9574 setFunctionHasBranchProtectedScope(); 9575 9576 DSAStack->setParentTeamsRegionLoc(StartLoc); 9577 9578 return OMPTeamsDistributeSimdDirective::Create( 9579 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9580 } 9581 9582 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9583 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9584 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9585 if (!AStmt) 9586 return StmtError(); 9587 9588 auto *CS = cast<CapturedStmt>(AStmt); 9589 // 1.2.2 OpenMP Language Terminology 9590 // Structured block - An executable statement with a single entry at the 9591 // top and a single exit at the bottom. 9592 // The point of exit cannot be a branch out of the structured block. 9593 // longjmp() and throw() must not violate the entry/exit criteria. 9594 CS->getCapturedDecl()->setNothrow(); 9595 9596 for (int ThisCaptureLevel = 9597 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9598 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9599 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9600 // 1.2.2 OpenMP Language Terminology 9601 // Structured block - An executable statement with a single entry at the 9602 // top and a single exit at the bottom. 9603 // The point of exit cannot be a branch out of the structured block. 9604 // longjmp() and throw() must not violate the entry/exit criteria. 9605 CS->getCapturedDecl()->setNothrow(); 9606 } 9607 9608 OMPLoopDirective::HelperExprs B; 9609 // In presence of clause 'collapse' with number of loops, it will 9610 // define the nested loops number. 9611 unsigned NestedLoopCount = checkOpenMPLoop( 9612 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9613 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9614 VarsWithImplicitDSA, B); 9615 9616 if (NestedLoopCount == 0) 9617 return StmtError(); 9618 9619 assert((CurContext->isDependentContext() || B.builtAll()) && 9620 "omp for loop exprs were not built"); 9621 9622 if (!CurContext->isDependentContext()) { 9623 // Finalize the clauses that need pre-built expressions for CodeGen. 9624 for (OMPClause *C : Clauses) { 9625 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9626 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9627 B.NumIterations, *this, CurScope, 9628 DSAStack)) 9629 return StmtError(); 9630 } 9631 } 9632 9633 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9634 return StmtError(); 9635 9636 setFunctionHasBranchProtectedScope(); 9637 9638 DSAStack->setParentTeamsRegionLoc(StartLoc); 9639 9640 return OMPTeamsDistributeParallelForSimdDirective::Create( 9641 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9642 } 9643 9644 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9645 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9646 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9647 if (!AStmt) 9648 return StmtError(); 9649 9650 auto *CS = cast<CapturedStmt>(AStmt); 9651 // 1.2.2 OpenMP Language Terminology 9652 // Structured block - An executable statement with a single entry at the 9653 // top and a single exit at the bottom. 9654 // The point of exit cannot be a branch out of the structured block. 9655 // longjmp() and throw() must not violate the entry/exit criteria. 9656 CS->getCapturedDecl()->setNothrow(); 9657 9658 for (int ThisCaptureLevel = 9659 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9660 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9661 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9662 // 1.2.2 OpenMP Language Terminology 9663 // Structured block - An executable statement with a single entry at the 9664 // top and a single exit at the bottom. 9665 // The point of exit cannot be a branch out of the structured block. 9666 // longjmp() and throw() must not violate the entry/exit criteria. 9667 CS->getCapturedDecl()->setNothrow(); 9668 } 9669 9670 OMPLoopDirective::HelperExprs B; 9671 // In presence of clause 'collapse' with number of loops, it will 9672 // define the nested loops number. 9673 unsigned NestedLoopCount = checkOpenMPLoop( 9674 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9675 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9676 VarsWithImplicitDSA, B); 9677 9678 if (NestedLoopCount == 0) 9679 return StmtError(); 9680 9681 assert((CurContext->isDependentContext() || B.builtAll()) && 9682 "omp for loop exprs were not built"); 9683 9684 setFunctionHasBranchProtectedScope(); 9685 9686 DSAStack->setParentTeamsRegionLoc(StartLoc); 9687 9688 return OMPTeamsDistributeParallelForDirective::Create( 9689 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9690 DSAStack->isCancelRegion()); 9691 } 9692 9693 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9694 Stmt *AStmt, 9695 SourceLocation StartLoc, 9696 SourceLocation EndLoc) { 9697 if (!AStmt) 9698 return StmtError(); 9699 9700 auto *CS = cast<CapturedStmt>(AStmt); 9701 // 1.2.2 OpenMP Language Terminology 9702 // Structured block - An executable statement with a single entry at the 9703 // top and a single exit at the bottom. 9704 // The point of exit cannot be a branch out of the structured block. 9705 // longjmp() and throw() must not violate the entry/exit criteria. 9706 CS->getCapturedDecl()->setNothrow(); 9707 9708 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9709 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9710 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9711 // 1.2.2 OpenMP Language Terminology 9712 // Structured block - An executable statement with a single entry at the 9713 // top and a single exit at the bottom. 9714 // The point of exit cannot be a branch out of the structured block. 9715 // longjmp() and throw() must not violate the entry/exit criteria. 9716 CS->getCapturedDecl()->setNothrow(); 9717 } 9718 setFunctionHasBranchProtectedScope(); 9719 9720 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9721 AStmt); 9722 } 9723 9724 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9725 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9726 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9727 if (!AStmt) 9728 return StmtError(); 9729 9730 auto *CS = cast<CapturedStmt>(AStmt); 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 for (int ThisCaptureLevel = 9738 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9739 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9740 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9741 // 1.2.2 OpenMP Language Terminology 9742 // Structured block - An executable statement with a single entry at the 9743 // top and a single exit at the bottom. 9744 // The point of exit cannot be a branch out of the structured block. 9745 // longjmp() and throw() must not violate the entry/exit criteria. 9746 CS->getCapturedDecl()->setNothrow(); 9747 } 9748 9749 OMPLoopDirective::HelperExprs B; 9750 // In presence of clause 'collapse' with number of loops, it will 9751 // define the nested loops number. 9752 unsigned NestedLoopCount = checkOpenMPLoop( 9753 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9754 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9755 VarsWithImplicitDSA, B); 9756 if (NestedLoopCount == 0) 9757 return StmtError(); 9758 9759 assert((CurContext->isDependentContext() || B.builtAll()) && 9760 "omp target teams distribute loop exprs were not built"); 9761 9762 setFunctionHasBranchProtectedScope(); 9763 return OMPTargetTeamsDistributeDirective::Create( 9764 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9765 } 9766 9767 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 9768 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9769 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9770 if (!AStmt) 9771 return StmtError(); 9772 9773 auto *CS = cast<CapturedStmt>(AStmt); 9774 // 1.2.2 OpenMP Language Terminology 9775 // Structured block - An executable statement with a single entry at the 9776 // top and a single exit at the bottom. 9777 // The point of exit cannot be a branch out of the structured block. 9778 // longjmp() and throw() must not violate the entry/exit criteria. 9779 CS->getCapturedDecl()->setNothrow(); 9780 for (int ThisCaptureLevel = 9781 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 9782 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9783 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9784 // 1.2.2 OpenMP Language Terminology 9785 // Structured block - An executable statement with a single entry at the 9786 // top and a single exit at the bottom. 9787 // The point of exit cannot be a branch out of the structured block. 9788 // longjmp() and throw() must not violate the entry/exit criteria. 9789 CS->getCapturedDecl()->setNothrow(); 9790 } 9791 9792 OMPLoopDirective::HelperExprs B; 9793 // In presence of clause 'collapse' with number of loops, it will 9794 // define the nested loops number. 9795 unsigned NestedLoopCount = checkOpenMPLoop( 9796 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9797 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9798 VarsWithImplicitDSA, B); 9799 if (NestedLoopCount == 0) 9800 return StmtError(); 9801 9802 assert((CurContext->isDependentContext() || B.builtAll()) && 9803 "omp target teams distribute parallel for loop exprs were not built"); 9804 9805 if (!CurContext->isDependentContext()) { 9806 // Finalize the clauses that need pre-built expressions for CodeGen. 9807 for (OMPClause *C : Clauses) { 9808 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9809 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9810 B.NumIterations, *this, CurScope, 9811 DSAStack)) 9812 return StmtError(); 9813 } 9814 } 9815 9816 setFunctionHasBranchProtectedScope(); 9817 return OMPTargetTeamsDistributeParallelForDirective::Create( 9818 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9819 DSAStack->isCancelRegion()); 9820 } 9821 9822 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9823 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9824 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9825 if (!AStmt) 9826 return StmtError(); 9827 9828 auto *CS = cast<CapturedStmt>(AStmt); 9829 // 1.2.2 OpenMP Language Terminology 9830 // Structured block - An executable statement with a single entry at the 9831 // top and a single exit at the bottom. 9832 // The point of exit cannot be a branch out of the structured block. 9833 // longjmp() and throw() must not violate the entry/exit criteria. 9834 CS->getCapturedDecl()->setNothrow(); 9835 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9836 OMPD_target_teams_distribute_parallel_for_simd); 9837 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9838 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9839 // 1.2.2 OpenMP Language Terminology 9840 // Structured block - An executable statement with a single entry at the 9841 // top and a single exit at the bottom. 9842 // The point of exit cannot be a branch out of the structured block. 9843 // longjmp() and throw() must not violate the entry/exit criteria. 9844 CS->getCapturedDecl()->setNothrow(); 9845 } 9846 9847 OMPLoopDirective::HelperExprs B; 9848 // In presence of clause 'collapse' with number of loops, it will 9849 // define the nested loops number. 9850 unsigned NestedLoopCount = 9851 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9852 getCollapseNumberExpr(Clauses), 9853 nullptr /*ordered not a clause on distribute*/, CS, *this, 9854 *DSAStack, VarsWithImplicitDSA, B); 9855 if (NestedLoopCount == 0) 9856 return StmtError(); 9857 9858 assert((CurContext->isDependentContext() || B.builtAll()) && 9859 "omp target teams distribute parallel for simd loop exprs were not " 9860 "built"); 9861 9862 if (!CurContext->isDependentContext()) { 9863 // Finalize the clauses that need pre-built expressions for CodeGen. 9864 for (OMPClause *C : Clauses) { 9865 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9866 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9867 B.NumIterations, *this, CurScope, 9868 DSAStack)) 9869 return StmtError(); 9870 } 9871 } 9872 9873 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9874 return StmtError(); 9875 9876 setFunctionHasBranchProtectedScope(); 9877 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9878 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9879 } 9880 9881 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9882 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9883 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9884 if (!AStmt) 9885 return StmtError(); 9886 9887 auto *CS = cast<CapturedStmt>(AStmt); 9888 // 1.2.2 OpenMP Language Terminology 9889 // Structured block - An executable statement with a single entry at the 9890 // top and a single exit at the bottom. 9891 // The point of exit cannot be a branch out of the structured block. 9892 // longjmp() and throw() must not violate the entry/exit criteria. 9893 CS->getCapturedDecl()->setNothrow(); 9894 for (int ThisCaptureLevel = 9895 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9896 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9897 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 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 } 9905 9906 OMPLoopDirective::HelperExprs B; 9907 // In presence of clause 'collapse' with number of loops, it will 9908 // define the nested loops number. 9909 unsigned NestedLoopCount = checkOpenMPLoop( 9910 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9911 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9912 VarsWithImplicitDSA, B); 9913 if (NestedLoopCount == 0) 9914 return StmtError(); 9915 9916 assert((CurContext->isDependentContext() || B.builtAll()) && 9917 "omp target teams distribute simd loop exprs were not built"); 9918 9919 if (!CurContext->isDependentContext()) { 9920 // Finalize the clauses that need pre-built expressions for CodeGen. 9921 for (OMPClause *C : Clauses) { 9922 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9923 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9924 B.NumIterations, *this, CurScope, 9925 DSAStack)) 9926 return StmtError(); 9927 } 9928 } 9929 9930 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9931 return StmtError(); 9932 9933 setFunctionHasBranchProtectedScope(); 9934 return OMPTargetTeamsDistributeSimdDirective::Create( 9935 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9936 } 9937 9938 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9939 SourceLocation StartLoc, 9940 SourceLocation LParenLoc, 9941 SourceLocation EndLoc) { 9942 OMPClause *Res = nullptr; 9943 switch (Kind) { 9944 case OMPC_final: 9945 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9946 break; 9947 case OMPC_num_threads: 9948 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9949 break; 9950 case OMPC_safelen: 9951 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9952 break; 9953 case OMPC_simdlen: 9954 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9955 break; 9956 case OMPC_allocator: 9957 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9958 break; 9959 case OMPC_collapse: 9960 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9961 break; 9962 case OMPC_ordered: 9963 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9964 break; 9965 case OMPC_device: 9966 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9967 break; 9968 case OMPC_num_teams: 9969 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9970 break; 9971 case OMPC_thread_limit: 9972 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9973 break; 9974 case OMPC_priority: 9975 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9976 break; 9977 case OMPC_grainsize: 9978 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9979 break; 9980 case OMPC_num_tasks: 9981 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9982 break; 9983 case OMPC_hint: 9984 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9985 break; 9986 case OMPC_if: 9987 case OMPC_default: 9988 case OMPC_proc_bind: 9989 case OMPC_schedule: 9990 case OMPC_private: 9991 case OMPC_firstprivate: 9992 case OMPC_lastprivate: 9993 case OMPC_shared: 9994 case OMPC_reduction: 9995 case OMPC_task_reduction: 9996 case OMPC_in_reduction: 9997 case OMPC_linear: 9998 case OMPC_aligned: 9999 case OMPC_copyin: 10000 case OMPC_copyprivate: 10001 case OMPC_nowait: 10002 case OMPC_untied: 10003 case OMPC_mergeable: 10004 case OMPC_threadprivate: 10005 case OMPC_allocate: 10006 case OMPC_flush: 10007 case OMPC_read: 10008 case OMPC_write: 10009 case OMPC_update: 10010 case OMPC_capture: 10011 case OMPC_seq_cst: 10012 case OMPC_depend: 10013 case OMPC_threads: 10014 case OMPC_simd: 10015 case OMPC_map: 10016 case OMPC_nogroup: 10017 case OMPC_dist_schedule: 10018 case OMPC_defaultmap: 10019 case OMPC_unknown: 10020 case OMPC_uniform: 10021 case OMPC_to: 10022 case OMPC_from: 10023 case OMPC_use_device_ptr: 10024 case OMPC_is_device_ptr: 10025 case OMPC_unified_address: 10026 case OMPC_unified_shared_memory: 10027 case OMPC_reverse_offload: 10028 case OMPC_dynamic_allocators: 10029 case OMPC_atomic_default_mem_order: 10030 case OMPC_device_type: 10031 llvm_unreachable("Clause is not allowed."); 10032 } 10033 return Res; 10034 } 10035 10036 // An OpenMP directive such as 'target parallel' has two captured regions: 10037 // for the 'target' and 'parallel' respectively. This function returns 10038 // the region in which to capture expressions associated with a clause. 10039 // A return value of OMPD_unknown signifies that the expression should not 10040 // be captured. 10041 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10042 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10043 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10044 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10045 switch (CKind) { 10046 case OMPC_if: 10047 switch (DKind) { 10048 case OMPD_target_parallel: 10049 case OMPD_target_parallel_for: 10050 case OMPD_target_parallel_for_simd: 10051 // If this clause applies to the nested 'parallel' region, capture within 10052 // the 'target' region, otherwise do not capture. 10053 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10054 CaptureRegion = OMPD_target; 10055 break; 10056 case OMPD_target_teams_distribute_parallel_for: 10057 case OMPD_target_teams_distribute_parallel_for_simd: 10058 // If this clause applies to the nested 'parallel' region, capture within 10059 // the 'teams' region, otherwise do not capture. 10060 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10061 CaptureRegion = OMPD_teams; 10062 break; 10063 case OMPD_teams_distribute_parallel_for: 10064 case OMPD_teams_distribute_parallel_for_simd: 10065 CaptureRegion = OMPD_teams; 10066 break; 10067 case OMPD_target_update: 10068 case OMPD_target_enter_data: 10069 case OMPD_target_exit_data: 10070 CaptureRegion = OMPD_task; 10071 break; 10072 case OMPD_cancel: 10073 case OMPD_parallel: 10074 case OMPD_parallel_sections: 10075 case OMPD_parallel_for: 10076 case OMPD_parallel_for_simd: 10077 case OMPD_target: 10078 case OMPD_target_simd: 10079 case OMPD_target_teams: 10080 case OMPD_target_teams_distribute: 10081 case OMPD_target_teams_distribute_simd: 10082 case OMPD_distribute_parallel_for: 10083 case OMPD_distribute_parallel_for_simd: 10084 case OMPD_task: 10085 case OMPD_taskloop: 10086 case OMPD_taskloop_simd: 10087 case OMPD_target_data: 10088 // Do not capture if-clause expressions. 10089 break; 10090 case OMPD_threadprivate: 10091 case OMPD_allocate: 10092 case OMPD_taskyield: 10093 case OMPD_barrier: 10094 case OMPD_taskwait: 10095 case OMPD_cancellation_point: 10096 case OMPD_flush: 10097 case OMPD_declare_reduction: 10098 case OMPD_declare_mapper: 10099 case OMPD_declare_simd: 10100 case OMPD_declare_variant: 10101 case OMPD_declare_target: 10102 case OMPD_end_declare_target: 10103 case OMPD_teams: 10104 case OMPD_simd: 10105 case OMPD_for: 10106 case OMPD_for_simd: 10107 case OMPD_sections: 10108 case OMPD_section: 10109 case OMPD_single: 10110 case OMPD_master: 10111 case OMPD_critical: 10112 case OMPD_taskgroup: 10113 case OMPD_distribute: 10114 case OMPD_ordered: 10115 case OMPD_atomic: 10116 case OMPD_distribute_simd: 10117 case OMPD_teams_distribute: 10118 case OMPD_teams_distribute_simd: 10119 case OMPD_requires: 10120 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10121 case OMPD_unknown: 10122 llvm_unreachable("Unknown OpenMP directive"); 10123 } 10124 break; 10125 case OMPC_num_threads: 10126 switch (DKind) { 10127 case OMPD_target_parallel: 10128 case OMPD_target_parallel_for: 10129 case OMPD_target_parallel_for_simd: 10130 CaptureRegion = OMPD_target; 10131 break; 10132 case OMPD_teams_distribute_parallel_for: 10133 case OMPD_teams_distribute_parallel_for_simd: 10134 case OMPD_target_teams_distribute_parallel_for: 10135 case OMPD_target_teams_distribute_parallel_for_simd: 10136 CaptureRegion = OMPD_teams; 10137 break; 10138 case OMPD_parallel: 10139 case OMPD_parallel_sections: 10140 case OMPD_parallel_for: 10141 case OMPD_parallel_for_simd: 10142 case OMPD_distribute_parallel_for: 10143 case OMPD_distribute_parallel_for_simd: 10144 // Do not capture num_threads-clause expressions. 10145 break; 10146 case OMPD_target_data: 10147 case OMPD_target_enter_data: 10148 case OMPD_target_exit_data: 10149 case OMPD_target_update: 10150 case OMPD_target: 10151 case OMPD_target_simd: 10152 case OMPD_target_teams: 10153 case OMPD_target_teams_distribute: 10154 case OMPD_target_teams_distribute_simd: 10155 case OMPD_cancel: 10156 case OMPD_task: 10157 case OMPD_taskloop: 10158 case OMPD_taskloop_simd: 10159 case OMPD_threadprivate: 10160 case OMPD_allocate: 10161 case OMPD_taskyield: 10162 case OMPD_barrier: 10163 case OMPD_taskwait: 10164 case OMPD_cancellation_point: 10165 case OMPD_flush: 10166 case OMPD_declare_reduction: 10167 case OMPD_declare_mapper: 10168 case OMPD_declare_simd: 10169 case OMPD_declare_variant: 10170 case OMPD_declare_target: 10171 case OMPD_end_declare_target: 10172 case OMPD_teams: 10173 case OMPD_simd: 10174 case OMPD_for: 10175 case OMPD_for_simd: 10176 case OMPD_sections: 10177 case OMPD_section: 10178 case OMPD_single: 10179 case OMPD_master: 10180 case OMPD_critical: 10181 case OMPD_taskgroup: 10182 case OMPD_distribute: 10183 case OMPD_ordered: 10184 case OMPD_atomic: 10185 case OMPD_distribute_simd: 10186 case OMPD_teams_distribute: 10187 case OMPD_teams_distribute_simd: 10188 case OMPD_requires: 10189 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10190 case OMPD_unknown: 10191 llvm_unreachable("Unknown OpenMP directive"); 10192 } 10193 break; 10194 case OMPC_num_teams: 10195 switch (DKind) { 10196 case OMPD_target_teams: 10197 case OMPD_target_teams_distribute: 10198 case OMPD_target_teams_distribute_simd: 10199 case OMPD_target_teams_distribute_parallel_for: 10200 case OMPD_target_teams_distribute_parallel_for_simd: 10201 CaptureRegion = OMPD_target; 10202 break; 10203 case OMPD_teams_distribute_parallel_for: 10204 case OMPD_teams_distribute_parallel_for_simd: 10205 case OMPD_teams: 10206 case OMPD_teams_distribute: 10207 case OMPD_teams_distribute_simd: 10208 // Do not capture num_teams-clause expressions. 10209 break; 10210 case OMPD_distribute_parallel_for: 10211 case OMPD_distribute_parallel_for_simd: 10212 case OMPD_task: 10213 case OMPD_taskloop: 10214 case OMPD_taskloop_simd: 10215 case OMPD_target_data: 10216 case OMPD_target_enter_data: 10217 case OMPD_target_exit_data: 10218 case OMPD_target_update: 10219 case OMPD_cancel: 10220 case OMPD_parallel: 10221 case OMPD_parallel_sections: 10222 case OMPD_parallel_for: 10223 case OMPD_parallel_for_simd: 10224 case OMPD_target: 10225 case OMPD_target_simd: 10226 case OMPD_target_parallel: 10227 case OMPD_target_parallel_for: 10228 case OMPD_target_parallel_for_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_simd: 10243 case OMPD_for: 10244 case OMPD_for_simd: 10245 case OMPD_sections: 10246 case OMPD_section: 10247 case OMPD_single: 10248 case OMPD_master: 10249 case OMPD_critical: 10250 case OMPD_taskgroup: 10251 case OMPD_distribute: 10252 case OMPD_ordered: 10253 case OMPD_atomic: 10254 case OMPD_distribute_simd: 10255 case OMPD_requires: 10256 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10257 case OMPD_unknown: 10258 llvm_unreachable("Unknown OpenMP directive"); 10259 } 10260 break; 10261 case OMPC_thread_limit: 10262 switch (DKind) { 10263 case OMPD_target_teams: 10264 case OMPD_target_teams_distribute: 10265 case OMPD_target_teams_distribute_simd: 10266 case OMPD_target_teams_distribute_parallel_for: 10267 case OMPD_target_teams_distribute_parallel_for_simd: 10268 CaptureRegion = OMPD_target; 10269 break; 10270 case OMPD_teams_distribute_parallel_for: 10271 case OMPD_teams_distribute_parallel_for_simd: 10272 case OMPD_teams: 10273 case OMPD_teams_distribute: 10274 case OMPD_teams_distribute_simd: 10275 // Do not capture thread_limit-clause expressions. 10276 break; 10277 case OMPD_distribute_parallel_for: 10278 case OMPD_distribute_parallel_for_simd: 10279 case OMPD_task: 10280 case OMPD_taskloop: 10281 case OMPD_taskloop_simd: 10282 case OMPD_target_data: 10283 case OMPD_target_enter_data: 10284 case OMPD_target_exit_data: 10285 case OMPD_target_update: 10286 case OMPD_cancel: 10287 case OMPD_parallel: 10288 case OMPD_parallel_sections: 10289 case OMPD_parallel_for: 10290 case OMPD_parallel_for_simd: 10291 case OMPD_target: 10292 case OMPD_target_simd: 10293 case OMPD_target_parallel: 10294 case OMPD_target_parallel_for: 10295 case OMPD_target_parallel_for_simd: 10296 case OMPD_threadprivate: 10297 case OMPD_allocate: 10298 case OMPD_taskyield: 10299 case OMPD_barrier: 10300 case OMPD_taskwait: 10301 case OMPD_cancellation_point: 10302 case OMPD_flush: 10303 case OMPD_declare_reduction: 10304 case OMPD_declare_mapper: 10305 case OMPD_declare_simd: 10306 case OMPD_declare_variant: 10307 case OMPD_declare_target: 10308 case OMPD_end_declare_target: 10309 case OMPD_simd: 10310 case OMPD_for: 10311 case OMPD_for_simd: 10312 case OMPD_sections: 10313 case OMPD_section: 10314 case OMPD_single: 10315 case OMPD_master: 10316 case OMPD_critical: 10317 case OMPD_taskgroup: 10318 case OMPD_distribute: 10319 case OMPD_ordered: 10320 case OMPD_atomic: 10321 case OMPD_distribute_simd: 10322 case OMPD_requires: 10323 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10324 case OMPD_unknown: 10325 llvm_unreachable("Unknown OpenMP directive"); 10326 } 10327 break; 10328 case OMPC_schedule: 10329 switch (DKind) { 10330 case OMPD_parallel_for: 10331 case OMPD_parallel_for_simd: 10332 case OMPD_distribute_parallel_for: 10333 case OMPD_distribute_parallel_for_simd: 10334 case OMPD_teams_distribute_parallel_for: 10335 case OMPD_teams_distribute_parallel_for_simd: 10336 case OMPD_target_parallel_for: 10337 case OMPD_target_parallel_for_simd: 10338 case OMPD_target_teams_distribute_parallel_for: 10339 case OMPD_target_teams_distribute_parallel_for_simd: 10340 CaptureRegion = OMPD_parallel; 10341 break; 10342 case OMPD_for: 10343 case OMPD_for_simd: 10344 // Do not capture schedule-clause expressions. 10345 break; 10346 case OMPD_task: 10347 case OMPD_taskloop: 10348 case OMPD_taskloop_simd: 10349 case OMPD_target_data: 10350 case OMPD_target_enter_data: 10351 case OMPD_target_exit_data: 10352 case OMPD_target_update: 10353 case OMPD_teams: 10354 case OMPD_teams_distribute: 10355 case OMPD_teams_distribute_simd: 10356 case OMPD_target_teams_distribute: 10357 case OMPD_target_teams_distribute_simd: 10358 case OMPD_target: 10359 case OMPD_target_simd: 10360 case OMPD_target_parallel: 10361 case OMPD_cancel: 10362 case OMPD_parallel: 10363 case OMPD_parallel_sections: 10364 case OMPD_threadprivate: 10365 case OMPD_allocate: 10366 case OMPD_taskyield: 10367 case OMPD_barrier: 10368 case OMPD_taskwait: 10369 case OMPD_cancellation_point: 10370 case OMPD_flush: 10371 case OMPD_declare_reduction: 10372 case OMPD_declare_mapper: 10373 case OMPD_declare_simd: 10374 case OMPD_declare_variant: 10375 case OMPD_declare_target: 10376 case OMPD_end_declare_target: 10377 case OMPD_simd: 10378 case OMPD_sections: 10379 case OMPD_section: 10380 case OMPD_single: 10381 case OMPD_master: 10382 case OMPD_critical: 10383 case OMPD_taskgroup: 10384 case OMPD_distribute: 10385 case OMPD_ordered: 10386 case OMPD_atomic: 10387 case OMPD_distribute_simd: 10388 case OMPD_target_teams: 10389 case OMPD_requires: 10390 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10391 case OMPD_unknown: 10392 llvm_unreachable("Unknown OpenMP directive"); 10393 } 10394 break; 10395 case OMPC_dist_schedule: 10396 switch (DKind) { 10397 case OMPD_teams_distribute_parallel_for: 10398 case OMPD_teams_distribute_parallel_for_simd: 10399 case OMPD_teams_distribute: 10400 case OMPD_teams_distribute_simd: 10401 case OMPD_target_teams_distribute_parallel_for: 10402 case OMPD_target_teams_distribute_parallel_for_simd: 10403 case OMPD_target_teams_distribute: 10404 case OMPD_target_teams_distribute_simd: 10405 CaptureRegion = OMPD_teams; 10406 break; 10407 case OMPD_distribute_parallel_for: 10408 case OMPD_distribute_parallel_for_simd: 10409 case OMPD_distribute: 10410 case OMPD_distribute_simd: 10411 // Do not capture thread_limit-clause expressions. 10412 break; 10413 case OMPD_parallel_for: 10414 case OMPD_parallel_for_simd: 10415 case OMPD_target_parallel_for_simd: 10416 case OMPD_target_parallel_for: 10417 case OMPD_task: 10418 case OMPD_taskloop: 10419 case OMPD_taskloop_simd: 10420 case OMPD_target_data: 10421 case OMPD_target_enter_data: 10422 case OMPD_target_exit_data: 10423 case OMPD_target_update: 10424 case OMPD_teams: 10425 case OMPD_target: 10426 case OMPD_target_simd: 10427 case OMPD_target_parallel: 10428 case OMPD_cancel: 10429 case OMPD_parallel: 10430 case OMPD_parallel_sections: 10431 case OMPD_threadprivate: 10432 case OMPD_allocate: 10433 case OMPD_taskyield: 10434 case OMPD_barrier: 10435 case OMPD_taskwait: 10436 case OMPD_cancellation_point: 10437 case OMPD_flush: 10438 case OMPD_declare_reduction: 10439 case OMPD_declare_mapper: 10440 case OMPD_declare_simd: 10441 case OMPD_declare_variant: 10442 case OMPD_declare_target: 10443 case OMPD_end_declare_target: 10444 case OMPD_simd: 10445 case OMPD_for: 10446 case OMPD_for_simd: 10447 case OMPD_sections: 10448 case OMPD_section: 10449 case OMPD_single: 10450 case OMPD_master: 10451 case OMPD_critical: 10452 case OMPD_taskgroup: 10453 case OMPD_ordered: 10454 case OMPD_atomic: 10455 case OMPD_target_teams: 10456 case OMPD_requires: 10457 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10458 case OMPD_unknown: 10459 llvm_unreachable("Unknown OpenMP directive"); 10460 } 10461 break; 10462 case OMPC_device: 10463 switch (DKind) { 10464 case OMPD_target_update: 10465 case OMPD_target_enter_data: 10466 case OMPD_target_exit_data: 10467 case OMPD_target: 10468 case OMPD_target_simd: 10469 case OMPD_target_teams: 10470 case OMPD_target_parallel: 10471 case OMPD_target_teams_distribute: 10472 case OMPD_target_teams_distribute_simd: 10473 case OMPD_target_parallel_for: 10474 case OMPD_target_parallel_for_simd: 10475 case OMPD_target_teams_distribute_parallel_for: 10476 case OMPD_target_teams_distribute_parallel_for_simd: 10477 CaptureRegion = OMPD_task; 10478 break; 10479 case OMPD_target_data: 10480 // Do not capture device-clause expressions. 10481 break; 10482 case OMPD_teams_distribute_parallel_for: 10483 case OMPD_teams_distribute_parallel_for_simd: 10484 case OMPD_teams: 10485 case OMPD_teams_distribute: 10486 case OMPD_teams_distribute_simd: 10487 case OMPD_distribute_parallel_for: 10488 case OMPD_distribute_parallel_for_simd: 10489 case OMPD_task: 10490 case OMPD_taskloop: 10491 case OMPD_taskloop_simd: 10492 case OMPD_cancel: 10493 case OMPD_parallel: 10494 case OMPD_parallel_sections: 10495 case OMPD_parallel_for: 10496 case OMPD_parallel_for_simd: 10497 case OMPD_threadprivate: 10498 case OMPD_allocate: 10499 case OMPD_taskyield: 10500 case OMPD_barrier: 10501 case OMPD_taskwait: 10502 case OMPD_cancellation_point: 10503 case OMPD_flush: 10504 case OMPD_declare_reduction: 10505 case OMPD_declare_mapper: 10506 case OMPD_declare_simd: 10507 case OMPD_declare_variant: 10508 case OMPD_declare_target: 10509 case OMPD_end_declare_target: 10510 case OMPD_simd: 10511 case OMPD_for: 10512 case OMPD_for_simd: 10513 case OMPD_sections: 10514 case OMPD_section: 10515 case OMPD_single: 10516 case OMPD_master: 10517 case OMPD_critical: 10518 case OMPD_taskgroup: 10519 case OMPD_distribute: 10520 case OMPD_ordered: 10521 case OMPD_atomic: 10522 case OMPD_distribute_simd: 10523 case OMPD_requires: 10524 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10525 case OMPD_unknown: 10526 llvm_unreachable("Unknown OpenMP directive"); 10527 } 10528 break; 10529 case OMPC_firstprivate: 10530 case OMPC_lastprivate: 10531 case OMPC_reduction: 10532 case OMPC_task_reduction: 10533 case OMPC_in_reduction: 10534 case OMPC_linear: 10535 case OMPC_default: 10536 case OMPC_proc_bind: 10537 case OMPC_final: 10538 case OMPC_safelen: 10539 case OMPC_simdlen: 10540 case OMPC_allocator: 10541 case OMPC_collapse: 10542 case OMPC_private: 10543 case OMPC_shared: 10544 case OMPC_aligned: 10545 case OMPC_copyin: 10546 case OMPC_copyprivate: 10547 case OMPC_ordered: 10548 case OMPC_nowait: 10549 case OMPC_untied: 10550 case OMPC_mergeable: 10551 case OMPC_threadprivate: 10552 case OMPC_allocate: 10553 case OMPC_flush: 10554 case OMPC_read: 10555 case OMPC_write: 10556 case OMPC_update: 10557 case OMPC_capture: 10558 case OMPC_seq_cst: 10559 case OMPC_depend: 10560 case OMPC_threads: 10561 case OMPC_simd: 10562 case OMPC_map: 10563 case OMPC_priority: 10564 case OMPC_grainsize: 10565 case OMPC_nogroup: 10566 case OMPC_num_tasks: 10567 case OMPC_hint: 10568 case OMPC_defaultmap: 10569 case OMPC_unknown: 10570 case OMPC_uniform: 10571 case OMPC_to: 10572 case OMPC_from: 10573 case OMPC_use_device_ptr: 10574 case OMPC_is_device_ptr: 10575 case OMPC_unified_address: 10576 case OMPC_unified_shared_memory: 10577 case OMPC_reverse_offload: 10578 case OMPC_dynamic_allocators: 10579 case OMPC_atomic_default_mem_order: 10580 case OMPC_device_type: 10581 llvm_unreachable("Unexpected OpenMP clause."); 10582 } 10583 return CaptureRegion; 10584 } 10585 10586 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10587 Expr *Condition, SourceLocation StartLoc, 10588 SourceLocation LParenLoc, 10589 SourceLocation NameModifierLoc, 10590 SourceLocation ColonLoc, 10591 SourceLocation EndLoc) { 10592 Expr *ValExpr = Condition; 10593 Stmt *HelperValStmt = nullptr; 10594 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10595 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10596 !Condition->isInstantiationDependent() && 10597 !Condition->containsUnexpandedParameterPack()) { 10598 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10599 if (Val.isInvalid()) 10600 return nullptr; 10601 10602 ValExpr = Val.get(); 10603 10604 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10605 CaptureRegion = 10606 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10607 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10608 ValExpr = MakeFullExpr(ValExpr).get(); 10609 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10610 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10611 HelperValStmt = buildPreInits(Context, Captures); 10612 } 10613 } 10614 10615 return new (Context) 10616 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10617 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10618 } 10619 10620 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10621 SourceLocation StartLoc, 10622 SourceLocation LParenLoc, 10623 SourceLocation EndLoc) { 10624 Expr *ValExpr = Condition; 10625 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10626 !Condition->isInstantiationDependent() && 10627 !Condition->containsUnexpandedParameterPack()) { 10628 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10629 if (Val.isInvalid()) 10630 return nullptr; 10631 10632 ValExpr = MakeFullExpr(Val.get()).get(); 10633 } 10634 10635 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10636 } 10637 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10638 Expr *Op) { 10639 if (!Op) 10640 return ExprError(); 10641 10642 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10643 public: 10644 IntConvertDiagnoser() 10645 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10646 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10647 QualType T) override { 10648 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10649 } 10650 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10651 QualType T) override { 10652 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10653 } 10654 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10655 QualType T, 10656 QualType ConvTy) override { 10657 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10658 } 10659 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 10660 QualType ConvTy) override { 10661 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10662 << ConvTy->isEnumeralType() << ConvTy; 10663 } 10664 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 10665 QualType T) override { 10666 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 10667 } 10668 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 10669 QualType ConvTy) override { 10670 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10671 << ConvTy->isEnumeralType() << ConvTy; 10672 } 10673 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 10674 QualType) override { 10675 llvm_unreachable("conversion functions are permitted"); 10676 } 10677 } ConvertDiagnoser; 10678 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 10679 } 10680 10681 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 10682 OpenMPClauseKind CKind, 10683 bool StrictlyPositive) { 10684 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 10685 !ValExpr->isInstantiationDependent()) { 10686 SourceLocation Loc = ValExpr->getExprLoc(); 10687 ExprResult Value = 10688 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 10689 if (Value.isInvalid()) 10690 return false; 10691 10692 ValExpr = Value.get(); 10693 // The expression must evaluate to a non-negative integer value. 10694 llvm::APSInt Result; 10695 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 10696 Result.isSigned() && 10697 !((!StrictlyPositive && Result.isNonNegative()) || 10698 (StrictlyPositive && Result.isStrictlyPositive()))) { 10699 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 10700 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10701 << ValExpr->getSourceRange(); 10702 return false; 10703 } 10704 } 10705 return true; 10706 } 10707 10708 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 10709 SourceLocation StartLoc, 10710 SourceLocation LParenLoc, 10711 SourceLocation EndLoc) { 10712 Expr *ValExpr = NumThreads; 10713 Stmt *HelperValStmt = nullptr; 10714 10715 // OpenMP [2.5, Restrictions] 10716 // The num_threads expression must evaluate to a positive integer value. 10717 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 10718 /*StrictlyPositive=*/true)) 10719 return nullptr; 10720 10721 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10722 OpenMPDirectiveKind CaptureRegion = 10723 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 10724 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10725 ValExpr = MakeFullExpr(ValExpr).get(); 10726 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10727 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10728 HelperValStmt = buildPreInits(Context, Captures); 10729 } 10730 10731 return new (Context) OMPNumThreadsClause( 10732 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 10733 } 10734 10735 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 10736 OpenMPClauseKind CKind, 10737 bool StrictlyPositive) { 10738 if (!E) 10739 return ExprError(); 10740 if (E->isValueDependent() || E->isTypeDependent() || 10741 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 10742 return E; 10743 llvm::APSInt Result; 10744 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 10745 if (ICE.isInvalid()) 10746 return ExprError(); 10747 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 10748 (!StrictlyPositive && !Result.isNonNegative())) { 10749 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 10750 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10751 << E->getSourceRange(); 10752 return ExprError(); 10753 } 10754 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 10755 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 10756 << E->getSourceRange(); 10757 return ExprError(); 10758 } 10759 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 10760 DSAStack->setAssociatedLoops(Result.getExtValue()); 10761 else if (CKind == OMPC_ordered) 10762 DSAStack->setAssociatedLoops(Result.getExtValue()); 10763 return ICE; 10764 } 10765 10766 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 10767 SourceLocation LParenLoc, 10768 SourceLocation EndLoc) { 10769 // OpenMP [2.8.1, simd construct, Description] 10770 // The parameter of the safelen clause must be a constant 10771 // positive integer expression. 10772 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 10773 if (Safelen.isInvalid()) 10774 return nullptr; 10775 return new (Context) 10776 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 10777 } 10778 10779 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 10780 SourceLocation LParenLoc, 10781 SourceLocation EndLoc) { 10782 // OpenMP [2.8.1, simd construct, Description] 10783 // The parameter of the simdlen clause must be a constant 10784 // positive integer expression. 10785 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 10786 if (Simdlen.isInvalid()) 10787 return nullptr; 10788 return new (Context) 10789 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 10790 } 10791 10792 /// Tries to find omp_allocator_handle_t type. 10793 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 10794 DSAStackTy *Stack) { 10795 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 10796 if (!OMPAllocatorHandleT.isNull()) 10797 return true; 10798 // Build the predefined allocator expressions. 10799 bool ErrorFound = false; 10800 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 10801 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 10802 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 10803 StringRef Allocator = 10804 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 10805 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 10806 auto *VD = dyn_cast_or_null<ValueDecl>( 10807 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 10808 if (!VD) { 10809 ErrorFound = true; 10810 break; 10811 } 10812 QualType AllocatorType = 10813 VD->getType().getNonLValueExprType(S.getASTContext()); 10814 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10815 if (!Res.isUsable()) { 10816 ErrorFound = true; 10817 break; 10818 } 10819 if (OMPAllocatorHandleT.isNull()) 10820 OMPAllocatorHandleT = AllocatorType; 10821 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10822 ErrorFound = true; 10823 break; 10824 } 10825 Stack->setAllocator(AllocatorKind, Res.get()); 10826 } 10827 if (ErrorFound) { 10828 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10829 return false; 10830 } 10831 OMPAllocatorHandleT.addConst(); 10832 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10833 return true; 10834 } 10835 10836 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10837 SourceLocation LParenLoc, 10838 SourceLocation EndLoc) { 10839 // OpenMP [2.11.3, allocate Directive, Description] 10840 // allocator is an expression of omp_allocator_handle_t type. 10841 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10842 return nullptr; 10843 10844 ExprResult Allocator = DefaultLvalueConversion(A); 10845 if (Allocator.isInvalid()) 10846 return nullptr; 10847 Allocator = PerformImplicitConversion(Allocator.get(), 10848 DSAStack->getOMPAllocatorHandleT(), 10849 Sema::AA_Initializing, 10850 /*AllowExplicit=*/true); 10851 if (Allocator.isInvalid()) 10852 return nullptr; 10853 return new (Context) 10854 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10855 } 10856 10857 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10858 SourceLocation StartLoc, 10859 SourceLocation LParenLoc, 10860 SourceLocation EndLoc) { 10861 // OpenMP [2.7.1, loop construct, Description] 10862 // OpenMP [2.8.1, simd construct, Description] 10863 // OpenMP [2.9.6, distribute construct, Description] 10864 // The parameter of the collapse clause must be a constant 10865 // positive integer expression. 10866 ExprResult NumForLoopsResult = 10867 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10868 if (NumForLoopsResult.isInvalid()) 10869 return nullptr; 10870 return new (Context) 10871 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10872 } 10873 10874 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10875 SourceLocation EndLoc, 10876 SourceLocation LParenLoc, 10877 Expr *NumForLoops) { 10878 // OpenMP [2.7.1, loop construct, Description] 10879 // OpenMP [2.8.1, simd construct, Description] 10880 // OpenMP [2.9.6, distribute construct, Description] 10881 // The parameter of the ordered clause must be a constant 10882 // positive integer expression if any. 10883 if (NumForLoops && LParenLoc.isValid()) { 10884 ExprResult NumForLoopsResult = 10885 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10886 if (NumForLoopsResult.isInvalid()) 10887 return nullptr; 10888 NumForLoops = NumForLoopsResult.get(); 10889 } else { 10890 NumForLoops = nullptr; 10891 } 10892 auto *Clause = OMPOrderedClause::Create( 10893 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10894 StartLoc, LParenLoc, EndLoc); 10895 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10896 return Clause; 10897 } 10898 10899 OMPClause *Sema::ActOnOpenMPSimpleClause( 10900 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10901 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10902 OMPClause *Res = nullptr; 10903 switch (Kind) { 10904 case OMPC_default: 10905 Res = 10906 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10907 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10908 break; 10909 case OMPC_proc_bind: 10910 Res = ActOnOpenMPProcBindClause( 10911 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10912 LParenLoc, EndLoc); 10913 break; 10914 case OMPC_atomic_default_mem_order: 10915 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10916 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10917 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10918 break; 10919 case OMPC_if: 10920 case OMPC_final: 10921 case OMPC_num_threads: 10922 case OMPC_safelen: 10923 case OMPC_simdlen: 10924 case OMPC_allocator: 10925 case OMPC_collapse: 10926 case OMPC_schedule: 10927 case OMPC_private: 10928 case OMPC_firstprivate: 10929 case OMPC_lastprivate: 10930 case OMPC_shared: 10931 case OMPC_reduction: 10932 case OMPC_task_reduction: 10933 case OMPC_in_reduction: 10934 case OMPC_linear: 10935 case OMPC_aligned: 10936 case OMPC_copyin: 10937 case OMPC_copyprivate: 10938 case OMPC_ordered: 10939 case OMPC_nowait: 10940 case OMPC_untied: 10941 case OMPC_mergeable: 10942 case OMPC_threadprivate: 10943 case OMPC_allocate: 10944 case OMPC_flush: 10945 case OMPC_read: 10946 case OMPC_write: 10947 case OMPC_update: 10948 case OMPC_capture: 10949 case OMPC_seq_cst: 10950 case OMPC_depend: 10951 case OMPC_device: 10952 case OMPC_threads: 10953 case OMPC_simd: 10954 case OMPC_map: 10955 case OMPC_num_teams: 10956 case OMPC_thread_limit: 10957 case OMPC_priority: 10958 case OMPC_grainsize: 10959 case OMPC_nogroup: 10960 case OMPC_num_tasks: 10961 case OMPC_hint: 10962 case OMPC_dist_schedule: 10963 case OMPC_defaultmap: 10964 case OMPC_unknown: 10965 case OMPC_uniform: 10966 case OMPC_to: 10967 case OMPC_from: 10968 case OMPC_use_device_ptr: 10969 case OMPC_is_device_ptr: 10970 case OMPC_unified_address: 10971 case OMPC_unified_shared_memory: 10972 case OMPC_reverse_offload: 10973 case OMPC_dynamic_allocators: 10974 case OMPC_device_type: 10975 llvm_unreachable("Clause is not allowed."); 10976 } 10977 return Res; 10978 } 10979 10980 static std::string 10981 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10982 ArrayRef<unsigned> Exclude = llvm::None) { 10983 SmallString<256> Buffer; 10984 llvm::raw_svector_ostream Out(Buffer); 10985 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10986 unsigned Skipped = Exclude.size(); 10987 auto S = Exclude.begin(), E = Exclude.end(); 10988 for (unsigned I = First; I < Last; ++I) { 10989 if (std::find(S, E, I) != E) { 10990 --Skipped; 10991 continue; 10992 } 10993 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10994 if (I == Bound - Skipped) 10995 Out << " or "; 10996 else if (I != Bound + 1 - Skipped) 10997 Out << ", "; 10998 } 10999 return Out.str(); 11000 } 11001 11002 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11003 SourceLocation KindKwLoc, 11004 SourceLocation StartLoc, 11005 SourceLocation LParenLoc, 11006 SourceLocation EndLoc) { 11007 if (Kind == OMPC_DEFAULT_unknown) { 11008 static_assert(OMPC_DEFAULT_unknown > 0, 11009 "OMPC_DEFAULT_unknown not greater than 0"); 11010 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11011 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11012 /*Last=*/OMPC_DEFAULT_unknown) 11013 << getOpenMPClauseName(OMPC_default); 11014 return nullptr; 11015 } 11016 switch (Kind) { 11017 case OMPC_DEFAULT_none: 11018 DSAStack->setDefaultDSANone(KindKwLoc); 11019 break; 11020 case OMPC_DEFAULT_shared: 11021 DSAStack->setDefaultDSAShared(KindKwLoc); 11022 break; 11023 case OMPC_DEFAULT_unknown: 11024 llvm_unreachable("Clause kind is not allowed."); 11025 break; 11026 } 11027 return new (Context) 11028 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11029 } 11030 11031 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11032 SourceLocation KindKwLoc, 11033 SourceLocation StartLoc, 11034 SourceLocation LParenLoc, 11035 SourceLocation EndLoc) { 11036 if (Kind == OMPC_PROC_BIND_unknown) { 11037 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11038 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11039 /*Last=*/OMPC_PROC_BIND_unknown) 11040 << getOpenMPClauseName(OMPC_proc_bind); 11041 return nullptr; 11042 } 11043 return new (Context) 11044 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11045 } 11046 11047 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11048 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11049 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11050 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11051 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11052 << getListOfPossibleValues( 11053 OMPC_atomic_default_mem_order, /*First=*/0, 11054 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11055 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11056 return nullptr; 11057 } 11058 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11059 LParenLoc, EndLoc); 11060 } 11061 11062 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11063 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11064 SourceLocation StartLoc, SourceLocation LParenLoc, 11065 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11066 SourceLocation EndLoc) { 11067 OMPClause *Res = nullptr; 11068 switch (Kind) { 11069 case OMPC_schedule: 11070 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11071 assert(Argument.size() == NumberOfElements && 11072 ArgumentLoc.size() == NumberOfElements); 11073 Res = ActOnOpenMPScheduleClause( 11074 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11075 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11076 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11077 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11078 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11079 break; 11080 case OMPC_if: 11081 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11082 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11083 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11084 DelimLoc, EndLoc); 11085 break; 11086 case OMPC_dist_schedule: 11087 Res = ActOnOpenMPDistScheduleClause( 11088 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11089 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11090 break; 11091 case OMPC_defaultmap: 11092 enum { Modifier, DefaultmapKind }; 11093 Res = ActOnOpenMPDefaultmapClause( 11094 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11095 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11096 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11097 EndLoc); 11098 break; 11099 case OMPC_final: 11100 case OMPC_num_threads: 11101 case OMPC_safelen: 11102 case OMPC_simdlen: 11103 case OMPC_allocator: 11104 case OMPC_collapse: 11105 case OMPC_default: 11106 case OMPC_proc_bind: 11107 case OMPC_private: 11108 case OMPC_firstprivate: 11109 case OMPC_lastprivate: 11110 case OMPC_shared: 11111 case OMPC_reduction: 11112 case OMPC_task_reduction: 11113 case OMPC_in_reduction: 11114 case OMPC_linear: 11115 case OMPC_aligned: 11116 case OMPC_copyin: 11117 case OMPC_copyprivate: 11118 case OMPC_ordered: 11119 case OMPC_nowait: 11120 case OMPC_untied: 11121 case OMPC_mergeable: 11122 case OMPC_threadprivate: 11123 case OMPC_allocate: 11124 case OMPC_flush: 11125 case OMPC_read: 11126 case OMPC_write: 11127 case OMPC_update: 11128 case OMPC_capture: 11129 case OMPC_seq_cst: 11130 case OMPC_depend: 11131 case OMPC_device: 11132 case OMPC_threads: 11133 case OMPC_simd: 11134 case OMPC_map: 11135 case OMPC_num_teams: 11136 case OMPC_thread_limit: 11137 case OMPC_priority: 11138 case OMPC_grainsize: 11139 case OMPC_nogroup: 11140 case OMPC_num_tasks: 11141 case OMPC_hint: 11142 case OMPC_unknown: 11143 case OMPC_uniform: 11144 case OMPC_to: 11145 case OMPC_from: 11146 case OMPC_use_device_ptr: 11147 case OMPC_is_device_ptr: 11148 case OMPC_unified_address: 11149 case OMPC_unified_shared_memory: 11150 case OMPC_reverse_offload: 11151 case OMPC_dynamic_allocators: 11152 case OMPC_atomic_default_mem_order: 11153 case OMPC_device_type: 11154 llvm_unreachable("Clause is not allowed."); 11155 } 11156 return Res; 11157 } 11158 11159 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11160 OpenMPScheduleClauseModifier M2, 11161 SourceLocation M1Loc, SourceLocation M2Loc) { 11162 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11163 SmallVector<unsigned, 2> Excluded; 11164 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11165 Excluded.push_back(M2); 11166 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11167 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11168 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11169 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11170 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11171 << getListOfPossibleValues(OMPC_schedule, 11172 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11173 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11174 Excluded) 11175 << getOpenMPClauseName(OMPC_schedule); 11176 return true; 11177 } 11178 return false; 11179 } 11180 11181 OMPClause *Sema::ActOnOpenMPScheduleClause( 11182 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11183 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11184 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11185 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11186 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11187 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11188 return nullptr; 11189 // OpenMP, 2.7.1, Loop Construct, Restrictions 11190 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11191 // but not both. 11192 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11193 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11194 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11195 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11196 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11197 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11198 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11199 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11200 return nullptr; 11201 } 11202 if (Kind == OMPC_SCHEDULE_unknown) { 11203 std::string Values; 11204 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11205 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11206 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11207 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11208 Exclude); 11209 } else { 11210 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11211 /*Last=*/OMPC_SCHEDULE_unknown); 11212 } 11213 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11214 << Values << getOpenMPClauseName(OMPC_schedule); 11215 return nullptr; 11216 } 11217 // OpenMP, 2.7.1, Loop Construct, Restrictions 11218 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11219 // schedule(guided). 11220 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11221 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11222 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11223 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11224 diag::err_omp_schedule_nonmonotonic_static); 11225 return nullptr; 11226 } 11227 Expr *ValExpr = ChunkSize; 11228 Stmt *HelperValStmt = nullptr; 11229 if (ChunkSize) { 11230 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11231 !ChunkSize->isInstantiationDependent() && 11232 !ChunkSize->containsUnexpandedParameterPack()) { 11233 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11234 ExprResult Val = 11235 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11236 if (Val.isInvalid()) 11237 return nullptr; 11238 11239 ValExpr = Val.get(); 11240 11241 // OpenMP [2.7.1, Restrictions] 11242 // chunk_size must be a loop invariant integer expression with a positive 11243 // value. 11244 llvm::APSInt Result; 11245 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11246 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11247 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11248 << "schedule" << 1 << ChunkSize->getSourceRange(); 11249 return nullptr; 11250 } 11251 } else if (getOpenMPCaptureRegionForClause( 11252 DSAStack->getCurrentDirective(), OMPC_schedule) != 11253 OMPD_unknown && 11254 !CurContext->isDependentContext()) { 11255 ValExpr = MakeFullExpr(ValExpr).get(); 11256 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11257 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11258 HelperValStmt = buildPreInits(Context, Captures); 11259 } 11260 } 11261 } 11262 11263 return new (Context) 11264 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11265 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11266 } 11267 11268 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11269 SourceLocation StartLoc, 11270 SourceLocation EndLoc) { 11271 OMPClause *Res = nullptr; 11272 switch (Kind) { 11273 case OMPC_ordered: 11274 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11275 break; 11276 case OMPC_nowait: 11277 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11278 break; 11279 case OMPC_untied: 11280 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11281 break; 11282 case OMPC_mergeable: 11283 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11284 break; 11285 case OMPC_read: 11286 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11287 break; 11288 case OMPC_write: 11289 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11290 break; 11291 case OMPC_update: 11292 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11293 break; 11294 case OMPC_capture: 11295 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11296 break; 11297 case OMPC_seq_cst: 11298 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11299 break; 11300 case OMPC_threads: 11301 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11302 break; 11303 case OMPC_simd: 11304 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11305 break; 11306 case OMPC_nogroup: 11307 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11308 break; 11309 case OMPC_unified_address: 11310 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11311 break; 11312 case OMPC_unified_shared_memory: 11313 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11314 break; 11315 case OMPC_reverse_offload: 11316 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11317 break; 11318 case OMPC_dynamic_allocators: 11319 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11320 break; 11321 case OMPC_if: 11322 case OMPC_final: 11323 case OMPC_num_threads: 11324 case OMPC_safelen: 11325 case OMPC_simdlen: 11326 case OMPC_allocator: 11327 case OMPC_collapse: 11328 case OMPC_schedule: 11329 case OMPC_private: 11330 case OMPC_firstprivate: 11331 case OMPC_lastprivate: 11332 case OMPC_shared: 11333 case OMPC_reduction: 11334 case OMPC_task_reduction: 11335 case OMPC_in_reduction: 11336 case OMPC_linear: 11337 case OMPC_aligned: 11338 case OMPC_copyin: 11339 case OMPC_copyprivate: 11340 case OMPC_default: 11341 case OMPC_proc_bind: 11342 case OMPC_threadprivate: 11343 case OMPC_allocate: 11344 case OMPC_flush: 11345 case OMPC_depend: 11346 case OMPC_device: 11347 case OMPC_map: 11348 case OMPC_num_teams: 11349 case OMPC_thread_limit: 11350 case OMPC_priority: 11351 case OMPC_grainsize: 11352 case OMPC_num_tasks: 11353 case OMPC_hint: 11354 case OMPC_dist_schedule: 11355 case OMPC_defaultmap: 11356 case OMPC_unknown: 11357 case OMPC_uniform: 11358 case OMPC_to: 11359 case OMPC_from: 11360 case OMPC_use_device_ptr: 11361 case OMPC_is_device_ptr: 11362 case OMPC_atomic_default_mem_order: 11363 case OMPC_device_type: 11364 llvm_unreachable("Clause is not allowed."); 11365 } 11366 return Res; 11367 } 11368 11369 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11370 SourceLocation EndLoc) { 11371 DSAStack->setNowaitRegion(); 11372 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11373 } 11374 11375 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11376 SourceLocation EndLoc) { 11377 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11378 } 11379 11380 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11381 SourceLocation EndLoc) { 11382 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11383 } 11384 11385 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11386 SourceLocation EndLoc) { 11387 return new (Context) OMPReadClause(StartLoc, EndLoc); 11388 } 11389 11390 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11391 SourceLocation EndLoc) { 11392 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11393 } 11394 11395 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11396 SourceLocation EndLoc) { 11397 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11398 } 11399 11400 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11401 SourceLocation EndLoc) { 11402 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11403 } 11404 11405 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11406 SourceLocation EndLoc) { 11407 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11408 } 11409 11410 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11411 SourceLocation EndLoc) { 11412 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11413 } 11414 11415 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11416 SourceLocation EndLoc) { 11417 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11418 } 11419 11420 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11421 SourceLocation EndLoc) { 11422 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11423 } 11424 11425 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11426 SourceLocation EndLoc) { 11427 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11428 } 11429 11430 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11431 SourceLocation EndLoc) { 11432 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11433 } 11434 11435 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11436 SourceLocation EndLoc) { 11437 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11438 } 11439 11440 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11441 SourceLocation EndLoc) { 11442 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11443 } 11444 11445 OMPClause *Sema::ActOnOpenMPVarListClause( 11446 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11447 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11448 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11449 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11450 OpenMPLinearClauseKind LinKind, 11451 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11452 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11453 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11454 SourceLocation StartLoc = Locs.StartLoc; 11455 SourceLocation LParenLoc = Locs.LParenLoc; 11456 SourceLocation EndLoc = Locs.EndLoc; 11457 OMPClause *Res = nullptr; 11458 switch (Kind) { 11459 case OMPC_private: 11460 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11461 break; 11462 case OMPC_firstprivate: 11463 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11464 break; 11465 case OMPC_lastprivate: 11466 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11467 break; 11468 case OMPC_shared: 11469 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11470 break; 11471 case OMPC_reduction: 11472 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11473 EndLoc, ReductionOrMapperIdScopeSpec, 11474 ReductionOrMapperId); 11475 break; 11476 case OMPC_task_reduction: 11477 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11478 EndLoc, ReductionOrMapperIdScopeSpec, 11479 ReductionOrMapperId); 11480 break; 11481 case OMPC_in_reduction: 11482 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11483 EndLoc, ReductionOrMapperIdScopeSpec, 11484 ReductionOrMapperId); 11485 break; 11486 case OMPC_linear: 11487 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11488 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11489 break; 11490 case OMPC_aligned: 11491 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11492 ColonLoc, EndLoc); 11493 break; 11494 case OMPC_copyin: 11495 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11496 break; 11497 case OMPC_copyprivate: 11498 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11499 break; 11500 case OMPC_flush: 11501 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11502 break; 11503 case OMPC_depend: 11504 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11505 StartLoc, LParenLoc, EndLoc); 11506 break; 11507 case OMPC_map: 11508 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11509 ReductionOrMapperIdScopeSpec, 11510 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11511 DepLinMapLoc, ColonLoc, VarList, Locs); 11512 break; 11513 case OMPC_to: 11514 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11515 ReductionOrMapperId, Locs); 11516 break; 11517 case OMPC_from: 11518 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11519 ReductionOrMapperId, Locs); 11520 break; 11521 case OMPC_use_device_ptr: 11522 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11523 break; 11524 case OMPC_is_device_ptr: 11525 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11526 break; 11527 case OMPC_allocate: 11528 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11529 ColonLoc, EndLoc); 11530 break; 11531 case OMPC_if: 11532 case OMPC_final: 11533 case OMPC_num_threads: 11534 case OMPC_safelen: 11535 case OMPC_simdlen: 11536 case OMPC_allocator: 11537 case OMPC_collapse: 11538 case OMPC_default: 11539 case OMPC_proc_bind: 11540 case OMPC_schedule: 11541 case OMPC_ordered: 11542 case OMPC_nowait: 11543 case OMPC_untied: 11544 case OMPC_mergeable: 11545 case OMPC_threadprivate: 11546 case OMPC_read: 11547 case OMPC_write: 11548 case OMPC_update: 11549 case OMPC_capture: 11550 case OMPC_seq_cst: 11551 case OMPC_device: 11552 case OMPC_threads: 11553 case OMPC_simd: 11554 case OMPC_num_teams: 11555 case OMPC_thread_limit: 11556 case OMPC_priority: 11557 case OMPC_grainsize: 11558 case OMPC_nogroup: 11559 case OMPC_num_tasks: 11560 case OMPC_hint: 11561 case OMPC_dist_schedule: 11562 case OMPC_defaultmap: 11563 case OMPC_unknown: 11564 case OMPC_uniform: 11565 case OMPC_unified_address: 11566 case OMPC_unified_shared_memory: 11567 case OMPC_reverse_offload: 11568 case OMPC_dynamic_allocators: 11569 case OMPC_atomic_default_mem_order: 11570 case OMPC_device_type: 11571 llvm_unreachable("Clause is not allowed."); 11572 } 11573 return Res; 11574 } 11575 11576 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11577 ExprObjectKind OK, SourceLocation Loc) { 11578 ExprResult Res = BuildDeclRefExpr( 11579 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11580 if (!Res.isUsable()) 11581 return ExprError(); 11582 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11583 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11584 if (!Res.isUsable()) 11585 return ExprError(); 11586 } 11587 if (VK != VK_LValue && Res.get()->isGLValue()) { 11588 Res = DefaultLvalueConversion(Res.get()); 11589 if (!Res.isUsable()) 11590 return ExprError(); 11591 } 11592 return Res; 11593 } 11594 11595 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11596 SourceLocation StartLoc, 11597 SourceLocation LParenLoc, 11598 SourceLocation EndLoc) { 11599 SmallVector<Expr *, 8> Vars; 11600 SmallVector<Expr *, 8> PrivateCopies; 11601 for (Expr *RefExpr : VarList) { 11602 assert(RefExpr && "NULL expr in OpenMP private clause."); 11603 SourceLocation ELoc; 11604 SourceRange ERange; 11605 Expr *SimpleRefExpr = RefExpr; 11606 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11607 if (Res.second) { 11608 // It will be analyzed later. 11609 Vars.push_back(RefExpr); 11610 PrivateCopies.push_back(nullptr); 11611 } 11612 ValueDecl *D = Res.first; 11613 if (!D) 11614 continue; 11615 11616 QualType Type = D->getType(); 11617 auto *VD = dyn_cast<VarDecl>(D); 11618 11619 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11620 // A variable that appears in a private clause must not have an incomplete 11621 // type or a reference type. 11622 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11623 continue; 11624 Type = Type.getNonReferenceType(); 11625 11626 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11627 // A variable that is privatized must not have a const-qualified type 11628 // unless it is of class type with a mutable member. This restriction does 11629 // not apply to the firstprivate clause. 11630 // 11631 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11632 // A variable that appears in a private clause must not have a 11633 // const-qualified type unless it is of class type with a mutable member. 11634 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11635 continue; 11636 11637 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11638 // in a Construct] 11639 // Variables with the predetermined data-sharing attributes may not be 11640 // listed in data-sharing attributes clauses, except for the cases 11641 // listed below. For these exceptions only, listing a predetermined 11642 // variable in a data-sharing attribute clause is allowed and overrides 11643 // the variable's predetermined data-sharing attributes. 11644 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11645 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 11646 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11647 << getOpenMPClauseName(OMPC_private); 11648 reportOriginalDsa(*this, DSAStack, D, DVar); 11649 continue; 11650 } 11651 11652 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11653 // Variably modified types are not supported for tasks. 11654 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11655 isOpenMPTaskingDirective(CurrDir)) { 11656 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11657 << getOpenMPClauseName(OMPC_private) << Type 11658 << getOpenMPDirectiveName(CurrDir); 11659 bool IsDecl = 11660 !VD || 11661 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11662 Diag(D->getLocation(), 11663 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11664 << D; 11665 continue; 11666 } 11667 11668 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11669 // A list item cannot appear in both a map clause and a data-sharing 11670 // attribute clause on the same construct 11671 // 11672 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11673 // A list item cannot appear in both a map clause and a data-sharing 11674 // attribute clause on the same construct unless the construct is a 11675 // combined construct. 11676 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 11677 CurrDir == OMPD_target) { 11678 OpenMPClauseKind ConflictKind; 11679 if (DSAStack->checkMappableExprComponentListsForDecl( 11680 VD, /*CurrentRegionOnly=*/true, 11681 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 11682 OpenMPClauseKind WhereFoundClauseKind) -> bool { 11683 ConflictKind = WhereFoundClauseKind; 11684 return true; 11685 })) { 11686 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11687 << getOpenMPClauseName(OMPC_private) 11688 << getOpenMPClauseName(ConflictKind) 11689 << getOpenMPDirectiveName(CurrDir); 11690 reportOriginalDsa(*this, DSAStack, D, DVar); 11691 continue; 11692 } 11693 } 11694 11695 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 11696 // A variable of class type (or array thereof) that appears in a private 11697 // clause requires an accessible, unambiguous default constructor for the 11698 // class type. 11699 // Generate helper private variable and initialize it with the default 11700 // value. The address of the original variable is replaced by the address of 11701 // the new private variable in CodeGen. This new variable is not added to 11702 // IdResolver, so the code in the OpenMP region uses original variable for 11703 // proper diagnostics. 11704 Type = Type.getUnqualifiedType(); 11705 VarDecl *VDPrivate = 11706 buildVarDecl(*this, ELoc, Type, D->getName(), 11707 D->hasAttrs() ? &D->getAttrs() : nullptr, 11708 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11709 ActOnUninitializedDecl(VDPrivate); 11710 if (VDPrivate->isInvalidDecl()) 11711 continue; 11712 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11713 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 11714 11715 DeclRefExpr *Ref = nullptr; 11716 if (!VD && !CurContext->isDependentContext()) 11717 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11718 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 11719 Vars.push_back((VD || CurContext->isDependentContext()) 11720 ? RefExpr->IgnoreParens() 11721 : Ref); 11722 PrivateCopies.push_back(VDPrivateRefExpr); 11723 } 11724 11725 if (Vars.empty()) 11726 return nullptr; 11727 11728 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11729 PrivateCopies); 11730 } 11731 11732 namespace { 11733 class DiagsUninitializedSeveretyRAII { 11734 private: 11735 DiagnosticsEngine &Diags; 11736 SourceLocation SavedLoc; 11737 bool IsIgnored = false; 11738 11739 public: 11740 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 11741 bool IsIgnored) 11742 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 11743 if (!IsIgnored) { 11744 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 11745 /*Map*/ diag::Severity::Ignored, Loc); 11746 } 11747 } 11748 ~DiagsUninitializedSeveretyRAII() { 11749 if (!IsIgnored) 11750 Diags.popMappings(SavedLoc); 11751 } 11752 }; 11753 } 11754 11755 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 11756 SourceLocation StartLoc, 11757 SourceLocation LParenLoc, 11758 SourceLocation EndLoc) { 11759 SmallVector<Expr *, 8> Vars; 11760 SmallVector<Expr *, 8> PrivateCopies; 11761 SmallVector<Expr *, 8> Inits; 11762 SmallVector<Decl *, 4> ExprCaptures; 11763 bool IsImplicitClause = 11764 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 11765 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 11766 11767 for (Expr *RefExpr : VarList) { 11768 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 11769 SourceLocation ELoc; 11770 SourceRange ERange; 11771 Expr *SimpleRefExpr = RefExpr; 11772 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11773 if (Res.second) { 11774 // It will be analyzed later. 11775 Vars.push_back(RefExpr); 11776 PrivateCopies.push_back(nullptr); 11777 Inits.push_back(nullptr); 11778 } 11779 ValueDecl *D = Res.first; 11780 if (!D) 11781 continue; 11782 11783 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 11784 QualType Type = D->getType(); 11785 auto *VD = dyn_cast<VarDecl>(D); 11786 11787 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11788 // A variable that appears in a private clause must not have an incomplete 11789 // type or a reference type. 11790 if (RequireCompleteType(ELoc, Type, 11791 diag::err_omp_firstprivate_incomplete_type)) 11792 continue; 11793 Type = Type.getNonReferenceType(); 11794 11795 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 11796 // A variable of class type (or array thereof) that appears in a private 11797 // clause requires an accessible, unambiguous copy constructor for the 11798 // class type. 11799 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11800 11801 // If an implicit firstprivate variable found it was checked already. 11802 DSAStackTy::DSAVarData TopDVar; 11803 if (!IsImplicitClause) { 11804 DSAStackTy::DSAVarData DVar = 11805 DSAStack->getTopDSA(D, /*FromParent=*/false); 11806 TopDVar = DVar; 11807 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11808 bool IsConstant = ElemType.isConstant(Context); 11809 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 11810 // A list item that specifies a given variable may not appear in more 11811 // than one clause on the same directive, except that a variable may be 11812 // specified in both firstprivate and lastprivate clauses. 11813 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11814 // A list item may appear in a firstprivate or lastprivate clause but not 11815 // both. 11816 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 11817 (isOpenMPDistributeDirective(CurrDir) || 11818 DVar.CKind != OMPC_lastprivate) && 11819 DVar.RefExpr) { 11820 Diag(ELoc, diag::err_omp_wrong_dsa) 11821 << getOpenMPClauseName(DVar.CKind) 11822 << getOpenMPClauseName(OMPC_firstprivate); 11823 reportOriginalDsa(*this, DSAStack, D, DVar); 11824 continue; 11825 } 11826 11827 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11828 // in a Construct] 11829 // Variables with the predetermined data-sharing attributes may not be 11830 // listed in data-sharing attributes clauses, except for the cases 11831 // listed below. For these exceptions only, listing a predetermined 11832 // variable in a data-sharing attribute clause is allowed and overrides 11833 // the variable's predetermined data-sharing attributes. 11834 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11835 // in a Construct, C/C++, p.2] 11836 // Variables with const-qualified type having no mutable member may be 11837 // listed in a firstprivate clause, even if they are static data members. 11838 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11839 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11840 Diag(ELoc, diag::err_omp_wrong_dsa) 11841 << getOpenMPClauseName(DVar.CKind) 11842 << getOpenMPClauseName(OMPC_firstprivate); 11843 reportOriginalDsa(*this, DSAStack, D, DVar); 11844 continue; 11845 } 11846 11847 // OpenMP [2.9.3.4, Restrictions, p.2] 11848 // A list item that is private within a parallel region must not appear 11849 // in a firstprivate clause on a worksharing construct if any of the 11850 // worksharing regions arising from the worksharing construct ever bind 11851 // to any of the parallel regions arising from the parallel construct. 11852 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11853 // A list item that is private within a teams region must not appear in a 11854 // firstprivate clause on a distribute construct if any of the distribute 11855 // regions arising from the distribute construct ever bind to any of the 11856 // teams regions arising from the teams construct. 11857 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11858 // A list item that appears in a reduction clause of a teams construct 11859 // must not appear in a firstprivate clause on a distribute construct if 11860 // any of the distribute regions arising from the distribute construct 11861 // ever bind to any of the teams regions arising from the teams construct. 11862 if ((isOpenMPWorksharingDirective(CurrDir) || 11863 isOpenMPDistributeDirective(CurrDir)) && 11864 !isOpenMPParallelDirective(CurrDir) && 11865 !isOpenMPTeamsDirective(CurrDir)) { 11866 DVar = DSAStack->getImplicitDSA(D, true); 11867 if (DVar.CKind != OMPC_shared && 11868 (isOpenMPParallelDirective(DVar.DKind) || 11869 isOpenMPTeamsDirective(DVar.DKind) || 11870 DVar.DKind == OMPD_unknown)) { 11871 Diag(ELoc, diag::err_omp_required_access) 11872 << getOpenMPClauseName(OMPC_firstprivate) 11873 << getOpenMPClauseName(OMPC_shared); 11874 reportOriginalDsa(*this, DSAStack, D, DVar); 11875 continue; 11876 } 11877 } 11878 // OpenMP [2.9.3.4, Restrictions, p.3] 11879 // A list item that appears in a reduction clause of a parallel construct 11880 // must not appear in a firstprivate clause on a worksharing or task 11881 // construct if any of the worksharing or task regions arising from the 11882 // worksharing or task construct ever bind to any of the parallel regions 11883 // arising from the parallel construct. 11884 // OpenMP [2.9.3.4, Restrictions, p.4] 11885 // A list item that appears in a reduction clause in worksharing 11886 // construct must not appear in a firstprivate clause in a task construct 11887 // encountered during execution of any of the worksharing regions arising 11888 // from the worksharing construct. 11889 if (isOpenMPTaskingDirective(CurrDir)) { 11890 DVar = DSAStack->hasInnermostDSA( 11891 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11892 [](OpenMPDirectiveKind K) { 11893 return isOpenMPParallelDirective(K) || 11894 isOpenMPWorksharingDirective(K) || 11895 isOpenMPTeamsDirective(K); 11896 }, 11897 /*FromParent=*/true); 11898 if (DVar.CKind == OMPC_reduction && 11899 (isOpenMPParallelDirective(DVar.DKind) || 11900 isOpenMPWorksharingDirective(DVar.DKind) || 11901 isOpenMPTeamsDirective(DVar.DKind))) { 11902 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11903 << getOpenMPDirectiveName(DVar.DKind); 11904 reportOriginalDsa(*this, DSAStack, D, DVar); 11905 continue; 11906 } 11907 } 11908 11909 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11910 // A list item cannot appear in both a map clause and a data-sharing 11911 // attribute clause on the same construct 11912 // 11913 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11914 // A list item cannot appear in both a map clause and a data-sharing 11915 // attribute clause on the same construct unless the construct is a 11916 // combined construct. 11917 if ((LangOpts.OpenMP <= 45 && 11918 isOpenMPTargetExecutionDirective(CurrDir)) || 11919 CurrDir == OMPD_target) { 11920 OpenMPClauseKind ConflictKind; 11921 if (DSAStack->checkMappableExprComponentListsForDecl( 11922 VD, /*CurrentRegionOnly=*/true, 11923 [&ConflictKind]( 11924 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11925 OpenMPClauseKind WhereFoundClauseKind) { 11926 ConflictKind = WhereFoundClauseKind; 11927 return true; 11928 })) { 11929 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11930 << getOpenMPClauseName(OMPC_firstprivate) 11931 << getOpenMPClauseName(ConflictKind) 11932 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11933 reportOriginalDsa(*this, DSAStack, D, DVar); 11934 continue; 11935 } 11936 } 11937 } 11938 11939 // Variably modified types are not supported for tasks. 11940 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11941 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11942 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11943 << getOpenMPClauseName(OMPC_firstprivate) << Type 11944 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11945 bool IsDecl = 11946 !VD || 11947 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11948 Diag(D->getLocation(), 11949 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11950 << D; 11951 continue; 11952 } 11953 11954 Type = Type.getUnqualifiedType(); 11955 VarDecl *VDPrivate = 11956 buildVarDecl(*this, ELoc, Type, D->getName(), 11957 D->hasAttrs() ? &D->getAttrs() : nullptr, 11958 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11959 // Generate helper private variable and initialize it with the value of the 11960 // original variable. The address of the original variable is replaced by 11961 // the address of the new private variable in the CodeGen. This new variable 11962 // is not added to IdResolver, so the code in the OpenMP region uses 11963 // original variable for proper diagnostics and variable capturing. 11964 Expr *VDInitRefExpr = nullptr; 11965 // For arrays generate initializer for single element and replace it by the 11966 // original array element in CodeGen. 11967 if (Type->isArrayType()) { 11968 VarDecl *VDInit = 11969 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11970 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11971 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11972 ElemType = ElemType.getUnqualifiedType(); 11973 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11974 ".firstprivate.temp"); 11975 InitializedEntity Entity = 11976 InitializedEntity::InitializeVariable(VDInitTemp); 11977 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11978 11979 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11980 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11981 if (Result.isInvalid()) 11982 VDPrivate->setInvalidDecl(); 11983 else 11984 VDPrivate->setInit(Result.getAs<Expr>()); 11985 // Remove temp variable declaration. 11986 Context.Deallocate(VDInitTemp); 11987 } else { 11988 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11989 ".firstprivate.temp"); 11990 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11991 RefExpr->getExprLoc()); 11992 AddInitializerToDecl(VDPrivate, 11993 DefaultLvalueConversion(VDInitRefExpr).get(), 11994 /*DirectInit=*/false); 11995 } 11996 if (VDPrivate->isInvalidDecl()) { 11997 if (IsImplicitClause) { 11998 Diag(RefExpr->getExprLoc(), 11999 diag::note_omp_task_predetermined_firstprivate_here); 12000 } 12001 continue; 12002 } 12003 CurContext->addDecl(VDPrivate); 12004 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12005 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12006 RefExpr->getExprLoc()); 12007 DeclRefExpr *Ref = nullptr; 12008 if (!VD && !CurContext->isDependentContext()) { 12009 if (TopDVar.CKind == OMPC_lastprivate) { 12010 Ref = TopDVar.PrivateCopy; 12011 } else { 12012 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12013 if (!isOpenMPCapturedDecl(D)) 12014 ExprCaptures.push_back(Ref->getDecl()); 12015 } 12016 } 12017 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12018 Vars.push_back((VD || CurContext->isDependentContext()) 12019 ? RefExpr->IgnoreParens() 12020 : Ref); 12021 PrivateCopies.push_back(VDPrivateRefExpr); 12022 Inits.push_back(VDInitRefExpr); 12023 } 12024 12025 if (Vars.empty()) 12026 return nullptr; 12027 12028 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12029 Vars, PrivateCopies, Inits, 12030 buildPreInits(Context, ExprCaptures)); 12031 } 12032 12033 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12034 SourceLocation StartLoc, 12035 SourceLocation LParenLoc, 12036 SourceLocation EndLoc) { 12037 SmallVector<Expr *, 8> Vars; 12038 SmallVector<Expr *, 8> SrcExprs; 12039 SmallVector<Expr *, 8> DstExprs; 12040 SmallVector<Expr *, 8> AssignmentOps; 12041 SmallVector<Decl *, 4> ExprCaptures; 12042 SmallVector<Expr *, 4> ExprPostUpdates; 12043 for (Expr *RefExpr : VarList) { 12044 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12045 SourceLocation ELoc; 12046 SourceRange ERange; 12047 Expr *SimpleRefExpr = RefExpr; 12048 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12049 if (Res.second) { 12050 // It will be analyzed later. 12051 Vars.push_back(RefExpr); 12052 SrcExprs.push_back(nullptr); 12053 DstExprs.push_back(nullptr); 12054 AssignmentOps.push_back(nullptr); 12055 } 12056 ValueDecl *D = Res.first; 12057 if (!D) 12058 continue; 12059 12060 QualType Type = D->getType(); 12061 auto *VD = dyn_cast<VarDecl>(D); 12062 12063 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12064 // A variable that appears in a lastprivate clause must not have an 12065 // incomplete type or a reference type. 12066 if (RequireCompleteType(ELoc, Type, 12067 diag::err_omp_lastprivate_incomplete_type)) 12068 continue; 12069 Type = Type.getNonReferenceType(); 12070 12071 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12072 // A variable that is privatized must not have a const-qualified type 12073 // unless it is of class type with a mutable member. This restriction does 12074 // not apply to the firstprivate clause. 12075 // 12076 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12077 // A variable that appears in a lastprivate clause must not have a 12078 // const-qualified type unless it is of class type with a mutable member. 12079 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12080 continue; 12081 12082 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12083 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12084 // in a Construct] 12085 // Variables with the predetermined data-sharing attributes may not be 12086 // listed in data-sharing attributes clauses, except for the cases 12087 // listed below. 12088 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12089 // A list item may appear in a firstprivate or lastprivate clause but not 12090 // both. 12091 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12092 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12093 (isOpenMPDistributeDirective(CurrDir) || 12094 DVar.CKind != OMPC_firstprivate) && 12095 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12096 Diag(ELoc, diag::err_omp_wrong_dsa) 12097 << getOpenMPClauseName(DVar.CKind) 12098 << getOpenMPClauseName(OMPC_lastprivate); 12099 reportOriginalDsa(*this, DSAStack, D, DVar); 12100 continue; 12101 } 12102 12103 // OpenMP [2.14.3.5, Restrictions, p.2] 12104 // A list item that is private within a parallel region, or that appears in 12105 // the reduction clause of a parallel construct, must not appear in a 12106 // lastprivate clause on a worksharing construct if any of the corresponding 12107 // worksharing regions ever binds to any of the corresponding parallel 12108 // regions. 12109 DSAStackTy::DSAVarData TopDVar = DVar; 12110 if (isOpenMPWorksharingDirective(CurrDir) && 12111 !isOpenMPParallelDirective(CurrDir) && 12112 !isOpenMPTeamsDirective(CurrDir)) { 12113 DVar = DSAStack->getImplicitDSA(D, true); 12114 if (DVar.CKind != OMPC_shared) { 12115 Diag(ELoc, diag::err_omp_required_access) 12116 << getOpenMPClauseName(OMPC_lastprivate) 12117 << getOpenMPClauseName(OMPC_shared); 12118 reportOriginalDsa(*this, DSAStack, D, DVar); 12119 continue; 12120 } 12121 } 12122 12123 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12124 // A variable of class type (or array thereof) that appears in a 12125 // lastprivate clause requires an accessible, unambiguous default 12126 // constructor for the class type, unless the list item is also specified 12127 // in a firstprivate clause. 12128 // A variable of class type (or array thereof) that appears in a 12129 // lastprivate clause requires an accessible, unambiguous copy assignment 12130 // operator for the class type. 12131 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12132 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12133 Type.getUnqualifiedType(), ".lastprivate.src", 12134 D->hasAttrs() ? &D->getAttrs() : nullptr); 12135 DeclRefExpr *PseudoSrcExpr = 12136 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12137 VarDecl *DstVD = 12138 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12139 D->hasAttrs() ? &D->getAttrs() : nullptr); 12140 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12141 // For arrays generate assignment operation for single element and replace 12142 // it by the original array element in CodeGen. 12143 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12144 PseudoDstExpr, PseudoSrcExpr); 12145 if (AssignmentOp.isInvalid()) 12146 continue; 12147 AssignmentOp = 12148 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12149 if (AssignmentOp.isInvalid()) 12150 continue; 12151 12152 DeclRefExpr *Ref = nullptr; 12153 if (!VD && !CurContext->isDependentContext()) { 12154 if (TopDVar.CKind == OMPC_firstprivate) { 12155 Ref = TopDVar.PrivateCopy; 12156 } else { 12157 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12158 if (!isOpenMPCapturedDecl(D)) 12159 ExprCaptures.push_back(Ref->getDecl()); 12160 } 12161 if (TopDVar.CKind == OMPC_firstprivate || 12162 (!isOpenMPCapturedDecl(D) && 12163 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12164 ExprResult RefRes = DefaultLvalueConversion(Ref); 12165 if (!RefRes.isUsable()) 12166 continue; 12167 ExprResult PostUpdateRes = 12168 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12169 RefRes.get()); 12170 if (!PostUpdateRes.isUsable()) 12171 continue; 12172 ExprPostUpdates.push_back( 12173 IgnoredValueConversions(PostUpdateRes.get()).get()); 12174 } 12175 } 12176 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12177 Vars.push_back((VD || CurContext->isDependentContext()) 12178 ? RefExpr->IgnoreParens() 12179 : Ref); 12180 SrcExprs.push_back(PseudoSrcExpr); 12181 DstExprs.push_back(PseudoDstExpr); 12182 AssignmentOps.push_back(AssignmentOp.get()); 12183 } 12184 12185 if (Vars.empty()) 12186 return nullptr; 12187 12188 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12189 Vars, SrcExprs, DstExprs, AssignmentOps, 12190 buildPreInits(Context, ExprCaptures), 12191 buildPostUpdate(*this, ExprPostUpdates)); 12192 } 12193 12194 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12195 SourceLocation StartLoc, 12196 SourceLocation LParenLoc, 12197 SourceLocation EndLoc) { 12198 SmallVector<Expr *, 8> Vars; 12199 for (Expr *RefExpr : VarList) { 12200 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12201 SourceLocation ELoc; 12202 SourceRange ERange; 12203 Expr *SimpleRefExpr = RefExpr; 12204 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12205 if (Res.second) { 12206 // It will be analyzed later. 12207 Vars.push_back(RefExpr); 12208 } 12209 ValueDecl *D = Res.first; 12210 if (!D) 12211 continue; 12212 12213 auto *VD = dyn_cast<VarDecl>(D); 12214 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12215 // in a Construct] 12216 // Variables with the predetermined data-sharing attributes may not be 12217 // listed in data-sharing attributes clauses, except for the cases 12218 // listed below. For these exceptions only, listing a predetermined 12219 // variable in a data-sharing attribute clause is allowed and overrides 12220 // the variable's predetermined data-sharing attributes. 12221 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12222 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12223 DVar.RefExpr) { 12224 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12225 << getOpenMPClauseName(OMPC_shared); 12226 reportOriginalDsa(*this, DSAStack, D, DVar); 12227 continue; 12228 } 12229 12230 DeclRefExpr *Ref = nullptr; 12231 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12232 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12233 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12234 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12235 ? RefExpr->IgnoreParens() 12236 : Ref); 12237 } 12238 12239 if (Vars.empty()) 12240 return nullptr; 12241 12242 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12243 } 12244 12245 namespace { 12246 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12247 DSAStackTy *Stack; 12248 12249 public: 12250 bool VisitDeclRefExpr(DeclRefExpr *E) { 12251 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12252 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12253 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12254 return false; 12255 if (DVar.CKind != OMPC_unknown) 12256 return true; 12257 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12258 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12259 /*FromParent=*/true); 12260 return DVarPrivate.CKind != OMPC_unknown; 12261 } 12262 return false; 12263 } 12264 bool VisitStmt(Stmt *S) { 12265 for (Stmt *Child : S->children()) { 12266 if (Child && Visit(Child)) 12267 return true; 12268 } 12269 return false; 12270 } 12271 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12272 }; 12273 } // namespace 12274 12275 namespace { 12276 // Transform MemberExpression for specified FieldDecl of current class to 12277 // DeclRefExpr to specified OMPCapturedExprDecl. 12278 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12279 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12280 ValueDecl *Field = nullptr; 12281 DeclRefExpr *CapturedExpr = nullptr; 12282 12283 public: 12284 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12285 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12286 12287 ExprResult TransformMemberExpr(MemberExpr *E) { 12288 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12289 E->getMemberDecl() == Field) { 12290 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12291 return CapturedExpr; 12292 } 12293 return BaseTransform::TransformMemberExpr(E); 12294 } 12295 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12296 }; 12297 } // namespace 12298 12299 template <typename T, typename U> 12300 static T filterLookupForUDReductionAndMapper( 12301 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12302 for (U &Set : Lookups) { 12303 for (auto *D : Set) { 12304 if (T Res = Gen(cast<ValueDecl>(D))) 12305 return Res; 12306 } 12307 } 12308 return T(); 12309 } 12310 12311 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12312 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12313 12314 for (auto RD : D->redecls()) { 12315 // Don't bother with extra checks if we already know this one isn't visible. 12316 if (RD == D) 12317 continue; 12318 12319 auto ND = cast<NamedDecl>(RD); 12320 if (LookupResult::isVisible(SemaRef, ND)) 12321 return ND; 12322 } 12323 12324 return nullptr; 12325 } 12326 12327 static void 12328 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12329 SourceLocation Loc, QualType Ty, 12330 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12331 // Find all of the associated namespaces and classes based on the 12332 // arguments we have. 12333 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12334 Sema::AssociatedClassSet AssociatedClasses; 12335 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12336 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12337 AssociatedClasses); 12338 12339 // C++ [basic.lookup.argdep]p3: 12340 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12341 // and let Y be the lookup set produced by argument dependent 12342 // lookup (defined as follows). If X contains [...] then Y is 12343 // empty. Otherwise Y is the set of declarations found in the 12344 // namespaces associated with the argument types as described 12345 // below. The set of declarations found by the lookup of the name 12346 // is the union of X and Y. 12347 // 12348 // Here, we compute Y and add its members to the overloaded 12349 // candidate set. 12350 for (auto *NS : AssociatedNamespaces) { 12351 // When considering an associated namespace, the lookup is the 12352 // same as the lookup performed when the associated namespace is 12353 // used as a qualifier (3.4.3.2) except that: 12354 // 12355 // -- Any using-directives in the associated namespace are 12356 // ignored. 12357 // 12358 // -- Any namespace-scope friend functions declared in 12359 // associated classes are visible within their respective 12360 // namespaces even if they are not visible during an ordinary 12361 // lookup (11.4). 12362 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12363 for (auto *D : R) { 12364 auto *Underlying = D; 12365 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12366 Underlying = USD->getTargetDecl(); 12367 12368 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12369 !isa<OMPDeclareMapperDecl>(Underlying)) 12370 continue; 12371 12372 if (!SemaRef.isVisible(D)) { 12373 D = findAcceptableDecl(SemaRef, D); 12374 if (!D) 12375 continue; 12376 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12377 Underlying = USD->getTargetDecl(); 12378 } 12379 Lookups.emplace_back(); 12380 Lookups.back().addDecl(Underlying); 12381 } 12382 } 12383 } 12384 12385 static ExprResult 12386 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12387 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12388 const DeclarationNameInfo &ReductionId, QualType Ty, 12389 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12390 if (ReductionIdScopeSpec.isInvalid()) 12391 return ExprError(); 12392 SmallVector<UnresolvedSet<8>, 4> Lookups; 12393 if (S) { 12394 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12395 Lookup.suppressDiagnostics(); 12396 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12397 NamedDecl *D = Lookup.getRepresentativeDecl(); 12398 do { 12399 S = S->getParent(); 12400 } while (S && !S->isDeclScope(D)); 12401 if (S) 12402 S = S->getParent(); 12403 Lookups.emplace_back(); 12404 Lookups.back().append(Lookup.begin(), Lookup.end()); 12405 Lookup.clear(); 12406 } 12407 } else if (auto *ULE = 12408 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12409 Lookups.push_back(UnresolvedSet<8>()); 12410 Decl *PrevD = nullptr; 12411 for (NamedDecl *D : ULE->decls()) { 12412 if (D == PrevD) 12413 Lookups.push_back(UnresolvedSet<8>()); 12414 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12415 Lookups.back().addDecl(DRD); 12416 PrevD = D; 12417 } 12418 } 12419 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12420 Ty->isInstantiationDependentType() || 12421 Ty->containsUnexpandedParameterPack() || 12422 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12423 return !D->isInvalidDecl() && 12424 (D->getType()->isDependentType() || 12425 D->getType()->isInstantiationDependentType() || 12426 D->getType()->containsUnexpandedParameterPack()); 12427 })) { 12428 UnresolvedSet<8> ResSet; 12429 for (const UnresolvedSet<8> &Set : Lookups) { 12430 if (Set.empty()) 12431 continue; 12432 ResSet.append(Set.begin(), Set.end()); 12433 // The last item marks the end of all declarations at the specified scope. 12434 ResSet.addDecl(Set[Set.size() - 1]); 12435 } 12436 return UnresolvedLookupExpr::Create( 12437 SemaRef.Context, /*NamingClass=*/nullptr, 12438 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12439 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12440 } 12441 // Lookup inside the classes. 12442 // C++ [over.match.oper]p3: 12443 // For a unary operator @ with an operand of a type whose 12444 // cv-unqualified version is T1, and for a binary operator @ with 12445 // a left operand of a type whose cv-unqualified version is T1 and 12446 // a right operand of a type whose cv-unqualified version is T2, 12447 // three sets of candidate functions, designated member 12448 // candidates, non-member candidates and built-in candidates, are 12449 // constructed as follows: 12450 // -- If T1 is a complete class type or a class currently being 12451 // defined, the set of member candidates is the result of the 12452 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12453 // the set of member candidates is empty. 12454 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12455 Lookup.suppressDiagnostics(); 12456 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12457 // Complete the type if it can be completed. 12458 // If the type is neither complete nor being defined, bail out now. 12459 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12460 TyRec->getDecl()->getDefinition()) { 12461 Lookup.clear(); 12462 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12463 if (Lookup.empty()) { 12464 Lookups.emplace_back(); 12465 Lookups.back().append(Lookup.begin(), Lookup.end()); 12466 } 12467 } 12468 } 12469 // Perform ADL. 12470 if (SemaRef.getLangOpts().CPlusPlus) 12471 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12472 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12473 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12474 if (!D->isInvalidDecl() && 12475 SemaRef.Context.hasSameType(D->getType(), Ty)) 12476 return D; 12477 return nullptr; 12478 })) 12479 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12480 VK_LValue, Loc); 12481 if (SemaRef.getLangOpts().CPlusPlus) { 12482 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12483 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12484 if (!D->isInvalidDecl() && 12485 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12486 !Ty.isMoreQualifiedThan(D->getType())) 12487 return D; 12488 return nullptr; 12489 })) { 12490 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12491 /*DetectVirtual=*/false); 12492 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12493 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12494 VD->getType().getUnqualifiedType()))) { 12495 if (SemaRef.CheckBaseClassAccess( 12496 Loc, VD->getType(), Ty, Paths.front(), 12497 /*DiagID=*/0) != Sema::AR_inaccessible) { 12498 SemaRef.BuildBasePathArray(Paths, BasePath); 12499 return SemaRef.BuildDeclRefExpr( 12500 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12501 } 12502 } 12503 } 12504 } 12505 } 12506 if (ReductionIdScopeSpec.isSet()) { 12507 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12508 return ExprError(); 12509 } 12510 return ExprEmpty(); 12511 } 12512 12513 namespace { 12514 /// Data for the reduction-based clauses. 12515 struct ReductionData { 12516 /// List of original reduction items. 12517 SmallVector<Expr *, 8> Vars; 12518 /// List of private copies of the reduction items. 12519 SmallVector<Expr *, 8> Privates; 12520 /// LHS expressions for the reduction_op expressions. 12521 SmallVector<Expr *, 8> LHSs; 12522 /// RHS expressions for the reduction_op expressions. 12523 SmallVector<Expr *, 8> RHSs; 12524 /// Reduction operation expression. 12525 SmallVector<Expr *, 8> ReductionOps; 12526 /// Taskgroup descriptors for the corresponding reduction items in 12527 /// in_reduction clauses. 12528 SmallVector<Expr *, 8> TaskgroupDescriptors; 12529 /// List of captures for clause. 12530 SmallVector<Decl *, 4> ExprCaptures; 12531 /// List of postupdate expressions. 12532 SmallVector<Expr *, 4> ExprPostUpdates; 12533 ReductionData() = delete; 12534 /// Reserves required memory for the reduction data. 12535 ReductionData(unsigned Size) { 12536 Vars.reserve(Size); 12537 Privates.reserve(Size); 12538 LHSs.reserve(Size); 12539 RHSs.reserve(Size); 12540 ReductionOps.reserve(Size); 12541 TaskgroupDescriptors.reserve(Size); 12542 ExprCaptures.reserve(Size); 12543 ExprPostUpdates.reserve(Size); 12544 } 12545 /// Stores reduction item and reduction operation only (required for dependent 12546 /// reduction item). 12547 void push(Expr *Item, Expr *ReductionOp) { 12548 Vars.emplace_back(Item); 12549 Privates.emplace_back(nullptr); 12550 LHSs.emplace_back(nullptr); 12551 RHSs.emplace_back(nullptr); 12552 ReductionOps.emplace_back(ReductionOp); 12553 TaskgroupDescriptors.emplace_back(nullptr); 12554 } 12555 /// Stores reduction data. 12556 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12557 Expr *TaskgroupDescriptor) { 12558 Vars.emplace_back(Item); 12559 Privates.emplace_back(Private); 12560 LHSs.emplace_back(LHS); 12561 RHSs.emplace_back(RHS); 12562 ReductionOps.emplace_back(ReductionOp); 12563 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12564 } 12565 }; 12566 } // namespace 12567 12568 static bool checkOMPArraySectionConstantForReduction( 12569 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12570 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12571 const Expr *Length = OASE->getLength(); 12572 if (Length == nullptr) { 12573 // For array sections of the form [1:] or [:], we would need to analyze 12574 // the lower bound... 12575 if (OASE->getColonLoc().isValid()) 12576 return false; 12577 12578 // This is an array subscript which has implicit length 1! 12579 SingleElement = true; 12580 ArraySizes.push_back(llvm::APSInt::get(1)); 12581 } else { 12582 Expr::EvalResult Result; 12583 if (!Length->EvaluateAsInt(Result, Context)) 12584 return false; 12585 12586 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12587 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12588 ArraySizes.push_back(ConstantLengthValue); 12589 } 12590 12591 // Get the base of this array section and walk up from there. 12592 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12593 12594 // We require length = 1 for all array sections except the right-most to 12595 // guarantee that the memory region is contiguous and has no holes in it. 12596 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12597 Length = TempOASE->getLength(); 12598 if (Length == nullptr) { 12599 // For array sections of the form [1:] or [:], we would need to analyze 12600 // the lower bound... 12601 if (OASE->getColonLoc().isValid()) 12602 return false; 12603 12604 // This is an array subscript which has implicit length 1! 12605 ArraySizes.push_back(llvm::APSInt::get(1)); 12606 } else { 12607 Expr::EvalResult Result; 12608 if (!Length->EvaluateAsInt(Result, Context)) 12609 return false; 12610 12611 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12612 if (ConstantLengthValue.getSExtValue() != 1) 12613 return false; 12614 12615 ArraySizes.push_back(ConstantLengthValue); 12616 } 12617 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12618 } 12619 12620 // If we have a single element, we don't need to add the implicit lengths. 12621 if (!SingleElement) { 12622 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12623 // Has implicit length 1! 12624 ArraySizes.push_back(llvm::APSInt::get(1)); 12625 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12626 } 12627 } 12628 12629 // This array section can be privatized as a single value or as a constant 12630 // sized array. 12631 return true; 12632 } 12633 12634 static bool actOnOMPReductionKindClause( 12635 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12636 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12637 SourceLocation ColonLoc, SourceLocation EndLoc, 12638 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12639 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12640 DeclarationName DN = ReductionId.getName(); 12641 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12642 BinaryOperatorKind BOK = BO_Comma; 12643 12644 ASTContext &Context = S.Context; 12645 // OpenMP [2.14.3.6, reduction clause] 12646 // C 12647 // reduction-identifier is either an identifier or one of the following 12648 // operators: +, -, *, &, |, ^, && and || 12649 // C++ 12650 // reduction-identifier is either an id-expression or one of the following 12651 // operators: +, -, *, &, |, ^, && and || 12652 switch (OOK) { 12653 case OO_Plus: 12654 case OO_Minus: 12655 BOK = BO_Add; 12656 break; 12657 case OO_Star: 12658 BOK = BO_Mul; 12659 break; 12660 case OO_Amp: 12661 BOK = BO_And; 12662 break; 12663 case OO_Pipe: 12664 BOK = BO_Or; 12665 break; 12666 case OO_Caret: 12667 BOK = BO_Xor; 12668 break; 12669 case OO_AmpAmp: 12670 BOK = BO_LAnd; 12671 break; 12672 case OO_PipePipe: 12673 BOK = BO_LOr; 12674 break; 12675 case OO_New: 12676 case OO_Delete: 12677 case OO_Array_New: 12678 case OO_Array_Delete: 12679 case OO_Slash: 12680 case OO_Percent: 12681 case OO_Tilde: 12682 case OO_Exclaim: 12683 case OO_Equal: 12684 case OO_Less: 12685 case OO_Greater: 12686 case OO_LessEqual: 12687 case OO_GreaterEqual: 12688 case OO_PlusEqual: 12689 case OO_MinusEqual: 12690 case OO_StarEqual: 12691 case OO_SlashEqual: 12692 case OO_PercentEqual: 12693 case OO_CaretEqual: 12694 case OO_AmpEqual: 12695 case OO_PipeEqual: 12696 case OO_LessLess: 12697 case OO_GreaterGreater: 12698 case OO_LessLessEqual: 12699 case OO_GreaterGreaterEqual: 12700 case OO_EqualEqual: 12701 case OO_ExclaimEqual: 12702 case OO_Spaceship: 12703 case OO_PlusPlus: 12704 case OO_MinusMinus: 12705 case OO_Comma: 12706 case OO_ArrowStar: 12707 case OO_Arrow: 12708 case OO_Call: 12709 case OO_Subscript: 12710 case OO_Conditional: 12711 case OO_Coawait: 12712 case NUM_OVERLOADED_OPERATORS: 12713 llvm_unreachable("Unexpected reduction identifier"); 12714 case OO_None: 12715 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 12716 if (II->isStr("max")) 12717 BOK = BO_GT; 12718 else if (II->isStr("min")) 12719 BOK = BO_LT; 12720 } 12721 break; 12722 } 12723 SourceRange ReductionIdRange; 12724 if (ReductionIdScopeSpec.isValid()) 12725 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 12726 else 12727 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 12728 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 12729 12730 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 12731 bool FirstIter = true; 12732 for (Expr *RefExpr : VarList) { 12733 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 12734 // OpenMP [2.1, C/C++] 12735 // A list item is a variable or array section, subject to the restrictions 12736 // specified in Section 2.4 on page 42 and in each of the sections 12737 // describing clauses and directives for which a list appears. 12738 // OpenMP [2.14.3.3, Restrictions, p.1] 12739 // A variable that is part of another variable (as an array or 12740 // structure element) cannot appear in a private clause. 12741 if (!FirstIter && IR != ER) 12742 ++IR; 12743 FirstIter = false; 12744 SourceLocation ELoc; 12745 SourceRange ERange; 12746 Expr *SimpleRefExpr = RefExpr; 12747 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 12748 /*AllowArraySection=*/true); 12749 if (Res.second) { 12750 // Try to find 'declare reduction' corresponding construct before using 12751 // builtin/overloaded operators. 12752 QualType Type = Context.DependentTy; 12753 CXXCastPath BasePath; 12754 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12755 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12756 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12757 Expr *ReductionOp = nullptr; 12758 if (S.CurContext->isDependentContext() && 12759 (DeclareReductionRef.isUnset() || 12760 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 12761 ReductionOp = DeclareReductionRef.get(); 12762 // It will be analyzed later. 12763 RD.push(RefExpr, ReductionOp); 12764 } 12765 ValueDecl *D = Res.first; 12766 if (!D) 12767 continue; 12768 12769 Expr *TaskgroupDescriptor = nullptr; 12770 QualType Type; 12771 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 12772 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 12773 if (ASE) { 12774 Type = ASE->getType().getNonReferenceType(); 12775 } else if (OASE) { 12776 QualType BaseType = 12777 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 12778 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 12779 Type = ATy->getElementType(); 12780 else 12781 Type = BaseType->getPointeeType(); 12782 Type = Type.getNonReferenceType(); 12783 } else { 12784 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 12785 } 12786 auto *VD = dyn_cast<VarDecl>(D); 12787 12788 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12789 // A variable that appears in a private clause must not have an incomplete 12790 // type or a reference type. 12791 if (S.RequireCompleteType(ELoc, D->getType(), 12792 diag::err_omp_reduction_incomplete_type)) 12793 continue; 12794 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12795 // A list item that appears in a reduction clause must not be 12796 // const-qualified. 12797 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 12798 /*AcceptIfMutable*/ false, ASE || OASE)) 12799 continue; 12800 12801 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 12802 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 12803 // If a list-item is a reference type then it must bind to the same object 12804 // for all threads of the team. 12805 if (!ASE && !OASE) { 12806 if (VD) { 12807 VarDecl *VDDef = VD->getDefinition(); 12808 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 12809 DSARefChecker Check(Stack); 12810 if (Check.Visit(VDDef->getInit())) { 12811 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 12812 << getOpenMPClauseName(ClauseKind) << ERange; 12813 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 12814 continue; 12815 } 12816 } 12817 } 12818 12819 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12820 // in a Construct] 12821 // Variables with the predetermined data-sharing attributes may not be 12822 // listed in data-sharing attributes clauses, except for the cases 12823 // listed below. For these exceptions only, listing a predetermined 12824 // variable in a data-sharing attribute clause is allowed and overrides 12825 // the variable's predetermined data-sharing attributes. 12826 // OpenMP [2.14.3.6, Restrictions, p.3] 12827 // Any number of reduction clauses can be specified on the directive, 12828 // but a list item can appear only once in the reduction clauses for that 12829 // directive. 12830 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 12831 if (DVar.CKind == OMPC_reduction) { 12832 S.Diag(ELoc, diag::err_omp_once_referenced) 12833 << getOpenMPClauseName(ClauseKind); 12834 if (DVar.RefExpr) 12835 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12836 continue; 12837 } 12838 if (DVar.CKind != OMPC_unknown) { 12839 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12840 << getOpenMPClauseName(DVar.CKind) 12841 << getOpenMPClauseName(OMPC_reduction); 12842 reportOriginalDsa(S, Stack, D, DVar); 12843 continue; 12844 } 12845 12846 // OpenMP [2.14.3.6, Restrictions, p.1] 12847 // A list item that appears in a reduction clause of a worksharing 12848 // construct must be shared in the parallel regions to which any of the 12849 // worksharing regions arising from the worksharing construct bind. 12850 if (isOpenMPWorksharingDirective(CurrDir) && 12851 !isOpenMPParallelDirective(CurrDir) && 12852 !isOpenMPTeamsDirective(CurrDir)) { 12853 DVar = Stack->getImplicitDSA(D, true); 12854 if (DVar.CKind != OMPC_shared) { 12855 S.Diag(ELoc, diag::err_omp_required_access) 12856 << getOpenMPClauseName(OMPC_reduction) 12857 << getOpenMPClauseName(OMPC_shared); 12858 reportOriginalDsa(S, Stack, D, DVar); 12859 continue; 12860 } 12861 } 12862 } 12863 12864 // Try to find 'declare reduction' corresponding construct before using 12865 // builtin/overloaded operators. 12866 CXXCastPath BasePath; 12867 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12868 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12869 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12870 if (DeclareReductionRef.isInvalid()) 12871 continue; 12872 if (S.CurContext->isDependentContext() && 12873 (DeclareReductionRef.isUnset() || 12874 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12875 RD.push(RefExpr, DeclareReductionRef.get()); 12876 continue; 12877 } 12878 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12879 // Not allowed reduction identifier is found. 12880 S.Diag(ReductionId.getBeginLoc(), 12881 diag::err_omp_unknown_reduction_identifier) 12882 << Type << ReductionIdRange; 12883 continue; 12884 } 12885 12886 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12887 // The type of a list item that appears in a reduction clause must be valid 12888 // for the reduction-identifier. For a max or min reduction in C, the type 12889 // of the list item must be an allowed arithmetic data type: char, int, 12890 // float, double, or _Bool, possibly modified with long, short, signed, or 12891 // unsigned. For a max or min reduction in C++, the type of the list item 12892 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12893 // double, or bool, possibly modified with long, short, signed, or unsigned. 12894 if (DeclareReductionRef.isUnset()) { 12895 if ((BOK == BO_GT || BOK == BO_LT) && 12896 !(Type->isScalarType() || 12897 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12898 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12899 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12900 if (!ASE && !OASE) { 12901 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12902 VarDecl::DeclarationOnly; 12903 S.Diag(D->getLocation(), 12904 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12905 << D; 12906 } 12907 continue; 12908 } 12909 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12910 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12911 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12912 << getOpenMPClauseName(ClauseKind); 12913 if (!ASE && !OASE) { 12914 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12915 VarDecl::DeclarationOnly; 12916 S.Diag(D->getLocation(), 12917 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12918 << D; 12919 } 12920 continue; 12921 } 12922 } 12923 12924 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12925 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12926 D->hasAttrs() ? &D->getAttrs() : nullptr); 12927 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12928 D->hasAttrs() ? &D->getAttrs() : nullptr); 12929 QualType PrivateTy = Type; 12930 12931 // Try if we can determine constant lengths for all array sections and avoid 12932 // the VLA. 12933 bool ConstantLengthOASE = false; 12934 if (OASE) { 12935 bool SingleElement; 12936 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12937 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12938 Context, OASE, SingleElement, ArraySizes); 12939 12940 // If we don't have a single element, we must emit a constant array type. 12941 if (ConstantLengthOASE && !SingleElement) { 12942 for (llvm::APSInt &Size : ArraySizes) 12943 PrivateTy = Context.getConstantArrayType( 12944 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12945 } 12946 } 12947 12948 if ((OASE && !ConstantLengthOASE) || 12949 (!OASE && !ASE && 12950 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12951 if (!Context.getTargetInfo().isVLASupported()) { 12952 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 12953 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12954 S.Diag(ELoc, diag::note_vla_unsupported); 12955 } else { 12956 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12957 S.targetDiag(ELoc, diag::note_vla_unsupported); 12958 } 12959 continue; 12960 } 12961 // For arrays/array sections only: 12962 // Create pseudo array type for private copy. The size for this array will 12963 // be generated during codegen. 12964 // For array subscripts or single variables Private Ty is the same as Type 12965 // (type of the variable or single array element). 12966 PrivateTy = Context.getVariableArrayType( 12967 Type, 12968 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12969 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12970 } else if (!ASE && !OASE && 12971 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12972 PrivateTy = D->getType().getNonReferenceType(); 12973 } 12974 // Private copy. 12975 VarDecl *PrivateVD = 12976 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12977 D->hasAttrs() ? &D->getAttrs() : nullptr, 12978 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12979 // Add initializer for private variable. 12980 Expr *Init = nullptr; 12981 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12982 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12983 if (DeclareReductionRef.isUsable()) { 12984 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12985 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12986 if (DRD->getInitializer()) { 12987 Init = DRDRef; 12988 RHSVD->setInit(DRDRef); 12989 RHSVD->setInitStyle(VarDecl::CallInit); 12990 } 12991 } else { 12992 switch (BOK) { 12993 case BO_Add: 12994 case BO_Xor: 12995 case BO_Or: 12996 case BO_LOr: 12997 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12998 if (Type->isScalarType() || Type->isAnyComplexType()) 12999 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13000 break; 13001 case BO_Mul: 13002 case BO_LAnd: 13003 if (Type->isScalarType() || Type->isAnyComplexType()) { 13004 // '*' and '&&' reduction ops - initializer is '1'. 13005 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13006 } 13007 break; 13008 case BO_And: { 13009 // '&' reduction op - initializer is '~0'. 13010 QualType OrigType = Type; 13011 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13012 Type = ComplexTy->getElementType(); 13013 if (Type->isRealFloatingType()) { 13014 llvm::APFloat InitValue = 13015 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13016 /*isIEEE=*/true); 13017 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13018 Type, ELoc); 13019 } else if (Type->isScalarType()) { 13020 uint64_t Size = Context.getTypeSize(Type); 13021 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13022 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13023 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13024 } 13025 if (Init && OrigType->isAnyComplexType()) { 13026 // Init = 0xFFFF + 0xFFFFi; 13027 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13028 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13029 } 13030 Type = OrigType; 13031 break; 13032 } 13033 case BO_LT: 13034 case BO_GT: { 13035 // 'min' reduction op - initializer is 'Largest representable number in 13036 // the reduction list item type'. 13037 // 'max' reduction op - initializer is 'Least representable number in 13038 // the reduction list item type'. 13039 if (Type->isIntegerType() || Type->isPointerType()) { 13040 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13041 uint64_t Size = Context.getTypeSize(Type); 13042 QualType IntTy = 13043 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13044 llvm::APInt InitValue = 13045 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13046 : llvm::APInt::getMinValue(Size) 13047 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13048 : llvm::APInt::getMaxValue(Size); 13049 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13050 if (Type->isPointerType()) { 13051 // Cast to pointer type. 13052 ExprResult CastExpr = S.BuildCStyleCastExpr( 13053 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13054 if (CastExpr.isInvalid()) 13055 continue; 13056 Init = CastExpr.get(); 13057 } 13058 } else if (Type->isRealFloatingType()) { 13059 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13060 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13061 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13062 Type, ELoc); 13063 } 13064 break; 13065 } 13066 case BO_PtrMemD: 13067 case BO_PtrMemI: 13068 case BO_MulAssign: 13069 case BO_Div: 13070 case BO_Rem: 13071 case BO_Sub: 13072 case BO_Shl: 13073 case BO_Shr: 13074 case BO_LE: 13075 case BO_GE: 13076 case BO_EQ: 13077 case BO_NE: 13078 case BO_Cmp: 13079 case BO_AndAssign: 13080 case BO_XorAssign: 13081 case BO_OrAssign: 13082 case BO_Assign: 13083 case BO_AddAssign: 13084 case BO_SubAssign: 13085 case BO_DivAssign: 13086 case BO_RemAssign: 13087 case BO_ShlAssign: 13088 case BO_ShrAssign: 13089 case BO_Comma: 13090 llvm_unreachable("Unexpected reduction operation"); 13091 } 13092 } 13093 if (Init && DeclareReductionRef.isUnset()) 13094 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13095 else if (!Init) 13096 S.ActOnUninitializedDecl(RHSVD); 13097 if (RHSVD->isInvalidDecl()) 13098 continue; 13099 if (!RHSVD->hasInit() && 13100 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13101 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13102 << Type << ReductionIdRange; 13103 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13104 VarDecl::DeclarationOnly; 13105 S.Diag(D->getLocation(), 13106 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13107 << D; 13108 continue; 13109 } 13110 // Store initializer for single element in private copy. Will be used during 13111 // codegen. 13112 PrivateVD->setInit(RHSVD->getInit()); 13113 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13114 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13115 ExprResult ReductionOp; 13116 if (DeclareReductionRef.isUsable()) { 13117 QualType RedTy = DeclareReductionRef.get()->getType(); 13118 QualType PtrRedTy = Context.getPointerType(RedTy); 13119 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13120 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13121 if (!BasePath.empty()) { 13122 LHS = S.DefaultLvalueConversion(LHS.get()); 13123 RHS = S.DefaultLvalueConversion(RHS.get()); 13124 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13125 CK_UncheckedDerivedToBase, LHS.get(), 13126 &BasePath, LHS.get()->getValueKind()); 13127 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13128 CK_UncheckedDerivedToBase, RHS.get(), 13129 &BasePath, RHS.get()->getValueKind()); 13130 } 13131 FunctionProtoType::ExtProtoInfo EPI; 13132 QualType Params[] = {PtrRedTy, PtrRedTy}; 13133 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13134 auto *OVE = new (Context) OpaqueValueExpr( 13135 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13136 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13137 Expr *Args[] = {LHS.get(), RHS.get()}; 13138 ReductionOp = 13139 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13140 } else { 13141 ReductionOp = S.BuildBinOp( 13142 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13143 if (ReductionOp.isUsable()) { 13144 if (BOK != BO_LT && BOK != BO_GT) { 13145 ReductionOp = 13146 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13147 BO_Assign, LHSDRE, ReductionOp.get()); 13148 } else { 13149 auto *ConditionalOp = new (Context) 13150 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13151 Type, VK_LValue, OK_Ordinary); 13152 ReductionOp = 13153 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13154 BO_Assign, LHSDRE, ConditionalOp); 13155 } 13156 if (ReductionOp.isUsable()) 13157 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13158 /*DiscardedValue*/ false); 13159 } 13160 if (!ReductionOp.isUsable()) 13161 continue; 13162 } 13163 13164 // OpenMP [2.15.4.6, Restrictions, p.2] 13165 // A list item that appears in an in_reduction clause of a task construct 13166 // must appear in a task_reduction clause of a construct associated with a 13167 // taskgroup region that includes the participating task in its taskgroup 13168 // set. The construct associated with the innermost region that meets this 13169 // condition must specify the same reduction-identifier as the in_reduction 13170 // clause. 13171 if (ClauseKind == OMPC_in_reduction) { 13172 SourceRange ParentSR; 13173 BinaryOperatorKind ParentBOK; 13174 const Expr *ParentReductionOp; 13175 Expr *ParentBOKTD, *ParentReductionOpTD; 13176 DSAStackTy::DSAVarData ParentBOKDSA = 13177 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13178 ParentBOKTD); 13179 DSAStackTy::DSAVarData ParentReductionOpDSA = 13180 Stack->getTopMostTaskgroupReductionData( 13181 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13182 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13183 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13184 if (!IsParentBOK && !IsParentReductionOp) { 13185 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13186 continue; 13187 } 13188 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13189 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13190 IsParentReductionOp) { 13191 bool EmitError = true; 13192 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13193 llvm::FoldingSetNodeID RedId, ParentRedId; 13194 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13195 DeclareReductionRef.get()->Profile(RedId, Context, 13196 /*Canonical=*/true); 13197 EmitError = RedId != ParentRedId; 13198 } 13199 if (EmitError) { 13200 S.Diag(ReductionId.getBeginLoc(), 13201 diag::err_omp_reduction_identifier_mismatch) 13202 << ReductionIdRange << RefExpr->getSourceRange(); 13203 S.Diag(ParentSR.getBegin(), 13204 diag::note_omp_previous_reduction_identifier) 13205 << ParentSR 13206 << (IsParentBOK ? ParentBOKDSA.RefExpr 13207 : ParentReductionOpDSA.RefExpr) 13208 ->getSourceRange(); 13209 continue; 13210 } 13211 } 13212 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13213 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13214 } 13215 13216 DeclRefExpr *Ref = nullptr; 13217 Expr *VarsExpr = RefExpr->IgnoreParens(); 13218 if (!VD && !S.CurContext->isDependentContext()) { 13219 if (ASE || OASE) { 13220 TransformExprToCaptures RebuildToCapture(S, D); 13221 VarsExpr = 13222 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13223 Ref = RebuildToCapture.getCapturedExpr(); 13224 } else { 13225 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13226 } 13227 if (!S.isOpenMPCapturedDecl(D)) { 13228 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13229 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13230 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13231 if (!RefRes.isUsable()) 13232 continue; 13233 ExprResult PostUpdateRes = 13234 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13235 RefRes.get()); 13236 if (!PostUpdateRes.isUsable()) 13237 continue; 13238 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13239 Stack->getCurrentDirective() == OMPD_taskgroup) { 13240 S.Diag(RefExpr->getExprLoc(), 13241 diag::err_omp_reduction_non_addressable_expression) 13242 << RefExpr->getSourceRange(); 13243 continue; 13244 } 13245 RD.ExprPostUpdates.emplace_back( 13246 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13247 } 13248 } 13249 } 13250 // All reduction items are still marked as reduction (to do not increase 13251 // code base size). 13252 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13253 if (CurrDir == OMPD_taskgroup) { 13254 if (DeclareReductionRef.isUsable()) 13255 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13256 DeclareReductionRef.get()); 13257 else 13258 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13259 } 13260 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13261 TaskgroupDescriptor); 13262 } 13263 return RD.Vars.empty(); 13264 } 13265 13266 OMPClause *Sema::ActOnOpenMPReductionClause( 13267 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13268 SourceLocation ColonLoc, SourceLocation EndLoc, 13269 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13270 ArrayRef<Expr *> UnresolvedReductions) { 13271 ReductionData RD(VarList.size()); 13272 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13273 StartLoc, LParenLoc, ColonLoc, EndLoc, 13274 ReductionIdScopeSpec, ReductionId, 13275 UnresolvedReductions, RD)) 13276 return nullptr; 13277 13278 return OMPReductionClause::Create( 13279 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13280 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13281 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13282 buildPreInits(Context, RD.ExprCaptures), 13283 buildPostUpdate(*this, RD.ExprPostUpdates)); 13284 } 13285 13286 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13287 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13288 SourceLocation ColonLoc, SourceLocation EndLoc, 13289 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13290 ArrayRef<Expr *> UnresolvedReductions) { 13291 ReductionData RD(VarList.size()); 13292 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13293 StartLoc, LParenLoc, ColonLoc, EndLoc, 13294 ReductionIdScopeSpec, ReductionId, 13295 UnresolvedReductions, RD)) 13296 return nullptr; 13297 13298 return OMPTaskReductionClause::Create( 13299 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13300 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13301 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13302 buildPreInits(Context, RD.ExprCaptures), 13303 buildPostUpdate(*this, RD.ExprPostUpdates)); 13304 } 13305 13306 OMPClause *Sema::ActOnOpenMPInReductionClause( 13307 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13308 SourceLocation ColonLoc, SourceLocation EndLoc, 13309 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13310 ArrayRef<Expr *> UnresolvedReductions) { 13311 ReductionData RD(VarList.size()); 13312 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13313 StartLoc, LParenLoc, ColonLoc, EndLoc, 13314 ReductionIdScopeSpec, ReductionId, 13315 UnresolvedReductions, RD)) 13316 return nullptr; 13317 13318 return OMPInReductionClause::Create( 13319 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13320 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13321 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13322 buildPreInits(Context, RD.ExprCaptures), 13323 buildPostUpdate(*this, RD.ExprPostUpdates)); 13324 } 13325 13326 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13327 SourceLocation LinLoc) { 13328 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13329 LinKind == OMPC_LINEAR_unknown) { 13330 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13331 return true; 13332 } 13333 return false; 13334 } 13335 13336 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13337 OpenMPLinearClauseKind LinKind, 13338 QualType Type) { 13339 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13340 // A variable must not have an incomplete type or a reference type. 13341 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13342 return true; 13343 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13344 !Type->isReferenceType()) { 13345 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13346 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13347 return true; 13348 } 13349 Type = Type.getNonReferenceType(); 13350 13351 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13352 // A variable that is privatized must not have a const-qualified type 13353 // unless it is of class type with a mutable member. This restriction does 13354 // not apply to the firstprivate clause. 13355 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13356 return true; 13357 13358 // A list item must be of integral or pointer type. 13359 Type = Type.getUnqualifiedType().getCanonicalType(); 13360 const auto *Ty = Type.getTypePtrOrNull(); 13361 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13362 !Ty->isPointerType())) { 13363 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13364 if (D) { 13365 bool IsDecl = 13366 !VD || 13367 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13368 Diag(D->getLocation(), 13369 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13370 << D; 13371 } 13372 return true; 13373 } 13374 return false; 13375 } 13376 13377 OMPClause *Sema::ActOnOpenMPLinearClause( 13378 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13379 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13380 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13381 SmallVector<Expr *, 8> Vars; 13382 SmallVector<Expr *, 8> Privates; 13383 SmallVector<Expr *, 8> Inits; 13384 SmallVector<Decl *, 4> ExprCaptures; 13385 SmallVector<Expr *, 4> ExprPostUpdates; 13386 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13387 LinKind = OMPC_LINEAR_val; 13388 for (Expr *RefExpr : VarList) { 13389 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13390 SourceLocation ELoc; 13391 SourceRange ERange; 13392 Expr *SimpleRefExpr = RefExpr; 13393 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13394 if (Res.second) { 13395 // It will be analyzed later. 13396 Vars.push_back(RefExpr); 13397 Privates.push_back(nullptr); 13398 Inits.push_back(nullptr); 13399 } 13400 ValueDecl *D = Res.first; 13401 if (!D) 13402 continue; 13403 13404 QualType Type = D->getType(); 13405 auto *VD = dyn_cast<VarDecl>(D); 13406 13407 // OpenMP [2.14.3.7, linear clause] 13408 // A list-item cannot appear in more than one linear clause. 13409 // A list-item that appears in a linear clause cannot appear in any 13410 // other data-sharing attribute clause. 13411 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13412 if (DVar.RefExpr) { 13413 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13414 << getOpenMPClauseName(OMPC_linear); 13415 reportOriginalDsa(*this, DSAStack, D, DVar); 13416 continue; 13417 } 13418 13419 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13420 continue; 13421 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13422 13423 // Build private copy of original var. 13424 VarDecl *Private = 13425 buildVarDecl(*this, ELoc, Type, D->getName(), 13426 D->hasAttrs() ? &D->getAttrs() : nullptr, 13427 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13428 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13429 // Build var to save initial value. 13430 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13431 Expr *InitExpr; 13432 DeclRefExpr *Ref = nullptr; 13433 if (!VD && !CurContext->isDependentContext()) { 13434 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13435 if (!isOpenMPCapturedDecl(D)) { 13436 ExprCaptures.push_back(Ref->getDecl()); 13437 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13438 ExprResult RefRes = DefaultLvalueConversion(Ref); 13439 if (!RefRes.isUsable()) 13440 continue; 13441 ExprResult PostUpdateRes = 13442 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13443 SimpleRefExpr, RefRes.get()); 13444 if (!PostUpdateRes.isUsable()) 13445 continue; 13446 ExprPostUpdates.push_back( 13447 IgnoredValueConversions(PostUpdateRes.get()).get()); 13448 } 13449 } 13450 } 13451 if (LinKind == OMPC_LINEAR_uval) 13452 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13453 else 13454 InitExpr = VD ? SimpleRefExpr : Ref; 13455 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13456 /*DirectInit=*/false); 13457 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13458 13459 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13460 Vars.push_back((VD || CurContext->isDependentContext()) 13461 ? RefExpr->IgnoreParens() 13462 : Ref); 13463 Privates.push_back(PrivateRef); 13464 Inits.push_back(InitRef); 13465 } 13466 13467 if (Vars.empty()) 13468 return nullptr; 13469 13470 Expr *StepExpr = Step; 13471 Expr *CalcStepExpr = nullptr; 13472 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13473 !Step->isInstantiationDependent() && 13474 !Step->containsUnexpandedParameterPack()) { 13475 SourceLocation StepLoc = Step->getBeginLoc(); 13476 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13477 if (Val.isInvalid()) 13478 return nullptr; 13479 StepExpr = Val.get(); 13480 13481 // Build var to save the step value. 13482 VarDecl *SaveVar = 13483 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13484 ExprResult SaveRef = 13485 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13486 ExprResult CalcStep = 13487 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13488 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13489 13490 // Warn about zero linear step (it would be probably better specified as 13491 // making corresponding variables 'const'). 13492 llvm::APSInt Result; 13493 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13494 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13495 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13496 << (Vars.size() > 1); 13497 if (!IsConstant && CalcStep.isUsable()) { 13498 // Calculate the step beforehand instead of doing this on each iteration. 13499 // (This is not used if the number of iterations may be kfold-ed). 13500 CalcStepExpr = CalcStep.get(); 13501 } 13502 } 13503 13504 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13505 ColonLoc, EndLoc, Vars, Privates, Inits, 13506 StepExpr, CalcStepExpr, 13507 buildPreInits(Context, ExprCaptures), 13508 buildPostUpdate(*this, ExprPostUpdates)); 13509 } 13510 13511 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13512 Expr *NumIterations, Sema &SemaRef, 13513 Scope *S, DSAStackTy *Stack) { 13514 // Walk the vars and build update/final expressions for the CodeGen. 13515 SmallVector<Expr *, 8> Updates; 13516 SmallVector<Expr *, 8> Finals; 13517 SmallVector<Expr *, 8> UsedExprs; 13518 Expr *Step = Clause.getStep(); 13519 Expr *CalcStep = Clause.getCalcStep(); 13520 // OpenMP [2.14.3.7, linear clause] 13521 // If linear-step is not specified it is assumed to be 1. 13522 if (!Step) 13523 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13524 else if (CalcStep) 13525 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13526 bool HasErrors = false; 13527 auto CurInit = Clause.inits().begin(); 13528 auto CurPrivate = Clause.privates().begin(); 13529 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13530 for (Expr *RefExpr : Clause.varlists()) { 13531 SourceLocation ELoc; 13532 SourceRange ERange; 13533 Expr *SimpleRefExpr = RefExpr; 13534 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13535 ValueDecl *D = Res.first; 13536 if (Res.second || !D) { 13537 Updates.push_back(nullptr); 13538 Finals.push_back(nullptr); 13539 HasErrors = true; 13540 continue; 13541 } 13542 auto &&Info = Stack->isLoopControlVariable(D); 13543 // OpenMP [2.15.11, distribute simd Construct] 13544 // A list item may not appear in a linear clause, unless it is the loop 13545 // iteration variable. 13546 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13547 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13548 SemaRef.Diag(ELoc, 13549 diag::err_omp_linear_distribute_var_non_loop_iteration); 13550 Updates.push_back(nullptr); 13551 Finals.push_back(nullptr); 13552 HasErrors = true; 13553 continue; 13554 } 13555 Expr *InitExpr = *CurInit; 13556 13557 // Build privatized reference to the current linear var. 13558 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13559 Expr *CapturedRef; 13560 if (LinKind == OMPC_LINEAR_uval) 13561 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13562 else 13563 CapturedRef = 13564 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13565 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13566 /*RefersToCapture=*/true); 13567 13568 // Build update: Var = InitExpr + IV * Step 13569 ExprResult Update; 13570 if (!Info.first) 13571 Update = buildCounterUpdate( 13572 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13573 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13574 else 13575 Update = *CurPrivate; 13576 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13577 /*DiscardedValue*/ false); 13578 13579 // Build final: Var = InitExpr + NumIterations * Step 13580 ExprResult Final; 13581 if (!Info.first) 13582 Final = 13583 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13584 InitExpr, NumIterations, Step, /*Subtract=*/false, 13585 /*IsNonRectangularLB=*/false); 13586 else 13587 Final = *CurPrivate; 13588 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13589 /*DiscardedValue*/ false); 13590 13591 if (!Update.isUsable() || !Final.isUsable()) { 13592 Updates.push_back(nullptr); 13593 Finals.push_back(nullptr); 13594 UsedExprs.push_back(nullptr); 13595 HasErrors = true; 13596 } else { 13597 Updates.push_back(Update.get()); 13598 Finals.push_back(Final.get()); 13599 if (!Info.first) 13600 UsedExprs.push_back(SimpleRefExpr); 13601 } 13602 ++CurInit; 13603 ++CurPrivate; 13604 } 13605 if (Expr *S = Clause.getStep()) 13606 UsedExprs.push_back(S); 13607 // Fill the remaining part with the nullptr. 13608 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13609 Clause.setUpdates(Updates); 13610 Clause.setFinals(Finals); 13611 Clause.setUsedExprs(UsedExprs); 13612 return HasErrors; 13613 } 13614 13615 OMPClause *Sema::ActOnOpenMPAlignedClause( 13616 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13617 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13618 SmallVector<Expr *, 8> Vars; 13619 for (Expr *RefExpr : VarList) { 13620 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13621 SourceLocation ELoc; 13622 SourceRange ERange; 13623 Expr *SimpleRefExpr = RefExpr; 13624 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13625 if (Res.second) { 13626 // It will be analyzed later. 13627 Vars.push_back(RefExpr); 13628 } 13629 ValueDecl *D = Res.first; 13630 if (!D) 13631 continue; 13632 13633 QualType QType = D->getType(); 13634 auto *VD = dyn_cast<VarDecl>(D); 13635 13636 // OpenMP [2.8.1, simd construct, Restrictions] 13637 // The type of list items appearing in the aligned clause must be 13638 // array, pointer, reference to array, or reference to pointer. 13639 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13640 const Type *Ty = QType.getTypePtrOrNull(); 13641 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 13642 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 13643 << QType << getLangOpts().CPlusPlus << ERange; 13644 bool IsDecl = 13645 !VD || 13646 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13647 Diag(D->getLocation(), 13648 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13649 << D; 13650 continue; 13651 } 13652 13653 // OpenMP [2.8.1, simd construct, Restrictions] 13654 // A list-item cannot appear in more than one aligned clause. 13655 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 13656 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 13657 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 13658 << getOpenMPClauseName(OMPC_aligned); 13659 continue; 13660 } 13661 13662 DeclRefExpr *Ref = nullptr; 13663 if (!VD && isOpenMPCapturedDecl(D)) 13664 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13665 Vars.push_back(DefaultFunctionArrayConversion( 13666 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 13667 .get()); 13668 } 13669 13670 // OpenMP [2.8.1, simd construct, Description] 13671 // The parameter of the aligned clause, alignment, must be a constant 13672 // positive integer expression. 13673 // If no optional parameter is specified, implementation-defined default 13674 // alignments for SIMD instructions on the target platforms are assumed. 13675 if (Alignment != nullptr) { 13676 ExprResult AlignResult = 13677 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 13678 if (AlignResult.isInvalid()) 13679 return nullptr; 13680 Alignment = AlignResult.get(); 13681 } 13682 if (Vars.empty()) 13683 return nullptr; 13684 13685 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 13686 EndLoc, Vars, Alignment); 13687 } 13688 13689 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 13690 SourceLocation StartLoc, 13691 SourceLocation LParenLoc, 13692 SourceLocation EndLoc) { 13693 SmallVector<Expr *, 8> Vars; 13694 SmallVector<Expr *, 8> SrcExprs; 13695 SmallVector<Expr *, 8> DstExprs; 13696 SmallVector<Expr *, 8> AssignmentOps; 13697 for (Expr *RefExpr : VarList) { 13698 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 13699 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13700 // It will be analyzed later. 13701 Vars.push_back(RefExpr); 13702 SrcExprs.push_back(nullptr); 13703 DstExprs.push_back(nullptr); 13704 AssignmentOps.push_back(nullptr); 13705 continue; 13706 } 13707 13708 SourceLocation ELoc = RefExpr->getExprLoc(); 13709 // OpenMP [2.1, C/C++] 13710 // A list item is a variable name. 13711 // OpenMP [2.14.4.1, Restrictions, p.1] 13712 // A list item that appears in a copyin clause must be threadprivate. 13713 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 13714 if (!DE || !isa<VarDecl>(DE->getDecl())) { 13715 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 13716 << 0 << RefExpr->getSourceRange(); 13717 continue; 13718 } 13719 13720 Decl *D = DE->getDecl(); 13721 auto *VD = cast<VarDecl>(D); 13722 13723 QualType Type = VD->getType(); 13724 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 13725 // It will be analyzed later. 13726 Vars.push_back(DE); 13727 SrcExprs.push_back(nullptr); 13728 DstExprs.push_back(nullptr); 13729 AssignmentOps.push_back(nullptr); 13730 continue; 13731 } 13732 13733 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 13734 // A list item that appears in a copyin clause must be threadprivate. 13735 if (!DSAStack->isThreadPrivate(VD)) { 13736 Diag(ELoc, diag::err_omp_required_access) 13737 << getOpenMPClauseName(OMPC_copyin) 13738 << getOpenMPDirectiveName(OMPD_threadprivate); 13739 continue; 13740 } 13741 13742 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13743 // A variable of class type (or array thereof) that appears in a 13744 // copyin clause requires an accessible, unambiguous copy assignment 13745 // operator for the class type. 13746 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13747 VarDecl *SrcVD = 13748 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 13749 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13750 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 13751 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 13752 VarDecl *DstVD = 13753 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 13754 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13755 DeclRefExpr *PseudoDstExpr = 13756 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 13757 // For arrays generate assignment operation for single element and replace 13758 // it by the original array element in CodeGen. 13759 ExprResult AssignmentOp = 13760 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 13761 PseudoSrcExpr); 13762 if (AssignmentOp.isInvalid()) 13763 continue; 13764 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 13765 /*DiscardedValue*/ false); 13766 if (AssignmentOp.isInvalid()) 13767 continue; 13768 13769 DSAStack->addDSA(VD, DE, OMPC_copyin); 13770 Vars.push_back(DE); 13771 SrcExprs.push_back(PseudoSrcExpr); 13772 DstExprs.push_back(PseudoDstExpr); 13773 AssignmentOps.push_back(AssignmentOp.get()); 13774 } 13775 13776 if (Vars.empty()) 13777 return nullptr; 13778 13779 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13780 SrcExprs, DstExprs, AssignmentOps); 13781 } 13782 13783 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 13784 SourceLocation StartLoc, 13785 SourceLocation LParenLoc, 13786 SourceLocation EndLoc) { 13787 SmallVector<Expr *, 8> Vars; 13788 SmallVector<Expr *, 8> SrcExprs; 13789 SmallVector<Expr *, 8> DstExprs; 13790 SmallVector<Expr *, 8> AssignmentOps; 13791 for (Expr *RefExpr : VarList) { 13792 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13793 SourceLocation ELoc; 13794 SourceRange ERange; 13795 Expr *SimpleRefExpr = RefExpr; 13796 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13797 if (Res.second) { 13798 // It will be analyzed later. 13799 Vars.push_back(RefExpr); 13800 SrcExprs.push_back(nullptr); 13801 DstExprs.push_back(nullptr); 13802 AssignmentOps.push_back(nullptr); 13803 } 13804 ValueDecl *D = Res.first; 13805 if (!D) 13806 continue; 13807 13808 QualType Type = D->getType(); 13809 auto *VD = dyn_cast<VarDecl>(D); 13810 13811 // OpenMP [2.14.4.2, Restrictions, p.2] 13812 // A list item that appears in a copyprivate clause may not appear in a 13813 // private or firstprivate clause on the single construct. 13814 if (!VD || !DSAStack->isThreadPrivate(VD)) { 13815 DSAStackTy::DSAVarData DVar = 13816 DSAStack->getTopDSA(D, /*FromParent=*/false); 13817 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 13818 DVar.RefExpr) { 13819 Diag(ELoc, diag::err_omp_wrong_dsa) 13820 << getOpenMPClauseName(DVar.CKind) 13821 << getOpenMPClauseName(OMPC_copyprivate); 13822 reportOriginalDsa(*this, DSAStack, D, DVar); 13823 continue; 13824 } 13825 13826 // OpenMP [2.11.4.2, Restrictions, p.1] 13827 // All list items that appear in a copyprivate clause must be either 13828 // threadprivate or private in the enclosing context. 13829 if (DVar.CKind == OMPC_unknown) { 13830 DVar = DSAStack->getImplicitDSA(D, false); 13831 if (DVar.CKind == OMPC_shared) { 13832 Diag(ELoc, diag::err_omp_required_access) 13833 << getOpenMPClauseName(OMPC_copyprivate) 13834 << "threadprivate or private in the enclosing context"; 13835 reportOriginalDsa(*this, DSAStack, D, DVar); 13836 continue; 13837 } 13838 } 13839 } 13840 13841 // Variably modified types are not supported. 13842 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 13843 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13844 << getOpenMPClauseName(OMPC_copyprivate) << Type 13845 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13846 bool IsDecl = 13847 !VD || 13848 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13849 Diag(D->getLocation(), 13850 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13851 << D; 13852 continue; 13853 } 13854 13855 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13856 // A variable of class type (or array thereof) that appears in a 13857 // copyin clause requires an accessible, unambiguous copy assignment 13858 // operator for the class type. 13859 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13860 .getUnqualifiedType(); 13861 VarDecl *SrcVD = 13862 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13863 D->hasAttrs() ? &D->getAttrs() : nullptr); 13864 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13865 VarDecl *DstVD = 13866 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13867 D->hasAttrs() ? &D->getAttrs() : nullptr); 13868 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13869 ExprResult AssignmentOp = BuildBinOp( 13870 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13871 if (AssignmentOp.isInvalid()) 13872 continue; 13873 AssignmentOp = 13874 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13875 if (AssignmentOp.isInvalid()) 13876 continue; 13877 13878 // No need to mark vars as copyprivate, they are already threadprivate or 13879 // implicitly private. 13880 assert(VD || isOpenMPCapturedDecl(D)); 13881 Vars.push_back( 13882 VD ? RefExpr->IgnoreParens() 13883 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13884 SrcExprs.push_back(PseudoSrcExpr); 13885 DstExprs.push_back(PseudoDstExpr); 13886 AssignmentOps.push_back(AssignmentOp.get()); 13887 } 13888 13889 if (Vars.empty()) 13890 return nullptr; 13891 13892 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13893 Vars, SrcExprs, DstExprs, AssignmentOps); 13894 } 13895 13896 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13897 SourceLocation StartLoc, 13898 SourceLocation LParenLoc, 13899 SourceLocation EndLoc) { 13900 if (VarList.empty()) 13901 return nullptr; 13902 13903 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13904 } 13905 13906 OMPClause * 13907 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13908 SourceLocation DepLoc, SourceLocation ColonLoc, 13909 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13910 SourceLocation LParenLoc, SourceLocation EndLoc) { 13911 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13912 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13913 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13914 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13915 return nullptr; 13916 } 13917 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13918 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13919 DepKind == OMPC_DEPEND_sink)) { 13920 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13921 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13922 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13923 /*Last=*/OMPC_DEPEND_unknown, Except) 13924 << getOpenMPClauseName(OMPC_depend); 13925 return nullptr; 13926 } 13927 SmallVector<Expr *, 8> Vars; 13928 DSAStackTy::OperatorOffsetTy OpsOffs; 13929 llvm::APSInt DepCounter(/*BitWidth=*/32); 13930 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13931 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13932 if (const Expr *OrderedCountExpr = 13933 DSAStack->getParentOrderedRegionParam().first) { 13934 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13935 TotalDepCount.setIsUnsigned(/*Val=*/true); 13936 } 13937 } 13938 for (Expr *RefExpr : VarList) { 13939 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13940 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13941 // It will be analyzed later. 13942 Vars.push_back(RefExpr); 13943 continue; 13944 } 13945 13946 SourceLocation ELoc = RefExpr->getExprLoc(); 13947 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13948 if (DepKind == OMPC_DEPEND_sink) { 13949 if (DSAStack->getParentOrderedRegionParam().first && 13950 DepCounter >= TotalDepCount) { 13951 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13952 continue; 13953 } 13954 ++DepCounter; 13955 // OpenMP [2.13.9, Summary] 13956 // depend(dependence-type : vec), where dependence-type is: 13957 // 'sink' and where vec is the iteration vector, which has the form: 13958 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13959 // where n is the value specified by the ordered clause in the loop 13960 // directive, xi denotes the loop iteration variable of the i-th nested 13961 // loop associated with the loop directive, and di is a constant 13962 // non-negative integer. 13963 if (CurContext->isDependentContext()) { 13964 // It will be analyzed later. 13965 Vars.push_back(RefExpr); 13966 continue; 13967 } 13968 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13969 OverloadedOperatorKind OOK = OO_None; 13970 SourceLocation OOLoc; 13971 Expr *LHS = SimpleExpr; 13972 Expr *RHS = nullptr; 13973 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13974 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13975 OOLoc = BO->getOperatorLoc(); 13976 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13977 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13978 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13979 OOK = OCE->getOperator(); 13980 OOLoc = OCE->getOperatorLoc(); 13981 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13982 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13983 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13984 OOK = MCE->getMethodDecl() 13985 ->getNameInfo() 13986 .getName() 13987 .getCXXOverloadedOperator(); 13988 OOLoc = MCE->getCallee()->getExprLoc(); 13989 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13990 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13991 } 13992 SourceLocation ELoc; 13993 SourceRange ERange; 13994 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13995 if (Res.second) { 13996 // It will be analyzed later. 13997 Vars.push_back(RefExpr); 13998 } 13999 ValueDecl *D = Res.first; 14000 if (!D) 14001 continue; 14002 14003 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14004 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14005 continue; 14006 } 14007 if (RHS) { 14008 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14009 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14010 if (RHSRes.isInvalid()) 14011 continue; 14012 } 14013 if (!CurContext->isDependentContext() && 14014 DSAStack->getParentOrderedRegionParam().first && 14015 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14016 const ValueDecl *VD = 14017 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14018 if (VD) 14019 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14020 << 1 << VD; 14021 else 14022 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14023 continue; 14024 } 14025 OpsOffs.emplace_back(RHS, OOK); 14026 } else { 14027 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14028 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14029 (ASE && 14030 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14031 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14032 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14033 << RefExpr->getSourceRange(); 14034 continue; 14035 } 14036 14037 ExprResult Res; 14038 { 14039 Sema::TentativeAnalysisScope Trap(*this); 14040 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14041 RefExpr->IgnoreParenImpCasts()); 14042 } 14043 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14044 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14045 << RefExpr->getSourceRange(); 14046 continue; 14047 } 14048 } 14049 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14050 } 14051 14052 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14053 TotalDepCount > VarList.size() && 14054 DSAStack->getParentOrderedRegionParam().first && 14055 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14056 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14057 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14058 } 14059 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14060 Vars.empty()) 14061 return nullptr; 14062 14063 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14064 DepKind, DepLoc, ColonLoc, Vars, 14065 TotalDepCount.getZExtValue()); 14066 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14067 DSAStack->isParentOrderedRegion()) 14068 DSAStack->addDoacrossDependClause(C, OpsOffs); 14069 return C; 14070 } 14071 14072 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14073 SourceLocation LParenLoc, 14074 SourceLocation EndLoc) { 14075 Expr *ValExpr = Device; 14076 Stmt *HelperValStmt = nullptr; 14077 14078 // OpenMP [2.9.1, Restrictions] 14079 // The device expression must evaluate to a non-negative integer value. 14080 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14081 /*StrictlyPositive=*/false)) 14082 return nullptr; 14083 14084 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14085 OpenMPDirectiveKind CaptureRegion = 14086 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14087 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14088 ValExpr = MakeFullExpr(ValExpr).get(); 14089 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14090 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14091 HelperValStmt = buildPreInits(Context, Captures); 14092 } 14093 14094 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14095 StartLoc, LParenLoc, EndLoc); 14096 } 14097 14098 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14099 DSAStackTy *Stack, QualType QTy, 14100 bool FullCheck = true) { 14101 NamedDecl *ND; 14102 if (QTy->isIncompleteType(&ND)) { 14103 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14104 return false; 14105 } 14106 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14107 !QTy.isTrivialType(SemaRef.Context)) 14108 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14109 return true; 14110 } 14111 14112 /// Return true if it can be proven that the provided array expression 14113 /// (array section or array subscript) does NOT specify the whole size of the 14114 /// array whose base type is \a BaseQTy. 14115 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14116 const Expr *E, 14117 QualType BaseQTy) { 14118 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14119 14120 // If this is an array subscript, it refers to the whole size if the size of 14121 // the dimension is constant and equals 1. Also, an array section assumes the 14122 // format of an array subscript if no colon is used. 14123 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14124 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14125 return ATy->getSize().getSExtValue() != 1; 14126 // Size can't be evaluated statically. 14127 return false; 14128 } 14129 14130 assert(OASE && "Expecting array section if not an array subscript."); 14131 const Expr *LowerBound = OASE->getLowerBound(); 14132 const Expr *Length = OASE->getLength(); 14133 14134 // If there is a lower bound that does not evaluates to zero, we are not 14135 // covering the whole dimension. 14136 if (LowerBound) { 14137 Expr::EvalResult Result; 14138 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14139 return false; // Can't get the integer value as a constant. 14140 14141 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14142 if (ConstLowerBound.getSExtValue()) 14143 return true; 14144 } 14145 14146 // If we don't have a length we covering the whole dimension. 14147 if (!Length) 14148 return false; 14149 14150 // If the base is a pointer, we don't have a way to get the size of the 14151 // pointee. 14152 if (BaseQTy->isPointerType()) 14153 return false; 14154 14155 // We can only check if the length is the same as the size of the dimension 14156 // if we have a constant array. 14157 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14158 if (!CATy) 14159 return false; 14160 14161 Expr::EvalResult Result; 14162 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14163 return false; // Can't get the integer value as a constant. 14164 14165 llvm::APSInt ConstLength = Result.Val.getInt(); 14166 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14167 } 14168 14169 // Return true if it can be proven that the provided array expression (array 14170 // section or array subscript) does NOT specify a single element of the array 14171 // whose base type is \a BaseQTy. 14172 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14173 const Expr *E, 14174 QualType BaseQTy) { 14175 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14176 14177 // An array subscript always refer to a single element. Also, an array section 14178 // assumes the format of an array subscript if no colon is used. 14179 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14180 return false; 14181 14182 assert(OASE && "Expecting array section if not an array subscript."); 14183 const Expr *Length = OASE->getLength(); 14184 14185 // If we don't have a length we have to check if the array has unitary size 14186 // for this dimension. Also, we should always expect a length if the base type 14187 // is pointer. 14188 if (!Length) { 14189 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14190 return ATy->getSize().getSExtValue() != 1; 14191 // We cannot assume anything. 14192 return false; 14193 } 14194 14195 // Check if the length evaluates to 1. 14196 Expr::EvalResult Result; 14197 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14198 return false; // Can't get the integer value as a constant. 14199 14200 llvm::APSInt ConstLength = Result.Val.getInt(); 14201 return ConstLength.getSExtValue() != 1; 14202 } 14203 14204 // Return the expression of the base of the mappable expression or null if it 14205 // cannot be determined and do all the necessary checks to see if the expression 14206 // is valid as a standalone mappable expression. In the process, record all the 14207 // components of the expression. 14208 static const Expr *checkMapClauseExpressionBase( 14209 Sema &SemaRef, Expr *E, 14210 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14211 OpenMPClauseKind CKind, bool NoDiagnose) { 14212 SourceLocation ELoc = E->getExprLoc(); 14213 SourceRange ERange = E->getSourceRange(); 14214 14215 // The base of elements of list in a map clause have to be either: 14216 // - a reference to variable or field. 14217 // - a member expression. 14218 // - an array expression. 14219 // 14220 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14221 // reference to 'r'. 14222 // 14223 // If we have: 14224 // 14225 // struct SS { 14226 // Bla S; 14227 // foo() { 14228 // #pragma omp target map (S.Arr[:12]); 14229 // } 14230 // } 14231 // 14232 // We want to retrieve the member expression 'this->S'; 14233 14234 const Expr *RelevantExpr = nullptr; 14235 14236 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14237 // If a list item is an array section, it must specify contiguous storage. 14238 // 14239 // For this restriction it is sufficient that we make sure only references 14240 // to variables or fields and array expressions, and that no array sections 14241 // exist except in the rightmost expression (unless they cover the whole 14242 // dimension of the array). E.g. these would be invalid: 14243 // 14244 // r.ArrS[3:5].Arr[6:7] 14245 // 14246 // r.ArrS[3:5].x 14247 // 14248 // but these would be valid: 14249 // r.ArrS[3].Arr[6:7] 14250 // 14251 // r.ArrS[3].x 14252 14253 bool AllowUnitySizeArraySection = true; 14254 bool AllowWholeSizeArraySection = true; 14255 14256 while (!RelevantExpr) { 14257 E = E->IgnoreParenImpCasts(); 14258 14259 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14260 if (!isa<VarDecl>(CurE->getDecl())) 14261 return nullptr; 14262 14263 RelevantExpr = CurE; 14264 14265 // If we got a reference to a declaration, we should not expect any array 14266 // section before that. 14267 AllowUnitySizeArraySection = false; 14268 AllowWholeSizeArraySection = false; 14269 14270 // Record the component. 14271 CurComponents.emplace_back(CurE, CurE->getDecl()); 14272 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14273 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14274 14275 if (isa<CXXThisExpr>(BaseE)) 14276 // We found a base expression: this->Val. 14277 RelevantExpr = CurE; 14278 else 14279 E = BaseE; 14280 14281 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14282 if (!NoDiagnose) { 14283 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14284 << CurE->getSourceRange(); 14285 return nullptr; 14286 } 14287 if (RelevantExpr) 14288 return nullptr; 14289 continue; 14290 } 14291 14292 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14293 14294 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14295 // A bit-field cannot appear in a map clause. 14296 // 14297 if (FD->isBitField()) { 14298 if (!NoDiagnose) { 14299 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14300 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14301 return nullptr; 14302 } 14303 if (RelevantExpr) 14304 return nullptr; 14305 continue; 14306 } 14307 14308 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14309 // If the type of a list item is a reference to a type T then the type 14310 // will be considered to be T for all purposes of this clause. 14311 QualType CurType = BaseE->getType().getNonReferenceType(); 14312 14313 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14314 // A list item cannot be a variable that is a member of a structure with 14315 // a union type. 14316 // 14317 if (CurType->isUnionType()) { 14318 if (!NoDiagnose) { 14319 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14320 << CurE->getSourceRange(); 14321 return nullptr; 14322 } 14323 continue; 14324 } 14325 14326 // If we got a member expression, we should not expect any array section 14327 // before that: 14328 // 14329 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14330 // If a list item is an element of a structure, only the rightmost symbol 14331 // of the variable reference can be an array section. 14332 // 14333 AllowUnitySizeArraySection = false; 14334 AllowWholeSizeArraySection = false; 14335 14336 // Record the component. 14337 CurComponents.emplace_back(CurE, FD); 14338 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14339 E = CurE->getBase()->IgnoreParenImpCasts(); 14340 14341 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14342 if (!NoDiagnose) { 14343 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14344 << 0 << CurE->getSourceRange(); 14345 return nullptr; 14346 } 14347 continue; 14348 } 14349 14350 // If we got an array subscript that express the whole dimension we 14351 // can have any array expressions before. If it only expressing part of 14352 // the dimension, we can only have unitary-size array expressions. 14353 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14354 E->getType())) 14355 AllowWholeSizeArraySection = false; 14356 14357 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14358 Expr::EvalResult Result; 14359 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14360 if (!Result.Val.getInt().isNullValue()) { 14361 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14362 diag::err_omp_invalid_map_this_expr); 14363 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14364 diag::note_omp_invalid_subscript_on_this_ptr_map); 14365 } 14366 } 14367 RelevantExpr = TE; 14368 } 14369 14370 // Record the component - we don't have any declaration associated. 14371 CurComponents.emplace_back(CurE, nullptr); 14372 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14373 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14374 E = CurE->getBase()->IgnoreParenImpCasts(); 14375 14376 QualType CurType = 14377 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14378 14379 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14380 // If the type of a list item is a reference to a type T then the type 14381 // will be considered to be T for all purposes of this clause. 14382 if (CurType->isReferenceType()) 14383 CurType = CurType->getPointeeType(); 14384 14385 bool IsPointer = CurType->isAnyPointerType(); 14386 14387 if (!IsPointer && !CurType->isArrayType()) { 14388 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14389 << 0 << CurE->getSourceRange(); 14390 return nullptr; 14391 } 14392 14393 bool NotWhole = 14394 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14395 bool NotUnity = 14396 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14397 14398 if (AllowWholeSizeArraySection) { 14399 // Any array section is currently allowed. Allowing a whole size array 14400 // section implies allowing a unity array section as well. 14401 // 14402 // If this array section refers to the whole dimension we can still 14403 // accept other array sections before this one, except if the base is a 14404 // pointer. Otherwise, only unitary sections are accepted. 14405 if (NotWhole || IsPointer) 14406 AllowWholeSizeArraySection = false; 14407 } else if (AllowUnitySizeArraySection && NotUnity) { 14408 // A unity or whole array section is not allowed and that is not 14409 // compatible with the properties of the current array section. 14410 SemaRef.Diag( 14411 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14412 << CurE->getSourceRange(); 14413 return nullptr; 14414 } 14415 14416 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14417 Expr::EvalResult ResultR; 14418 Expr::EvalResult ResultL; 14419 if (CurE->getLength()->EvaluateAsInt(ResultR, 14420 SemaRef.getASTContext())) { 14421 if (!ResultR.Val.getInt().isOneValue()) { 14422 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14423 diag::err_omp_invalid_map_this_expr); 14424 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14425 diag::note_omp_invalid_length_on_this_ptr_mapping); 14426 } 14427 } 14428 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14429 ResultL, SemaRef.getASTContext())) { 14430 if (!ResultL.Val.getInt().isNullValue()) { 14431 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14432 diag::err_omp_invalid_map_this_expr); 14433 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14434 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14435 } 14436 } 14437 RelevantExpr = TE; 14438 } 14439 14440 // Record the component - we don't have any declaration associated. 14441 CurComponents.emplace_back(CurE, nullptr); 14442 } else { 14443 if (!NoDiagnose) { 14444 // If nothing else worked, this is not a valid map clause expression. 14445 SemaRef.Diag( 14446 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14447 << ERange; 14448 } 14449 return nullptr; 14450 } 14451 } 14452 14453 return RelevantExpr; 14454 } 14455 14456 // Return true if expression E associated with value VD has conflicts with other 14457 // map information. 14458 static bool checkMapConflicts( 14459 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14460 bool CurrentRegionOnly, 14461 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14462 OpenMPClauseKind CKind) { 14463 assert(VD && E); 14464 SourceLocation ELoc = E->getExprLoc(); 14465 SourceRange ERange = E->getSourceRange(); 14466 14467 // In order to easily check the conflicts we need to match each component of 14468 // the expression under test with the components of the expressions that are 14469 // already in the stack. 14470 14471 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14472 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14473 "Map clause expression with unexpected base!"); 14474 14475 // Variables to help detecting enclosing problems in data environment nests. 14476 bool IsEnclosedByDataEnvironmentExpr = false; 14477 const Expr *EnclosingExpr = nullptr; 14478 14479 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14480 VD, CurrentRegionOnly, 14481 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14482 ERange, CKind, &EnclosingExpr, 14483 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14484 StackComponents, 14485 OpenMPClauseKind) { 14486 assert(!StackComponents.empty() && 14487 "Map clause expression with no components!"); 14488 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14489 "Map clause expression with unexpected base!"); 14490 (void)VD; 14491 14492 // The whole expression in the stack. 14493 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14494 14495 // Expressions must start from the same base. Here we detect at which 14496 // point both expressions diverge from each other and see if we can 14497 // detect if the memory referred to both expressions is contiguous and 14498 // do not overlap. 14499 auto CI = CurComponents.rbegin(); 14500 auto CE = CurComponents.rend(); 14501 auto SI = StackComponents.rbegin(); 14502 auto SE = StackComponents.rend(); 14503 for (; CI != CE && SI != SE; ++CI, ++SI) { 14504 14505 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14506 // At most one list item can be an array item derived from a given 14507 // variable in map clauses of the same construct. 14508 if (CurrentRegionOnly && 14509 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14510 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14511 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14512 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14513 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14514 diag::err_omp_multiple_array_items_in_map_clause) 14515 << CI->getAssociatedExpression()->getSourceRange(); 14516 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14517 diag::note_used_here) 14518 << SI->getAssociatedExpression()->getSourceRange(); 14519 return true; 14520 } 14521 14522 // Do both expressions have the same kind? 14523 if (CI->getAssociatedExpression()->getStmtClass() != 14524 SI->getAssociatedExpression()->getStmtClass()) 14525 break; 14526 14527 // Are we dealing with different variables/fields? 14528 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14529 break; 14530 } 14531 // Check if the extra components of the expressions in the enclosing 14532 // data environment are redundant for the current base declaration. 14533 // If they are, the maps completely overlap, which is legal. 14534 for (; SI != SE; ++SI) { 14535 QualType Type; 14536 if (const auto *ASE = 14537 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14538 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14539 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14540 SI->getAssociatedExpression())) { 14541 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14542 Type = 14543 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14544 } 14545 if (Type.isNull() || Type->isAnyPointerType() || 14546 checkArrayExpressionDoesNotReferToWholeSize( 14547 SemaRef, SI->getAssociatedExpression(), Type)) 14548 break; 14549 } 14550 14551 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14552 // List items of map clauses in the same construct must not share 14553 // original storage. 14554 // 14555 // If the expressions are exactly the same or one is a subset of the 14556 // other, it means they are sharing storage. 14557 if (CI == CE && SI == SE) { 14558 if (CurrentRegionOnly) { 14559 if (CKind == OMPC_map) { 14560 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14561 } else { 14562 assert(CKind == OMPC_to || CKind == OMPC_from); 14563 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14564 << ERange; 14565 } 14566 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14567 << RE->getSourceRange(); 14568 return true; 14569 } 14570 // If we find the same expression in the enclosing data environment, 14571 // that is legal. 14572 IsEnclosedByDataEnvironmentExpr = true; 14573 return false; 14574 } 14575 14576 QualType DerivedType = 14577 std::prev(CI)->getAssociatedDeclaration()->getType(); 14578 SourceLocation DerivedLoc = 14579 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14580 14581 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14582 // If the type of a list item is a reference to a type T then the type 14583 // will be considered to be T for all purposes of this clause. 14584 DerivedType = DerivedType.getNonReferenceType(); 14585 14586 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14587 // A variable for which the type is pointer and an array section 14588 // derived from that variable must not appear as list items of map 14589 // clauses of the same construct. 14590 // 14591 // Also, cover one of the cases in: 14592 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14593 // If any part of the original storage of a list item has corresponding 14594 // storage in the device data environment, all of the original storage 14595 // must have corresponding storage in the device data environment. 14596 // 14597 if (DerivedType->isAnyPointerType()) { 14598 if (CI == CE || SI == SE) { 14599 SemaRef.Diag( 14600 DerivedLoc, 14601 diag::err_omp_pointer_mapped_along_with_derived_section) 14602 << DerivedLoc; 14603 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14604 << RE->getSourceRange(); 14605 return true; 14606 } 14607 if (CI->getAssociatedExpression()->getStmtClass() != 14608 SI->getAssociatedExpression()->getStmtClass() || 14609 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14610 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14611 assert(CI != CE && SI != SE); 14612 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14613 << DerivedLoc; 14614 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14615 << RE->getSourceRange(); 14616 return true; 14617 } 14618 } 14619 14620 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14621 // List items of map clauses in the same construct must not share 14622 // original storage. 14623 // 14624 // An expression is a subset of the other. 14625 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14626 if (CKind == OMPC_map) { 14627 if (CI != CE || SI != SE) { 14628 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14629 // a pointer. 14630 auto Begin = 14631 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14632 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14633 auto It = Begin; 14634 while (It != End && !It->getAssociatedDeclaration()) 14635 std::advance(It, 1); 14636 assert(It != End && 14637 "Expected at least one component with the declaration."); 14638 if (It != Begin && It->getAssociatedDeclaration() 14639 ->getType() 14640 .getCanonicalType() 14641 ->isAnyPointerType()) { 14642 IsEnclosedByDataEnvironmentExpr = false; 14643 EnclosingExpr = nullptr; 14644 return false; 14645 } 14646 } 14647 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14648 } else { 14649 assert(CKind == OMPC_to || CKind == OMPC_from); 14650 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14651 << ERange; 14652 } 14653 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14654 << RE->getSourceRange(); 14655 return true; 14656 } 14657 14658 // The current expression uses the same base as other expression in the 14659 // data environment but does not contain it completely. 14660 if (!CurrentRegionOnly && SI != SE) 14661 EnclosingExpr = RE; 14662 14663 // The current expression is a subset of the expression in the data 14664 // environment. 14665 IsEnclosedByDataEnvironmentExpr |= 14666 (!CurrentRegionOnly && CI != CE && SI == SE); 14667 14668 return false; 14669 }); 14670 14671 if (CurrentRegionOnly) 14672 return FoundError; 14673 14674 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14675 // If any part of the original storage of a list item has corresponding 14676 // storage in the device data environment, all of the original storage must 14677 // have corresponding storage in the device data environment. 14678 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 14679 // If a list item is an element of a structure, and a different element of 14680 // the structure has a corresponding list item in the device data environment 14681 // prior to a task encountering the construct associated with the map clause, 14682 // then the list item must also have a corresponding list item in the device 14683 // data environment prior to the task encountering the construct. 14684 // 14685 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 14686 SemaRef.Diag(ELoc, 14687 diag::err_omp_original_storage_is_shared_and_does_not_contain) 14688 << ERange; 14689 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 14690 << EnclosingExpr->getSourceRange(); 14691 return true; 14692 } 14693 14694 return FoundError; 14695 } 14696 14697 // Look up the user-defined mapper given the mapper name and mapped type, and 14698 // build a reference to it. 14699 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 14700 CXXScopeSpec &MapperIdScopeSpec, 14701 const DeclarationNameInfo &MapperId, 14702 QualType Type, 14703 Expr *UnresolvedMapper) { 14704 if (MapperIdScopeSpec.isInvalid()) 14705 return ExprError(); 14706 // Find all user-defined mappers with the given MapperId. 14707 SmallVector<UnresolvedSet<8>, 4> Lookups; 14708 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 14709 Lookup.suppressDiagnostics(); 14710 if (S) { 14711 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 14712 NamedDecl *D = Lookup.getRepresentativeDecl(); 14713 while (S && !S->isDeclScope(D)) 14714 S = S->getParent(); 14715 if (S) 14716 S = S->getParent(); 14717 Lookups.emplace_back(); 14718 Lookups.back().append(Lookup.begin(), Lookup.end()); 14719 Lookup.clear(); 14720 } 14721 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 14722 // Extract the user-defined mappers with the given MapperId. 14723 Lookups.push_back(UnresolvedSet<8>()); 14724 for (NamedDecl *D : ULE->decls()) { 14725 auto *DMD = cast<OMPDeclareMapperDecl>(D); 14726 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 14727 Lookups.back().addDecl(DMD); 14728 } 14729 } 14730 // Defer the lookup for dependent types. The results will be passed through 14731 // UnresolvedMapper on instantiation. 14732 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 14733 Type->isInstantiationDependentType() || 14734 Type->containsUnexpandedParameterPack() || 14735 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14736 return !D->isInvalidDecl() && 14737 (D->getType()->isDependentType() || 14738 D->getType()->isInstantiationDependentType() || 14739 D->getType()->containsUnexpandedParameterPack()); 14740 })) { 14741 UnresolvedSet<8> URS; 14742 for (const UnresolvedSet<8> &Set : Lookups) { 14743 if (Set.empty()) 14744 continue; 14745 URS.append(Set.begin(), Set.end()); 14746 } 14747 return UnresolvedLookupExpr::Create( 14748 SemaRef.Context, /*NamingClass=*/nullptr, 14749 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 14750 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 14751 } 14752 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14753 // The type must be of struct, union or class type in C and C++ 14754 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 14755 return ExprEmpty(); 14756 SourceLocation Loc = MapperId.getLoc(); 14757 // Perform argument dependent lookup. 14758 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 14759 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 14760 // Return the first user-defined mapper with the desired type. 14761 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14762 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 14763 if (!D->isInvalidDecl() && 14764 SemaRef.Context.hasSameType(D->getType(), Type)) 14765 return D; 14766 return nullptr; 14767 })) 14768 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14769 // Find the first user-defined mapper with a type derived from the desired 14770 // type. 14771 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14772 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 14773 if (!D->isInvalidDecl() && 14774 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 14775 !Type.isMoreQualifiedThan(D->getType())) 14776 return D; 14777 return nullptr; 14778 })) { 14779 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14780 /*DetectVirtual=*/false); 14781 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 14782 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14783 VD->getType().getUnqualifiedType()))) { 14784 if (SemaRef.CheckBaseClassAccess( 14785 Loc, VD->getType(), Type, Paths.front(), 14786 /*DiagID=*/0) != Sema::AR_inaccessible) { 14787 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14788 } 14789 } 14790 } 14791 } 14792 // Report error if a mapper is specified, but cannot be found. 14793 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 14794 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 14795 << Type << MapperId.getName(); 14796 return ExprError(); 14797 } 14798 return ExprEmpty(); 14799 } 14800 14801 namespace { 14802 // Utility struct that gathers all the related lists associated with a mappable 14803 // expression. 14804 struct MappableVarListInfo { 14805 // The list of expressions. 14806 ArrayRef<Expr *> VarList; 14807 // The list of processed expressions. 14808 SmallVector<Expr *, 16> ProcessedVarList; 14809 // The mappble components for each expression. 14810 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 14811 // The base declaration of the variable. 14812 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 14813 // The reference to the user-defined mapper associated with every expression. 14814 SmallVector<Expr *, 16> UDMapperList; 14815 14816 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 14817 // We have a list of components and base declarations for each entry in the 14818 // variable list. 14819 VarComponents.reserve(VarList.size()); 14820 VarBaseDeclarations.reserve(VarList.size()); 14821 } 14822 }; 14823 } 14824 14825 // Check the validity of the provided variable list for the provided clause kind 14826 // \a CKind. In the check process the valid expressions, mappable expression 14827 // components, variables, and user-defined mappers are extracted and used to 14828 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 14829 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 14830 // and \a MapperId are expected to be valid if the clause kind is 'map'. 14831 static void checkMappableExpressionList( 14832 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 14833 MappableVarListInfo &MVLI, SourceLocation StartLoc, 14834 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 14835 ArrayRef<Expr *> UnresolvedMappers, 14836 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 14837 bool IsMapTypeImplicit = false) { 14838 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 14839 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 14840 "Unexpected clause kind with mappable expressions!"); 14841 14842 // If the identifier of user-defined mapper is not specified, it is "default". 14843 // We do not change the actual name in this clause to distinguish whether a 14844 // mapper is specified explicitly, i.e., it is not explicitly specified when 14845 // MapperId.getName() is empty. 14846 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 14847 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14848 MapperId.setName(DeclNames.getIdentifier( 14849 &SemaRef.getASTContext().Idents.get("default"))); 14850 } 14851 14852 // Iterators to find the current unresolved mapper expression. 14853 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14854 bool UpdateUMIt = false; 14855 Expr *UnresolvedMapper = nullptr; 14856 14857 // Keep track of the mappable components and base declarations in this clause. 14858 // Each entry in the list is going to have a list of components associated. We 14859 // record each set of the components so that we can build the clause later on. 14860 // In the end we should have the same amount of declarations and component 14861 // lists. 14862 14863 for (Expr *RE : MVLI.VarList) { 14864 assert(RE && "Null expr in omp to/from/map clause"); 14865 SourceLocation ELoc = RE->getExprLoc(); 14866 14867 // Find the current unresolved mapper expression. 14868 if (UpdateUMIt && UMIt != UMEnd) { 14869 UMIt++; 14870 assert( 14871 UMIt != UMEnd && 14872 "Expect the size of UnresolvedMappers to match with that of VarList"); 14873 } 14874 UpdateUMIt = true; 14875 if (UMIt != UMEnd) 14876 UnresolvedMapper = *UMIt; 14877 14878 const Expr *VE = RE->IgnoreParenLValueCasts(); 14879 14880 if (VE->isValueDependent() || VE->isTypeDependent() || 14881 VE->isInstantiationDependent() || 14882 VE->containsUnexpandedParameterPack()) { 14883 // Try to find the associated user-defined mapper. 14884 ExprResult ER = buildUserDefinedMapperRef( 14885 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14886 VE->getType().getCanonicalType(), UnresolvedMapper); 14887 if (ER.isInvalid()) 14888 continue; 14889 MVLI.UDMapperList.push_back(ER.get()); 14890 // We can only analyze this information once the missing information is 14891 // resolved. 14892 MVLI.ProcessedVarList.push_back(RE); 14893 continue; 14894 } 14895 14896 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14897 14898 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14899 SemaRef.Diag(ELoc, 14900 diag::err_omp_expected_named_var_member_or_array_expression) 14901 << RE->getSourceRange(); 14902 continue; 14903 } 14904 14905 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14906 ValueDecl *CurDeclaration = nullptr; 14907 14908 // Obtain the array or member expression bases if required. Also, fill the 14909 // components array with all the components identified in the process. 14910 const Expr *BE = checkMapClauseExpressionBase( 14911 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14912 if (!BE) 14913 continue; 14914 14915 assert(!CurComponents.empty() && 14916 "Invalid mappable expression information."); 14917 14918 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14919 // Add store "this" pointer to class in DSAStackTy for future checking 14920 DSAS->addMappedClassesQualTypes(TE->getType()); 14921 // Try to find the associated user-defined mapper. 14922 ExprResult ER = buildUserDefinedMapperRef( 14923 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14924 VE->getType().getCanonicalType(), UnresolvedMapper); 14925 if (ER.isInvalid()) 14926 continue; 14927 MVLI.UDMapperList.push_back(ER.get()); 14928 // Skip restriction checking for variable or field declarations 14929 MVLI.ProcessedVarList.push_back(RE); 14930 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14931 MVLI.VarComponents.back().append(CurComponents.begin(), 14932 CurComponents.end()); 14933 MVLI.VarBaseDeclarations.push_back(nullptr); 14934 continue; 14935 } 14936 14937 // For the following checks, we rely on the base declaration which is 14938 // expected to be associated with the last component. The declaration is 14939 // expected to be a variable or a field (if 'this' is being mapped). 14940 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14941 assert(CurDeclaration && "Null decl on map clause."); 14942 assert( 14943 CurDeclaration->isCanonicalDecl() && 14944 "Expecting components to have associated only canonical declarations."); 14945 14946 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14947 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14948 14949 assert((VD || FD) && "Only variables or fields are expected here!"); 14950 (void)FD; 14951 14952 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14953 // threadprivate variables cannot appear in a map clause. 14954 // OpenMP 4.5 [2.10.5, target update Construct] 14955 // threadprivate variables cannot appear in a from clause. 14956 if (VD && DSAS->isThreadPrivate(VD)) { 14957 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14958 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14959 << getOpenMPClauseName(CKind); 14960 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14961 continue; 14962 } 14963 14964 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14965 // A list item cannot appear in both a map clause and a data-sharing 14966 // attribute clause on the same construct. 14967 14968 // Check conflicts with other map clause expressions. We check the conflicts 14969 // with the current construct separately from the enclosing data 14970 // environment, because the restrictions are different. We only have to 14971 // check conflicts across regions for the map clauses. 14972 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14973 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14974 break; 14975 if (CKind == OMPC_map && 14976 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14977 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14978 break; 14979 14980 // OpenMP 4.5 [2.10.5, target update Construct] 14981 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14982 // If the type of a list item is a reference to a type T then the type will 14983 // be considered to be T for all purposes of this clause. 14984 auto I = llvm::find_if( 14985 CurComponents, 14986 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14987 return MC.getAssociatedDeclaration(); 14988 }); 14989 assert(I != CurComponents.end() && "Null decl on map clause."); 14990 QualType Type = 14991 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14992 14993 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14994 // A list item in a to or from clause must have a mappable type. 14995 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14996 // A list item must have a mappable type. 14997 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14998 DSAS, Type)) 14999 continue; 15000 15001 if (CKind == OMPC_map) { 15002 // target enter data 15003 // OpenMP [2.10.2, Restrictions, p. 99] 15004 // A map-type must be specified in all map clauses and must be either 15005 // to or alloc. 15006 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15007 if (DKind == OMPD_target_enter_data && 15008 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15009 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15010 << (IsMapTypeImplicit ? 1 : 0) 15011 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15012 << getOpenMPDirectiveName(DKind); 15013 continue; 15014 } 15015 15016 // target exit_data 15017 // OpenMP [2.10.3, Restrictions, p. 102] 15018 // A map-type must be specified in all map clauses and must be either 15019 // from, release, or delete. 15020 if (DKind == OMPD_target_exit_data && 15021 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15022 MapType == OMPC_MAP_delete)) { 15023 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15024 << (IsMapTypeImplicit ? 1 : 0) 15025 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15026 << getOpenMPDirectiveName(DKind); 15027 continue; 15028 } 15029 15030 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15031 // A list item cannot appear in both a map clause and a data-sharing 15032 // attribute clause on the same construct 15033 // 15034 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15035 // A list item cannot appear in both a map clause and a data-sharing 15036 // attribute clause on the same construct unless the construct is a 15037 // combined construct. 15038 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15039 isOpenMPTargetExecutionDirective(DKind)) || 15040 DKind == OMPD_target)) { 15041 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15042 if (isOpenMPPrivate(DVar.CKind)) { 15043 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15044 << getOpenMPClauseName(DVar.CKind) 15045 << getOpenMPClauseName(OMPC_map) 15046 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15047 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15048 continue; 15049 } 15050 } 15051 } 15052 15053 // Try to find the associated user-defined mapper. 15054 ExprResult ER = buildUserDefinedMapperRef( 15055 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15056 Type.getCanonicalType(), UnresolvedMapper); 15057 if (ER.isInvalid()) 15058 continue; 15059 MVLI.UDMapperList.push_back(ER.get()); 15060 15061 // Save the current expression. 15062 MVLI.ProcessedVarList.push_back(RE); 15063 15064 // Store the components in the stack so that they can be used to check 15065 // against other clauses later on. 15066 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15067 /*WhereFoundClauseKind=*/OMPC_map); 15068 15069 // Save the components and declaration to create the clause. For purposes of 15070 // the clause creation, any component list that has has base 'this' uses 15071 // null as base declaration. 15072 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15073 MVLI.VarComponents.back().append(CurComponents.begin(), 15074 CurComponents.end()); 15075 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15076 : CurDeclaration); 15077 } 15078 } 15079 15080 OMPClause *Sema::ActOnOpenMPMapClause( 15081 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15082 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15083 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15084 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15085 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15086 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15087 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15088 OMPC_MAP_MODIFIER_unknown, 15089 OMPC_MAP_MODIFIER_unknown}; 15090 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15091 15092 // Process map-type-modifiers, flag errors for duplicate modifiers. 15093 unsigned Count = 0; 15094 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15095 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15096 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15097 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15098 continue; 15099 } 15100 assert(Count < OMPMapClause::NumberOfModifiers && 15101 "Modifiers exceed the allowed number of map type modifiers"); 15102 Modifiers[Count] = MapTypeModifiers[I]; 15103 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15104 ++Count; 15105 } 15106 15107 MappableVarListInfo MVLI(VarList); 15108 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15109 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15110 MapType, IsMapTypeImplicit); 15111 15112 // We need to produce a map clause even if we don't have variables so that 15113 // other diagnostics related with non-existing map clauses are accurate. 15114 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15115 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15116 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15117 MapperIdScopeSpec.getWithLocInContext(Context), 15118 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15119 } 15120 15121 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15122 TypeResult ParsedType) { 15123 assert(ParsedType.isUsable()); 15124 15125 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15126 if (ReductionType.isNull()) 15127 return QualType(); 15128 15129 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15130 // A type name in a declare reduction directive cannot be a function type, an 15131 // array type, a reference type, or a type qualified with const, volatile or 15132 // restrict. 15133 if (ReductionType.hasQualifiers()) { 15134 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15135 return QualType(); 15136 } 15137 15138 if (ReductionType->isFunctionType()) { 15139 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15140 return QualType(); 15141 } 15142 if (ReductionType->isReferenceType()) { 15143 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15144 return QualType(); 15145 } 15146 if (ReductionType->isArrayType()) { 15147 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15148 return QualType(); 15149 } 15150 return ReductionType; 15151 } 15152 15153 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15154 Scope *S, DeclContext *DC, DeclarationName Name, 15155 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15156 AccessSpecifier AS, Decl *PrevDeclInScope) { 15157 SmallVector<Decl *, 8> Decls; 15158 Decls.reserve(ReductionTypes.size()); 15159 15160 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15161 forRedeclarationInCurContext()); 15162 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15163 // A reduction-identifier may not be re-declared in the current scope for the 15164 // same type or for a type that is compatible according to the base language 15165 // rules. 15166 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15167 OMPDeclareReductionDecl *PrevDRD = nullptr; 15168 bool InCompoundScope = true; 15169 if (S != nullptr) { 15170 // Find previous declaration with the same name not referenced in other 15171 // declarations. 15172 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15173 InCompoundScope = 15174 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15175 LookupName(Lookup, S); 15176 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15177 /*AllowInlineNamespace=*/false); 15178 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15179 LookupResult::Filter Filter = Lookup.makeFilter(); 15180 while (Filter.hasNext()) { 15181 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15182 if (InCompoundScope) { 15183 auto I = UsedAsPrevious.find(PrevDecl); 15184 if (I == UsedAsPrevious.end()) 15185 UsedAsPrevious[PrevDecl] = false; 15186 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15187 UsedAsPrevious[D] = true; 15188 } 15189 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15190 PrevDecl->getLocation(); 15191 } 15192 Filter.done(); 15193 if (InCompoundScope) { 15194 for (const auto &PrevData : UsedAsPrevious) { 15195 if (!PrevData.second) { 15196 PrevDRD = PrevData.first; 15197 break; 15198 } 15199 } 15200 } 15201 } else if (PrevDeclInScope != nullptr) { 15202 auto *PrevDRDInScope = PrevDRD = 15203 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15204 do { 15205 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15206 PrevDRDInScope->getLocation(); 15207 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15208 } while (PrevDRDInScope != nullptr); 15209 } 15210 for (const auto &TyData : ReductionTypes) { 15211 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15212 bool Invalid = false; 15213 if (I != PreviousRedeclTypes.end()) { 15214 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15215 << TyData.first; 15216 Diag(I->second, diag::note_previous_definition); 15217 Invalid = true; 15218 } 15219 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15220 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15221 Name, TyData.first, PrevDRD); 15222 DC->addDecl(DRD); 15223 DRD->setAccess(AS); 15224 Decls.push_back(DRD); 15225 if (Invalid) 15226 DRD->setInvalidDecl(); 15227 else 15228 PrevDRD = DRD; 15229 } 15230 15231 return DeclGroupPtrTy::make( 15232 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15233 } 15234 15235 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15236 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15237 15238 // Enter new function scope. 15239 PushFunctionScope(); 15240 setFunctionHasBranchProtectedScope(); 15241 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15242 15243 if (S != nullptr) 15244 PushDeclContext(S, DRD); 15245 else 15246 CurContext = DRD; 15247 15248 PushExpressionEvaluationContext( 15249 ExpressionEvaluationContext::PotentiallyEvaluated); 15250 15251 QualType ReductionType = DRD->getType(); 15252 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15253 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15254 // uses semantics of argument handles by value, but it should be passed by 15255 // reference. C lang does not support references, so pass all parameters as 15256 // pointers. 15257 // Create 'T omp_in;' variable. 15258 VarDecl *OmpInParm = 15259 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15260 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15261 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15262 // uses semantics of argument handles by value, but it should be passed by 15263 // reference. C lang does not support references, so pass all parameters as 15264 // pointers. 15265 // Create 'T omp_out;' variable. 15266 VarDecl *OmpOutParm = 15267 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15268 if (S != nullptr) { 15269 PushOnScopeChains(OmpInParm, S); 15270 PushOnScopeChains(OmpOutParm, S); 15271 } else { 15272 DRD->addDecl(OmpInParm); 15273 DRD->addDecl(OmpOutParm); 15274 } 15275 Expr *InE = 15276 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15277 Expr *OutE = 15278 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15279 DRD->setCombinerData(InE, OutE); 15280 } 15281 15282 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15283 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15284 DiscardCleanupsInEvaluationContext(); 15285 PopExpressionEvaluationContext(); 15286 15287 PopDeclContext(); 15288 PopFunctionScopeInfo(); 15289 15290 if (Combiner != nullptr) 15291 DRD->setCombiner(Combiner); 15292 else 15293 DRD->setInvalidDecl(); 15294 } 15295 15296 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15297 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15298 15299 // Enter new function scope. 15300 PushFunctionScope(); 15301 setFunctionHasBranchProtectedScope(); 15302 15303 if (S != nullptr) 15304 PushDeclContext(S, DRD); 15305 else 15306 CurContext = DRD; 15307 15308 PushExpressionEvaluationContext( 15309 ExpressionEvaluationContext::PotentiallyEvaluated); 15310 15311 QualType ReductionType = DRD->getType(); 15312 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15313 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15314 // uses semantics of argument handles by value, but it should be passed by 15315 // reference. C lang does not support references, so pass all parameters as 15316 // pointers. 15317 // Create 'T omp_priv;' variable. 15318 VarDecl *OmpPrivParm = 15319 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15320 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15321 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15322 // uses semantics of argument handles by value, but it should be passed by 15323 // reference. C lang does not support references, so pass all parameters as 15324 // pointers. 15325 // Create 'T omp_orig;' variable. 15326 VarDecl *OmpOrigParm = 15327 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15328 if (S != nullptr) { 15329 PushOnScopeChains(OmpPrivParm, S); 15330 PushOnScopeChains(OmpOrigParm, S); 15331 } else { 15332 DRD->addDecl(OmpPrivParm); 15333 DRD->addDecl(OmpOrigParm); 15334 } 15335 Expr *OrigE = 15336 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15337 Expr *PrivE = 15338 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15339 DRD->setInitializerData(OrigE, PrivE); 15340 return OmpPrivParm; 15341 } 15342 15343 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15344 VarDecl *OmpPrivParm) { 15345 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15346 DiscardCleanupsInEvaluationContext(); 15347 PopExpressionEvaluationContext(); 15348 15349 PopDeclContext(); 15350 PopFunctionScopeInfo(); 15351 15352 if (Initializer != nullptr) { 15353 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15354 } else if (OmpPrivParm->hasInit()) { 15355 DRD->setInitializer(OmpPrivParm->getInit(), 15356 OmpPrivParm->isDirectInit() 15357 ? OMPDeclareReductionDecl::DirectInit 15358 : OMPDeclareReductionDecl::CopyInit); 15359 } else { 15360 DRD->setInvalidDecl(); 15361 } 15362 } 15363 15364 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15365 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15366 for (Decl *D : DeclReductions.get()) { 15367 if (IsValid) { 15368 if (S) 15369 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15370 /*AddToContext=*/false); 15371 } else { 15372 D->setInvalidDecl(); 15373 } 15374 } 15375 return DeclReductions; 15376 } 15377 15378 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15379 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15380 QualType T = TInfo->getType(); 15381 if (D.isInvalidType()) 15382 return true; 15383 15384 if (getLangOpts().CPlusPlus) { 15385 // Check that there are no default arguments (C++ only). 15386 CheckExtraCXXDefaultArguments(D); 15387 } 15388 15389 return CreateParsedType(T, TInfo); 15390 } 15391 15392 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15393 TypeResult ParsedType) { 15394 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15395 15396 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15397 assert(!MapperType.isNull() && "Expect valid mapper type"); 15398 15399 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15400 // The type must be of struct, union or class type in C and C++ 15401 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15402 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15403 return QualType(); 15404 } 15405 return MapperType; 15406 } 15407 15408 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15409 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15410 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15411 Decl *PrevDeclInScope) { 15412 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15413 forRedeclarationInCurContext()); 15414 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15415 // A mapper-identifier may not be redeclared in the current scope for the 15416 // same type or for a type that is compatible according to the base language 15417 // rules. 15418 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15419 OMPDeclareMapperDecl *PrevDMD = nullptr; 15420 bool InCompoundScope = true; 15421 if (S != nullptr) { 15422 // Find previous declaration with the same name not referenced in other 15423 // declarations. 15424 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15425 InCompoundScope = 15426 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15427 LookupName(Lookup, S); 15428 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15429 /*AllowInlineNamespace=*/false); 15430 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15431 LookupResult::Filter Filter = Lookup.makeFilter(); 15432 while (Filter.hasNext()) { 15433 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15434 if (InCompoundScope) { 15435 auto I = UsedAsPrevious.find(PrevDecl); 15436 if (I == UsedAsPrevious.end()) 15437 UsedAsPrevious[PrevDecl] = false; 15438 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15439 UsedAsPrevious[D] = true; 15440 } 15441 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15442 PrevDecl->getLocation(); 15443 } 15444 Filter.done(); 15445 if (InCompoundScope) { 15446 for (const auto &PrevData : UsedAsPrevious) { 15447 if (!PrevData.second) { 15448 PrevDMD = PrevData.first; 15449 break; 15450 } 15451 } 15452 } 15453 } else if (PrevDeclInScope) { 15454 auto *PrevDMDInScope = PrevDMD = 15455 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15456 do { 15457 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15458 PrevDMDInScope->getLocation(); 15459 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15460 } while (PrevDMDInScope != nullptr); 15461 } 15462 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15463 bool Invalid = false; 15464 if (I != PreviousRedeclTypes.end()) { 15465 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15466 << MapperType << Name; 15467 Diag(I->second, diag::note_previous_definition); 15468 Invalid = true; 15469 } 15470 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15471 MapperType, VN, PrevDMD); 15472 DC->addDecl(DMD); 15473 DMD->setAccess(AS); 15474 if (Invalid) 15475 DMD->setInvalidDecl(); 15476 15477 // Enter new function scope. 15478 PushFunctionScope(); 15479 setFunctionHasBranchProtectedScope(); 15480 15481 CurContext = DMD; 15482 15483 return DMD; 15484 } 15485 15486 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15487 Scope *S, 15488 QualType MapperType, 15489 SourceLocation StartLoc, 15490 DeclarationName VN) { 15491 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15492 if (S) 15493 PushOnScopeChains(VD, S); 15494 else 15495 DMD->addDecl(VD); 15496 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15497 DMD->setMapperVarRef(MapperVarRefExpr); 15498 } 15499 15500 Sema::DeclGroupPtrTy 15501 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15502 ArrayRef<OMPClause *> ClauseList) { 15503 PopDeclContext(); 15504 PopFunctionScopeInfo(); 15505 15506 if (D) { 15507 if (S) 15508 PushOnScopeChains(D, S, /*AddToContext=*/false); 15509 D->CreateClauses(Context, ClauseList); 15510 } 15511 15512 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15513 } 15514 15515 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15516 SourceLocation StartLoc, 15517 SourceLocation LParenLoc, 15518 SourceLocation EndLoc) { 15519 Expr *ValExpr = NumTeams; 15520 Stmt *HelperValStmt = nullptr; 15521 15522 // OpenMP [teams Constrcut, Restrictions] 15523 // The num_teams expression must evaluate to a positive integer value. 15524 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15525 /*StrictlyPositive=*/true)) 15526 return nullptr; 15527 15528 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15529 OpenMPDirectiveKind CaptureRegion = 15530 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15531 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15532 ValExpr = MakeFullExpr(ValExpr).get(); 15533 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15534 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15535 HelperValStmt = buildPreInits(Context, Captures); 15536 } 15537 15538 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15539 StartLoc, LParenLoc, EndLoc); 15540 } 15541 15542 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15543 SourceLocation StartLoc, 15544 SourceLocation LParenLoc, 15545 SourceLocation EndLoc) { 15546 Expr *ValExpr = ThreadLimit; 15547 Stmt *HelperValStmt = nullptr; 15548 15549 // OpenMP [teams Constrcut, Restrictions] 15550 // The thread_limit expression must evaluate to a positive integer value. 15551 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15552 /*StrictlyPositive=*/true)) 15553 return nullptr; 15554 15555 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15556 OpenMPDirectiveKind CaptureRegion = 15557 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15558 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15559 ValExpr = MakeFullExpr(ValExpr).get(); 15560 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15561 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15562 HelperValStmt = buildPreInits(Context, Captures); 15563 } 15564 15565 return new (Context) OMPThreadLimitClause( 15566 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15567 } 15568 15569 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15570 SourceLocation StartLoc, 15571 SourceLocation LParenLoc, 15572 SourceLocation EndLoc) { 15573 Expr *ValExpr = Priority; 15574 15575 // OpenMP [2.9.1, task Constrcut] 15576 // The priority-value is a non-negative numerical scalar expression. 15577 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 15578 /*StrictlyPositive=*/false)) 15579 return nullptr; 15580 15581 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15582 } 15583 15584 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15585 SourceLocation StartLoc, 15586 SourceLocation LParenLoc, 15587 SourceLocation EndLoc) { 15588 Expr *ValExpr = Grainsize; 15589 15590 // OpenMP [2.9.2, taskloop Constrcut] 15591 // The parameter of the grainsize clause must be a positive integer 15592 // expression. 15593 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 15594 /*StrictlyPositive=*/true)) 15595 return nullptr; 15596 15597 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15598 } 15599 15600 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15601 SourceLocation StartLoc, 15602 SourceLocation LParenLoc, 15603 SourceLocation EndLoc) { 15604 Expr *ValExpr = NumTasks; 15605 15606 // OpenMP [2.9.2, taskloop Constrcut] 15607 // The parameter of the num_tasks clause must be a positive integer 15608 // expression. 15609 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 15610 /*StrictlyPositive=*/true)) 15611 return nullptr; 15612 15613 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15614 } 15615 15616 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15617 SourceLocation LParenLoc, 15618 SourceLocation EndLoc) { 15619 // OpenMP [2.13.2, critical construct, Description] 15620 // ... where hint-expression is an integer constant expression that evaluates 15621 // to a valid lock hint. 15622 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15623 if (HintExpr.isInvalid()) 15624 return nullptr; 15625 return new (Context) 15626 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 15627 } 15628 15629 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 15630 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 15631 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 15632 SourceLocation EndLoc) { 15633 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 15634 std::string Values; 15635 Values += "'"; 15636 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 15637 Values += "'"; 15638 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 15639 << Values << getOpenMPClauseName(OMPC_dist_schedule); 15640 return nullptr; 15641 } 15642 Expr *ValExpr = ChunkSize; 15643 Stmt *HelperValStmt = nullptr; 15644 if (ChunkSize) { 15645 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 15646 !ChunkSize->isInstantiationDependent() && 15647 !ChunkSize->containsUnexpandedParameterPack()) { 15648 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 15649 ExprResult Val = 15650 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 15651 if (Val.isInvalid()) 15652 return nullptr; 15653 15654 ValExpr = Val.get(); 15655 15656 // OpenMP [2.7.1, Restrictions] 15657 // chunk_size must be a loop invariant integer expression with a positive 15658 // value. 15659 llvm::APSInt Result; 15660 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 15661 if (Result.isSigned() && !Result.isStrictlyPositive()) { 15662 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 15663 << "dist_schedule" << ChunkSize->getSourceRange(); 15664 return nullptr; 15665 } 15666 } else if (getOpenMPCaptureRegionForClause( 15667 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 15668 OMPD_unknown && 15669 !CurContext->isDependentContext()) { 15670 ValExpr = MakeFullExpr(ValExpr).get(); 15671 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15672 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15673 HelperValStmt = buildPreInits(Context, Captures); 15674 } 15675 } 15676 } 15677 15678 return new (Context) 15679 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 15680 Kind, ValExpr, HelperValStmt); 15681 } 15682 15683 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 15684 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 15685 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 15686 SourceLocation KindLoc, SourceLocation EndLoc) { 15687 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 15688 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 15689 std::string Value; 15690 SourceLocation Loc; 15691 Value += "'"; 15692 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 15693 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15694 OMPC_DEFAULTMAP_MODIFIER_tofrom); 15695 Loc = MLoc; 15696 } else { 15697 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15698 OMPC_DEFAULTMAP_scalar); 15699 Loc = KindLoc; 15700 } 15701 Value += "'"; 15702 Diag(Loc, diag::err_omp_unexpected_clause_value) 15703 << Value << getOpenMPClauseName(OMPC_defaultmap); 15704 return nullptr; 15705 } 15706 DSAStack->setDefaultDMAToFromScalar(StartLoc); 15707 15708 return new (Context) 15709 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 15710 } 15711 15712 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 15713 DeclContext *CurLexicalContext = getCurLexicalContext(); 15714 if (!CurLexicalContext->isFileContext() && 15715 !CurLexicalContext->isExternCContext() && 15716 !CurLexicalContext->isExternCXXContext() && 15717 !isa<CXXRecordDecl>(CurLexicalContext) && 15718 !isa<ClassTemplateDecl>(CurLexicalContext) && 15719 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 15720 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 15721 Diag(Loc, diag::err_omp_region_not_file_context); 15722 return false; 15723 } 15724 ++DeclareTargetNestingLevel; 15725 return true; 15726 } 15727 15728 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 15729 assert(DeclareTargetNestingLevel > 0 && 15730 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 15731 --DeclareTargetNestingLevel; 15732 } 15733 15734 NamedDecl * 15735 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 15736 const DeclarationNameInfo &Id, 15737 NamedDeclSetType &SameDirectiveDecls) { 15738 LookupResult Lookup(*this, Id, LookupOrdinaryName); 15739 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 15740 15741 if (Lookup.isAmbiguous()) 15742 return nullptr; 15743 Lookup.suppressDiagnostics(); 15744 15745 if (!Lookup.isSingleResult()) { 15746 VarOrFuncDeclFilterCCC CCC(*this); 15747 if (TypoCorrection Corrected = 15748 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 15749 CTK_ErrorRecovery)) { 15750 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 15751 << Id.getName()); 15752 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 15753 return nullptr; 15754 } 15755 15756 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 15757 return nullptr; 15758 } 15759 15760 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 15761 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 15762 !isa<FunctionTemplateDecl>(ND)) { 15763 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 15764 return nullptr; 15765 } 15766 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 15767 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 15768 return ND; 15769 } 15770 15771 void Sema::ActOnOpenMPDeclareTargetName( 15772 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 15773 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 15774 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 15775 isa<FunctionTemplateDecl>(ND)) && 15776 "Expected variable, function or function template."); 15777 15778 // Diagnose marking after use as it may lead to incorrect diagnosis and 15779 // codegen. 15780 if (LangOpts.OpenMP >= 50 && 15781 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 15782 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 15783 15784 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15785 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 15786 if (DevTy.hasValue() && *DevTy != DT) { 15787 Diag(Loc, diag::err_omp_device_type_mismatch) 15788 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 15789 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 15790 return; 15791 } 15792 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15793 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 15794 if (!Res) { 15795 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 15796 SourceRange(Loc, Loc)); 15797 ND->addAttr(A); 15798 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15799 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 15800 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 15801 } else if (*Res != MT) { 15802 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 15803 } 15804 } 15805 15806 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 15807 Sema &SemaRef, Decl *D) { 15808 if (!D || !isa<VarDecl>(D)) 15809 return; 15810 auto *VD = cast<VarDecl>(D); 15811 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15812 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15813 if (SemaRef.LangOpts.OpenMP >= 50 && 15814 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 15815 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 15816 VD->hasGlobalStorage()) { 15817 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15818 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15819 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 15820 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 15821 // If a lambda declaration and definition appears between a 15822 // declare target directive and the matching end declare target 15823 // directive, all variables that are captured by the lambda 15824 // expression must also appear in a to clause. 15825 SemaRef.Diag(VD->getLocation(), 15826 diag::err_omp_lambda_capture_in_declare_target_not_to); 15827 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 15828 << VD << 0 << SR; 15829 return; 15830 } 15831 } 15832 if (MapTy.hasValue()) 15833 return; 15834 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 15835 SemaRef.Diag(SL, diag::note_used_here) << SR; 15836 } 15837 15838 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 15839 Sema &SemaRef, DSAStackTy *Stack, 15840 ValueDecl *VD) { 15841 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 15842 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 15843 /*FullCheck=*/false); 15844 } 15845 15846 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 15847 SourceLocation IdLoc) { 15848 if (!D || D->isInvalidDecl()) 15849 return; 15850 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 15851 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 15852 if (auto *VD = dyn_cast<VarDecl>(D)) { 15853 // Only global variables can be marked as declare target. 15854 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 15855 !VD->isStaticDataMember()) 15856 return; 15857 // 2.10.6: threadprivate variable cannot appear in a declare target 15858 // directive. 15859 if (DSAStack->isThreadPrivate(VD)) { 15860 Diag(SL, diag::err_omp_threadprivate_in_target); 15861 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 15862 return; 15863 } 15864 } 15865 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 15866 D = FTD->getTemplatedDecl(); 15867 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 15868 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15869 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 15870 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 15871 Diag(IdLoc, diag::err_omp_function_in_link_clause); 15872 Diag(FD->getLocation(), diag::note_defined_here) << FD; 15873 return; 15874 } 15875 // Mark the function as must be emitted for the device. 15876 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15877 OMPDeclareTargetDeclAttr::getDeviceType(FD); 15878 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 15879 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 15880 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 15881 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 15882 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 15883 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 15884 } 15885 if (auto *VD = dyn_cast<ValueDecl>(D)) { 15886 // Problem if any with var declared with incomplete type will be reported 15887 // as normal, so no need to check it here. 15888 if ((E || !VD->getType()->isIncompleteType()) && 15889 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 15890 return; 15891 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 15892 // Checking declaration inside declare target region. 15893 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 15894 isa<FunctionTemplateDecl>(D)) { 15895 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 15896 Context, OMPDeclareTargetDeclAttr::MT_To, 15897 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 15898 D->addAttr(A); 15899 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15900 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 15901 } 15902 return; 15903 } 15904 } 15905 if (!E) 15906 return; 15907 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 15908 } 15909 15910 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15911 CXXScopeSpec &MapperIdScopeSpec, 15912 DeclarationNameInfo &MapperId, 15913 const OMPVarListLocTy &Locs, 15914 ArrayRef<Expr *> UnresolvedMappers) { 15915 MappableVarListInfo MVLI(VarList); 15916 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15917 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15918 if (MVLI.ProcessedVarList.empty()) 15919 return nullptr; 15920 15921 return OMPToClause::Create( 15922 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15923 MVLI.VarComponents, MVLI.UDMapperList, 15924 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15925 } 15926 15927 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15928 CXXScopeSpec &MapperIdScopeSpec, 15929 DeclarationNameInfo &MapperId, 15930 const OMPVarListLocTy &Locs, 15931 ArrayRef<Expr *> UnresolvedMappers) { 15932 MappableVarListInfo MVLI(VarList); 15933 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15934 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15935 if (MVLI.ProcessedVarList.empty()) 15936 return nullptr; 15937 15938 return OMPFromClause::Create( 15939 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15940 MVLI.VarComponents, MVLI.UDMapperList, 15941 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15942 } 15943 15944 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 15945 const OMPVarListLocTy &Locs) { 15946 MappableVarListInfo MVLI(VarList); 15947 SmallVector<Expr *, 8> PrivateCopies; 15948 SmallVector<Expr *, 8> Inits; 15949 15950 for (Expr *RefExpr : VarList) { 15951 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 15952 SourceLocation ELoc; 15953 SourceRange ERange; 15954 Expr *SimpleRefExpr = RefExpr; 15955 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15956 if (Res.second) { 15957 // It will be analyzed later. 15958 MVLI.ProcessedVarList.push_back(RefExpr); 15959 PrivateCopies.push_back(nullptr); 15960 Inits.push_back(nullptr); 15961 } 15962 ValueDecl *D = Res.first; 15963 if (!D) 15964 continue; 15965 15966 QualType Type = D->getType(); 15967 Type = Type.getNonReferenceType().getUnqualifiedType(); 15968 15969 auto *VD = dyn_cast<VarDecl>(D); 15970 15971 // Item should be a pointer or reference to pointer. 15972 if (!Type->isPointerType()) { 15973 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 15974 << 0 << RefExpr->getSourceRange(); 15975 continue; 15976 } 15977 15978 // Build the private variable and the expression that refers to it. 15979 auto VDPrivate = 15980 buildVarDecl(*this, ELoc, Type, D->getName(), 15981 D->hasAttrs() ? &D->getAttrs() : nullptr, 15982 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15983 if (VDPrivate->isInvalidDecl()) 15984 continue; 15985 15986 CurContext->addDecl(VDPrivate); 15987 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15988 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15989 15990 // Add temporary variable to initialize the private copy of the pointer. 15991 VarDecl *VDInit = 15992 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15993 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15994 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15995 AddInitializerToDecl(VDPrivate, 15996 DefaultLvalueConversion(VDInitRefExpr).get(), 15997 /*DirectInit=*/false); 15998 15999 // If required, build a capture to implement the privatization initialized 16000 // with the current list item value. 16001 DeclRefExpr *Ref = nullptr; 16002 if (!VD) 16003 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16004 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16005 PrivateCopies.push_back(VDPrivateRefExpr); 16006 Inits.push_back(VDInitRefExpr); 16007 16008 // We need to add a data sharing attribute for this variable to make sure it 16009 // is correctly captured. A variable that shows up in a use_device_ptr has 16010 // similar properties of a first private variable. 16011 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16012 16013 // Create a mappable component for the list item. List items in this clause 16014 // only need a component. 16015 MVLI.VarBaseDeclarations.push_back(D); 16016 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16017 MVLI.VarComponents.back().push_back( 16018 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16019 } 16020 16021 if (MVLI.ProcessedVarList.empty()) 16022 return nullptr; 16023 16024 return OMPUseDevicePtrClause::Create( 16025 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16026 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16027 } 16028 16029 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16030 const OMPVarListLocTy &Locs) { 16031 MappableVarListInfo MVLI(VarList); 16032 for (Expr *RefExpr : VarList) { 16033 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16034 SourceLocation ELoc; 16035 SourceRange ERange; 16036 Expr *SimpleRefExpr = RefExpr; 16037 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16038 if (Res.second) { 16039 // It will be analyzed later. 16040 MVLI.ProcessedVarList.push_back(RefExpr); 16041 } 16042 ValueDecl *D = Res.first; 16043 if (!D) 16044 continue; 16045 16046 QualType Type = D->getType(); 16047 // item should be a pointer or array or reference to pointer or array 16048 if (!Type.getNonReferenceType()->isPointerType() && 16049 !Type.getNonReferenceType()->isArrayType()) { 16050 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16051 << 0 << RefExpr->getSourceRange(); 16052 continue; 16053 } 16054 16055 // Check if the declaration in the clause does not show up in any data 16056 // sharing attribute. 16057 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16058 if (isOpenMPPrivate(DVar.CKind)) { 16059 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16060 << getOpenMPClauseName(DVar.CKind) 16061 << getOpenMPClauseName(OMPC_is_device_ptr) 16062 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16063 reportOriginalDsa(*this, DSAStack, D, DVar); 16064 continue; 16065 } 16066 16067 const Expr *ConflictExpr; 16068 if (DSAStack->checkMappableExprComponentListsForDecl( 16069 D, /*CurrentRegionOnly=*/true, 16070 [&ConflictExpr]( 16071 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16072 OpenMPClauseKind) -> bool { 16073 ConflictExpr = R.front().getAssociatedExpression(); 16074 return true; 16075 })) { 16076 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16077 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16078 << ConflictExpr->getSourceRange(); 16079 continue; 16080 } 16081 16082 // Store the components in the stack so that they can be used to check 16083 // against other clauses later on. 16084 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16085 DSAStack->addMappableExpressionComponents( 16086 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16087 16088 // Record the expression we've just processed. 16089 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16090 16091 // Create a mappable component for the list item. List items in this clause 16092 // only need a component. We use a null declaration to signal fields in 16093 // 'this'. 16094 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16095 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16096 "Unexpected device pointer expression!"); 16097 MVLI.VarBaseDeclarations.push_back( 16098 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16099 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16100 MVLI.VarComponents.back().push_back(MC); 16101 } 16102 16103 if (MVLI.ProcessedVarList.empty()) 16104 return nullptr; 16105 16106 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16107 MVLI.VarBaseDeclarations, 16108 MVLI.VarComponents); 16109 } 16110 16111 OMPClause *Sema::ActOnOpenMPAllocateClause( 16112 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16113 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16114 if (Allocator) { 16115 // OpenMP [2.11.4 allocate Clause, Description] 16116 // allocator is an expression of omp_allocator_handle_t type. 16117 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16118 return nullptr; 16119 16120 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16121 if (AllocatorRes.isInvalid()) 16122 return nullptr; 16123 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16124 DSAStack->getOMPAllocatorHandleT(), 16125 Sema::AA_Initializing, 16126 /*AllowExplicit=*/true); 16127 if (AllocatorRes.isInvalid()) 16128 return nullptr; 16129 Allocator = AllocatorRes.get(); 16130 } else { 16131 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16132 // allocate clauses that appear on a target construct or on constructs in a 16133 // target region must specify an allocator expression unless a requires 16134 // directive with the dynamic_allocators clause is present in the same 16135 // compilation unit. 16136 if (LangOpts.OpenMPIsDevice && 16137 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16138 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16139 } 16140 // Analyze and build list of variables. 16141 SmallVector<Expr *, 8> Vars; 16142 for (Expr *RefExpr : VarList) { 16143 assert(RefExpr && "NULL expr in OpenMP private clause."); 16144 SourceLocation ELoc; 16145 SourceRange ERange; 16146 Expr *SimpleRefExpr = RefExpr; 16147 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16148 if (Res.second) { 16149 // It will be analyzed later. 16150 Vars.push_back(RefExpr); 16151 } 16152 ValueDecl *D = Res.first; 16153 if (!D) 16154 continue; 16155 16156 auto *VD = dyn_cast<VarDecl>(D); 16157 DeclRefExpr *Ref = nullptr; 16158 if (!VD && !CurContext->isDependentContext()) 16159 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16160 Vars.push_back((VD || CurContext->isDependentContext()) 16161 ? RefExpr->IgnoreParens() 16162 : Ref); 16163 } 16164 16165 if (Vars.empty()) 16166 return nullptr; 16167 16168 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16169 ColonLoc, EndLoc, Vars); 16170 } 16171