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 parent directive. 526 OpenMPDirectiveKind getParentDirective() const { 527 const SharingMapTy *Parent = getSecondOnStackOrNull(); 528 return Parent ? Parent->Directive : OMPD_unknown; 529 } 530 531 /// Add requires decl to internal vector 532 void addRequiresDecl(OMPRequiresDecl *RD) { 533 RequiresDecls.push_back(RD); 534 } 535 536 /// Checks if the defined 'requires' directive has specified type of clause. 537 template <typename ClauseType> 538 bool hasRequiresDeclWithClause() { 539 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 540 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 541 return isa<ClauseType>(C); 542 }); 543 }); 544 } 545 546 /// Checks for a duplicate clause amongst previously declared requires 547 /// directives 548 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 549 bool IsDuplicate = false; 550 for (OMPClause *CNew : ClauseList) { 551 for (const OMPRequiresDecl *D : RequiresDecls) { 552 for (const OMPClause *CPrev : D->clauselists()) { 553 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 554 SemaRef.Diag(CNew->getBeginLoc(), 555 diag::err_omp_requires_clause_redeclaration) 556 << getOpenMPClauseName(CNew->getClauseKind()); 557 SemaRef.Diag(CPrev->getBeginLoc(), 558 diag::note_omp_requires_previous_clause) 559 << getOpenMPClauseName(CPrev->getClauseKind()); 560 IsDuplicate = true; 561 } 562 } 563 } 564 } 565 return IsDuplicate; 566 } 567 568 /// Add location of previously encountered target to internal vector 569 void addTargetDirLocation(SourceLocation LocStart) { 570 TargetLocations.push_back(LocStart); 571 } 572 573 // Return previously encountered target region locations. 574 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 575 return TargetLocations; 576 } 577 578 /// Set default data sharing attribute to none. 579 void setDefaultDSANone(SourceLocation Loc) { 580 getTopOfStack().DefaultAttr = DSA_none; 581 getTopOfStack().DefaultAttrLoc = Loc; 582 } 583 /// Set default data sharing attribute to shared. 584 void setDefaultDSAShared(SourceLocation Loc) { 585 getTopOfStack().DefaultAttr = DSA_shared; 586 getTopOfStack().DefaultAttrLoc = Loc; 587 } 588 /// Set default data mapping attribute to 'tofrom:scalar'. 589 void setDefaultDMAToFromScalar(SourceLocation Loc) { 590 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 591 getTopOfStack().DefaultMapAttrLoc = Loc; 592 } 593 594 DefaultDataSharingAttributes getDefaultDSA() const { 595 return isStackEmpty() ? DSA_unspecified 596 : getTopOfStack().DefaultAttr; 597 } 598 SourceLocation getDefaultDSALocation() const { 599 return isStackEmpty() ? SourceLocation() 600 : getTopOfStack().DefaultAttrLoc; 601 } 602 DefaultMapAttributes getDefaultDMA() const { 603 return isStackEmpty() ? DMA_unspecified 604 : getTopOfStack().DefaultMapAttr; 605 } 606 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 607 return getStackElemAtLevel(Level).DefaultMapAttr; 608 } 609 SourceLocation getDefaultDMALocation() const { 610 return isStackEmpty() ? SourceLocation() 611 : getTopOfStack().DefaultMapAttrLoc; 612 } 613 614 /// Checks if the specified variable is a threadprivate. 615 bool isThreadPrivate(VarDecl *D) { 616 const DSAVarData DVar = getTopDSA(D, false); 617 return isOpenMPThreadPrivate(DVar.CKind); 618 } 619 620 /// Marks current region as ordered (it has an 'ordered' clause). 621 void setOrderedRegion(bool IsOrdered, const Expr *Param, 622 OMPOrderedClause *Clause) { 623 if (IsOrdered) 624 getTopOfStack().OrderedRegion.emplace(Param, Clause); 625 else 626 getTopOfStack().OrderedRegion.reset(); 627 } 628 /// Returns true, if region is ordered (has associated 'ordered' clause), 629 /// false - otherwise. 630 bool isOrderedRegion() const { 631 if (const SharingMapTy *Top = getTopOfStackOrNull()) 632 return Top->OrderedRegion.hasValue(); 633 return false; 634 } 635 /// Returns optional parameter for the ordered region. 636 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 637 if (const SharingMapTy *Top = getTopOfStackOrNull()) 638 if (Top->OrderedRegion.hasValue()) 639 return Top->OrderedRegion.getValue(); 640 return std::make_pair(nullptr, nullptr); 641 } 642 /// Returns true, if parent region is ordered (has associated 643 /// 'ordered' clause), false - otherwise. 644 bool isParentOrderedRegion() const { 645 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 646 return Parent->OrderedRegion.hasValue(); 647 return false; 648 } 649 /// Returns optional parameter for the ordered region. 650 std::pair<const Expr *, OMPOrderedClause *> 651 getParentOrderedRegionParam() const { 652 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 653 if (Parent->OrderedRegion.hasValue()) 654 return Parent->OrderedRegion.getValue(); 655 return std::make_pair(nullptr, nullptr); 656 } 657 /// Marks current region as nowait (it has a 'nowait' clause). 658 void setNowaitRegion(bool IsNowait = true) { 659 getTopOfStack().NowaitRegion = IsNowait; 660 } 661 /// Returns true, if parent region is nowait (has associated 662 /// 'nowait' clause), false - otherwise. 663 bool isParentNowaitRegion() const { 664 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 665 return Parent->NowaitRegion; 666 return false; 667 } 668 /// Marks parent region as cancel region. 669 void setParentCancelRegion(bool Cancel = true) { 670 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 671 Parent->CancelRegion |= Cancel; 672 } 673 /// Return true if current region has inner cancel construct. 674 bool isCancelRegion() const { 675 const SharingMapTy *Top = getTopOfStackOrNull(); 676 return Top ? Top->CancelRegion : false; 677 } 678 679 /// Set collapse value for the region. 680 void setAssociatedLoops(unsigned Val) { 681 getTopOfStack().AssociatedLoops = Val; 682 if (Val > 1) 683 getTopOfStack().HasMutipleLoops = true; 684 } 685 /// Return collapse value for region. 686 unsigned getAssociatedLoops() const { 687 const SharingMapTy *Top = getTopOfStackOrNull(); 688 return Top ? Top->AssociatedLoops : 0; 689 } 690 /// Returns true if the construct is associated with multiple loops. 691 bool hasMutipleLoops() const { 692 const SharingMapTy *Top = getTopOfStackOrNull(); 693 return Top ? Top->HasMutipleLoops : false; 694 } 695 696 /// Marks current target region as one with closely nested teams 697 /// region. 698 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 699 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 700 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 701 } 702 /// Returns true, if current region has closely nested teams region. 703 bool hasInnerTeamsRegion() const { 704 return getInnerTeamsRegionLoc().isValid(); 705 } 706 /// Returns location of the nested teams region (if any). 707 SourceLocation getInnerTeamsRegionLoc() const { 708 const SharingMapTy *Top = getTopOfStackOrNull(); 709 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 710 } 711 712 Scope *getCurScope() const { 713 const SharingMapTy *Top = getTopOfStackOrNull(); 714 return Top ? Top->CurScope : nullptr; 715 } 716 SourceLocation getConstructLoc() const { 717 const SharingMapTy *Top = getTopOfStackOrNull(); 718 return Top ? Top->ConstructLoc : SourceLocation(); 719 } 720 721 /// Do the check specified in \a Check to all component lists and return true 722 /// if any issue is found. 723 bool checkMappableExprComponentListsForDecl( 724 const ValueDecl *VD, bool CurrentRegionOnly, 725 const llvm::function_ref< 726 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 727 OpenMPClauseKind)> 728 Check) const { 729 if (isStackEmpty()) 730 return false; 731 auto SI = begin(); 732 auto SE = end(); 733 734 if (SI == SE) 735 return false; 736 737 if (CurrentRegionOnly) 738 SE = std::next(SI); 739 else 740 std::advance(SI, 1); 741 742 for (; SI != SE; ++SI) { 743 auto MI = SI->MappedExprComponents.find(VD); 744 if (MI != SI->MappedExprComponents.end()) 745 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 746 MI->second.Components) 747 if (Check(L, MI->second.Kind)) 748 return true; 749 } 750 return false; 751 } 752 753 /// Do the check specified in \a Check to all component lists at a given level 754 /// and return true if any issue is found. 755 bool checkMappableExprComponentListsForDeclAtLevel( 756 const ValueDecl *VD, unsigned Level, 757 const llvm::function_ref< 758 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 759 OpenMPClauseKind)> 760 Check) const { 761 if (getStackSize() <= Level) 762 return false; 763 764 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 765 auto MI = StackElem.MappedExprComponents.find(VD); 766 if (MI != StackElem.MappedExprComponents.end()) 767 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 768 MI->second.Components) 769 if (Check(L, MI->second.Kind)) 770 return true; 771 return false; 772 } 773 774 /// Create a new mappable expression component list associated with a given 775 /// declaration and initialize it with the provided list of components. 776 void addMappableExpressionComponents( 777 const ValueDecl *VD, 778 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 779 OpenMPClauseKind WhereFoundClauseKind) { 780 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 781 // Create new entry and append the new components there. 782 MEC.Components.resize(MEC.Components.size() + 1); 783 MEC.Components.back().append(Components.begin(), Components.end()); 784 MEC.Kind = WhereFoundClauseKind; 785 } 786 787 unsigned getNestingLevel() const { 788 assert(!isStackEmpty()); 789 return getStackSize() - 1; 790 } 791 void addDoacrossDependClause(OMPDependClause *C, 792 const OperatorOffsetTy &OpsOffs) { 793 SharingMapTy *Parent = getSecondOnStackOrNull(); 794 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 795 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 796 } 797 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 798 getDoacrossDependClauses() const { 799 const SharingMapTy &StackElem = getTopOfStack(); 800 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 801 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 802 return llvm::make_range(Ref.begin(), Ref.end()); 803 } 804 return llvm::make_range(StackElem.DoacrossDepends.end(), 805 StackElem.DoacrossDepends.end()); 806 } 807 808 // Store types of classes which have been explicitly mapped 809 void addMappedClassesQualTypes(QualType QT) { 810 SharingMapTy &StackElem = getTopOfStack(); 811 StackElem.MappedClassesQualTypes.insert(QT); 812 } 813 814 // Return set of mapped classes types 815 bool isClassPreviouslyMapped(QualType QT) const { 816 const SharingMapTy &StackElem = getTopOfStack(); 817 return StackElem.MappedClassesQualTypes.count(QT) != 0; 818 } 819 820 /// Adds global declare target to the parent target region. 821 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 822 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 823 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 824 "Expected declare target link global."); 825 for (auto &Elem : *this) { 826 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 827 Elem.DeclareTargetLinkVarDecls.push_back(E); 828 return; 829 } 830 } 831 } 832 833 /// Returns the list of globals with declare target link if current directive 834 /// is target. 835 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 836 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 837 "Expected target executable directive."); 838 return getTopOfStack().DeclareTargetLinkVarDecls; 839 } 840 }; 841 842 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 843 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 844 } 845 846 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 847 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 848 DKind == OMPD_unknown; 849 } 850 851 } // namespace 852 853 static const Expr *getExprAsWritten(const Expr *E) { 854 if (const auto *FE = dyn_cast<FullExpr>(E)) 855 E = FE->getSubExpr(); 856 857 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 858 E = MTE->GetTemporaryExpr(); 859 860 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 861 E = Binder->getSubExpr(); 862 863 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 864 E = ICE->getSubExprAsWritten(); 865 return E->IgnoreParens(); 866 } 867 868 static Expr *getExprAsWritten(Expr *E) { 869 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 870 } 871 872 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 873 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 874 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 875 D = ME->getMemberDecl(); 876 const auto *VD = dyn_cast<VarDecl>(D); 877 const auto *FD = dyn_cast<FieldDecl>(D); 878 if (VD != nullptr) { 879 VD = VD->getCanonicalDecl(); 880 D = VD; 881 } else { 882 assert(FD); 883 FD = FD->getCanonicalDecl(); 884 D = FD; 885 } 886 return D; 887 } 888 889 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 890 return const_cast<ValueDecl *>( 891 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 892 } 893 894 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 895 ValueDecl *D) const { 896 D = getCanonicalDecl(D); 897 auto *VD = dyn_cast<VarDecl>(D); 898 const auto *FD = dyn_cast<FieldDecl>(D); 899 DSAVarData DVar; 900 if (Iter == end()) { 901 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 902 // in a region but not in construct] 903 // File-scope or namespace-scope variables referenced in called routines 904 // in the region are shared unless they appear in a threadprivate 905 // directive. 906 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 907 DVar.CKind = OMPC_shared; 908 909 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 910 // in a region but not in construct] 911 // Variables with static storage duration that are declared in called 912 // routines in the region are shared. 913 if (VD && VD->hasGlobalStorage()) 914 DVar.CKind = OMPC_shared; 915 916 // Non-static data members are shared by default. 917 if (FD) 918 DVar.CKind = OMPC_shared; 919 920 return DVar; 921 } 922 923 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 924 // in a Construct, C/C++, predetermined, p.1] 925 // Variables with automatic storage duration that are declared in a scope 926 // inside the construct are private. 927 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 928 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 929 DVar.CKind = OMPC_private; 930 return DVar; 931 } 932 933 DVar.DKind = Iter->Directive; 934 // Explicitly specified attributes and local variables with predetermined 935 // attributes. 936 if (Iter->SharingMap.count(D)) { 937 const DSAInfo &Data = Iter->SharingMap.lookup(D); 938 DVar.RefExpr = Data.RefExpr.getPointer(); 939 DVar.PrivateCopy = Data.PrivateCopy; 940 DVar.CKind = Data.Attributes; 941 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 942 return DVar; 943 } 944 945 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 946 // in a Construct, C/C++, implicitly determined, p.1] 947 // In a parallel or task construct, the data-sharing attributes of these 948 // variables are determined by the default clause, if present. 949 switch (Iter->DefaultAttr) { 950 case DSA_shared: 951 DVar.CKind = OMPC_shared; 952 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 953 return DVar; 954 case DSA_none: 955 return DVar; 956 case DSA_unspecified: 957 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 958 // in a Construct, implicitly determined, p.2] 959 // In a parallel construct, if no default clause is present, these 960 // variables are shared. 961 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 962 if (isOpenMPParallelDirective(DVar.DKind) || 963 isOpenMPTeamsDirective(DVar.DKind)) { 964 DVar.CKind = OMPC_shared; 965 return DVar; 966 } 967 968 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 969 // in a Construct, implicitly determined, p.4] 970 // In a task construct, if no default clause is present, a variable that in 971 // the enclosing context is determined to be shared by all implicit tasks 972 // bound to the current team is shared. 973 if (isOpenMPTaskingDirective(DVar.DKind)) { 974 DSAVarData DVarTemp; 975 const_iterator I = Iter, E = end(); 976 do { 977 ++I; 978 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 979 // Referenced in a Construct, implicitly determined, p.6] 980 // In a task construct, if no default clause is present, a variable 981 // whose data-sharing attribute is not determined by the rules above is 982 // firstprivate. 983 DVarTemp = getDSA(I, D); 984 if (DVarTemp.CKind != OMPC_shared) { 985 DVar.RefExpr = nullptr; 986 DVar.CKind = OMPC_firstprivate; 987 return DVar; 988 } 989 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 990 DVar.CKind = 991 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 992 return DVar; 993 } 994 } 995 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 996 // in a Construct, implicitly determined, p.3] 997 // For constructs other than task, if no default clause is present, these 998 // variables inherit their data-sharing attributes from the enclosing 999 // context. 1000 return getDSA(++Iter, D); 1001 } 1002 1003 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1004 const Expr *NewDE) { 1005 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1006 D = getCanonicalDecl(D); 1007 SharingMapTy &StackElem = getTopOfStack(); 1008 auto It = StackElem.AlignedMap.find(D); 1009 if (It == StackElem.AlignedMap.end()) { 1010 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1011 StackElem.AlignedMap[D] = NewDE; 1012 return nullptr; 1013 } 1014 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1015 return It->second; 1016 } 1017 1018 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1019 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1020 D = getCanonicalDecl(D); 1021 SharingMapTy &StackElem = getTopOfStack(); 1022 StackElem.LCVMap.try_emplace( 1023 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1024 } 1025 1026 const DSAStackTy::LCDeclInfo 1027 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1028 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1029 D = getCanonicalDecl(D); 1030 const SharingMapTy &StackElem = getTopOfStack(); 1031 auto It = StackElem.LCVMap.find(D); 1032 if (It != StackElem.LCVMap.end()) 1033 return It->second; 1034 return {0, nullptr}; 1035 } 1036 1037 const DSAStackTy::LCDeclInfo 1038 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1039 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1040 assert(Parent && "Data-sharing attributes stack is empty"); 1041 D = getCanonicalDecl(D); 1042 auto It = Parent->LCVMap.find(D); 1043 if (It != Parent->LCVMap.end()) 1044 return It->second; 1045 return {0, nullptr}; 1046 } 1047 1048 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1049 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1050 assert(Parent && "Data-sharing attributes stack is empty"); 1051 if (Parent->LCVMap.size() < I) 1052 return nullptr; 1053 for (const auto &Pair : Parent->LCVMap) 1054 if (Pair.second.first == I) 1055 return Pair.first; 1056 return nullptr; 1057 } 1058 1059 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1060 DeclRefExpr *PrivateCopy) { 1061 D = getCanonicalDecl(D); 1062 if (A == OMPC_threadprivate) { 1063 DSAInfo &Data = Threadprivates[D]; 1064 Data.Attributes = A; 1065 Data.RefExpr.setPointer(E); 1066 Data.PrivateCopy = nullptr; 1067 } else { 1068 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1069 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1070 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1071 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1072 (isLoopControlVariable(D).first && A == OMPC_private)); 1073 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1074 Data.RefExpr.setInt(/*IntVal=*/true); 1075 return; 1076 } 1077 const bool IsLastprivate = 1078 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1079 Data.Attributes = A; 1080 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1081 Data.PrivateCopy = PrivateCopy; 1082 if (PrivateCopy) { 1083 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1084 Data.Attributes = A; 1085 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1086 Data.PrivateCopy = nullptr; 1087 } 1088 } 1089 } 1090 1091 /// Build a variable declaration for OpenMP loop iteration variable. 1092 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1093 StringRef Name, const AttrVec *Attrs = nullptr, 1094 DeclRefExpr *OrigRef = nullptr) { 1095 DeclContext *DC = SemaRef.CurContext; 1096 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1097 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1098 auto *Decl = 1099 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1100 if (Attrs) { 1101 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1102 I != E; ++I) 1103 Decl->addAttr(*I); 1104 } 1105 Decl->setImplicit(); 1106 if (OrigRef) { 1107 Decl->addAttr( 1108 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1109 } 1110 return Decl; 1111 } 1112 1113 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1114 SourceLocation Loc, 1115 bool RefersToCapture = false) { 1116 D->setReferenced(); 1117 D->markUsed(S.Context); 1118 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1119 SourceLocation(), D, RefersToCapture, Loc, Ty, 1120 VK_LValue); 1121 } 1122 1123 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1124 BinaryOperatorKind BOK) { 1125 D = getCanonicalDecl(D); 1126 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1127 assert( 1128 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1129 "Additional reduction info may be specified only for reduction items."); 1130 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1131 assert(ReductionData.ReductionRange.isInvalid() && 1132 getTopOfStack().Directive == OMPD_taskgroup && 1133 "Additional reduction info may be specified only once for reduction " 1134 "items."); 1135 ReductionData.set(BOK, SR); 1136 Expr *&TaskgroupReductionRef = 1137 getTopOfStack().TaskgroupReductionRef; 1138 if (!TaskgroupReductionRef) { 1139 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1140 SemaRef.Context.VoidPtrTy, ".task_red."); 1141 TaskgroupReductionRef = 1142 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1143 } 1144 } 1145 1146 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1147 const Expr *ReductionRef) { 1148 D = getCanonicalDecl(D); 1149 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1150 assert( 1151 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1152 "Additional reduction info may be specified only for reduction items."); 1153 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1154 assert(ReductionData.ReductionRange.isInvalid() && 1155 getTopOfStack().Directive == OMPD_taskgroup && 1156 "Additional reduction info may be specified only once for reduction " 1157 "items."); 1158 ReductionData.set(ReductionRef, SR); 1159 Expr *&TaskgroupReductionRef = 1160 getTopOfStack().TaskgroupReductionRef; 1161 if (!TaskgroupReductionRef) { 1162 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1163 SemaRef.Context.VoidPtrTy, ".task_red."); 1164 TaskgroupReductionRef = 1165 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1166 } 1167 } 1168 1169 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1170 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1171 Expr *&TaskgroupDescriptor) const { 1172 D = getCanonicalDecl(D); 1173 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1174 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1175 const DSAInfo &Data = I->SharingMap.lookup(D); 1176 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1177 continue; 1178 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1179 if (!ReductionData.ReductionOp || 1180 ReductionData.ReductionOp.is<const Expr *>()) 1181 return DSAVarData(); 1182 SR = ReductionData.ReductionRange; 1183 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1184 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1185 "expression for the descriptor is not " 1186 "set."); 1187 TaskgroupDescriptor = I->TaskgroupReductionRef; 1188 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1189 Data.PrivateCopy, I->DefaultAttrLoc); 1190 } 1191 return DSAVarData(); 1192 } 1193 1194 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1195 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1196 Expr *&TaskgroupDescriptor) const { 1197 D = getCanonicalDecl(D); 1198 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1199 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1200 const DSAInfo &Data = I->SharingMap.lookup(D); 1201 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1202 continue; 1203 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1204 if (!ReductionData.ReductionOp || 1205 !ReductionData.ReductionOp.is<const Expr *>()) 1206 return DSAVarData(); 1207 SR = ReductionData.ReductionRange; 1208 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1209 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1210 "expression for the descriptor is not " 1211 "set."); 1212 TaskgroupDescriptor = I->TaskgroupReductionRef; 1213 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1214 Data.PrivateCopy, I->DefaultAttrLoc); 1215 } 1216 return DSAVarData(); 1217 } 1218 1219 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1220 D = D->getCanonicalDecl(); 1221 for (const_iterator E = end(); I != E; ++I) { 1222 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1223 isOpenMPTargetExecutionDirective(I->Directive)) { 1224 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1225 Scope *CurScope = getCurScope(); 1226 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1227 CurScope = CurScope->getParent(); 1228 return CurScope != TopScope; 1229 } 1230 } 1231 return false; 1232 } 1233 1234 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1235 bool AcceptIfMutable = true, 1236 bool *IsClassType = nullptr) { 1237 ASTContext &Context = SemaRef.getASTContext(); 1238 Type = Type.getNonReferenceType().getCanonicalType(); 1239 bool IsConstant = Type.isConstant(Context); 1240 Type = Context.getBaseElementType(Type); 1241 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1242 ? Type->getAsCXXRecordDecl() 1243 : nullptr; 1244 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1245 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1246 RD = CTD->getTemplatedDecl(); 1247 if (IsClassType) 1248 *IsClassType = RD; 1249 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1250 RD->hasDefinition() && RD->hasMutableFields()); 1251 } 1252 1253 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1254 QualType Type, OpenMPClauseKind CKind, 1255 SourceLocation ELoc, 1256 bool AcceptIfMutable = true, 1257 bool ListItemNotVar = false) { 1258 ASTContext &Context = SemaRef.getASTContext(); 1259 bool IsClassType; 1260 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1261 unsigned Diag = ListItemNotVar 1262 ? diag::err_omp_const_list_item 1263 : IsClassType ? diag::err_omp_const_not_mutable_variable 1264 : diag::err_omp_const_variable; 1265 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1266 if (!ListItemNotVar && D) { 1267 const VarDecl *VD = dyn_cast<VarDecl>(D); 1268 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1269 VarDecl::DeclarationOnly; 1270 SemaRef.Diag(D->getLocation(), 1271 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1272 << D; 1273 } 1274 return true; 1275 } 1276 return false; 1277 } 1278 1279 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1280 bool FromParent) { 1281 D = getCanonicalDecl(D); 1282 DSAVarData DVar; 1283 1284 auto *VD = dyn_cast<VarDecl>(D); 1285 auto TI = Threadprivates.find(D); 1286 if (TI != Threadprivates.end()) { 1287 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1288 DVar.CKind = OMPC_threadprivate; 1289 return DVar; 1290 } 1291 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1292 DVar.RefExpr = buildDeclRefExpr( 1293 SemaRef, VD, D->getType().getNonReferenceType(), 1294 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1295 DVar.CKind = OMPC_threadprivate; 1296 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1297 return DVar; 1298 } 1299 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1300 // in a Construct, C/C++, predetermined, p.1] 1301 // Variables appearing in threadprivate directives are threadprivate. 1302 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1303 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1304 SemaRef.getLangOpts().OpenMPUseTLS && 1305 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1306 (VD && VD->getStorageClass() == SC_Register && 1307 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1308 DVar.RefExpr = buildDeclRefExpr( 1309 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1310 DVar.CKind = OMPC_threadprivate; 1311 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1312 return DVar; 1313 } 1314 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1315 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1316 !isLoopControlVariable(D).first) { 1317 const_iterator IterTarget = 1318 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1319 return isOpenMPTargetExecutionDirective(Data.Directive); 1320 }); 1321 if (IterTarget != end()) { 1322 const_iterator ParentIterTarget = IterTarget + 1; 1323 for (const_iterator Iter = begin(); 1324 Iter != ParentIterTarget; ++Iter) { 1325 if (isOpenMPLocal(VD, Iter)) { 1326 DVar.RefExpr = 1327 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1328 D->getLocation()); 1329 DVar.CKind = OMPC_threadprivate; 1330 return DVar; 1331 } 1332 } 1333 if (!isClauseParsingMode() || IterTarget != begin()) { 1334 auto DSAIter = IterTarget->SharingMap.find(D); 1335 if (DSAIter != IterTarget->SharingMap.end() && 1336 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1337 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1338 DVar.CKind = OMPC_threadprivate; 1339 return DVar; 1340 } 1341 const_iterator End = end(); 1342 if (!SemaRef.isOpenMPCapturedByRef( 1343 D, std::distance(ParentIterTarget, End))) { 1344 DVar.RefExpr = 1345 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1346 IterTarget->ConstructLoc); 1347 DVar.CKind = OMPC_threadprivate; 1348 return DVar; 1349 } 1350 } 1351 } 1352 } 1353 1354 if (isStackEmpty()) 1355 // Not in OpenMP execution region and top scope was already checked. 1356 return DVar; 1357 1358 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1359 // in a Construct, C/C++, predetermined, p.4] 1360 // Static data members are shared. 1361 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1362 // in a Construct, C/C++, predetermined, p.7] 1363 // Variables with static storage duration that are declared in a scope 1364 // inside the construct are shared. 1365 if (VD && VD->isStaticDataMember()) { 1366 // Check for explicitly specified attributes. 1367 const_iterator I = begin(); 1368 const_iterator EndI = end(); 1369 if (FromParent && I != EndI) 1370 ++I; 1371 auto It = I->SharingMap.find(D); 1372 if (It != I->SharingMap.end()) { 1373 const DSAInfo &Data = It->getSecond(); 1374 DVar.RefExpr = Data.RefExpr.getPointer(); 1375 DVar.PrivateCopy = Data.PrivateCopy; 1376 DVar.CKind = Data.Attributes; 1377 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1378 DVar.DKind = I->Directive; 1379 return DVar; 1380 } 1381 1382 DVar.CKind = OMPC_shared; 1383 return DVar; 1384 } 1385 1386 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1387 // The predetermined shared attribute for const-qualified types having no 1388 // mutable members was removed after OpenMP 3.1. 1389 if (SemaRef.LangOpts.OpenMP <= 31) { 1390 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1391 // in a Construct, C/C++, predetermined, p.6] 1392 // Variables with const qualified type having no mutable member are 1393 // shared. 1394 if (isConstNotMutableType(SemaRef, D->getType())) { 1395 // Variables with const-qualified type having no mutable member may be 1396 // listed in a firstprivate clause, even if they are static data members. 1397 DSAVarData DVarTemp = hasInnermostDSA( 1398 D, 1399 [](OpenMPClauseKind C) { 1400 return C == OMPC_firstprivate || C == OMPC_shared; 1401 }, 1402 MatchesAlways, FromParent); 1403 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1404 return DVarTemp; 1405 1406 DVar.CKind = OMPC_shared; 1407 return DVar; 1408 } 1409 } 1410 1411 // Explicitly specified attributes and local variables with predetermined 1412 // attributes. 1413 const_iterator I = begin(); 1414 const_iterator EndI = end(); 1415 if (FromParent && I != EndI) 1416 ++I; 1417 auto It = I->SharingMap.find(D); 1418 if (It != I->SharingMap.end()) { 1419 const DSAInfo &Data = It->getSecond(); 1420 DVar.RefExpr = Data.RefExpr.getPointer(); 1421 DVar.PrivateCopy = Data.PrivateCopy; 1422 DVar.CKind = Data.Attributes; 1423 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1424 DVar.DKind = I->Directive; 1425 } 1426 1427 return DVar; 1428 } 1429 1430 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1431 bool FromParent) const { 1432 if (isStackEmpty()) { 1433 const_iterator I; 1434 return getDSA(I, D); 1435 } 1436 D = getCanonicalDecl(D); 1437 const_iterator StartI = begin(); 1438 const_iterator EndI = end(); 1439 if (FromParent && StartI != EndI) 1440 ++StartI; 1441 return getDSA(StartI, D); 1442 } 1443 1444 const DSAStackTy::DSAVarData 1445 DSAStackTy::hasDSA(ValueDecl *D, 1446 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1447 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1448 bool FromParent) const { 1449 if (isStackEmpty()) 1450 return {}; 1451 D = getCanonicalDecl(D); 1452 const_iterator I = begin(); 1453 const_iterator EndI = end(); 1454 if (FromParent && I != EndI) 1455 ++I; 1456 for (; I != EndI; ++I) { 1457 if (!DPred(I->Directive) && 1458 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1459 continue; 1460 const_iterator NewI = I; 1461 DSAVarData DVar = getDSA(NewI, D); 1462 if (I == NewI && CPred(DVar.CKind)) 1463 return DVar; 1464 } 1465 return {}; 1466 } 1467 1468 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1469 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1470 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1471 bool FromParent) const { 1472 if (isStackEmpty()) 1473 return {}; 1474 D = getCanonicalDecl(D); 1475 const_iterator StartI = begin(); 1476 const_iterator EndI = end(); 1477 if (FromParent && StartI != EndI) 1478 ++StartI; 1479 if (StartI == EndI || !DPred(StartI->Directive)) 1480 return {}; 1481 const_iterator NewI = StartI; 1482 DSAVarData DVar = getDSA(NewI, D); 1483 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1484 } 1485 1486 bool DSAStackTy::hasExplicitDSA( 1487 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1488 unsigned Level, bool NotLastprivate) const { 1489 if (getStackSize() <= Level) 1490 return false; 1491 D = getCanonicalDecl(D); 1492 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1493 auto I = StackElem.SharingMap.find(D); 1494 if (I != StackElem.SharingMap.end() && 1495 I->getSecond().RefExpr.getPointer() && 1496 CPred(I->getSecond().Attributes) && 1497 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1498 return true; 1499 // Check predetermined rules for the loop control variables. 1500 auto LI = StackElem.LCVMap.find(D); 1501 if (LI != StackElem.LCVMap.end()) 1502 return CPred(OMPC_private); 1503 return false; 1504 } 1505 1506 bool DSAStackTy::hasExplicitDirective( 1507 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1508 unsigned Level) const { 1509 if (getStackSize() <= Level) 1510 return false; 1511 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1512 return DPred(StackElem.Directive); 1513 } 1514 1515 bool DSAStackTy::hasDirective( 1516 const llvm::function_ref<bool(OpenMPDirectiveKind, 1517 const DeclarationNameInfo &, SourceLocation)> 1518 DPred, 1519 bool FromParent) const { 1520 // We look only in the enclosing region. 1521 size_t Skip = FromParent ? 2 : 1; 1522 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1523 I != E; ++I) { 1524 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1525 return true; 1526 } 1527 return false; 1528 } 1529 1530 void Sema::InitDataSharingAttributesStack() { 1531 VarDataSharingAttributesStack = new DSAStackTy(*this); 1532 } 1533 1534 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1535 1536 void Sema::pushOpenMPFunctionRegion() { 1537 DSAStack->pushFunction(); 1538 } 1539 1540 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1541 DSAStack->popFunction(OldFSI); 1542 } 1543 1544 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1545 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1546 "Expected OpenMP device compilation."); 1547 return !S.isInOpenMPTargetExecutionDirective() && 1548 !S.isInOpenMPDeclareTargetContext(); 1549 } 1550 1551 /// Do we know that we will eventually codegen the given function? 1552 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1553 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1554 "Expected OpenMP device compilation."); 1555 // Templates are emitted when they're instantiated. 1556 if (FD->isDependentContext()) 1557 return false; 1558 1559 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1560 FD->getCanonicalDecl())) 1561 return true; 1562 1563 // Otherwise, the function is known-emitted if it's in our set of 1564 // known-emitted functions. 1565 return S.DeviceKnownEmittedFns.count(FD) > 0; 1566 } 1567 1568 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1569 unsigned DiagID) { 1570 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1571 "Expected OpenMP device compilation."); 1572 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1573 !isKnownEmitted(*this, getCurFunctionDecl())) 1574 ? DeviceDiagBuilder::K_Deferred 1575 : DeviceDiagBuilder::K_Immediate, 1576 Loc, DiagID, getCurFunctionDecl(), *this); 1577 } 1578 1579 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1580 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1581 "Expected OpenMP device compilation."); 1582 assert(Callee && "Callee may not be null."); 1583 FunctionDecl *Caller = getCurFunctionDecl(); 1584 1585 // If the caller is known-emitted, mark the callee as known-emitted. 1586 // Otherwise, mark the call in our call graph so we can traverse it later. 1587 if (!isOpenMPDeviceDelayedContext(*this) || 1588 (Caller && isKnownEmitted(*this, Caller))) 1589 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1590 else if (Caller) 1591 DeviceCallGraph[Caller].insert({Callee, Loc}); 1592 } 1593 1594 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1595 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1596 "OpenMP device compilation mode is expected."); 1597 QualType Ty = E->getType(); 1598 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1599 ((Ty->isFloat128Type() || 1600 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1601 !Context.getTargetInfo().hasFloat128Type()) || 1602 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1603 !Context.getTargetInfo().hasInt128Type())) 1604 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1605 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1606 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1607 } 1608 1609 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1610 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1611 1612 ASTContext &Ctx = getASTContext(); 1613 bool IsByRef = true; 1614 1615 // Find the directive that is associated with the provided scope. 1616 D = cast<ValueDecl>(D->getCanonicalDecl()); 1617 QualType Ty = D->getType(); 1618 1619 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1620 // This table summarizes how a given variable should be passed to the device 1621 // given its type and the clauses where it appears. This table is based on 1622 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1623 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1624 // 1625 // ========================================================================= 1626 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1627 // | |(tofrom:scalar)| | pvt | | | | 1628 // ========================================================================= 1629 // | scl | | | | - | | bycopy| 1630 // | scl | | - | x | - | - | bycopy| 1631 // | scl | | x | - | - | - | null | 1632 // | scl | x | | | - | | byref | 1633 // | scl | x | - | x | - | - | bycopy| 1634 // | scl | x | x | - | - | - | null | 1635 // | scl | | - | - | - | x | byref | 1636 // | scl | x | - | - | - | x | byref | 1637 // 1638 // | agg | n.a. | | | - | | byref | 1639 // | agg | n.a. | - | x | - | - | byref | 1640 // | agg | n.a. | x | - | - | - | null | 1641 // | agg | n.a. | - | - | - | x | byref | 1642 // | agg | n.a. | - | - | - | x[] | byref | 1643 // 1644 // | ptr | n.a. | | | - | | bycopy| 1645 // | ptr | n.a. | - | x | - | - | bycopy| 1646 // | ptr | n.a. | x | - | - | - | null | 1647 // | ptr | n.a. | - | - | - | x | byref | 1648 // | ptr | n.a. | - | - | - | x[] | bycopy| 1649 // | ptr | n.a. | - | - | x | | bycopy| 1650 // | ptr | n.a. | - | - | x | x | bycopy| 1651 // | ptr | n.a. | - | - | x | x[] | bycopy| 1652 // ========================================================================= 1653 // Legend: 1654 // scl - scalar 1655 // ptr - pointer 1656 // agg - aggregate 1657 // x - applies 1658 // - - invalid in this combination 1659 // [] - mapped with an array section 1660 // byref - should be mapped by reference 1661 // byval - should be mapped by value 1662 // null - initialize a local variable to null on the device 1663 // 1664 // Observations: 1665 // - All scalar declarations that show up in a map clause have to be passed 1666 // by reference, because they may have been mapped in the enclosing data 1667 // environment. 1668 // - If the scalar value does not fit the size of uintptr, it has to be 1669 // passed by reference, regardless the result in the table above. 1670 // - For pointers mapped by value that have either an implicit map or an 1671 // array section, the runtime library may pass the NULL value to the 1672 // device instead of the value passed to it by the compiler. 1673 1674 if (Ty->isReferenceType()) 1675 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1676 1677 // Locate map clauses and see if the variable being captured is referred to 1678 // in any of those clauses. Here we only care about variables, not fields, 1679 // because fields are part of aggregates. 1680 bool IsVariableUsedInMapClause = false; 1681 bool IsVariableAssociatedWithSection = false; 1682 1683 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1684 D, Level, 1685 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1686 OMPClauseMappableExprCommon::MappableExprComponentListRef 1687 MapExprComponents, 1688 OpenMPClauseKind WhereFoundClauseKind) { 1689 // Only the map clause information influences how a variable is 1690 // captured. E.g. is_device_ptr does not require changing the default 1691 // behavior. 1692 if (WhereFoundClauseKind != OMPC_map) 1693 return false; 1694 1695 auto EI = MapExprComponents.rbegin(); 1696 auto EE = MapExprComponents.rend(); 1697 1698 assert(EI != EE && "Invalid map expression!"); 1699 1700 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1701 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1702 1703 ++EI; 1704 if (EI == EE) 1705 return false; 1706 1707 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1708 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1709 isa<MemberExpr>(EI->getAssociatedExpression())) { 1710 IsVariableAssociatedWithSection = true; 1711 // There is nothing more we need to know about this variable. 1712 return true; 1713 } 1714 1715 // Keep looking for more map info. 1716 return false; 1717 }); 1718 1719 if (IsVariableUsedInMapClause) { 1720 // If variable is identified in a map clause it is always captured by 1721 // reference except if it is a pointer that is dereferenced somehow. 1722 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1723 } else { 1724 // By default, all the data that has a scalar type is mapped by copy 1725 // (except for reduction variables). 1726 IsByRef = 1727 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1728 !Ty->isAnyPointerType()) || 1729 !Ty->isScalarType() || 1730 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1731 DSAStack->hasExplicitDSA( 1732 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1733 } 1734 } 1735 1736 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1737 IsByRef = 1738 !DSAStack->hasExplicitDSA( 1739 D, 1740 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1741 Level, /*NotLastprivate=*/true) && 1742 // If the variable is artificial and must be captured by value - try to 1743 // capture by value. 1744 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1745 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1746 } 1747 1748 // When passing data by copy, we need to make sure it fits the uintptr size 1749 // and alignment, because the runtime library only deals with uintptr types. 1750 // If it does not fit the uintptr size, we need to pass the data by reference 1751 // instead. 1752 if (!IsByRef && 1753 (Ctx.getTypeSizeInChars(Ty) > 1754 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1755 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1756 IsByRef = true; 1757 } 1758 1759 return IsByRef; 1760 } 1761 1762 unsigned Sema::getOpenMPNestingLevel() const { 1763 assert(getLangOpts().OpenMP); 1764 return DSAStack->getNestingLevel(); 1765 } 1766 1767 bool Sema::isInOpenMPTargetExecutionDirective() const { 1768 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1769 !DSAStack->isClauseParsingMode()) || 1770 DSAStack->hasDirective( 1771 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1772 SourceLocation) -> bool { 1773 return isOpenMPTargetExecutionDirective(K); 1774 }, 1775 false); 1776 } 1777 1778 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1779 unsigned StopAt) { 1780 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1781 D = getCanonicalDecl(D); 1782 1783 // If we want to determine whether the variable should be captured from the 1784 // perspective of the current capturing scope, and we've already left all the 1785 // capturing scopes of the top directive on the stack, check from the 1786 // perspective of its parent directive (if any) instead. 1787 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1788 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1789 1790 // If we are attempting to capture a global variable in a directive with 1791 // 'target' we return true so that this global is also mapped to the device. 1792 // 1793 auto *VD = dyn_cast<VarDecl>(D); 1794 if (VD && !VD->hasLocalStorage() && 1795 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1796 if (isInOpenMPDeclareTargetContext()) { 1797 // Try to mark variable as declare target if it is used in capturing 1798 // regions. 1799 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1800 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1801 return nullptr; 1802 } else if (isInOpenMPTargetExecutionDirective()) { 1803 // If the declaration is enclosed in a 'declare target' directive, 1804 // then it should not be captured. 1805 // 1806 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1807 return nullptr; 1808 return VD; 1809 } 1810 } 1811 1812 if (CheckScopeInfo) { 1813 bool OpenMPFound = false; 1814 for (unsigned I = StopAt + 1; I > 0; --I) { 1815 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1816 if(!isa<CapturingScopeInfo>(FSI)) 1817 return nullptr; 1818 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1819 if (RSI->CapRegionKind == CR_OpenMP) { 1820 OpenMPFound = true; 1821 break; 1822 } 1823 } 1824 if (!OpenMPFound) 1825 return nullptr; 1826 } 1827 1828 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1829 (!DSAStack->isClauseParsingMode() || 1830 DSAStack->getParentDirective() != OMPD_unknown)) { 1831 auto &&Info = DSAStack->isLoopControlVariable(D); 1832 if (Info.first || 1833 (VD && VD->hasLocalStorage() && 1834 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1835 (VD && DSAStack->isForceVarCapturing())) 1836 return VD ? VD : Info.second; 1837 DSAStackTy::DSAVarData DVarPrivate = 1838 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1839 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1840 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1841 // Threadprivate variables must not be captured. 1842 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1843 return nullptr; 1844 // The variable is not private or it is the variable in the directive with 1845 // default(none) clause and not used in any clause. 1846 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1847 [](OpenMPDirectiveKind) { return true; }, 1848 DSAStack->isClauseParsingMode()); 1849 if (DVarPrivate.CKind != OMPC_unknown || 1850 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1851 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1852 } 1853 return nullptr; 1854 } 1855 1856 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1857 unsigned Level) const { 1858 SmallVector<OpenMPDirectiveKind, 4> Regions; 1859 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1860 FunctionScopesIndex -= Regions.size(); 1861 } 1862 1863 void Sema::startOpenMPLoop() { 1864 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1865 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1866 DSAStack->loopInit(); 1867 } 1868 1869 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1870 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1871 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1872 if (DSAStack->getAssociatedLoops() > 0 && 1873 !DSAStack->isLoopStarted()) { 1874 DSAStack->resetPossibleLoopCounter(D); 1875 DSAStack->loopStart(); 1876 return true; 1877 } 1878 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1879 DSAStack->isLoopControlVariable(D).first) && 1880 !DSAStack->hasExplicitDSA( 1881 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1882 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1883 return true; 1884 } 1885 if (const auto *VD = dyn_cast<VarDecl>(D)) { 1886 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 1887 DSAStack->isForceVarCapturing() && 1888 !DSAStack->hasExplicitDSA( 1889 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 1890 return true; 1891 } 1892 return DSAStack->hasExplicitDSA( 1893 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1894 (DSAStack->isClauseParsingMode() && 1895 DSAStack->getClauseParsingMode() == OMPC_private) || 1896 // Consider taskgroup reduction descriptor variable a private to avoid 1897 // possible capture in the region. 1898 (DSAStack->hasExplicitDirective( 1899 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1900 Level) && 1901 DSAStack->isTaskgroupReductionRef(D, Level)); 1902 } 1903 1904 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1905 unsigned Level) { 1906 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1907 D = getCanonicalDecl(D); 1908 OpenMPClauseKind OMPC = OMPC_unknown; 1909 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1910 const unsigned NewLevel = I - 1; 1911 if (DSAStack->hasExplicitDSA(D, 1912 [&OMPC](const OpenMPClauseKind K) { 1913 if (isOpenMPPrivate(K)) { 1914 OMPC = K; 1915 return true; 1916 } 1917 return false; 1918 }, 1919 NewLevel)) 1920 break; 1921 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1922 D, NewLevel, 1923 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1924 OpenMPClauseKind) { return true; })) { 1925 OMPC = OMPC_map; 1926 break; 1927 } 1928 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1929 NewLevel)) { 1930 OMPC = OMPC_map; 1931 if (D->getType()->isScalarType() && 1932 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1933 DefaultMapAttributes::DMA_tofrom_scalar) 1934 OMPC = OMPC_firstprivate; 1935 break; 1936 } 1937 } 1938 if (OMPC != OMPC_unknown) 1939 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1940 } 1941 1942 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1943 unsigned Level) const { 1944 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1945 // Return true if the current level is no longer enclosed in a target region. 1946 1947 const auto *VD = dyn_cast<VarDecl>(D); 1948 return VD && !VD->hasLocalStorage() && 1949 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1950 Level); 1951 } 1952 1953 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1954 1955 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1956 const DeclarationNameInfo &DirName, 1957 Scope *CurScope, SourceLocation Loc) { 1958 DSAStack->push(DKind, DirName, CurScope, Loc); 1959 PushExpressionEvaluationContext( 1960 ExpressionEvaluationContext::PotentiallyEvaluated); 1961 } 1962 1963 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1964 DSAStack->setClauseParsingMode(K); 1965 } 1966 1967 void Sema::EndOpenMPClause() { 1968 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1969 } 1970 1971 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 1972 ArrayRef<OMPClause *> Clauses); 1973 1974 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1975 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1976 // A variable of class type (or array thereof) that appears in a lastprivate 1977 // clause requires an accessible, unambiguous default constructor for the 1978 // class type, unless the list item is also specified in a firstprivate 1979 // clause. 1980 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1981 for (OMPClause *C : D->clauses()) { 1982 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1983 SmallVector<Expr *, 8> PrivateCopies; 1984 for (Expr *DE : Clause->varlists()) { 1985 if (DE->isValueDependent() || DE->isTypeDependent()) { 1986 PrivateCopies.push_back(nullptr); 1987 continue; 1988 } 1989 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1990 auto *VD = cast<VarDecl>(DRE->getDecl()); 1991 QualType Type = VD->getType().getNonReferenceType(); 1992 const DSAStackTy::DSAVarData DVar = 1993 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1994 if (DVar.CKind == OMPC_lastprivate) { 1995 // Generate helper private variable and initialize it with the 1996 // default value. The address of the original variable is replaced 1997 // by the address of the new private variable in CodeGen. This new 1998 // variable is not added to IdResolver, so the code in the OpenMP 1999 // region uses original variable for proper diagnostics. 2000 VarDecl *VDPrivate = buildVarDecl( 2001 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2002 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2003 ActOnUninitializedDecl(VDPrivate); 2004 if (VDPrivate->isInvalidDecl()) { 2005 PrivateCopies.push_back(nullptr); 2006 continue; 2007 } 2008 PrivateCopies.push_back(buildDeclRefExpr( 2009 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2010 } else { 2011 // The variable is also a firstprivate, so initialization sequence 2012 // for private copy is generated already. 2013 PrivateCopies.push_back(nullptr); 2014 } 2015 } 2016 Clause->setPrivateCopies(PrivateCopies); 2017 } 2018 } 2019 // Check allocate clauses. 2020 if (!CurContext->isDependentContext()) 2021 checkAllocateClauses(*this, DSAStack, D->clauses()); 2022 } 2023 2024 DSAStack->pop(); 2025 DiscardCleanupsInEvaluationContext(); 2026 PopExpressionEvaluationContext(); 2027 } 2028 2029 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2030 Expr *NumIterations, Sema &SemaRef, 2031 Scope *S, DSAStackTy *Stack); 2032 2033 namespace { 2034 2035 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2036 private: 2037 Sema &SemaRef; 2038 2039 public: 2040 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2041 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2042 NamedDecl *ND = Candidate.getCorrectionDecl(); 2043 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2044 return VD->hasGlobalStorage() && 2045 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2046 SemaRef.getCurScope()); 2047 } 2048 return false; 2049 } 2050 2051 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2052 return llvm::make_unique<VarDeclFilterCCC>(*this); 2053 } 2054 2055 }; 2056 2057 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2058 private: 2059 Sema &SemaRef; 2060 2061 public: 2062 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2063 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2064 NamedDecl *ND = Candidate.getCorrectionDecl(); 2065 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2066 isa<FunctionDecl>(ND))) { 2067 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2068 SemaRef.getCurScope()); 2069 } 2070 return false; 2071 } 2072 2073 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2074 return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this); 2075 } 2076 }; 2077 2078 } // namespace 2079 2080 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2081 CXXScopeSpec &ScopeSpec, 2082 const DeclarationNameInfo &Id, 2083 OpenMPDirectiveKind Kind) { 2084 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2085 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2086 2087 if (Lookup.isAmbiguous()) 2088 return ExprError(); 2089 2090 VarDecl *VD; 2091 if (!Lookup.isSingleResult()) { 2092 VarDeclFilterCCC CCC(*this); 2093 if (TypoCorrection Corrected = 2094 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2095 CTK_ErrorRecovery)) { 2096 diagnoseTypo(Corrected, 2097 PDiag(Lookup.empty() 2098 ? diag::err_undeclared_var_use_suggest 2099 : diag::err_omp_expected_var_arg_suggest) 2100 << Id.getName()); 2101 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2102 } else { 2103 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2104 : diag::err_omp_expected_var_arg) 2105 << Id.getName(); 2106 return ExprError(); 2107 } 2108 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2109 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2110 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2111 return ExprError(); 2112 } 2113 Lookup.suppressDiagnostics(); 2114 2115 // OpenMP [2.9.2, Syntax, C/C++] 2116 // Variables must be file-scope, namespace-scope, or static block-scope. 2117 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2118 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2119 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2120 bool IsDecl = 2121 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2122 Diag(VD->getLocation(), 2123 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2124 << VD; 2125 return ExprError(); 2126 } 2127 2128 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2129 NamedDecl *ND = CanonicalVD; 2130 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2131 // A threadprivate directive for file-scope variables must appear outside 2132 // any definition or declaration. 2133 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2134 !getCurLexicalContext()->isTranslationUnit()) { 2135 Diag(Id.getLoc(), diag::err_omp_var_scope) 2136 << getOpenMPDirectiveName(Kind) << VD; 2137 bool IsDecl = 2138 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2139 Diag(VD->getLocation(), 2140 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2141 << VD; 2142 return ExprError(); 2143 } 2144 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2145 // A threadprivate directive for static class member variables must appear 2146 // in the class definition, in the same scope in which the member 2147 // variables are declared. 2148 if (CanonicalVD->isStaticDataMember() && 2149 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2150 Diag(Id.getLoc(), diag::err_omp_var_scope) 2151 << getOpenMPDirectiveName(Kind) << VD; 2152 bool IsDecl = 2153 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2154 Diag(VD->getLocation(), 2155 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2156 << VD; 2157 return ExprError(); 2158 } 2159 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2160 // A threadprivate directive for namespace-scope variables must appear 2161 // outside any definition or declaration other than the namespace 2162 // definition itself. 2163 if (CanonicalVD->getDeclContext()->isNamespace() && 2164 (!getCurLexicalContext()->isFileContext() || 2165 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2166 Diag(Id.getLoc(), diag::err_omp_var_scope) 2167 << getOpenMPDirectiveName(Kind) << VD; 2168 bool IsDecl = 2169 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2170 Diag(VD->getLocation(), 2171 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2172 << VD; 2173 return ExprError(); 2174 } 2175 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2176 // A threadprivate directive for static block-scope variables must appear 2177 // in the scope of the variable and not in a nested scope. 2178 if (CanonicalVD->isLocalVarDecl() && CurScope && 2179 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2180 Diag(Id.getLoc(), diag::err_omp_var_scope) 2181 << getOpenMPDirectiveName(Kind) << VD; 2182 bool IsDecl = 2183 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2184 Diag(VD->getLocation(), 2185 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2186 << VD; 2187 return ExprError(); 2188 } 2189 2190 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2191 // A threadprivate directive must lexically precede all references to any 2192 // of the variables in its list. 2193 if (Kind == OMPD_threadprivate && VD->isUsed() && 2194 !DSAStack->isThreadPrivate(VD)) { 2195 Diag(Id.getLoc(), diag::err_omp_var_used) 2196 << getOpenMPDirectiveName(Kind) << VD; 2197 return ExprError(); 2198 } 2199 2200 QualType ExprType = VD->getType().getNonReferenceType(); 2201 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2202 SourceLocation(), VD, 2203 /*RefersToEnclosingVariableOrCapture=*/false, 2204 Id.getLoc(), ExprType, VK_LValue); 2205 } 2206 2207 Sema::DeclGroupPtrTy 2208 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2209 ArrayRef<Expr *> VarList) { 2210 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2211 CurContext->addDecl(D); 2212 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2213 } 2214 return nullptr; 2215 } 2216 2217 namespace { 2218 class LocalVarRefChecker final 2219 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2220 Sema &SemaRef; 2221 2222 public: 2223 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2224 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2225 if (VD->hasLocalStorage()) { 2226 SemaRef.Diag(E->getBeginLoc(), 2227 diag::err_omp_local_var_in_threadprivate_init) 2228 << E->getSourceRange(); 2229 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2230 << VD << VD->getSourceRange(); 2231 return true; 2232 } 2233 } 2234 return false; 2235 } 2236 bool VisitStmt(const Stmt *S) { 2237 for (const Stmt *Child : S->children()) { 2238 if (Child && Visit(Child)) 2239 return true; 2240 } 2241 return false; 2242 } 2243 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2244 }; 2245 } // namespace 2246 2247 OMPThreadPrivateDecl * 2248 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2249 SmallVector<Expr *, 8> Vars; 2250 for (Expr *RefExpr : VarList) { 2251 auto *DE = cast<DeclRefExpr>(RefExpr); 2252 auto *VD = cast<VarDecl>(DE->getDecl()); 2253 SourceLocation ILoc = DE->getExprLoc(); 2254 2255 // Mark variable as used. 2256 VD->setReferenced(); 2257 VD->markUsed(Context); 2258 2259 QualType QType = VD->getType(); 2260 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2261 // It will be analyzed later. 2262 Vars.push_back(DE); 2263 continue; 2264 } 2265 2266 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2267 // A threadprivate variable must not have an incomplete type. 2268 if (RequireCompleteType(ILoc, VD->getType(), 2269 diag::err_omp_threadprivate_incomplete_type)) { 2270 continue; 2271 } 2272 2273 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2274 // A threadprivate variable must not have a reference type. 2275 if (VD->getType()->isReferenceType()) { 2276 Diag(ILoc, diag::err_omp_ref_type_arg) 2277 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2278 bool IsDecl = 2279 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2280 Diag(VD->getLocation(), 2281 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2282 << VD; 2283 continue; 2284 } 2285 2286 // Check if this is a TLS variable. If TLS is not being supported, produce 2287 // the corresponding diagnostic. 2288 if ((VD->getTLSKind() != VarDecl::TLS_None && 2289 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2290 getLangOpts().OpenMPUseTLS && 2291 getASTContext().getTargetInfo().isTLSSupported())) || 2292 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2293 !VD->isLocalVarDecl())) { 2294 Diag(ILoc, diag::err_omp_var_thread_local) 2295 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2296 bool IsDecl = 2297 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2298 Diag(VD->getLocation(), 2299 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2300 << VD; 2301 continue; 2302 } 2303 2304 // Check if initial value of threadprivate variable reference variable with 2305 // local storage (it is not supported by runtime). 2306 if (const Expr *Init = VD->getAnyInitializer()) { 2307 LocalVarRefChecker Checker(*this); 2308 if (Checker.Visit(Init)) 2309 continue; 2310 } 2311 2312 Vars.push_back(RefExpr); 2313 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2314 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2315 Context, SourceRange(Loc, Loc))); 2316 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2317 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2318 } 2319 OMPThreadPrivateDecl *D = nullptr; 2320 if (!Vars.empty()) { 2321 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2322 Vars); 2323 D->setAccess(AS_public); 2324 } 2325 return D; 2326 } 2327 2328 static OMPAllocateDeclAttr::AllocatorTypeTy 2329 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2330 if (!Allocator) 2331 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2332 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2333 Allocator->isInstantiationDependent() || 2334 Allocator->containsUnexpandedParameterPack()) 2335 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2336 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2337 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2338 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2339 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2340 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2341 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2342 llvm::FoldingSetNodeID AEId, DAEId; 2343 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2344 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2345 if (AEId == DAEId) { 2346 AllocatorKindRes = AllocatorKind; 2347 break; 2348 } 2349 } 2350 return AllocatorKindRes; 2351 } 2352 2353 static bool checkPreviousOMPAllocateAttribute( 2354 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2355 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2356 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2357 return false; 2358 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2359 Expr *PrevAllocator = A->getAllocator(); 2360 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2361 getAllocatorKind(S, Stack, PrevAllocator); 2362 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2363 if (AllocatorsMatch && 2364 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2365 Allocator && PrevAllocator) { 2366 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2367 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2368 llvm::FoldingSetNodeID AEId, PAEId; 2369 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2370 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2371 AllocatorsMatch = AEId == PAEId; 2372 } 2373 if (!AllocatorsMatch) { 2374 SmallString<256> AllocatorBuffer; 2375 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2376 if (Allocator) 2377 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2378 SmallString<256> PrevAllocatorBuffer; 2379 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2380 if (PrevAllocator) 2381 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2382 S.getPrintingPolicy()); 2383 2384 SourceLocation AllocatorLoc = 2385 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2386 SourceRange AllocatorRange = 2387 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2388 SourceLocation PrevAllocatorLoc = 2389 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2390 SourceRange PrevAllocatorRange = 2391 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2392 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2393 << (Allocator ? 1 : 0) << AllocatorStream.str() 2394 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2395 << AllocatorRange; 2396 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2397 << PrevAllocatorRange; 2398 return true; 2399 } 2400 return false; 2401 } 2402 2403 static void 2404 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2405 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2406 Expr *Allocator, SourceRange SR) { 2407 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2408 return; 2409 if (Allocator && 2410 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2411 Allocator->isInstantiationDependent() || 2412 Allocator->containsUnexpandedParameterPack())) 2413 return; 2414 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2415 Allocator, SR); 2416 VD->addAttr(A); 2417 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2418 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2419 } 2420 2421 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2422 SourceLocation Loc, ArrayRef<Expr *> VarList, 2423 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2424 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2425 Expr *Allocator = nullptr; 2426 if (Clauses.empty()) { 2427 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2428 // allocate directives that appear in a target region must specify an 2429 // allocator clause unless a requires directive with the dynamic_allocators 2430 // clause is present in the same compilation unit. 2431 if (LangOpts.OpenMPIsDevice && 2432 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2433 targetDiag(Loc, diag::err_expected_allocator_clause); 2434 } else { 2435 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2436 } 2437 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2438 getAllocatorKind(*this, DSAStack, Allocator); 2439 SmallVector<Expr *, 8> Vars; 2440 for (Expr *RefExpr : VarList) { 2441 auto *DE = cast<DeclRefExpr>(RefExpr); 2442 auto *VD = cast<VarDecl>(DE->getDecl()); 2443 2444 // Check if this is a TLS variable or global register. 2445 if (VD->getTLSKind() != VarDecl::TLS_None || 2446 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2447 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2448 !VD->isLocalVarDecl())) 2449 continue; 2450 2451 // If the used several times in the allocate directive, the same allocator 2452 // must be used. 2453 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2454 AllocatorKind, Allocator)) 2455 continue; 2456 2457 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2458 // If a list item has a static storage type, the allocator expression in the 2459 // allocator clause must be a constant expression that evaluates to one of 2460 // the predefined memory allocator values. 2461 if (Allocator && VD->hasGlobalStorage()) { 2462 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2463 Diag(Allocator->getExprLoc(), 2464 diag::err_omp_expected_predefined_allocator) 2465 << Allocator->getSourceRange(); 2466 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2467 VarDecl::DeclarationOnly; 2468 Diag(VD->getLocation(), 2469 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2470 << VD; 2471 continue; 2472 } 2473 } 2474 2475 Vars.push_back(RefExpr); 2476 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2477 DE->getSourceRange()); 2478 } 2479 if (Vars.empty()) 2480 return nullptr; 2481 if (!Owner) 2482 Owner = getCurLexicalContext(); 2483 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2484 D->setAccess(AS_public); 2485 Owner->addDecl(D); 2486 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2487 } 2488 2489 Sema::DeclGroupPtrTy 2490 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2491 ArrayRef<OMPClause *> ClauseList) { 2492 OMPRequiresDecl *D = nullptr; 2493 if (!CurContext->isFileContext()) { 2494 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2495 } else { 2496 D = CheckOMPRequiresDecl(Loc, ClauseList); 2497 if (D) { 2498 CurContext->addDecl(D); 2499 DSAStack->addRequiresDecl(D); 2500 } 2501 } 2502 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2503 } 2504 2505 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2506 ArrayRef<OMPClause *> ClauseList) { 2507 /// For target specific clauses, the requires directive cannot be 2508 /// specified after the handling of any of the target regions in the 2509 /// current compilation unit. 2510 ArrayRef<SourceLocation> TargetLocations = 2511 DSAStack->getEncounteredTargetLocs(); 2512 if (!TargetLocations.empty()) { 2513 for (const OMPClause *CNew : ClauseList) { 2514 // Check if any of the requires clauses affect target regions. 2515 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2516 isa<OMPUnifiedAddressClause>(CNew) || 2517 isa<OMPReverseOffloadClause>(CNew) || 2518 isa<OMPDynamicAllocatorsClause>(CNew)) { 2519 Diag(Loc, diag::err_omp_target_before_requires) 2520 << getOpenMPClauseName(CNew->getClauseKind()); 2521 for (SourceLocation TargetLoc : TargetLocations) { 2522 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2523 } 2524 } 2525 } 2526 } 2527 2528 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2529 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2530 ClauseList); 2531 return nullptr; 2532 } 2533 2534 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2535 const ValueDecl *D, 2536 const DSAStackTy::DSAVarData &DVar, 2537 bool IsLoopIterVar = false) { 2538 if (DVar.RefExpr) { 2539 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2540 << getOpenMPClauseName(DVar.CKind); 2541 return; 2542 } 2543 enum { 2544 PDSA_StaticMemberShared, 2545 PDSA_StaticLocalVarShared, 2546 PDSA_LoopIterVarPrivate, 2547 PDSA_LoopIterVarLinear, 2548 PDSA_LoopIterVarLastprivate, 2549 PDSA_ConstVarShared, 2550 PDSA_GlobalVarShared, 2551 PDSA_TaskVarFirstprivate, 2552 PDSA_LocalVarPrivate, 2553 PDSA_Implicit 2554 } Reason = PDSA_Implicit; 2555 bool ReportHint = false; 2556 auto ReportLoc = D->getLocation(); 2557 auto *VD = dyn_cast<VarDecl>(D); 2558 if (IsLoopIterVar) { 2559 if (DVar.CKind == OMPC_private) 2560 Reason = PDSA_LoopIterVarPrivate; 2561 else if (DVar.CKind == OMPC_lastprivate) 2562 Reason = PDSA_LoopIterVarLastprivate; 2563 else 2564 Reason = PDSA_LoopIterVarLinear; 2565 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2566 DVar.CKind == OMPC_firstprivate) { 2567 Reason = PDSA_TaskVarFirstprivate; 2568 ReportLoc = DVar.ImplicitDSALoc; 2569 } else if (VD && VD->isStaticLocal()) 2570 Reason = PDSA_StaticLocalVarShared; 2571 else if (VD && VD->isStaticDataMember()) 2572 Reason = PDSA_StaticMemberShared; 2573 else if (VD && VD->isFileVarDecl()) 2574 Reason = PDSA_GlobalVarShared; 2575 else if (D->getType().isConstant(SemaRef.getASTContext())) 2576 Reason = PDSA_ConstVarShared; 2577 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2578 ReportHint = true; 2579 Reason = PDSA_LocalVarPrivate; 2580 } 2581 if (Reason != PDSA_Implicit) { 2582 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2583 << Reason << ReportHint 2584 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2585 } else if (DVar.ImplicitDSALoc.isValid()) { 2586 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2587 << getOpenMPClauseName(DVar.CKind); 2588 } 2589 } 2590 2591 namespace { 2592 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2593 DSAStackTy *Stack; 2594 Sema &SemaRef; 2595 bool ErrorFound = false; 2596 CapturedStmt *CS = nullptr; 2597 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2598 llvm::SmallVector<Expr *, 4> ImplicitMap; 2599 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2600 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2601 2602 void VisitSubCaptures(OMPExecutableDirective *S) { 2603 // Check implicitly captured variables. 2604 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2605 return; 2606 visitSubCaptures(S->getInnermostCapturedStmt()); 2607 } 2608 2609 public: 2610 void VisitDeclRefExpr(DeclRefExpr *E) { 2611 if (E->isTypeDependent() || E->isValueDependent() || 2612 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2613 return; 2614 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2615 // Check the datasharing rules for the expressions in the clauses. 2616 if (!CS) { 2617 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2618 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2619 Visit(CED->getInit()); 2620 return; 2621 } 2622 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2623 // Do not analyze internal variables and do not enclose them into 2624 // implicit clauses. 2625 return; 2626 VD = VD->getCanonicalDecl(); 2627 // Skip internally declared variables. 2628 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2629 return; 2630 2631 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2632 // Check if the variable has explicit DSA set and stop analysis if it so. 2633 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2634 return; 2635 2636 // Skip internally declared static variables. 2637 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2638 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2639 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2640 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2641 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2642 return; 2643 2644 SourceLocation ELoc = E->getExprLoc(); 2645 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2646 // The default(none) clause requires that each variable that is referenced 2647 // in the construct, and does not have a predetermined data-sharing 2648 // attribute, must have its data-sharing attribute explicitly determined 2649 // by being listed in a data-sharing attribute clause. 2650 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2651 isImplicitOrExplicitTaskingRegion(DKind) && 2652 VarsWithInheritedDSA.count(VD) == 0) { 2653 VarsWithInheritedDSA[VD] = E; 2654 return; 2655 } 2656 2657 if (isOpenMPTargetExecutionDirective(DKind) && 2658 !Stack->isLoopControlVariable(VD).first) { 2659 if (!Stack->checkMappableExprComponentListsForDecl( 2660 VD, /*CurrentRegionOnly=*/true, 2661 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2662 StackComponents, 2663 OpenMPClauseKind) { 2664 // Variable is used if it has been marked as an array, array 2665 // section or the variable iself. 2666 return StackComponents.size() == 1 || 2667 std::all_of( 2668 std::next(StackComponents.rbegin()), 2669 StackComponents.rend(), 2670 [](const OMPClauseMappableExprCommon:: 2671 MappableComponent &MC) { 2672 return MC.getAssociatedDeclaration() == 2673 nullptr && 2674 (isa<OMPArraySectionExpr>( 2675 MC.getAssociatedExpression()) || 2676 isa<ArraySubscriptExpr>( 2677 MC.getAssociatedExpression())); 2678 }); 2679 })) { 2680 bool IsFirstprivate = false; 2681 // By default lambdas are captured as firstprivates. 2682 if (const auto *RD = 2683 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2684 IsFirstprivate = RD->isLambda(); 2685 IsFirstprivate = 2686 IsFirstprivate || 2687 (VD->getType().getNonReferenceType()->isScalarType() && 2688 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2689 if (IsFirstprivate) 2690 ImplicitFirstprivate.emplace_back(E); 2691 else 2692 ImplicitMap.emplace_back(E); 2693 return; 2694 } 2695 } 2696 2697 // OpenMP [2.9.3.6, Restrictions, p.2] 2698 // A list item that appears in a reduction clause of the innermost 2699 // enclosing worksharing or parallel construct may not be accessed in an 2700 // explicit task. 2701 DVar = Stack->hasInnermostDSA( 2702 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2703 [](OpenMPDirectiveKind K) { 2704 return isOpenMPParallelDirective(K) || 2705 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2706 }, 2707 /*FromParent=*/true); 2708 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2709 ErrorFound = true; 2710 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2711 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2712 return; 2713 } 2714 2715 // Define implicit data-sharing attributes for task. 2716 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2717 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2718 !Stack->isLoopControlVariable(VD).first) { 2719 ImplicitFirstprivate.push_back(E); 2720 return; 2721 } 2722 2723 // Store implicitly used globals with declare target link for parent 2724 // target. 2725 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2726 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2727 Stack->addToParentTargetRegionLinkGlobals(E); 2728 return; 2729 } 2730 } 2731 } 2732 void VisitMemberExpr(MemberExpr *E) { 2733 if (E->isTypeDependent() || E->isValueDependent() || 2734 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2735 return; 2736 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2737 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2738 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2739 if (!FD) 2740 return; 2741 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2742 // Check if the variable has explicit DSA set and stop analysis if it 2743 // so. 2744 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2745 return; 2746 2747 if (isOpenMPTargetExecutionDirective(DKind) && 2748 !Stack->isLoopControlVariable(FD).first && 2749 !Stack->checkMappableExprComponentListsForDecl( 2750 FD, /*CurrentRegionOnly=*/true, 2751 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2752 StackComponents, 2753 OpenMPClauseKind) { 2754 return isa<CXXThisExpr>( 2755 cast<MemberExpr>( 2756 StackComponents.back().getAssociatedExpression()) 2757 ->getBase() 2758 ->IgnoreParens()); 2759 })) { 2760 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2761 // A bit-field cannot appear in a map clause. 2762 // 2763 if (FD->isBitField()) 2764 return; 2765 2766 // Check to see if the member expression is referencing a class that 2767 // has already been explicitly mapped 2768 if (Stack->isClassPreviouslyMapped(TE->getType())) 2769 return; 2770 2771 ImplicitMap.emplace_back(E); 2772 return; 2773 } 2774 2775 SourceLocation ELoc = E->getExprLoc(); 2776 // OpenMP [2.9.3.6, Restrictions, p.2] 2777 // A list item that appears in a reduction clause of the innermost 2778 // enclosing worksharing or parallel construct may not be accessed in 2779 // an explicit task. 2780 DVar = Stack->hasInnermostDSA( 2781 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2782 [](OpenMPDirectiveKind K) { 2783 return isOpenMPParallelDirective(K) || 2784 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2785 }, 2786 /*FromParent=*/true); 2787 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2788 ErrorFound = true; 2789 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2790 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2791 return; 2792 } 2793 2794 // Define implicit data-sharing attributes for task. 2795 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2796 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2797 !Stack->isLoopControlVariable(FD).first) { 2798 // Check if there is a captured expression for the current field in the 2799 // region. Do not mark it as firstprivate unless there is no captured 2800 // expression. 2801 // TODO: try to make it firstprivate. 2802 if (DVar.CKind != OMPC_unknown) 2803 ImplicitFirstprivate.push_back(E); 2804 } 2805 return; 2806 } 2807 if (isOpenMPTargetExecutionDirective(DKind)) { 2808 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2809 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2810 /*NoDiagnose=*/true)) 2811 return; 2812 const auto *VD = cast<ValueDecl>( 2813 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2814 if (!Stack->checkMappableExprComponentListsForDecl( 2815 VD, /*CurrentRegionOnly=*/true, 2816 [&CurComponents]( 2817 OMPClauseMappableExprCommon::MappableExprComponentListRef 2818 StackComponents, 2819 OpenMPClauseKind) { 2820 auto CCI = CurComponents.rbegin(); 2821 auto CCE = CurComponents.rend(); 2822 for (const auto &SC : llvm::reverse(StackComponents)) { 2823 // Do both expressions have the same kind? 2824 if (CCI->getAssociatedExpression()->getStmtClass() != 2825 SC.getAssociatedExpression()->getStmtClass()) 2826 if (!(isa<OMPArraySectionExpr>( 2827 SC.getAssociatedExpression()) && 2828 isa<ArraySubscriptExpr>( 2829 CCI->getAssociatedExpression()))) 2830 return false; 2831 2832 const Decl *CCD = CCI->getAssociatedDeclaration(); 2833 const Decl *SCD = SC.getAssociatedDeclaration(); 2834 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2835 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2836 if (SCD != CCD) 2837 return false; 2838 std::advance(CCI, 1); 2839 if (CCI == CCE) 2840 break; 2841 } 2842 return true; 2843 })) { 2844 Visit(E->getBase()); 2845 } 2846 } else { 2847 Visit(E->getBase()); 2848 } 2849 } 2850 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2851 for (OMPClause *C : S->clauses()) { 2852 // Skip analysis of arguments of implicitly defined firstprivate clause 2853 // for task|target directives. 2854 // Skip analysis of arguments of implicitly defined map clause for target 2855 // directives. 2856 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2857 C->isImplicit())) { 2858 for (Stmt *CC : C->children()) { 2859 if (CC) 2860 Visit(CC); 2861 } 2862 } 2863 } 2864 // Check implicitly captured variables. 2865 VisitSubCaptures(S); 2866 } 2867 void VisitStmt(Stmt *S) { 2868 for (Stmt *C : S->children()) { 2869 if (C) { 2870 // Check implicitly captured variables in the task-based directives to 2871 // check if they must be firstprivatized. 2872 Visit(C); 2873 } 2874 } 2875 } 2876 2877 void visitSubCaptures(CapturedStmt *S) { 2878 for (const CapturedStmt::Capture &Cap : S->captures()) { 2879 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 2880 continue; 2881 VarDecl *VD = Cap.getCapturedVar(); 2882 // Do not try to map the variable if it or its sub-component was mapped 2883 // already. 2884 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2885 Stack->checkMappableExprComponentListsForDecl( 2886 VD, /*CurrentRegionOnly=*/true, 2887 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2888 OpenMPClauseKind) { return true; })) 2889 continue; 2890 DeclRefExpr *DRE = buildDeclRefExpr( 2891 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2892 Cap.getLocation(), /*RefersToCapture=*/true); 2893 Visit(DRE); 2894 } 2895 } 2896 bool isErrorFound() const { return ErrorFound; } 2897 ArrayRef<Expr *> getImplicitFirstprivate() const { 2898 return ImplicitFirstprivate; 2899 } 2900 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2901 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2902 return VarsWithInheritedDSA; 2903 } 2904 2905 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2906 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2907 // Process declare target link variables for the target directives. 2908 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2909 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2910 Visit(E); 2911 } 2912 } 2913 }; 2914 } // namespace 2915 2916 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2917 switch (DKind) { 2918 case OMPD_parallel: 2919 case OMPD_parallel_for: 2920 case OMPD_parallel_for_simd: 2921 case OMPD_parallel_sections: 2922 case OMPD_teams: 2923 case OMPD_teams_distribute: 2924 case OMPD_teams_distribute_simd: { 2925 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2926 QualType KmpInt32PtrTy = 2927 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2928 Sema::CapturedParamNameType Params[] = { 2929 std::make_pair(".global_tid.", KmpInt32PtrTy), 2930 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2931 std::make_pair(StringRef(), QualType()) // __context with shared vars 2932 }; 2933 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2934 Params); 2935 break; 2936 } 2937 case OMPD_target_teams: 2938 case OMPD_target_parallel: 2939 case OMPD_target_parallel_for: 2940 case OMPD_target_parallel_for_simd: 2941 case OMPD_target_teams_distribute: 2942 case OMPD_target_teams_distribute_simd: { 2943 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2944 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2945 QualType KmpInt32PtrTy = 2946 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2947 QualType Args[] = {VoidPtrTy}; 2948 FunctionProtoType::ExtProtoInfo EPI; 2949 EPI.Variadic = true; 2950 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2951 Sema::CapturedParamNameType Params[] = { 2952 std::make_pair(".global_tid.", KmpInt32Ty), 2953 std::make_pair(".part_id.", KmpInt32PtrTy), 2954 std::make_pair(".privates.", VoidPtrTy), 2955 std::make_pair( 2956 ".copy_fn.", 2957 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2958 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2959 std::make_pair(StringRef(), QualType()) // __context with shared vars 2960 }; 2961 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2962 Params); 2963 // Mark this captured region as inlined, because we don't use outlined 2964 // function directly. 2965 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2966 AlwaysInlineAttr::CreateImplicit( 2967 Context, AlwaysInlineAttr::Keyword_forceinline)); 2968 Sema::CapturedParamNameType ParamsTarget[] = { 2969 std::make_pair(StringRef(), QualType()) // __context with shared vars 2970 }; 2971 // Start a captured region for 'target' with no implicit parameters. 2972 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2973 ParamsTarget); 2974 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2975 std::make_pair(".global_tid.", KmpInt32PtrTy), 2976 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2977 std::make_pair(StringRef(), QualType()) // __context with shared vars 2978 }; 2979 // Start a captured region for 'teams' or 'parallel'. Both regions have 2980 // the same implicit parameters. 2981 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2982 ParamsTeamsOrParallel); 2983 break; 2984 } 2985 case OMPD_target: 2986 case OMPD_target_simd: { 2987 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2988 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2989 QualType KmpInt32PtrTy = 2990 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2991 QualType Args[] = {VoidPtrTy}; 2992 FunctionProtoType::ExtProtoInfo EPI; 2993 EPI.Variadic = true; 2994 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2995 Sema::CapturedParamNameType Params[] = { 2996 std::make_pair(".global_tid.", KmpInt32Ty), 2997 std::make_pair(".part_id.", KmpInt32PtrTy), 2998 std::make_pair(".privates.", VoidPtrTy), 2999 std::make_pair( 3000 ".copy_fn.", 3001 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3002 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3003 std::make_pair(StringRef(), QualType()) // __context with shared vars 3004 }; 3005 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3006 Params); 3007 // Mark this captured region as inlined, because we don't use outlined 3008 // function directly. 3009 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3010 AlwaysInlineAttr::CreateImplicit( 3011 Context, AlwaysInlineAttr::Keyword_forceinline)); 3012 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3013 std::make_pair(StringRef(), QualType())); 3014 break; 3015 } 3016 case OMPD_simd: 3017 case OMPD_for: 3018 case OMPD_for_simd: 3019 case OMPD_sections: 3020 case OMPD_section: 3021 case OMPD_single: 3022 case OMPD_master: 3023 case OMPD_critical: 3024 case OMPD_taskgroup: 3025 case OMPD_distribute: 3026 case OMPD_distribute_simd: 3027 case OMPD_ordered: 3028 case OMPD_atomic: 3029 case OMPD_target_data: { 3030 Sema::CapturedParamNameType Params[] = { 3031 std::make_pair(StringRef(), QualType()) // __context with shared vars 3032 }; 3033 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3034 Params); 3035 break; 3036 } 3037 case OMPD_task: { 3038 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3039 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3040 QualType KmpInt32PtrTy = 3041 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3042 QualType Args[] = {VoidPtrTy}; 3043 FunctionProtoType::ExtProtoInfo EPI; 3044 EPI.Variadic = true; 3045 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3046 Sema::CapturedParamNameType Params[] = { 3047 std::make_pair(".global_tid.", KmpInt32Ty), 3048 std::make_pair(".part_id.", KmpInt32PtrTy), 3049 std::make_pair(".privates.", VoidPtrTy), 3050 std::make_pair( 3051 ".copy_fn.", 3052 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3053 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3054 std::make_pair(StringRef(), QualType()) // __context with shared vars 3055 }; 3056 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3057 Params); 3058 // Mark this captured region as inlined, because we don't use outlined 3059 // function directly. 3060 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3061 AlwaysInlineAttr::CreateImplicit( 3062 Context, AlwaysInlineAttr::Keyword_forceinline)); 3063 break; 3064 } 3065 case OMPD_taskloop: 3066 case OMPD_taskloop_simd: { 3067 QualType KmpInt32Ty = 3068 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3069 .withConst(); 3070 QualType KmpUInt64Ty = 3071 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3072 .withConst(); 3073 QualType KmpInt64Ty = 3074 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3075 .withConst(); 3076 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3077 QualType KmpInt32PtrTy = 3078 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3079 QualType Args[] = {VoidPtrTy}; 3080 FunctionProtoType::ExtProtoInfo EPI; 3081 EPI.Variadic = true; 3082 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3083 Sema::CapturedParamNameType Params[] = { 3084 std::make_pair(".global_tid.", KmpInt32Ty), 3085 std::make_pair(".part_id.", KmpInt32PtrTy), 3086 std::make_pair(".privates.", VoidPtrTy), 3087 std::make_pair( 3088 ".copy_fn.", 3089 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3090 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3091 std::make_pair(".lb.", KmpUInt64Ty), 3092 std::make_pair(".ub.", KmpUInt64Ty), 3093 std::make_pair(".st.", KmpInt64Ty), 3094 std::make_pair(".liter.", KmpInt32Ty), 3095 std::make_pair(".reductions.", VoidPtrTy), 3096 std::make_pair(StringRef(), QualType()) // __context with shared vars 3097 }; 3098 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3099 Params); 3100 // Mark this captured region as inlined, because we don't use outlined 3101 // function directly. 3102 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3103 AlwaysInlineAttr::CreateImplicit( 3104 Context, AlwaysInlineAttr::Keyword_forceinline)); 3105 break; 3106 } 3107 case OMPD_distribute_parallel_for_simd: 3108 case OMPD_distribute_parallel_for: { 3109 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3110 QualType KmpInt32PtrTy = 3111 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3112 Sema::CapturedParamNameType Params[] = { 3113 std::make_pair(".global_tid.", KmpInt32PtrTy), 3114 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3115 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3116 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3117 std::make_pair(StringRef(), QualType()) // __context with shared vars 3118 }; 3119 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3120 Params); 3121 break; 3122 } 3123 case OMPD_target_teams_distribute_parallel_for: 3124 case OMPD_target_teams_distribute_parallel_for_simd: { 3125 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3126 QualType KmpInt32PtrTy = 3127 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3128 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3129 3130 QualType Args[] = {VoidPtrTy}; 3131 FunctionProtoType::ExtProtoInfo EPI; 3132 EPI.Variadic = true; 3133 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3134 Sema::CapturedParamNameType Params[] = { 3135 std::make_pair(".global_tid.", KmpInt32Ty), 3136 std::make_pair(".part_id.", KmpInt32PtrTy), 3137 std::make_pair(".privates.", VoidPtrTy), 3138 std::make_pair( 3139 ".copy_fn.", 3140 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3141 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3142 std::make_pair(StringRef(), QualType()) // __context with shared vars 3143 }; 3144 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3145 Params); 3146 // Mark this captured region as inlined, because we don't use outlined 3147 // function directly. 3148 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3149 AlwaysInlineAttr::CreateImplicit( 3150 Context, AlwaysInlineAttr::Keyword_forceinline)); 3151 Sema::CapturedParamNameType ParamsTarget[] = { 3152 std::make_pair(StringRef(), QualType()) // __context with shared vars 3153 }; 3154 // Start a captured region for 'target' with no implicit parameters. 3155 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3156 ParamsTarget); 3157 3158 Sema::CapturedParamNameType ParamsTeams[] = { 3159 std::make_pair(".global_tid.", KmpInt32PtrTy), 3160 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3161 std::make_pair(StringRef(), QualType()) // __context with shared vars 3162 }; 3163 // Start a captured region for 'target' with no implicit parameters. 3164 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3165 ParamsTeams); 3166 3167 Sema::CapturedParamNameType ParamsParallel[] = { 3168 std::make_pair(".global_tid.", KmpInt32PtrTy), 3169 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3170 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3171 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3172 std::make_pair(StringRef(), QualType()) // __context with shared vars 3173 }; 3174 // Start a captured region for 'teams' or 'parallel'. Both regions have 3175 // the same implicit parameters. 3176 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3177 ParamsParallel); 3178 break; 3179 } 3180 3181 case OMPD_teams_distribute_parallel_for: 3182 case OMPD_teams_distribute_parallel_for_simd: { 3183 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3184 QualType KmpInt32PtrTy = 3185 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3186 3187 Sema::CapturedParamNameType ParamsTeams[] = { 3188 std::make_pair(".global_tid.", KmpInt32PtrTy), 3189 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3190 std::make_pair(StringRef(), QualType()) // __context with shared vars 3191 }; 3192 // Start a captured region for 'target' with no implicit parameters. 3193 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3194 ParamsTeams); 3195 3196 Sema::CapturedParamNameType ParamsParallel[] = { 3197 std::make_pair(".global_tid.", KmpInt32PtrTy), 3198 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3199 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3200 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3201 std::make_pair(StringRef(), QualType()) // __context with shared vars 3202 }; 3203 // Start a captured region for 'teams' or 'parallel'. Both regions have 3204 // the same implicit parameters. 3205 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3206 ParamsParallel); 3207 break; 3208 } 3209 case OMPD_target_update: 3210 case OMPD_target_enter_data: 3211 case OMPD_target_exit_data: { 3212 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3213 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3214 QualType KmpInt32PtrTy = 3215 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3216 QualType Args[] = {VoidPtrTy}; 3217 FunctionProtoType::ExtProtoInfo EPI; 3218 EPI.Variadic = true; 3219 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3220 Sema::CapturedParamNameType Params[] = { 3221 std::make_pair(".global_tid.", KmpInt32Ty), 3222 std::make_pair(".part_id.", KmpInt32PtrTy), 3223 std::make_pair(".privates.", VoidPtrTy), 3224 std::make_pair( 3225 ".copy_fn.", 3226 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3227 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3228 std::make_pair(StringRef(), QualType()) // __context with shared vars 3229 }; 3230 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3231 Params); 3232 // Mark this captured region as inlined, because we don't use outlined 3233 // function directly. 3234 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3235 AlwaysInlineAttr::CreateImplicit( 3236 Context, AlwaysInlineAttr::Keyword_forceinline)); 3237 break; 3238 } 3239 case OMPD_threadprivate: 3240 case OMPD_allocate: 3241 case OMPD_taskyield: 3242 case OMPD_barrier: 3243 case OMPD_taskwait: 3244 case OMPD_cancellation_point: 3245 case OMPD_cancel: 3246 case OMPD_flush: 3247 case OMPD_declare_reduction: 3248 case OMPD_declare_mapper: 3249 case OMPD_declare_simd: 3250 case OMPD_declare_target: 3251 case OMPD_end_declare_target: 3252 case OMPD_requires: 3253 llvm_unreachable("OpenMP Directive is not allowed"); 3254 case OMPD_unknown: 3255 llvm_unreachable("Unknown OpenMP directive"); 3256 } 3257 } 3258 3259 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3260 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3261 getOpenMPCaptureRegions(CaptureRegions, DKind); 3262 return CaptureRegions.size(); 3263 } 3264 3265 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3266 Expr *CaptureExpr, bool WithInit, 3267 bool AsExpression) { 3268 assert(CaptureExpr); 3269 ASTContext &C = S.getASTContext(); 3270 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3271 QualType Ty = Init->getType(); 3272 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3273 if (S.getLangOpts().CPlusPlus) { 3274 Ty = C.getLValueReferenceType(Ty); 3275 } else { 3276 Ty = C.getPointerType(Ty); 3277 ExprResult Res = 3278 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3279 if (!Res.isUsable()) 3280 return nullptr; 3281 Init = Res.get(); 3282 } 3283 WithInit = true; 3284 } 3285 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3286 CaptureExpr->getBeginLoc()); 3287 if (!WithInit) 3288 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3289 S.CurContext->addHiddenDecl(CED); 3290 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3291 return CED; 3292 } 3293 3294 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3295 bool WithInit) { 3296 OMPCapturedExprDecl *CD; 3297 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3298 CD = cast<OMPCapturedExprDecl>(VD); 3299 else 3300 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3301 /*AsExpression=*/false); 3302 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3303 CaptureExpr->getExprLoc()); 3304 } 3305 3306 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3307 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3308 if (!Ref) { 3309 OMPCapturedExprDecl *CD = buildCaptureDecl( 3310 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3311 /*WithInit=*/true, /*AsExpression=*/true); 3312 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3313 CaptureExpr->getExprLoc()); 3314 } 3315 ExprResult Res = Ref; 3316 if (!S.getLangOpts().CPlusPlus && 3317 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3318 Ref->getType()->isPointerType()) { 3319 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3320 if (!Res.isUsable()) 3321 return ExprError(); 3322 } 3323 return S.DefaultLvalueConversion(Res.get()); 3324 } 3325 3326 namespace { 3327 // OpenMP directives parsed in this section are represented as a 3328 // CapturedStatement with an associated statement. If a syntax error 3329 // is detected during the parsing of the associated statement, the 3330 // compiler must abort processing and close the CapturedStatement. 3331 // 3332 // Combined directives such as 'target parallel' have more than one 3333 // nested CapturedStatements. This RAII ensures that we unwind out 3334 // of all the nested CapturedStatements when an error is found. 3335 class CaptureRegionUnwinderRAII { 3336 private: 3337 Sema &S; 3338 bool &ErrorFound; 3339 OpenMPDirectiveKind DKind = OMPD_unknown; 3340 3341 public: 3342 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3343 OpenMPDirectiveKind DKind) 3344 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3345 ~CaptureRegionUnwinderRAII() { 3346 if (ErrorFound) { 3347 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3348 while (--ThisCaptureLevel >= 0) 3349 S.ActOnCapturedRegionError(); 3350 } 3351 } 3352 }; 3353 } // namespace 3354 3355 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3356 // Capture variables captured by reference in lambdas for target-based 3357 // directives. 3358 if (!CurContext->isDependentContext() && 3359 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3360 isOpenMPTargetDataManagementDirective( 3361 DSAStack->getCurrentDirective()))) { 3362 QualType Type = V->getType(); 3363 if (const auto *RD = Type.getCanonicalType() 3364 .getNonReferenceType() 3365 ->getAsCXXRecordDecl()) { 3366 bool SavedForceCaptureByReferenceInTargetExecutable = 3367 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3368 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3369 /*V=*/true); 3370 if (RD->isLambda()) { 3371 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3372 FieldDecl *ThisCapture; 3373 RD->getCaptureFields(Captures, ThisCapture); 3374 for (const LambdaCapture &LC : RD->captures()) { 3375 if (LC.getCaptureKind() == LCK_ByRef) { 3376 VarDecl *VD = LC.getCapturedVar(); 3377 DeclContext *VDC = VD->getDeclContext(); 3378 if (!VDC->Encloses(CurContext)) 3379 continue; 3380 MarkVariableReferenced(LC.getLocation(), VD); 3381 } else if (LC.getCaptureKind() == LCK_This) { 3382 QualType ThisTy = getCurrentThisType(); 3383 if (!ThisTy.isNull() && 3384 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3385 CheckCXXThisCapture(LC.getLocation()); 3386 } 3387 } 3388 } 3389 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3390 SavedForceCaptureByReferenceInTargetExecutable); 3391 } 3392 } 3393 } 3394 3395 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3396 ArrayRef<OMPClause *> Clauses) { 3397 bool ErrorFound = false; 3398 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3399 *this, ErrorFound, DSAStack->getCurrentDirective()); 3400 if (!S.isUsable()) { 3401 ErrorFound = true; 3402 return StmtError(); 3403 } 3404 3405 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3406 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3407 OMPOrderedClause *OC = nullptr; 3408 OMPScheduleClause *SC = nullptr; 3409 SmallVector<const OMPLinearClause *, 4> LCs; 3410 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3411 // This is required for proper codegen. 3412 for (OMPClause *Clause : Clauses) { 3413 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3414 Clause->getClauseKind() == OMPC_in_reduction) { 3415 // Capture taskgroup task_reduction descriptors inside the tasking regions 3416 // with the corresponding in_reduction items. 3417 auto *IRC = cast<OMPInReductionClause>(Clause); 3418 for (Expr *E : IRC->taskgroup_descriptors()) 3419 if (E) 3420 MarkDeclarationsReferencedInExpr(E); 3421 } 3422 if (isOpenMPPrivate(Clause->getClauseKind()) || 3423 Clause->getClauseKind() == OMPC_copyprivate || 3424 (getLangOpts().OpenMPUseTLS && 3425 getASTContext().getTargetInfo().isTLSSupported() && 3426 Clause->getClauseKind() == OMPC_copyin)) { 3427 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3428 // Mark all variables in private list clauses as used in inner region. 3429 for (Stmt *VarRef : Clause->children()) { 3430 if (auto *E = cast_or_null<Expr>(VarRef)) { 3431 MarkDeclarationsReferencedInExpr(E); 3432 } 3433 } 3434 DSAStack->setForceVarCapturing(/*V=*/false); 3435 } else if (CaptureRegions.size() > 1 || 3436 CaptureRegions.back() != OMPD_unknown) { 3437 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3438 PICs.push_back(C); 3439 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3440 if (Expr *E = C->getPostUpdateExpr()) 3441 MarkDeclarationsReferencedInExpr(E); 3442 } 3443 } 3444 if (Clause->getClauseKind() == OMPC_schedule) 3445 SC = cast<OMPScheduleClause>(Clause); 3446 else if (Clause->getClauseKind() == OMPC_ordered) 3447 OC = cast<OMPOrderedClause>(Clause); 3448 else if (Clause->getClauseKind() == OMPC_linear) 3449 LCs.push_back(cast<OMPLinearClause>(Clause)); 3450 } 3451 // OpenMP, 2.7.1 Loop Construct, Restrictions 3452 // The nonmonotonic modifier cannot be specified if an ordered clause is 3453 // specified. 3454 if (SC && 3455 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3456 SC->getSecondScheduleModifier() == 3457 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3458 OC) { 3459 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3460 ? SC->getFirstScheduleModifierLoc() 3461 : SC->getSecondScheduleModifierLoc(), 3462 diag::err_omp_schedule_nonmonotonic_ordered) 3463 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3464 ErrorFound = true; 3465 } 3466 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3467 for (const OMPLinearClause *C : LCs) { 3468 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3469 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3470 } 3471 ErrorFound = true; 3472 } 3473 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3474 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3475 OC->getNumForLoops()) { 3476 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3477 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3478 ErrorFound = true; 3479 } 3480 if (ErrorFound) { 3481 return StmtError(); 3482 } 3483 StmtResult SR = S; 3484 unsigned CompletedRegions = 0; 3485 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3486 // Mark all variables in private list clauses as used in inner region. 3487 // Required for proper codegen of combined directives. 3488 // TODO: add processing for other clauses. 3489 if (ThisCaptureRegion != OMPD_unknown) { 3490 for (const clang::OMPClauseWithPreInit *C : PICs) { 3491 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3492 // Find the particular capture region for the clause if the 3493 // directive is a combined one with multiple capture regions. 3494 // If the directive is not a combined one, the capture region 3495 // associated with the clause is OMPD_unknown and is generated 3496 // only once. 3497 if (CaptureRegion == ThisCaptureRegion || 3498 CaptureRegion == OMPD_unknown) { 3499 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3500 for (Decl *D : DS->decls()) 3501 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3502 } 3503 } 3504 } 3505 } 3506 if (++CompletedRegions == CaptureRegions.size()) 3507 DSAStack->setBodyComplete(); 3508 SR = ActOnCapturedRegionEnd(SR.get()); 3509 } 3510 return SR; 3511 } 3512 3513 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3514 OpenMPDirectiveKind CancelRegion, 3515 SourceLocation StartLoc) { 3516 // CancelRegion is only needed for cancel and cancellation_point. 3517 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3518 return false; 3519 3520 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3521 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3522 return false; 3523 3524 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3525 << getOpenMPDirectiveName(CancelRegion); 3526 return true; 3527 } 3528 3529 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3530 OpenMPDirectiveKind CurrentRegion, 3531 const DeclarationNameInfo &CurrentName, 3532 OpenMPDirectiveKind CancelRegion, 3533 SourceLocation StartLoc) { 3534 if (Stack->getCurScope()) { 3535 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3536 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3537 bool NestingProhibited = false; 3538 bool CloseNesting = true; 3539 bool OrphanSeen = false; 3540 enum { 3541 NoRecommend, 3542 ShouldBeInParallelRegion, 3543 ShouldBeInOrderedRegion, 3544 ShouldBeInTargetRegion, 3545 ShouldBeInTeamsRegion 3546 } Recommend = NoRecommend; 3547 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3548 // OpenMP [2.16, Nesting of Regions] 3549 // OpenMP constructs may not be nested inside a simd region. 3550 // OpenMP [2.8.1,simd Construct, Restrictions] 3551 // An ordered construct with the simd clause is the only OpenMP 3552 // construct that can appear in the simd region. 3553 // Allowing a SIMD construct nested in another SIMD construct is an 3554 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3555 // message. 3556 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3557 ? diag::err_omp_prohibited_region_simd 3558 : diag::warn_omp_nesting_simd); 3559 return CurrentRegion != OMPD_simd; 3560 } 3561 if (ParentRegion == OMPD_atomic) { 3562 // OpenMP [2.16, Nesting of Regions] 3563 // OpenMP constructs may not be nested inside an atomic region. 3564 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3565 return true; 3566 } 3567 if (CurrentRegion == OMPD_section) { 3568 // OpenMP [2.7.2, sections Construct, Restrictions] 3569 // Orphaned section directives are prohibited. That is, the section 3570 // directives must appear within the sections construct and must not be 3571 // encountered elsewhere in the sections region. 3572 if (ParentRegion != OMPD_sections && 3573 ParentRegion != OMPD_parallel_sections) { 3574 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3575 << (ParentRegion != OMPD_unknown) 3576 << getOpenMPDirectiveName(ParentRegion); 3577 return true; 3578 } 3579 return false; 3580 } 3581 // Allow some constructs (except teams and cancellation constructs) to be 3582 // orphaned (they could be used in functions, called from OpenMP regions 3583 // with the required preconditions). 3584 if (ParentRegion == OMPD_unknown && 3585 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3586 CurrentRegion != OMPD_cancellation_point && 3587 CurrentRegion != OMPD_cancel) 3588 return false; 3589 if (CurrentRegion == OMPD_cancellation_point || 3590 CurrentRegion == OMPD_cancel) { 3591 // OpenMP [2.16, Nesting of Regions] 3592 // A cancellation point construct for which construct-type-clause is 3593 // taskgroup must be nested inside a task construct. A cancellation 3594 // point construct for which construct-type-clause is not taskgroup must 3595 // be closely nested inside an OpenMP construct that matches the type 3596 // specified in construct-type-clause. 3597 // A cancel construct for which construct-type-clause is taskgroup must be 3598 // nested inside a task construct. A cancel construct for which 3599 // construct-type-clause is not taskgroup must be closely nested inside an 3600 // OpenMP construct that matches the type specified in 3601 // construct-type-clause. 3602 NestingProhibited = 3603 !((CancelRegion == OMPD_parallel && 3604 (ParentRegion == OMPD_parallel || 3605 ParentRegion == OMPD_target_parallel)) || 3606 (CancelRegion == OMPD_for && 3607 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3608 ParentRegion == OMPD_target_parallel_for || 3609 ParentRegion == OMPD_distribute_parallel_for || 3610 ParentRegion == OMPD_teams_distribute_parallel_for || 3611 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3612 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3613 (CancelRegion == OMPD_sections && 3614 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3615 ParentRegion == OMPD_parallel_sections))); 3616 OrphanSeen = ParentRegion == OMPD_unknown; 3617 } else if (CurrentRegion == OMPD_master) { 3618 // OpenMP [2.16, Nesting of Regions] 3619 // A master region may not be closely nested inside a worksharing, 3620 // atomic, or explicit task region. 3621 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3622 isOpenMPTaskingDirective(ParentRegion); 3623 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3624 // OpenMP [2.16, Nesting of Regions] 3625 // A critical region may not be nested (closely or otherwise) inside a 3626 // critical region with the same name. Note that this restriction is not 3627 // sufficient to prevent deadlock. 3628 SourceLocation PreviousCriticalLoc; 3629 bool DeadLock = Stack->hasDirective( 3630 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3631 const DeclarationNameInfo &DNI, 3632 SourceLocation Loc) { 3633 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3634 PreviousCriticalLoc = Loc; 3635 return true; 3636 } 3637 return false; 3638 }, 3639 false /* skip top directive */); 3640 if (DeadLock) { 3641 SemaRef.Diag(StartLoc, 3642 diag::err_omp_prohibited_region_critical_same_name) 3643 << CurrentName.getName(); 3644 if (PreviousCriticalLoc.isValid()) 3645 SemaRef.Diag(PreviousCriticalLoc, 3646 diag::note_omp_previous_critical_region); 3647 return true; 3648 } 3649 } else if (CurrentRegion == OMPD_barrier) { 3650 // OpenMP [2.16, Nesting of Regions] 3651 // A barrier region may not be closely nested inside a worksharing, 3652 // explicit task, critical, ordered, atomic, or master region. 3653 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3654 isOpenMPTaskingDirective(ParentRegion) || 3655 ParentRegion == OMPD_master || 3656 ParentRegion == OMPD_critical || 3657 ParentRegion == OMPD_ordered; 3658 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3659 !isOpenMPParallelDirective(CurrentRegion) && 3660 !isOpenMPTeamsDirective(CurrentRegion)) { 3661 // OpenMP [2.16, Nesting of Regions] 3662 // A worksharing region may not be closely nested inside a worksharing, 3663 // explicit task, critical, ordered, atomic, or master region. 3664 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3665 isOpenMPTaskingDirective(ParentRegion) || 3666 ParentRegion == OMPD_master || 3667 ParentRegion == OMPD_critical || 3668 ParentRegion == OMPD_ordered; 3669 Recommend = ShouldBeInParallelRegion; 3670 } else if (CurrentRegion == OMPD_ordered) { 3671 // OpenMP [2.16, Nesting of Regions] 3672 // An ordered region may not be closely nested inside a critical, 3673 // atomic, or explicit task region. 3674 // An ordered region must be closely nested inside a loop region (or 3675 // parallel loop region) with an ordered clause. 3676 // OpenMP [2.8.1,simd Construct, Restrictions] 3677 // An ordered construct with the simd clause is the only OpenMP construct 3678 // that can appear in the simd region. 3679 NestingProhibited = ParentRegion == OMPD_critical || 3680 isOpenMPTaskingDirective(ParentRegion) || 3681 !(isOpenMPSimdDirective(ParentRegion) || 3682 Stack->isParentOrderedRegion()); 3683 Recommend = ShouldBeInOrderedRegion; 3684 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3685 // OpenMP [2.16, Nesting of Regions] 3686 // If specified, a teams construct must be contained within a target 3687 // construct. 3688 NestingProhibited = ParentRegion != OMPD_target; 3689 OrphanSeen = ParentRegion == OMPD_unknown; 3690 Recommend = ShouldBeInTargetRegion; 3691 } 3692 if (!NestingProhibited && 3693 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3694 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3695 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3696 // OpenMP [2.16, Nesting of Regions] 3697 // distribute, parallel, parallel sections, parallel workshare, and the 3698 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3699 // constructs that can be closely nested in the teams region. 3700 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3701 !isOpenMPDistributeDirective(CurrentRegion); 3702 Recommend = ShouldBeInParallelRegion; 3703 } 3704 if (!NestingProhibited && 3705 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3706 // OpenMP 4.5 [2.17 Nesting of Regions] 3707 // The region associated with the distribute construct must be strictly 3708 // nested inside a teams region 3709 NestingProhibited = 3710 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3711 Recommend = ShouldBeInTeamsRegion; 3712 } 3713 if (!NestingProhibited && 3714 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3715 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3716 // OpenMP 4.5 [2.17 Nesting of Regions] 3717 // If a target, target update, target data, target enter data, or 3718 // target exit data construct is encountered during execution of a 3719 // target region, the behavior is unspecified. 3720 NestingProhibited = Stack->hasDirective( 3721 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3722 SourceLocation) { 3723 if (isOpenMPTargetExecutionDirective(K)) { 3724 OffendingRegion = K; 3725 return true; 3726 } 3727 return false; 3728 }, 3729 false /* don't skip top directive */); 3730 CloseNesting = false; 3731 } 3732 if (NestingProhibited) { 3733 if (OrphanSeen) { 3734 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3735 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3736 } else { 3737 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3738 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3739 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3740 } 3741 return true; 3742 } 3743 } 3744 return false; 3745 } 3746 3747 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3748 ArrayRef<OMPClause *> Clauses, 3749 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3750 bool ErrorFound = false; 3751 unsigned NamedModifiersNumber = 0; 3752 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3753 OMPD_unknown + 1); 3754 SmallVector<SourceLocation, 4> NameModifierLoc; 3755 for (const OMPClause *C : Clauses) { 3756 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3757 // At most one if clause without a directive-name-modifier can appear on 3758 // the directive. 3759 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3760 if (FoundNameModifiers[CurNM]) { 3761 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3762 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3763 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3764 ErrorFound = true; 3765 } else if (CurNM != OMPD_unknown) { 3766 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3767 ++NamedModifiersNumber; 3768 } 3769 FoundNameModifiers[CurNM] = IC; 3770 if (CurNM == OMPD_unknown) 3771 continue; 3772 // Check if the specified name modifier is allowed for the current 3773 // directive. 3774 // At most one if clause with the particular directive-name-modifier can 3775 // appear on the directive. 3776 bool MatchFound = false; 3777 for (auto NM : AllowedNameModifiers) { 3778 if (CurNM == NM) { 3779 MatchFound = true; 3780 break; 3781 } 3782 } 3783 if (!MatchFound) { 3784 S.Diag(IC->getNameModifierLoc(), 3785 diag::err_omp_wrong_if_directive_name_modifier) 3786 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3787 ErrorFound = true; 3788 } 3789 } 3790 } 3791 // If any if clause on the directive includes a directive-name-modifier then 3792 // all if clauses on the directive must include a directive-name-modifier. 3793 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3794 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3795 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3796 diag::err_omp_no_more_if_clause); 3797 } else { 3798 std::string Values; 3799 std::string Sep(", "); 3800 unsigned AllowedCnt = 0; 3801 unsigned TotalAllowedNum = 3802 AllowedNameModifiers.size() - NamedModifiersNumber; 3803 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3804 ++Cnt) { 3805 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3806 if (!FoundNameModifiers[NM]) { 3807 Values += "'"; 3808 Values += getOpenMPDirectiveName(NM); 3809 Values += "'"; 3810 if (AllowedCnt + 2 == TotalAllowedNum) 3811 Values += " or "; 3812 else if (AllowedCnt + 1 != TotalAllowedNum) 3813 Values += Sep; 3814 ++AllowedCnt; 3815 } 3816 } 3817 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3818 diag::err_omp_unnamed_if_clause) 3819 << (TotalAllowedNum > 1) << Values; 3820 } 3821 for (SourceLocation Loc : NameModifierLoc) { 3822 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3823 } 3824 ErrorFound = true; 3825 } 3826 return ErrorFound; 3827 } 3828 3829 static std::pair<ValueDecl *, bool> 3830 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 3831 SourceRange &ERange, bool AllowArraySection = false) { 3832 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 3833 RefExpr->containsUnexpandedParameterPack()) 3834 return std::make_pair(nullptr, true); 3835 3836 // OpenMP [3.1, C/C++] 3837 // A list item is a variable name. 3838 // OpenMP [2.9.3.3, Restrictions, p.1] 3839 // A variable that is part of another variable (as an array or 3840 // structure element) cannot appear in a private clause. 3841 RefExpr = RefExpr->IgnoreParens(); 3842 enum { 3843 NoArrayExpr = -1, 3844 ArraySubscript = 0, 3845 OMPArraySection = 1 3846 } IsArrayExpr = NoArrayExpr; 3847 if (AllowArraySection) { 3848 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 3849 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 3850 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3851 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3852 RefExpr = Base; 3853 IsArrayExpr = ArraySubscript; 3854 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 3855 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 3856 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 3857 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 3858 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3859 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3860 RefExpr = Base; 3861 IsArrayExpr = OMPArraySection; 3862 } 3863 } 3864 ELoc = RefExpr->getExprLoc(); 3865 ERange = RefExpr->getSourceRange(); 3866 RefExpr = RefExpr->IgnoreParenImpCasts(); 3867 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 3868 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 3869 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 3870 (S.getCurrentThisType().isNull() || !ME || 3871 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 3872 !isa<FieldDecl>(ME->getMemberDecl()))) { 3873 if (IsArrayExpr != NoArrayExpr) { 3874 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 3875 << ERange; 3876 } else { 3877 S.Diag(ELoc, 3878 AllowArraySection 3879 ? diag::err_omp_expected_var_name_member_expr_or_array_item 3880 : diag::err_omp_expected_var_name_member_expr) 3881 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 3882 } 3883 return std::make_pair(nullptr, false); 3884 } 3885 return std::make_pair( 3886 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 3887 } 3888 3889 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 3890 ArrayRef<OMPClause *> Clauses) { 3891 assert(!S.CurContext->isDependentContext() && 3892 "Expected non-dependent context."); 3893 auto AllocateRange = 3894 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 3895 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 3896 DeclToCopy; 3897 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 3898 return isOpenMPPrivate(C->getClauseKind()); 3899 }); 3900 for (OMPClause *Cl : PrivateRange) { 3901 MutableArrayRef<Expr *>::iterator I, It, Et; 3902 if (Cl->getClauseKind() == OMPC_private) { 3903 auto *PC = cast<OMPPrivateClause>(Cl); 3904 I = PC->private_copies().begin(); 3905 It = PC->varlist_begin(); 3906 Et = PC->varlist_end(); 3907 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 3908 auto *PC = cast<OMPFirstprivateClause>(Cl); 3909 I = PC->private_copies().begin(); 3910 It = PC->varlist_begin(); 3911 Et = PC->varlist_end(); 3912 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 3913 auto *PC = cast<OMPLastprivateClause>(Cl); 3914 I = PC->private_copies().begin(); 3915 It = PC->varlist_begin(); 3916 Et = PC->varlist_end(); 3917 } else if (Cl->getClauseKind() == OMPC_linear) { 3918 auto *PC = cast<OMPLinearClause>(Cl); 3919 I = PC->privates().begin(); 3920 It = PC->varlist_begin(); 3921 Et = PC->varlist_end(); 3922 } else if (Cl->getClauseKind() == OMPC_reduction) { 3923 auto *PC = cast<OMPReductionClause>(Cl); 3924 I = PC->privates().begin(); 3925 It = PC->varlist_begin(); 3926 Et = PC->varlist_end(); 3927 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 3928 auto *PC = cast<OMPTaskReductionClause>(Cl); 3929 I = PC->privates().begin(); 3930 It = PC->varlist_begin(); 3931 Et = PC->varlist_end(); 3932 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 3933 auto *PC = cast<OMPInReductionClause>(Cl); 3934 I = PC->privates().begin(); 3935 It = PC->varlist_begin(); 3936 Et = PC->varlist_end(); 3937 } else { 3938 llvm_unreachable("Expected private clause."); 3939 } 3940 for (Expr *E : llvm::make_range(It, Et)) { 3941 if (!*I) { 3942 ++I; 3943 continue; 3944 } 3945 SourceLocation ELoc; 3946 SourceRange ERange; 3947 Expr *SimpleRefExpr = E; 3948 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 3949 /*AllowArraySection=*/true); 3950 DeclToCopy.try_emplace(Res.first, 3951 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 3952 ++I; 3953 } 3954 } 3955 for (OMPClause *C : AllocateRange) { 3956 auto *AC = cast<OMPAllocateClause>(C); 3957 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3958 getAllocatorKind(S, Stack, AC->getAllocator()); 3959 // OpenMP, 2.11.4 allocate Clause, Restrictions. 3960 // For task, taskloop or target directives, allocation requests to memory 3961 // allocators with the trait access set to thread result in unspecified 3962 // behavior. 3963 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 3964 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 3965 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 3966 S.Diag(AC->getAllocator()->getExprLoc(), 3967 diag::warn_omp_allocate_thread_on_task_target_directive) 3968 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3969 } 3970 for (Expr *E : AC->varlists()) { 3971 SourceLocation ELoc; 3972 SourceRange ERange; 3973 Expr *SimpleRefExpr = E; 3974 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 3975 ValueDecl *VD = Res.first; 3976 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 3977 if (!isOpenMPPrivate(Data.CKind)) { 3978 S.Diag(E->getExprLoc(), 3979 diag::err_omp_expected_private_copy_for_allocate); 3980 continue; 3981 } 3982 VarDecl *PrivateVD = DeclToCopy[VD]; 3983 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 3984 AllocatorKind, AC->getAllocator())) 3985 continue; 3986 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 3987 E->getSourceRange()); 3988 } 3989 } 3990 } 3991 3992 StmtResult Sema::ActOnOpenMPExecutableDirective( 3993 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3994 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3995 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3996 StmtResult Res = StmtError(); 3997 // First check CancelRegion which is then used in checkNestingOfRegions. 3998 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3999 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4000 StartLoc)) 4001 return StmtError(); 4002 4003 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4004 VarsWithInheritedDSAType VarsWithInheritedDSA; 4005 bool ErrorFound = false; 4006 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4007 if (AStmt && !CurContext->isDependentContext()) { 4008 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4009 4010 // Check default data sharing attributes for referenced variables. 4011 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4012 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4013 Stmt *S = AStmt; 4014 while (--ThisCaptureLevel >= 0) 4015 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4016 DSAChecker.Visit(S); 4017 if (!isOpenMPTargetDataManagementDirective(Kind) && 4018 !isOpenMPTaskingDirective(Kind)) { 4019 // Visit subcaptures to generate implicit clauses for captured vars. 4020 auto *CS = cast<CapturedStmt>(AStmt); 4021 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4022 getOpenMPCaptureRegions(CaptureRegions, Kind); 4023 // Ignore outer tasking regions for target directives. 4024 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4025 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4026 DSAChecker.visitSubCaptures(CS); 4027 } 4028 if (DSAChecker.isErrorFound()) 4029 return StmtError(); 4030 // Generate list of implicitly defined firstprivate variables. 4031 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4032 4033 SmallVector<Expr *, 4> ImplicitFirstprivates( 4034 DSAChecker.getImplicitFirstprivate().begin(), 4035 DSAChecker.getImplicitFirstprivate().end()); 4036 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4037 DSAChecker.getImplicitMap().end()); 4038 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4039 for (OMPClause *C : Clauses) { 4040 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4041 for (Expr *E : IRC->taskgroup_descriptors()) 4042 if (E) 4043 ImplicitFirstprivates.emplace_back(E); 4044 } 4045 } 4046 if (!ImplicitFirstprivates.empty()) { 4047 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4048 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4049 SourceLocation())) { 4050 ClausesWithImplicit.push_back(Implicit); 4051 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4052 ImplicitFirstprivates.size(); 4053 } else { 4054 ErrorFound = true; 4055 } 4056 } 4057 if (!ImplicitMaps.empty()) { 4058 CXXScopeSpec MapperIdScopeSpec; 4059 DeclarationNameInfo MapperId; 4060 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4061 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4062 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4063 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4064 ClausesWithImplicit.emplace_back(Implicit); 4065 ErrorFound |= 4066 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4067 } else { 4068 ErrorFound = true; 4069 } 4070 } 4071 } 4072 4073 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4074 switch (Kind) { 4075 case OMPD_parallel: 4076 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4077 EndLoc); 4078 AllowedNameModifiers.push_back(OMPD_parallel); 4079 break; 4080 case OMPD_simd: 4081 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4082 VarsWithInheritedDSA); 4083 break; 4084 case OMPD_for: 4085 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4086 VarsWithInheritedDSA); 4087 break; 4088 case OMPD_for_simd: 4089 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4090 EndLoc, VarsWithInheritedDSA); 4091 break; 4092 case OMPD_sections: 4093 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4094 EndLoc); 4095 break; 4096 case OMPD_section: 4097 assert(ClausesWithImplicit.empty() && 4098 "No clauses are allowed for 'omp section' directive"); 4099 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4100 break; 4101 case OMPD_single: 4102 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4103 EndLoc); 4104 break; 4105 case OMPD_master: 4106 assert(ClausesWithImplicit.empty() && 4107 "No clauses are allowed for 'omp master' directive"); 4108 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4109 break; 4110 case OMPD_critical: 4111 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4112 StartLoc, EndLoc); 4113 break; 4114 case OMPD_parallel_for: 4115 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4116 EndLoc, VarsWithInheritedDSA); 4117 AllowedNameModifiers.push_back(OMPD_parallel); 4118 break; 4119 case OMPD_parallel_for_simd: 4120 Res = ActOnOpenMPParallelForSimdDirective( 4121 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4122 AllowedNameModifiers.push_back(OMPD_parallel); 4123 break; 4124 case OMPD_parallel_sections: 4125 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4126 StartLoc, EndLoc); 4127 AllowedNameModifiers.push_back(OMPD_parallel); 4128 break; 4129 case OMPD_task: 4130 Res = 4131 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4132 AllowedNameModifiers.push_back(OMPD_task); 4133 break; 4134 case OMPD_taskyield: 4135 assert(ClausesWithImplicit.empty() && 4136 "No clauses are allowed for 'omp taskyield' directive"); 4137 assert(AStmt == nullptr && 4138 "No associated statement allowed for 'omp taskyield' directive"); 4139 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4140 break; 4141 case OMPD_barrier: 4142 assert(ClausesWithImplicit.empty() && 4143 "No clauses are allowed for 'omp barrier' directive"); 4144 assert(AStmt == nullptr && 4145 "No associated statement allowed for 'omp barrier' directive"); 4146 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4147 break; 4148 case OMPD_taskwait: 4149 assert(ClausesWithImplicit.empty() && 4150 "No clauses are allowed for 'omp taskwait' directive"); 4151 assert(AStmt == nullptr && 4152 "No associated statement allowed for 'omp taskwait' directive"); 4153 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4154 break; 4155 case OMPD_taskgroup: 4156 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4157 EndLoc); 4158 break; 4159 case OMPD_flush: 4160 assert(AStmt == nullptr && 4161 "No associated statement allowed for 'omp flush' directive"); 4162 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4163 break; 4164 case OMPD_ordered: 4165 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4166 EndLoc); 4167 break; 4168 case OMPD_atomic: 4169 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4170 EndLoc); 4171 break; 4172 case OMPD_teams: 4173 Res = 4174 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4175 break; 4176 case OMPD_target: 4177 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4178 EndLoc); 4179 AllowedNameModifiers.push_back(OMPD_target); 4180 break; 4181 case OMPD_target_parallel: 4182 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4183 StartLoc, EndLoc); 4184 AllowedNameModifiers.push_back(OMPD_target); 4185 AllowedNameModifiers.push_back(OMPD_parallel); 4186 break; 4187 case OMPD_target_parallel_for: 4188 Res = ActOnOpenMPTargetParallelForDirective( 4189 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4190 AllowedNameModifiers.push_back(OMPD_target); 4191 AllowedNameModifiers.push_back(OMPD_parallel); 4192 break; 4193 case OMPD_cancellation_point: 4194 assert(ClausesWithImplicit.empty() && 4195 "No clauses are allowed for 'omp cancellation point' directive"); 4196 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4197 "cancellation point' directive"); 4198 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4199 break; 4200 case OMPD_cancel: 4201 assert(AStmt == nullptr && 4202 "No associated statement allowed for 'omp cancel' directive"); 4203 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4204 CancelRegion); 4205 AllowedNameModifiers.push_back(OMPD_cancel); 4206 break; 4207 case OMPD_target_data: 4208 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4209 EndLoc); 4210 AllowedNameModifiers.push_back(OMPD_target_data); 4211 break; 4212 case OMPD_target_enter_data: 4213 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4214 EndLoc, AStmt); 4215 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4216 break; 4217 case OMPD_target_exit_data: 4218 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4219 EndLoc, AStmt); 4220 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4221 break; 4222 case OMPD_taskloop: 4223 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4224 EndLoc, VarsWithInheritedDSA); 4225 AllowedNameModifiers.push_back(OMPD_taskloop); 4226 break; 4227 case OMPD_taskloop_simd: 4228 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4229 EndLoc, VarsWithInheritedDSA); 4230 AllowedNameModifiers.push_back(OMPD_taskloop); 4231 break; 4232 case OMPD_distribute: 4233 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4234 EndLoc, VarsWithInheritedDSA); 4235 break; 4236 case OMPD_target_update: 4237 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4238 EndLoc, AStmt); 4239 AllowedNameModifiers.push_back(OMPD_target_update); 4240 break; 4241 case OMPD_distribute_parallel_for: 4242 Res = ActOnOpenMPDistributeParallelForDirective( 4243 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4244 AllowedNameModifiers.push_back(OMPD_parallel); 4245 break; 4246 case OMPD_distribute_parallel_for_simd: 4247 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4248 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4249 AllowedNameModifiers.push_back(OMPD_parallel); 4250 break; 4251 case OMPD_distribute_simd: 4252 Res = ActOnOpenMPDistributeSimdDirective( 4253 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4254 break; 4255 case OMPD_target_parallel_for_simd: 4256 Res = ActOnOpenMPTargetParallelForSimdDirective( 4257 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4258 AllowedNameModifiers.push_back(OMPD_target); 4259 AllowedNameModifiers.push_back(OMPD_parallel); 4260 break; 4261 case OMPD_target_simd: 4262 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4263 EndLoc, VarsWithInheritedDSA); 4264 AllowedNameModifiers.push_back(OMPD_target); 4265 break; 4266 case OMPD_teams_distribute: 4267 Res = ActOnOpenMPTeamsDistributeDirective( 4268 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4269 break; 4270 case OMPD_teams_distribute_simd: 4271 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4272 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4273 break; 4274 case OMPD_teams_distribute_parallel_for_simd: 4275 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4276 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4277 AllowedNameModifiers.push_back(OMPD_parallel); 4278 break; 4279 case OMPD_teams_distribute_parallel_for: 4280 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4281 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4282 AllowedNameModifiers.push_back(OMPD_parallel); 4283 break; 4284 case OMPD_target_teams: 4285 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4286 EndLoc); 4287 AllowedNameModifiers.push_back(OMPD_target); 4288 break; 4289 case OMPD_target_teams_distribute: 4290 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4291 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4292 AllowedNameModifiers.push_back(OMPD_target); 4293 break; 4294 case OMPD_target_teams_distribute_parallel_for: 4295 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4296 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4297 AllowedNameModifiers.push_back(OMPD_target); 4298 AllowedNameModifiers.push_back(OMPD_parallel); 4299 break; 4300 case OMPD_target_teams_distribute_parallel_for_simd: 4301 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4302 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4303 AllowedNameModifiers.push_back(OMPD_target); 4304 AllowedNameModifiers.push_back(OMPD_parallel); 4305 break; 4306 case OMPD_target_teams_distribute_simd: 4307 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4308 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4309 AllowedNameModifiers.push_back(OMPD_target); 4310 break; 4311 case OMPD_declare_target: 4312 case OMPD_end_declare_target: 4313 case OMPD_threadprivate: 4314 case OMPD_allocate: 4315 case OMPD_declare_reduction: 4316 case OMPD_declare_mapper: 4317 case OMPD_declare_simd: 4318 case OMPD_requires: 4319 llvm_unreachable("OpenMP Directive is not allowed"); 4320 case OMPD_unknown: 4321 llvm_unreachable("Unknown OpenMP directive"); 4322 } 4323 4324 ErrorFound = Res.isInvalid() || ErrorFound; 4325 4326 // Check variables in the clauses if default(none) was specified. 4327 if (DSAStack->getDefaultDSA() == DSA_none) { 4328 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4329 for (OMPClause *C : Clauses) { 4330 switch (C->getClauseKind()) { 4331 case OMPC_num_threads: 4332 case OMPC_dist_schedule: 4333 // Do not analyse if no parent teams directive. 4334 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4335 break; 4336 continue; 4337 case OMPC_if: 4338 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4339 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4340 break; 4341 continue; 4342 case OMPC_schedule: 4343 break; 4344 case OMPC_ordered: 4345 case OMPC_device: 4346 case OMPC_num_teams: 4347 case OMPC_thread_limit: 4348 case OMPC_priority: 4349 case OMPC_grainsize: 4350 case OMPC_num_tasks: 4351 case OMPC_hint: 4352 case OMPC_collapse: 4353 case OMPC_safelen: 4354 case OMPC_simdlen: 4355 case OMPC_final: 4356 case OMPC_default: 4357 case OMPC_proc_bind: 4358 case OMPC_private: 4359 case OMPC_firstprivate: 4360 case OMPC_lastprivate: 4361 case OMPC_shared: 4362 case OMPC_reduction: 4363 case OMPC_task_reduction: 4364 case OMPC_in_reduction: 4365 case OMPC_linear: 4366 case OMPC_aligned: 4367 case OMPC_copyin: 4368 case OMPC_copyprivate: 4369 case OMPC_nowait: 4370 case OMPC_untied: 4371 case OMPC_mergeable: 4372 case OMPC_allocate: 4373 case OMPC_read: 4374 case OMPC_write: 4375 case OMPC_update: 4376 case OMPC_capture: 4377 case OMPC_seq_cst: 4378 case OMPC_depend: 4379 case OMPC_threads: 4380 case OMPC_simd: 4381 case OMPC_map: 4382 case OMPC_nogroup: 4383 case OMPC_defaultmap: 4384 case OMPC_to: 4385 case OMPC_from: 4386 case OMPC_use_device_ptr: 4387 case OMPC_is_device_ptr: 4388 continue; 4389 case OMPC_allocator: 4390 case OMPC_flush: 4391 case OMPC_threadprivate: 4392 case OMPC_uniform: 4393 case OMPC_unknown: 4394 case OMPC_unified_address: 4395 case OMPC_unified_shared_memory: 4396 case OMPC_reverse_offload: 4397 case OMPC_dynamic_allocators: 4398 case OMPC_atomic_default_mem_order: 4399 llvm_unreachable("Unexpected clause"); 4400 } 4401 for (Stmt *CC : C->children()) { 4402 if (CC) 4403 DSAChecker.Visit(CC); 4404 } 4405 } 4406 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4407 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4408 } 4409 for (const auto &P : VarsWithInheritedDSA) { 4410 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4411 continue; 4412 ErrorFound = true; 4413 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4414 << P.first << P.second->getSourceRange(); 4415 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4416 } 4417 4418 if (!AllowedNameModifiers.empty()) 4419 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4420 ErrorFound; 4421 4422 if (ErrorFound) 4423 return StmtError(); 4424 4425 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4426 Res.getAs<OMPExecutableDirective>() 4427 ->getStructuredBlock() 4428 ->setIsOMPStructuredBlock(true); 4429 } 4430 4431 if (!CurContext->isDependentContext() && 4432 isOpenMPTargetExecutionDirective(Kind) && 4433 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4434 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4435 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4436 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4437 // Register target to DSA Stack. 4438 DSAStack->addTargetDirLocation(StartLoc); 4439 } 4440 4441 return Res; 4442 } 4443 4444 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4445 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4446 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4447 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4448 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4449 assert(Aligneds.size() == Alignments.size()); 4450 assert(Linears.size() == LinModifiers.size()); 4451 assert(Linears.size() == Steps.size()); 4452 if (!DG || DG.get().isNull()) 4453 return DeclGroupPtrTy(); 4454 4455 if (!DG.get().isSingleDecl()) { 4456 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4457 return DG; 4458 } 4459 Decl *ADecl = DG.get().getSingleDecl(); 4460 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4461 ADecl = FTD->getTemplatedDecl(); 4462 4463 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4464 if (!FD) { 4465 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4466 return DeclGroupPtrTy(); 4467 } 4468 4469 // OpenMP [2.8.2, declare simd construct, Description] 4470 // The parameter of the simdlen clause must be a constant positive integer 4471 // expression. 4472 ExprResult SL; 4473 if (Simdlen) 4474 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4475 // OpenMP [2.8.2, declare simd construct, Description] 4476 // The special this pointer can be used as if was one of the arguments to the 4477 // function in any of the linear, aligned, or uniform clauses. 4478 // The uniform clause declares one or more arguments to have an invariant 4479 // value for all concurrent invocations of the function in the execution of a 4480 // single SIMD loop. 4481 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4482 const Expr *UniformedLinearThis = nullptr; 4483 for (const Expr *E : Uniforms) { 4484 E = E->IgnoreParenImpCasts(); 4485 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4486 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4487 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4488 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4489 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4490 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4491 continue; 4492 } 4493 if (isa<CXXThisExpr>(E)) { 4494 UniformedLinearThis = E; 4495 continue; 4496 } 4497 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4498 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4499 } 4500 // OpenMP [2.8.2, declare simd construct, Description] 4501 // The aligned clause declares that the object to which each list item points 4502 // is aligned to the number of bytes expressed in the optional parameter of 4503 // the aligned clause. 4504 // The special this pointer can be used as if was one of the arguments to the 4505 // function in any of the linear, aligned, or uniform clauses. 4506 // The type of list items appearing in the aligned clause must be array, 4507 // pointer, reference to array, or reference to pointer. 4508 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4509 const Expr *AlignedThis = nullptr; 4510 for (const Expr *E : Aligneds) { 4511 E = E->IgnoreParenImpCasts(); 4512 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4513 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4514 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4515 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4516 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4517 ->getCanonicalDecl() == CanonPVD) { 4518 // OpenMP [2.8.1, simd construct, Restrictions] 4519 // A list-item cannot appear in more than one aligned clause. 4520 if (AlignedArgs.count(CanonPVD) > 0) { 4521 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4522 << 1 << E->getSourceRange(); 4523 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4524 diag::note_omp_explicit_dsa) 4525 << getOpenMPClauseName(OMPC_aligned); 4526 continue; 4527 } 4528 AlignedArgs[CanonPVD] = E; 4529 QualType QTy = PVD->getType() 4530 .getNonReferenceType() 4531 .getUnqualifiedType() 4532 .getCanonicalType(); 4533 const Type *Ty = QTy.getTypePtrOrNull(); 4534 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4535 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4536 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4537 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4538 } 4539 continue; 4540 } 4541 } 4542 if (isa<CXXThisExpr>(E)) { 4543 if (AlignedThis) { 4544 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4545 << 2 << E->getSourceRange(); 4546 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4547 << getOpenMPClauseName(OMPC_aligned); 4548 } 4549 AlignedThis = E; 4550 continue; 4551 } 4552 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4553 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4554 } 4555 // The optional parameter of the aligned clause, alignment, must be a constant 4556 // positive integer expression. If no optional parameter is specified, 4557 // implementation-defined default alignments for SIMD instructions on the 4558 // target platforms are assumed. 4559 SmallVector<const Expr *, 4> NewAligns; 4560 for (Expr *E : Alignments) { 4561 ExprResult Align; 4562 if (E) 4563 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4564 NewAligns.push_back(Align.get()); 4565 } 4566 // OpenMP [2.8.2, declare simd construct, Description] 4567 // The linear clause declares one or more list items to be private to a SIMD 4568 // lane and to have a linear relationship with respect to the iteration space 4569 // of a loop. 4570 // The special this pointer can be used as if was one of the arguments to the 4571 // function in any of the linear, aligned, or uniform clauses. 4572 // When a linear-step expression is specified in a linear clause it must be 4573 // either a constant integer expression or an integer-typed parameter that is 4574 // specified in a uniform clause on the directive. 4575 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4576 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4577 auto MI = LinModifiers.begin(); 4578 for (const Expr *E : Linears) { 4579 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4580 ++MI; 4581 E = E->IgnoreParenImpCasts(); 4582 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4583 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4584 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4585 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4586 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4587 ->getCanonicalDecl() == CanonPVD) { 4588 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4589 // A list-item cannot appear in more than one linear clause. 4590 if (LinearArgs.count(CanonPVD) > 0) { 4591 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4592 << getOpenMPClauseName(OMPC_linear) 4593 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4594 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4595 diag::note_omp_explicit_dsa) 4596 << getOpenMPClauseName(OMPC_linear); 4597 continue; 4598 } 4599 // Each argument can appear in at most one uniform or linear clause. 4600 if (UniformedArgs.count(CanonPVD) > 0) { 4601 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4602 << getOpenMPClauseName(OMPC_linear) 4603 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4604 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4605 diag::note_omp_explicit_dsa) 4606 << getOpenMPClauseName(OMPC_uniform); 4607 continue; 4608 } 4609 LinearArgs[CanonPVD] = E; 4610 if (E->isValueDependent() || E->isTypeDependent() || 4611 E->isInstantiationDependent() || 4612 E->containsUnexpandedParameterPack()) 4613 continue; 4614 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4615 PVD->getOriginalType()); 4616 continue; 4617 } 4618 } 4619 if (isa<CXXThisExpr>(E)) { 4620 if (UniformedLinearThis) { 4621 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4622 << getOpenMPClauseName(OMPC_linear) 4623 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4624 << E->getSourceRange(); 4625 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4626 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4627 : OMPC_linear); 4628 continue; 4629 } 4630 UniformedLinearThis = E; 4631 if (E->isValueDependent() || E->isTypeDependent() || 4632 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4633 continue; 4634 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4635 E->getType()); 4636 continue; 4637 } 4638 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4639 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4640 } 4641 Expr *Step = nullptr; 4642 Expr *NewStep = nullptr; 4643 SmallVector<Expr *, 4> NewSteps; 4644 for (Expr *E : Steps) { 4645 // Skip the same step expression, it was checked already. 4646 if (Step == E || !E) { 4647 NewSteps.push_back(E ? NewStep : nullptr); 4648 continue; 4649 } 4650 Step = E; 4651 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4652 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4653 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4654 if (UniformedArgs.count(CanonPVD) == 0) { 4655 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4656 << Step->getSourceRange(); 4657 } else if (E->isValueDependent() || E->isTypeDependent() || 4658 E->isInstantiationDependent() || 4659 E->containsUnexpandedParameterPack() || 4660 CanonPVD->getType()->hasIntegerRepresentation()) { 4661 NewSteps.push_back(Step); 4662 } else { 4663 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4664 << Step->getSourceRange(); 4665 } 4666 continue; 4667 } 4668 NewStep = Step; 4669 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4670 !Step->isInstantiationDependent() && 4671 !Step->containsUnexpandedParameterPack()) { 4672 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4673 .get(); 4674 if (NewStep) 4675 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4676 } 4677 NewSteps.push_back(NewStep); 4678 } 4679 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4680 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4681 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4682 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4683 const_cast<Expr **>(Linears.data()), Linears.size(), 4684 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4685 NewSteps.data(), NewSteps.size(), SR); 4686 ADecl->addAttr(NewAttr); 4687 return ConvertDeclToDeclGroup(ADecl); 4688 } 4689 4690 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4691 Stmt *AStmt, 4692 SourceLocation StartLoc, 4693 SourceLocation EndLoc) { 4694 if (!AStmt) 4695 return StmtError(); 4696 4697 auto *CS = cast<CapturedStmt>(AStmt); 4698 // 1.2.2 OpenMP Language Terminology 4699 // Structured block - An executable statement with a single entry at the 4700 // top and a single exit at the bottom. 4701 // The point of exit cannot be a branch out of the structured block. 4702 // longjmp() and throw() must not violate the entry/exit criteria. 4703 CS->getCapturedDecl()->setNothrow(); 4704 4705 setFunctionHasBranchProtectedScope(); 4706 4707 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4708 DSAStack->isCancelRegion()); 4709 } 4710 4711 namespace { 4712 /// Helper class for checking canonical form of the OpenMP loops and 4713 /// extracting iteration space of each loop in the loop nest, that will be used 4714 /// for IR generation. 4715 class OpenMPIterationSpaceChecker { 4716 /// Reference to Sema. 4717 Sema &SemaRef; 4718 /// Data-sharing stack. 4719 DSAStackTy &Stack; 4720 /// A location for diagnostics (when there is no some better location). 4721 SourceLocation DefaultLoc; 4722 /// A location for diagnostics (when increment is not compatible). 4723 SourceLocation ConditionLoc; 4724 /// A source location for referring to loop init later. 4725 SourceRange InitSrcRange; 4726 /// A source location for referring to condition later. 4727 SourceRange ConditionSrcRange; 4728 /// A source location for referring to increment later. 4729 SourceRange IncrementSrcRange; 4730 /// Loop variable. 4731 ValueDecl *LCDecl = nullptr; 4732 /// Reference to loop variable. 4733 Expr *LCRef = nullptr; 4734 /// Lower bound (initializer for the var). 4735 Expr *LB = nullptr; 4736 /// Upper bound. 4737 Expr *UB = nullptr; 4738 /// Loop step (increment). 4739 Expr *Step = nullptr; 4740 /// This flag is true when condition is one of: 4741 /// Var < UB 4742 /// Var <= UB 4743 /// UB > Var 4744 /// UB >= Var 4745 /// This will have no value when the condition is != 4746 llvm::Optional<bool> TestIsLessOp; 4747 /// This flag is true when condition is strict ( < or > ). 4748 bool TestIsStrictOp = false; 4749 /// This flag is true when step is subtracted on each iteration. 4750 bool SubtractStep = false; 4751 /// The outer loop counter this loop depends on (if any). 4752 const ValueDecl *DepDecl = nullptr; 4753 /// Contains number of loop (starts from 1) on which loop counter init 4754 /// expression of this loop depends on. 4755 Optional<unsigned> InitDependOnLC; 4756 /// Contains number of loop (starts from 1) on which loop counter condition 4757 /// expression of this loop depends on. 4758 Optional<unsigned> CondDependOnLC; 4759 /// Checks if the provide statement depends on the loop counter. 4760 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 4761 4762 public: 4763 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 4764 SourceLocation DefaultLoc) 4765 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 4766 ConditionLoc(DefaultLoc) {} 4767 /// Check init-expr for canonical loop form and save loop counter 4768 /// variable - #Var and its initialization value - #LB. 4769 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4770 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4771 /// for less/greater and for strict/non-strict comparison. 4772 bool checkAndSetCond(Expr *S); 4773 /// Check incr-expr for canonical loop form and return true if it 4774 /// does not conform, otherwise save loop step (#Step). 4775 bool checkAndSetInc(Expr *S); 4776 /// Return the loop counter variable. 4777 ValueDecl *getLoopDecl() const { return LCDecl; } 4778 /// Return the reference expression to loop counter variable. 4779 Expr *getLoopDeclRefExpr() const { return LCRef; } 4780 /// Source range of the loop init. 4781 SourceRange getInitSrcRange() const { return InitSrcRange; } 4782 /// Source range of the loop condition. 4783 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4784 /// Source range of the loop increment. 4785 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4786 /// True if the step should be subtracted. 4787 bool shouldSubtractStep() const { return SubtractStep; } 4788 /// True, if the compare operator is strict (<, > or !=). 4789 bool isStrictTestOp() const { return TestIsStrictOp; } 4790 /// Build the expression to calculate the number of iterations. 4791 Expr *buildNumIterations( 4792 Scope *S, const bool LimitedType, 4793 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4794 /// Build the precondition expression for the loops. 4795 Expr * 4796 buildPreCond(Scope *S, Expr *Cond, 4797 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4798 /// Build reference expression to the counter be used for codegen. 4799 DeclRefExpr * 4800 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4801 DSAStackTy &DSA) const; 4802 /// Build reference expression to the private counter be used for 4803 /// codegen. 4804 Expr *buildPrivateCounterVar() const; 4805 /// Build initialization of the counter be used for codegen. 4806 Expr *buildCounterInit() const; 4807 /// Build step of the counter be used for codegen. 4808 Expr *buildCounterStep() const; 4809 /// Build loop data with counter value for depend clauses in ordered 4810 /// directives. 4811 Expr * 4812 buildOrderedLoopData(Scope *S, Expr *Counter, 4813 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4814 SourceLocation Loc, Expr *Inc = nullptr, 4815 OverloadedOperatorKind OOK = OO_Amp); 4816 /// Return true if any expression is dependent. 4817 bool dependent() const; 4818 4819 private: 4820 /// Check the right-hand side of an assignment in the increment 4821 /// expression. 4822 bool checkAndSetIncRHS(Expr *RHS); 4823 /// Helper to set loop counter variable and its initializer. 4824 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 4825 bool EmitDiags); 4826 /// Helper to set upper bound. 4827 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4828 SourceRange SR, SourceLocation SL); 4829 /// Helper to set loop increment. 4830 bool setStep(Expr *NewStep, bool Subtract); 4831 }; 4832 4833 bool OpenMPIterationSpaceChecker::dependent() const { 4834 if (!LCDecl) { 4835 assert(!LB && !UB && !Step); 4836 return false; 4837 } 4838 return LCDecl->getType()->isDependentType() || 4839 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4840 (Step && Step->isValueDependent()); 4841 } 4842 4843 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4844 Expr *NewLCRefExpr, 4845 Expr *NewLB, bool EmitDiags) { 4846 // State consistency checking to ensure correct usage. 4847 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4848 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4849 if (!NewLCDecl || !NewLB) 4850 return true; 4851 LCDecl = getCanonicalDecl(NewLCDecl); 4852 LCRef = NewLCRefExpr; 4853 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4854 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4855 if ((Ctor->isCopyOrMoveConstructor() || 4856 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4857 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4858 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4859 LB = NewLB; 4860 if (EmitDiags) 4861 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 4862 return false; 4863 } 4864 4865 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4866 llvm::Optional<bool> LessOp, 4867 bool StrictOp, SourceRange SR, 4868 SourceLocation SL) { 4869 // State consistency checking to ensure correct usage. 4870 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4871 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4872 if (!NewUB) 4873 return true; 4874 UB = NewUB; 4875 if (LessOp) 4876 TestIsLessOp = LessOp; 4877 TestIsStrictOp = StrictOp; 4878 ConditionSrcRange = SR; 4879 ConditionLoc = SL; 4880 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 4881 return false; 4882 } 4883 4884 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4885 // State consistency checking to ensure correct usage. 4886 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4887 if (!NewStep) 4888 return true; 4889 if (!NewStep->isValueDependent()) { 4890 // Check that the step is integer expression. 4891 SourceLocation StepLoc = NewStep->getBeginLoc(); 4892 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4893 StepLoc, getExprAsWritten(NewStep)); 4894 if (Val.isInvalid()) 4895 return true; 4896 NewStep = Val.get(); 4897 4898 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4899 // If test-expr is of form var relational-op b and relational-op is < or 4900 // <= then incr-expr must cause var to increase on each iteration of the 4901 // loop. If test-expr is of form var relational-op b and relational-op is 4902 // > or >= then incr-expr must cause var to decrease on each iteration of 4903 // the loop. 4904 // If test-expr is of form b relational-op var and relational-op is < or 4905 // <= then incr-expr must cause var to decrease on each iteration of the 4906 // loop. If test-expr is of form b relational-op var and relational-op is 4907 // > or >= then incr-expr must cause var to increase on each iteration of 4908 // the loop. 4909 llvm::APSInt Result; 4910 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4911 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4912 bool IsConstNeg = 4913 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4914 bool IsConstPos = 4915 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4916 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4917 4918 // != with increment is treated as <; != with decrement is treated as > 4919 if (!TestIsLessOp.hasValue()) 4920 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4921 if (UB && (IsConstZero || 4922 (TestIsLessOp.getValue() ? 4923 (IsConstNeg || (IsUnsigned && Subtract)) : 4924 (IsConstPos || (IsUnsigned && !Subtract))))) { 4925 SemaRef.Diag(NewStep->getExprLoc(), 4926 diag::err_omp_loop_incr_not_compatible) 4927 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4928 SemaRef.Diag(ConditionLoc, 4929 diag::note_omp_loop_cond_requres_compatible_incr) 4930 << TestIsLessOp.getValue() << ConditionSrcRange; 4931 return true; 4932 } 4933 if (TestIsLessOp.getValue() == Subtract) { 4934 NewStep = 4935 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4936 .get(); 4937 Subtract = !Subtract; 4938 } 4939 } 4940 4941 Step = NewStep; 4942 SubtractStep = Subtract; 4943 return false; 4944 } 4945 4946 namespace { 4947 /// Checker for the non-rectangular loops. Checks if the initializer or 4948 /// condition expression references loop counter variable. 4949 class LoopCounterRefChecker final 4950 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 4951 Sema &SemaRef; 4952 DSAStackTy &Stack; 4953 const ValueDecl *CurLCDecl = nullptr; 4954 const ValueDecl *DepDecl = nullptr; 4955 const ValueDecl *PrevDepDecl = nullptr; 4956 bool IsInitializer = true; 4957 unsigned BaseLoopId = 0; 4958 bool checkDecl(const Expr *E, const ValueDecl *VD) { 4959 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 4960 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 4961 << (IsInitializer ? 0 : 1); 4962 return false; 4963 } 4964 const auto &&Data = Stack.isLoopControlVariable(VD); 4965 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 4966 // The type of the loop iterator on which we depend may not have a random 4967 // access iterator type. 4968 if (Data.first && VD->getType()->isRecordType()) { 4969 SmallString<128> Name; 4970 llvm::raw_svector_ostream OS(Name); 4971 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4972 /*Qualified=*/true); 4973 SemaRef.Diag(E->getExprLoc(), 4974 diag::err_omp_wrong_dependency_iterator_type) 4975 << OS.str(); 4976 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 4977 return false; 4978 } 4979 if (Data.first && 4980 (DepDecl || (PrevDepDecl && 4981 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 4982 if (!DepDecl && PrevDepDecl) 4983 DepDecl = PrevDepDecl; 4984 SmallString<128> Name; 4985 llvm::raw_svector_ostream OS(Name); 4986 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4987 /*Qualified=*/true); 4988 SemaRef.Diag(E->getExprLoc(), 4989 diag::err_omp_invariant_or_linear_dependency) 4990 << OS.str(); 4991 return false; 4992 } 4993 if (Data.first) { 4994 DepDecl = VD; 4995 BaseLoopId = Data.first; 4996 } 4997 return Data.first; 4998 } 4999 5000 public: 5001 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5002 const ValueDecl *VD = E->getDecl(); 5003 if (isa<VarDecl>(VD)) 5004 return checkDecl(E, VD); 5005 return false; 5006 } 5007 bool VisitMemberExpr(const MemberExpr *E) { 5008 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5009 const ValueDecl *VD = E->getMemberDecl(); 5010 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5011 return checkDecl(E, VD); 5012 } 5013 return false; 5014 } 5015 bool VisitStmt(const Stmt *S) { 5016 bool Res = true; 5017 for (const Stmt *Child : S->children()) 5018 Res = Child && Visit(Child) && Res; 5019 return Res; 5020 } 5021 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5022 const ValueDecl *CurLCDecl, bool IsInitializer, 5023 const ValueDecl *PrevDepDecl = nullptr) 5024 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5025 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5026 unsigned getBaseLoopId() const { 5027 assert(CurLCDecl && "Expected loop dependency."); 5028 return BaseLoopId; 5029 } 5030 const ValueDecl *getDepDecl() const { 5031 assert(CurLCDecl && "Expected loop dependency."); 5032 return DepDecl; 5033 } 5034 }; 5035 } // namespace 5036 5037 Optional<unsigned> 5038 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5039 bool IsInitializer) { 5040 // Check for the non-rectangular loops. 5041 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5042 DepDecl); 5043 if (LoopStmtChecker.Visit(S)) { 5044 DepDecl = LoopStmtChecker.getDepDecl(); 5045 return LoopStmtChecker.getBaseLoopId(); 5046 } 5047 return llvm::None; 5048 } 5049 5050 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5051 // Check init-expr for canonical loop form and save loop counter 5052 // variable - #Var and its initialization value - #LB. 5053 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5054 // var = lb 5055 // integer-type var = lb 5056 // random-access-iterator-type var = lb 5057 // pointer-type var = lb 5058 // 5059 if (!S) { 5060 if (EmitDiags) { 5061 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5062 } 5063 return true; 5064 } 5065 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5066 if (!ExprTemp->cleanupsHaveSideEffects()) 5067 S = ExprTemp->getSubExpr(); 5068 5069 InitSrcRange = S->getSourceRange(); 5070 if (Expr *E = dyn_cast<Expr>(S)) 5071 S = E->IgnoreParens(); 5072 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5073 if (BO->getOpcode() == BO_Assign) { 5074 Expr *LHS = BO->getLHS()->IgnoreParens(); 5075 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5076 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5077 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5078 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5079 EmitDiags); 5080 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5081 } 5082 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5083 if (ME->isArrow() && 5084 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5085 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5086 EmitDiags); 5087 } 5088 } 5089 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5090 if (DS->isSingleDecl()) { 5091 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5092 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5093 // Accept non-canonical init form here but emit ext. warning. 5094 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5095 SemaRef.Diag(S->getBeginLoc(), 5096 diag::ext_omp_loop_not_canonical_init) 5097 << S->getSourceRange(); 5098 return setLCDeclAndLB( 5099 Var, 5100 buildDeclRefExpr(SemaRef, Var, 5101 Var->getType().getNonReferenceType(), 5102 DS->getBeginLoc()), 5103 Var->getInit(), EmitDiags); 5104 } 5105 } 5106 } 5107 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5108 if (CE->getOperator() == OO_Equal) { 5109 Expr *LHS = CE->getArg(0); 5110 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5111 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5112 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5113 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5114 EmitDiags); 5115 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5116 } 5117 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5118 if (ME->isArrow() && 5119 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5120 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5121 EmitDiags); 5122 } 5123 } 5124 } 5125 5126 if (dependent() || SemaRef.CurContext->isDependentContext()) 5127 return false; 5128 if (EmitDiags) { 5129 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5130 << S->getSourceRange(); 5131 } 5132 return true; 5133 } 5134 5135 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5136 /// variable (which may be the loop variable) if possible. 5137 static const ValueDecl *getInitLCDecl(const Expr *E) { 5138 if (!E) 5139 return nullptr; 5140 E = getExprAsWritten(E); 5141 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5142 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5143 if ((Ctor->isCopyOrMoveConstructor() || 5144 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5145 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5146 E = CE->getArg(0)->IgnoreParenImpCasts(); 5147 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5148 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5149 return getCanonicalDecl(VD); 5150 } 5151 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5152 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5153 return getCanonicalDecl(ME->getMemberDecl()); 5154 return nullptr; 5155 } 5156 5157 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5158 // Check test-expr for canonical form, save upper-bound UB, flags for 5159 // less/greater and for strict/non-strict comparison. 5160 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5161 // var relational-op b 5162 // b relational-op var 5163 // 5164 if (!S) { 5165 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 5166 return true; 5167 } 5168 S = getExprAsWritten(S); 5169 SourceLocation CondLoc = S->getBeginLoc(); 5170 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5171 if (BO->isRelationalOp()) { 5172 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5173 return setUB(BO->getRHS(), 5174 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5175 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5176 BO->getSourceRange(), BO->getOperatorLoc()); 5177 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5178 return setUB(BO->getLHS(), 5179 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5180 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5181 BO->getSourceRange(), BO->getOperatorLoc()); 5182 } else if (BO->getOpcode() == BO_NE) 5183 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 5184 BO->getRHS() : BO->getLHS(), 5185 /*LessOp=*/llvm::None, 5186 /*StrictOp=*/true, 5187 BO->getSourceRange(), BO->getOperatorLoc()); 5188 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5189 if (CE->getNumArgs() == 2) { 5190 auto Op = CE->getOperator(); 5191 switch (Op) { 5192 case OO_Greater: 5193 case OO_GreaterEqual: 5194 case OO_Less: 5195 case OO_LessEqual: 5196 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5197 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5198 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5199 CE->getOperatorLoc()); 5200 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5201 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5202 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5203 CE->getOperatorLoc()); 5204 break; 5205 case OO_ExclaimEqual: 5206 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 5207 CE->getArg(1) : CE->getArg(0), 5208 /*LessOp=*/llvm::None, 5209 /*StrictOp=*/true, 5210 CE->getSourceRange(), 5211 CE->getOperatorLoc()); 5212 break; 5213 default: 5214 break; 5215 } 5216 } 5217 } 5218 if (dependent() || SemaRef.CurContext->isDependentContext()) 5219 return false; 5220 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5221 << S->getSourceRange() << LCDecl; 5222 return true; 5223 } 5224 5225 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5226 // RHS of canonical loop form increment can be: 5227 // var + incr 5228 // incr + var 5229 // var - incr 5230 // 5231 RHS = RHS->IgnoreParenImpCasts(); 5232 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5233 if (BO->isAdditiveOp()) { 5234 bool IsAdd = BO->getOpcode() == BO_Add; 5235 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5236 return setStep(BO->getRHS(), !IsAdd); 5237 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5238 return setStep(BO->getLHS(), /*Subtract=*/false); 5239 } 5240 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5241 bool IsAdd = CE->getOperator() == OO_Plus; 5242 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5243 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5244 return setStep(CE->getArg(1), !IsAdd); 5245 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5246 return setStep(CE->getArg(0), /*Subtract=*/false); 5247 } 5248 } 5249 if (dependent() || SemaRef.CurContext->isDependentContext()) 5250 return false; 5251 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5252 << RHS->getSourceRange() << LCDecl; 5253 return true; 5254 } 5255 5256 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5257 // Check incr-expr for canonical loop form and return true if it 5258 // does not conform. 5259 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5260 // ++var 5261 // var++ 5262 // --var 5263 // var-- 5264 // var += incr 5265 // var -= incr 5266 // var = var + incr 5267 // var = incr + var 5268 // var = var - incr 5269 // 5270 if (!S) { 5271 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5272 return true; 5273 } 5274 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5275 if (!ExprTemp->cleanupsHaveSideEffects()) 5276 S = ExprTemp->getSubExpr(); 5277 5278 IncrementSrcRange = S->getSourceRange(); 5279 S = S->IgnoreParens(); 5280 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5281 if (UO->isIncrementDecrementOp() && 5282 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5283 return setStep(SemaRef 5284 .ActOnIntegerConstant(UO->getBeginLoc(), 5285 (UO->isDecrementOp() ? -1 : 1)) 5286 .get(), 5287 /*Subtract=*/false); 5288 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5289 switch (BO->getOpcode()) { 5290 case BO_AddAssign: 5291 case BO_SubAssign: 5292 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5293 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5294 break; 5295 case BO_Assign: 5296 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5297 return checkAndSetIncRHS(BO->getRHS()); 5298 break; 5299 default: 5300 break; 5301 } 5302 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5303 switch (CE->getOperator()) { 5304 case OO_PlusPlus: 5305 case OO_MinusMinus: 5306 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5307 return setStep(SemaRef 5308 .ActOnIntegerConstant( 5309 CE->getBeginLoc(), 5310 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5311 .get(), 5312 /*Subtract=*/false); 5313 break; 5314 case OO_PlusEqual: 5315 case OO_MinusEqual: 5316 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5317 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5318 break; 5319 case OO_Equal: 5320 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5321 return checkAndSetIncRHS(CE->getArg(1)); 5322 break; 5323 default: 5324 break; 5325 } 5326 } 5327 if (dependent() || SemaRef.CurContext->isDependentContext()) 5328 return false; 5329 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5330 << S->getSourceRange() << LCDecl; 5331 return true; 5332 } 5333 5334 static ExprResult 5335 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5336 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5337 if (SemaRef.CurContext->isDependentContext()) 5338 return ExprResult(Capture); 5339 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5340 return SemaRef.PerformImplicitConversion( 5341 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5342 /*AllowExplicit=*/true); 5343 auto I = Captures.find(Capture); 5344 if (I != Captures.end()) 5345 return buildCapture(SemaRef, Capture, I->second); 5346 DeclRefExpr *Ref = nullptr; 5347 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5348 Captures[Capture] = Ref; 5349 return Res; 5350 } 5351 5352 /// Build the expression to calculate the number of iterations. 5353 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5354 Scope *S, const bool LimitedType, 5355 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5356 ExprResult Diff; 5357 QualType VarType = LCDecl->getType().getNonReferenceType(); 5358 if (VarType->isIntegerType() || VarType->isPointerType() || 5359 SemaRef.getLangOpts().CPlusPlus) { 5360 // Upper - Lower 5361 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5362 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5363 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5364 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5365 if (!Upper || !Lower) 5366 return nullptr; 5367 5368 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5369 5370 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5371 // BuildBinOp already emitted error, this one is to point user to upper 5372 // and lower bound, and to tell what is passed to 'operator-'. 5373 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5374 << Upper->getSourceRange() << Lower->getSourceRange(); 5375 return nullptr; 5376 } 5377 } 5378 5379 if (!Diff.isUsable()) 5380 return nullptr; 5381 5382 // Upper - Lower [- 1] 5383 if (TestIsStrictOp) 5384 Diff = SemaRef.BuildBinOp( 5385 S, DefaultLoc, BO_Sub, Diff.get(), 5386 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5387 if (!Diff.isUsable()) 5388 return nullptr; 5389 5390 // Upper - Lower [- 1] + Step 5391 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5392 if (!NewStep.isUsable()) 5393 return nullptr; 5394 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5395 if (!Diff.isUsable()) 5396 return nullptr; 5397 5398 // Parentheses (for dumping/debugging purposes only). 5399 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5400 if (!Diff.isUsable()) 5401 return nullptr; 5402 5403 // (Upper - Lower [- 1] + Step) / Step 5404 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5405 if (!Diff.isUsable()) 5406 return nullptr; 5407 5408 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5409 QualType Type = Diff.get()->getType(); 5410 ASTContext &C = SemaRef.Context; 5411 bool UseVarType = VarType->hasIntegerRepresentation() && 5412 C.getTypeSize(Type) > C.getTypeSize(VarType); 5413 if (!Type->isIntegerType() || UseVarType) { 5414 unsigned NewSize = 5415 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5416 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5417 : Type->hasSignedIntegerRepresentation(); 5418 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5419 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5420 Diff = SemaRef.PerformImplicitConversion( 5421 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5422 if (!Diff.isUsable()) 5423 return nullptr; 5424 } 5425 } 5426 if (LimitedType) { 5427 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5428 if (NewSize != C.getTypeSize(Type)) { 5429 if (NewSize < C.getTypeSize(Type)) { 5430 assert(NewSize == 64 && "incorrect loop var size"); 5431 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5432 << InitSrcRange << ConditionSrcRange; 5433 } 5434 QualType NewType = C.getIntTypeForBitwidth( 5435 NewSize, Type->hasSignedIntegerRepresentation() || 5436 C.getTypeSize(Type) < NewSize); 5437 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5438 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5439 Sema::AA_Converting, true); 5440 if (!Diff.isUsable()) 5441 return nullptr; 5442 } 5443 } 5444 } 5445 5446 return Diff.get(); 5447 } 5448 5449 Expr *OpenMPIterationSpaceChecker::buildPreCond( 5450 Scope *S, Expr *Cond, 5451 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5452 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 5453 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5454 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5455 5456 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 5457 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 5458 if (!NewLB.isUsable() || !NewUB.isUsable()) 5459 return nullptr; 5460 5461 ExprResult CondExpr = 5462 SemaRef.BuildBinOp(S, DefaultLoc, 5463 TestIsLessOp.getValue() ? 5464 (TestIsStrictOp ? BO_LT : BO_LE) : 5465 (TestIsStrictOp ? BO_GT : BO_GE), 5466 NewLB.get(), NewUB.get()); 5467 if (CondExpr.isUsable()) { 5468 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 5469 SemaRef.Context.BoolTy)) 5470 CondExpr = SemaRef.PerformImplicitConversion( 5471 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 5472 /*AllowExplicit=*/true); 5473 } 5474 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5475 // Otherwise use original loop condition and evaluate it in runtime. 5476 return CondExpr.isUsable() ? CondExpr.get() : Cond; 5477 } 5478 5479 /// Build reference expression to the counter be used for codegen. 5480 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 5481 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5482 DSAStackTy &DSA) const { 5483 auto *VD = dyn_cast<VarDecl>(LCDecl); 5484 if (!VD) { 5485 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 5486 DeclRefExpr *Ref = buildDeclRefExpr( 5487 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 5488 const DSAStackTy::DSAVarData Data = 5489 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 5490 // If the loop control decl is explicitly marked as private, do not mark it 5491 // as captured again. 5492 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 5493 Captures.insert(std::make_pair(LCRef, Ref)); 5494 return Ref; 5495 } 5496 return cast<DeclRefExpr>(LCRef); 5497 } 5498 5499 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 5500 if (LCDecl && !LCDecl->isInvalidDecl()) { 5501 QualType Type = LCDecl->getType().getNonReferenceType(); 5502 VarDecl *PrivateVar = buildVarDecl( 5503 SemaRef, DefaultLoc, Type, LCDecl->getName(), 5504 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 5505 isa<VarDecl>(LCDecl) 5506 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 5507 : nullptr); 5508 if (PrivateVar->isInvalidDecl()) 5509 return nullptr; 5510 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 5511 } 5512 return nullptr; 5513 } 5514 5515 /// Build initialization of the counter to be used for codegen. 5516 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 5517 5518 /// Build step of the counter be used for codegen. 5519 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 5520 5521 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 5522 Scope *S, Expr *Counter, 5523 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 5524 Expr *Inc, OverloadedOperatorKind OOK) { 5525 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 5526 if (!Cnt) 5527 return nullptr; 5528 if (Inc) { 5529 assert((OOK == OO_Plus || OOK == OO_Minus) && 5530 "Expected only + or - operations for depend clauses."); 5531 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 5532 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 5533 if (!Cnt) 5534 return nullptr; 5535 } 5536 ExprResult Diff; 5537 QualType VarType = LCDecl->getType().getNonReferenceType(); 5538 if (VarType->isIntegerType() || VarType->isPointerType() || 5539 SemaRef.getLangOpts().CPlusPlus) { 5540 // Upper - Lower 5541 Expr *Upper = TestIsLessOp.getValue() 5542 ? Cnt 5543 : tryBuildCapture(SemaRef, UB, Captures).get(); 5544 Expr *Lower = TestIsLessOp.getValue() 5545 ? tryBuildCapture(SemaRef, LB, Captures).get() 5546 : Cnt; 5547 if (!Upper || !Lower) 5548 return nullptr; 5549 5550 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5551 5552 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5553 // BuildBinOp already emitted error, this one is to point user to upper 5554 // and lower bound, and to tell what is passed to 'operator-'. 5555 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5556 << Upper->getSourceRange() << Lower->getSourceRange(); 5557 return nullptr; 5558 } 5559 } 5560 5561 if (!Diff.isUsable()) 5562 return nullptr; 5563 5564 // Parentheses (for dumping/debugging purposes only). 5565 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5566 if (!Diff.isUsable()) 5567 return nullptr; 5568 5569 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5570 if (!NewStep.isUsable()) 5571 return nullptr; 5572 // (Upper - Lower) / Step 5573 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5574 if (!Diff.isUsable()) 5575 return nullptr; 5576 5577 return Diff.get(); 5578 } 5579 5580 /// Iteration space of a single for loop. 5581 struct LoopIterationSpace final { 5582 /// True if the condition operator is the strict compare operator (<, > or 5583 /// !=). 5584 bool IsStrictCompare = false; 5585 /// Condition of the loop. 5586 Expr *PreCond = nullptr; 5587 /// This expression calculates the number of iterations in the loop. 5588 /// It is always possible to calculate it before starting the loop. 5589 Expr *NumIterations = nullptr; 5590 /// The loop counter variable. 5591 Expr *CounterVar = nullptr; 5592 /// Private loop counter variable. 5593 Expr *PrivateCounterVar = nullptr; 5594 /// This is initializer for the initial value of #CounterVar. 5595 Expr *CounterInit = nullptr; 5596 /// This is step for the #CounterVar used to generate its update: 5597 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5598 Expr *CounterStep = nullptr; 5599 /// Should step be subtracted? 5600 bool Subtract = false; 5601 /// Source range of the loop init. 5602 SourceRange InitSrcRange; 5603 /// Source range of the loop condition. 5604 SourceRange CondSrcRange; 5605 /// Source range of the loop increment. 5606 SourceRange IncSrcRange; 5607 }; 5608 5609 } // namespace 5610 5611 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5612 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5613 assert(Init && "Expected loop in canonical form."); 5614 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5615 if (AssociatedLoops > 0 && 5616 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5617 DSAStack->loopStart(); 5618 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 5619 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5620 if (ValueDecl *D = ISC.getLoopDecl()) { 5621 auto *VD = dyn_cast<VarDecl>(D); 5622 DeclRefExpr *PrivateRef = nullptr; 5623 if (!VD) { 5624 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5625 VD = Private; 5626 } else { 5627 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5628 /*WithInit=*/false); 5629 VD = cast<VarDecl>(PrivateRef->getDecl()); 5630 } 5631 } 5632 DSAStack->addLoopControlVariable(D, VD); 5633 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5634 if (LD != D->getCanonicalDecl()) { 5635 DSAStack->resetPossibleLoopCounter(); 5636 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5637 MarkDeclarationsReferencedInExpr( 5638 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5639 Var->getType().getNonLValueExprType(Context), 5640 ForLoc, /*RefersToCapture=*/true)); 5641 } 5642 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 5643 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 5644 // Referenced in a Construct, C/C++]. The loop iteration variable in the 5645 // associated for-loop of a simd construct with just one associated 5646 // for-loop may be listed in a linear clause with a constant-linear-step 5647 // that is the increment of the associated for-loop. The loop iteration 5648 // variable(s) in the associated for-loop(s) of a for or parallel for 5649 // construct may be listed in a private or lastprivate clause. 5650 DSAStackTy::DSAVarData DVar = 5651 DSAStack->getTopDSA(D, /*FromParent=*/false); 5652 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 5653 // is declared in the loop and it is predetermined as a private. 5654 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5655 OpenMPClauseKind PredeterminedCKind = 5656 isOpenMPSimdDirective(DKind) 5657 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 5658 : OMPC_private; 5659 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5660 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 5661 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 5662 DVar.CKind != OMPC_private))) || 5663 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5664 isOpenMPDistributeDirective(DKind)) && 5665 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5666 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5667 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 5668 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5669 << getOpenMPClauseName(DVar.CKind) 5670 << getOpenMPDirectiveName(DKind) 5671 << getOpenMPClauseName(PredeterminedCKind); 5672 if (DVar.RefExpr == nullptr) 5673 DVar.CKind = PredeterminedCKind; 5674 reportOriginalDsa(*this, DSAStack, D, DVar, 5675 /*IsLoopIterVar=*/true); 5676 } else if (LoopDeclRefExpr) { 5677 // Make the loop iteration variable private (for worksharing 5678 // constructs), linear (for simd directives with the only one 5679 // associated loop) or lastprivate (for simd directives with several 5680 // collapsed or ordered loops). 5681 if (DVar.CKind == OMPC_unknown) 5682 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 5683 PrivateRef); 5684 } 5685 } 5686 } 5687 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 5688 } 5689 } 5690 5691 /// Called on a for stmt to check and extract its iteration space 5692 /// for further processing (such as collapsing). 5693 static bool checkOpenMPIterationSpace( 5694 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 5695 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 5696 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 5697 Expr *OrderedLoopCountExpr, 5698 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5699 LoopIterationSpace &ResultIterSpace, 5700 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5701 // OpenMP [2.6, Canonical Loop Form] 5702 // for (init-expr; test-expr; incr-expr) structured-block 5703 auto *For = dyn_cast_or_null<ForStmt>(S); 5704 if (!For) { 5705 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 5706 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 5707 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 5708 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 5709 if (TotalNestedLoopCount > 1) { 5710 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 5711 SemaRef.Diag(DSA.getConstructLoc(), 5712 diag::note_omp_collapse_ordered_expr) 5713 << 2 << CollapseLoopCountExpr->getSourceRange() 5714 << OrderedLoopCountExpr->getSourceRange(); 5715 else if (CollapseLoopCountExpr) 5716 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5717 diag::note_omp_collapse_ordered_expr) 5718 << 0 << CollapseLoopCountExpr->getSourceRange(); 5719 else 5720 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5721 diag::note_omp_collapse_ordered_expr) 5722 << 1 << OrderedLoopCountExpr->getSourceRange(); 5723 } 5724 return true; 5725 } 5726 assert(For->getBody()); 5727 5728 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 5729 5730 // Check init. 5731 Stmt *Init = For->getInit(); 5732 if (ISC.checkAndSetInit(Init)) 5733 return true; 5734 5735 bool HasErrors = false; 5736 5737 // Check loop variable's type. 5738 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 5739 // OpenMP [2.6, Canonical Loop Form] 5740 // Var is one of the following: 5741 // A variable of signed or unsigned integer type. 5742 // For C++, a variable of a random access iterator type. 5743 // For C, a variable of a pointer type. 5744 QualType VarType = LCDecl->getType().getNonReferenceType(); 5745 if (!VarType->isDependentType() && !VarType->isIntegerType() && 5746 !VarType->isPointerType() && 5747 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 5748 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 5749 << SemaRef.getLangOpts().CPlusPlus; 5750 HasErrors = true; 5751 } 5752 5753 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 5754 // a Construct 5755 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5756 // parallel for construct is (are) private. 5757 // The loop iteration variable in the associated for-loop of a simd 5758 // construct with just one associated for-loop is linear with a 5759 // constant-linear-step that is the increment of the associated for-loop. 5760 // Exclude loop var from the list of variables with implicitly defined data 5761 // sharing attributes. 5762 VarsWithImplicitDSA.erase(LCDecl); 5763 5764 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5765 5766 // Check test-expr. 5767 HasErrors |= ISC.checkAndSetCond(For->getCond()); 5768 5769 // Check incr-expr. 5770 HasErrors |= ISC.checkAndSetInc(For->getInc()); 5771 } 5772 5773 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5774 return HasErrors; 5775 5776 // Build the loop's iteration space representation. 5777 ResultIterSpace.PreCond = 5778 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5779 ResultIterSpace.NumIterations = ISC.buildNumIterations( 5780 DSA.getCurScope(), 5781 (isOpenMPWorksharingDirective(DKind) || 5782 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5783 Captures); 5784 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 5785 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 5786 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 5787 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 5788 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 5789 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 5790 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 5791 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 5792 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); 5793 5794 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5795 ResultIterSpace.NumIterations == nullptr || 5796 ResultIterSpace.CounterVar == nullptr || 5797 ResultIterSpace.PrivateCounterVar == nullptr || 5798 ResultIterSpace.CounterInit == nullptr || 5799 ResultIterSpace.CounterStep == nullptr); 5800 if (!HasErrors && DSA.isOrderedRegion()) { 5801 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 5802 if (CurrentNestedLoopCount < 5803 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 5804 DSA.getOrderedRegionParam().second->setLoopNumIterations( 5805 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 5806 DSA.getOrderedRegionParam().second->setLoopCounter( 5807 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 5808 } 5809 } 5810 for (auto &Pair : DSA.getDoacrossDependClauses()) { 5811 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 5812 // Erroneous case - clause has some problems. 5813 continue; 5814 } 5815 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 5816 Pair.second.size() <= CurrentNestedLoopCount) { 5817 // Erroneous case - clause has some problems. 5818 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 5819 continue; 5820 } 5821 Expr *CntValue; 5822 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5823 CntValue = ISC.buildOrderedLoopData( 5824 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5825 Pair.first->getDependencyLoc()); 5826 else 5827 CntValue = ISC.buildOrderedLoopData( 5828 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5829 Pair.first->getDependencyLoc(), 5830 Pair.second[CurrentNestedLoopCount].first, 5831 Pair.second[CurrentNestedLoopCount].second); 5832 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 5833 } 5834 } 5835 5836 return HasErrors; 5837 } 5838 5839 /// Build 'VarRef = Start. 5840 static ExprResult 5841 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5842 ExprResult Start, 5843 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5844 // Build 'VarRef = Start. 5845 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5846 if (!NewStart.isUsable()) 5847 return ExprError(); 5848 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5849 VarRef.get()->getType())) { 5850 NewStart = SemaRef.PerformImplicitConversion( 5851 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5852 /*AllowExplicit=*/true); 5853 if (!NewStart.isUsable()) 5854 return ExprError(); 5855 } 5856 5857 ExprResult Init = 5858 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5859 return Init; 5860 } 5861 5862 /// Build 'VarRef = Start + Iter * Step'. 5863 static ExprResult buildCounterUpdate( 5864 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5865 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 5866 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 5867 // Add parentheses (for debugging purposes only). 5868 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5869 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5870 !Step.isUsable()) 5871 return ExprError(); 5872 5873 ExprResult NewStep = Step; 5874 if (Captures) 5875 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5876 if (NewStep.isInvalid()) 5877 return ExprError(); 5878 ExprResult Update = 5879 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5880 if (!Update.isUsable()) 5881 return ExprError(); 5882 5883 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5884 // 'VarRef = Start (+|-) Iter * Step'. 5885 ExprResult NewStart = Start; 5886 if (Captures) 5887 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5888 if (NewStart.isInvalid()) 5889 return ExprError(); 5890 5891 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5892 ExprResult SavedUpdate = Update; 5893 ExprResult UpdateVal; 5894 if (VarRef.get()->getType()->isOverloadableType() || 5895 NewStart.get()->getType()->isOverloadableType() || 5896 Update.get()->getType()->isOverloadableType()) { 5897 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5898 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5899 Update = 5900 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5901 if (Update.isUsable()) { 5902 UpdateVal = 5903 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5904 VarRef.get(), SavedUpdate.get()); 5905 if (UpdateVal.isUsable()) { 5906 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5907 UpdateVal.get()); 5908 } 5909 } 5910 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5911 } 5912 5913 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5914 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5915 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5916 NewStart.get(), SavedUpdate.get()); 5917 if (!Update.isUsable()) 5918 return ExprError(); 5919 5920 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5921 VarRef.get()->getType())) { 5922 Update = SemaRef.PerformImplicitConversion( 5923 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5924 if (!Update.isUsable()) 5925 return ExprError(); 5926 } 5927 5928 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5929 } 5930 return Update; 5931 } 5932 5933 /// Convert integer expression \a E to make it have at least \a Bits 5934 /// bits. 5935 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5936 if (E == nullptr) 5937 return ExprError(); 5938 ASTContext &C = SemaRef.Context; 5939 QualType OldType = E->getType(); 5940 unsigned HasBits = C.getTypeSize(OldType); 5941 if (HasBits >= Bits) 5942 return ExprResult(E); 5943 // OK to convert to signed, because new type has more bits than old. 5944 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5945 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5946 true); 5947 } 5948 5949 /// Check if the given expression \a E is a constant integer that fits 5950 /// into \a Bits bits. 5951 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5952 if (E == nullptr) 5953 return false; 5954 llvm::APSInt Result; 5955 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5956 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5957 return false; 5958 } 5959 5960 /// Build preinits statement for the given declarations. 5961 static Stmt *buildPreInits(ASTContext &Context, 5962 MutableArrayRef<Decl *> PreInits) { 5963 if (!PreInits.empty()) { 5964 return new (Context) DeclStmt( 5965 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5966 SourceLocation(), SourceLocation()); 5967 } 5968 return nullptr; 5969 } 5970 5971 /// Build preinits statement for the given declarations. 5972 static Stmt * 5973 buildPreInits(ASTContext &Context, 5974 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5975 if (!Captures.empty()) { 5976 SmallVector<Decl *, 16> PreInits; 5977 for (const auto &Pair : Captures) 5978 PreInits.push_back(Pair.second->getDecl()); 5979 return buildPreInits(Context, PreInits); 5980 } 5981 return nullptr; 5982 } 5983 5984 /// Build postupdate expression for the given list of postupdates expressions. 5985 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5986 Expr *PostUpdate = nullptr; 5987 if (!PostUpdates.empty()) { 5988 for (Expr *E : PostUpdates) { 5989 Expr *ConvE = S.BuildCStyleCastExpr( 5990 E->getExprLoc(), 5991 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5992 E->getExprLoc(), E) 5993 .get(); 5994 PostUpdate = PostUpdate 5995 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5996 PostUpdate, ConvE) 5997 .get() 5998 : ConvE; 5999 } 6000 } 6001 return PostUpdate; 6002 } 6003 6004 /// Called on a for stmt to check itself and nested loops (if any). 6005 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6006 /// number of collapsed loops otherwise. 6007 static unsigned 6008 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6009 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6010 DSAStackTy &DSA, 6011 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6012 OMPLoopDirective::HelperExprs &Built) { 6013 unsigned NestedLoopCount = 1; 6014 if (CollapseLoopCountExpr) { 6015 // Found 'collapse' clause - calculate collapse number. 6016 Expr::EvalResult Result; 6017 if (!CollapseLoopCountExpr->isValueDependent() && 6018 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6019 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6020 } else { 6021 Built.clear(/*Size=*/1); 6022 return 1; 6023 } 6024 } 6025 unsigned OrderedLoopCount = 1; 6026 if (OrderedLoopCountExpr) { 6027 // Found 'ordered' clause - calculate collapse number. 6028 Expr::EvalResult EVResult; 6029 if (!OrderedLoopCountExpr->isValueDependent() && 6030 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6031 SemaRef.getASTContext())) { 6032 llvm::APSInt Result = EVResult.Val.getInt(); 6033 if (Result.getLimitedValue() < NestedLoopCount) { 6034 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6035 diag::err_omp_wrong_ordered_loop_count) 6036 << OrderedLoopCountExpr->getSourceRange(); 6037 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6038 diag::note_collapse_loop_count) 6039 << CollapseLoopCountExpr->getSourceRange(); 6040 } 6041 OrderedLoopCount = Result.getLimitedValue(); 6042 } else { 6043 Built.clear(/*Size=*/1); 6044 return 1; 6045 } 6046 } 6047 // This is helper routine for loop directives (e.g., 'for', 'simd', 6048 // 'for simd', etc.). 6049 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6050 SmallVector<LoopIterationSpace, 4> IterSpaces( 6051 std::max(OrderedLoopCount, NestedLoopCount)); 6052 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6053 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6054 if (checkOpenMPIterationSpace( 6055 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6056 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6057 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 6058 Captures)) 6059 return 0; 6060 // Move on to the next nested for loop, or to the loop body. 6061 // OpenMP [2.8.1, simd construct, Restrictions] 6062 // All loops associated with the construct must be perfectly nested; that 6063 // is, there must be no intervening code nor any OpenMP directive between 6064 // any two loops. 6065 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6066 } 6067 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6068 if (checkOpenMPIterationSpace( 6069 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6070 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6071 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 6072 Captures)) 6073 return 0; 6074 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6075 // Handle initialization of captured loop iterator variables. 6076 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6077 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6078 Captures[DRE] = DRE; 6079 } 6080 } 6081 // Move on to the next nested for loop, or to the loop body. 6082 // OpenMP [2.8.1, simd construct, Restrictions] 6083 // All loops associated with the construct must be perfectly nested; that 6084 // is, there must be no intervening code nor any OpenMP directive between 6085 // any two loops. 6086 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6087 } 6088 6089 Built.clear(/* size */ NestedLoopCount); 6090 6091 if (SemaRef.CurContext->isDependentContext()) 6092 return NestedLoopCount; 6093 6094 // An example of what is generated for the following code: 6095 // 6096 // #pragma omp simd collapse(2) ordered(2) 6097 // for (i = 0; i < NI; ++i) 6098 // for (k = 0; k < NK; ++k) 6099 // for (j = J0; j < NJ; j+=2) { 6100 // <loop body> 6101 // } 6102 // 6103 // We generate the code below. 6104 // Note: the loop body may be outlined in CodeGen. 6105 // Note: some counters may be C++ classes, operator- is used to find number of 6106 // iterations and operator+= to calculate counter value. 6107 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6108 // or i64 is currently supported). 6109 // 6110 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6111 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6112 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6113 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6114 // // similar updates for vars in clauses (e.g. 'linear') 6115 // <loop body (using local i and j)> 6116 // } 6117 // i = NI; // assign final values of counters 6118 // j = NJ; 6119 // 6120 6121 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6122 // the iteration counts of the collapsed for loops. 6123 // Precondition tests if there is at least one iteration (all conditions are 6124 // true). 6125 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6126 Expr *N0 = IterSpaces[0].NumIterations; 6127 ExprResult LastIteration32 = 6128 widenIterationCount(/*Bits=*/32, 6129 SemaRef 6130 .PerformImplicitConversion( 6131 N0->IgnoreImpCasts(), N0->getType(), 6132 Sema::AA_Converting, /*AllowExplicit=*/true) 6133 .get(), 6134 SemaRef); 6135 ExprResult LastIteration64 = widenIterationCount( 6136 /*Bits=*/64, 6137 SemaRef 6138 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6139 Sema::AA_Converting, 6140 /*AllowExplicit=*/true) 6141 .get(), 6142 SemaRef); 6143 6144 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6145 return NestedLoopCount; 6146 6147 ASTContext &C = SemaRef.Context; 6148 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6149 6150 Scope *CurScope = DSA.getCurScope(); 6151 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6152 if (PreCond.isUsable()) { 6153 PreCond = 6154 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6155 PreCond.get(), IterSpaces[Cnt].PreCond); 6156 } 6157 Expr *N = IterSpaces[Cnt].NumIterations; 6158 SourceLocation Loc = N->getExprLoc(); 6159 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6160 if (LastIteration32.isUsable()) 6161 LastIteration32 = SemaRef.BuildBinOp( 6162 CurScope, Loc, BO_Mul, LastIteration32.get(), 6163 SemaRef 6164 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6165 Sema::AA_Converting, 6166 /*AllowExplicit=*/true) 6167 .get()); 6168 if (LastIteration64.isUsable()) 6169 LastIteration64 = SemaRef.BuildBinOp( 6170 CurScope, Loc, BO_Mul, LastIteration64.get(), 6171 SemaRef 6172 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6173 Sema::AA_Converting, 6174 /*AllowExplicit=*/true) 6175 .get()); 6176 } 6177 6178 // Choose either the 32-bit or 64-bit version. 6179 ExprResult LastIteration = LastIteration64; 6180 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6181 (LastIteration32.isUsable() && 6182 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6183 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6184 fitsInto( 6185 /*Bits=*/32, 6186 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6187 LastIteration64.get(), SemaRef)))) 6188 LastIteration = LastIteration32; 6189 QualType VType = LastIteration.get()->getType(); 6190 QualType RealVType = VType; 6191 QualType StrideVType = VType; 6192 if (isOpenMPTaskLoopDirective(DKind)) { 6193 VType = 6194 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6195 StrideVType = 6196 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6197 } 6198 6199 if (!LastIteration.isUsable()) 6200 return 0; 6201 6202 // Save the number of iterations. 6203 ExprResult NumIterations = LastIteration; 6204 { 6205 LastIteration = SemaRef.BuildBinOp( 6206 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6207 LastIteration.get(), 6208 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6209 if (!LastIteration.isUsable()) 6210 return 0; 6211 } 6212 6213 // Calculate the last iteration number beforehand instead of doing this on 6214 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6215 llvm::APSInt Result; 6216 bool IsConstant = 6217 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6218 ExprResult CalcLastIteration; 6219 if (!IsConstant) { 6220 ExprResult SaveRef = 6221 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6222 LastIteration = SaveRef; 6223 6224 // Prepare SaveRef + 1. 6225 NumIterations = SemaRef.BuildBinOp( 6226 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6227 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6228 if (!NumIterations.isUsable()) 6229 return 0; 6230 } 6231 6232 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6233 6234 // Build variables passed into runtime, necessary for worksharing directives. 6235 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6236 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6237 isOpenMPDistributeDirective(DKind)) { 6238 // Lower bound variable, initialized with zero. 6239 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6240 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6241 SemaRef.AddInitializerToDecl(LBDecl, 6242 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6243 /*DirectInit*/ false); 6244 6245 // Upper bound variable, initialized with last iteration number. 6246 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6247 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6248 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6249 /*DirectInit*/ false); 6250 6251 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6252 // This will be used to implement clause 'lastprivate'. 6253 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6254 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6255 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6256 SemaRef.AddInitializerToDecl(ILDecl, 6257 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6258 /*DirectInit*/ false); 6259 6260 // Stride variable returned by runtime (we initialize it to 1 by default). 6261 VarDecl *STDecl = 6262 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6263 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6264 SemaRef.AddInitializerToDecl(STDecl, 6265 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6266 /*DirectInit*/ false); 6267 6268 // Build expression: UB = min(UB, LastIteration) 6269 // It is necessary for CodeGen of directives with static scheduling. 6270 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6271 UB.get(), LastIteration.get()); 6272 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6273 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6274 LastIteration.get(), UB.get()); 6275 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6276 CondOp.get()); 6277 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6278 6279 // If we have a combined directive that combines 'distribute', 'for' or 6280 // 'simd' we need to be able to access the bounds of the schedule of the 6281 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6282 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6283 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6284 // Lower bound variable, initialized with zero. 6285 VarDecl *CombLBDecl = 6286 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6287 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6288 SemaRef.AddInitializerToDecl( 6289 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6290 /*DirectInit*/ false); 6291 6292 // Upper bound variable, initialized with last iteration number. 6293 VarDecl *CombUBDecl = 6294 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6295 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6296 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6297 /*DirectInit*/ false); 6298 6299 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6300 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6301 ExprResult CombCondOp = 6302 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6303 LastIteration.get(), CombUB.get()); 6304 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6305 CombCondOp.get()); 6306 CombEUB = 6307 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6308 6309 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6310 // We expect to have at least 2 more parameters than the 'parallel' 6311 // directive does - the lower and upper bounds of the previous schedule. 6312 assert(CD->getNumParams() >= 4 && 6313 "Unexpected number of parameters in loop combined directive"); 6314 6315 // Set the proper type for the bounds given what we learned from the 6316 // enclosed loops. 6317 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6318 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6319 6320 // Previous lower and upper bounds are obtained from the region 6321 // parameters. 6322 PrevLB = 6323 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6324 PrevUB = 6325 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6326 } 6327 } 6328 6329 // Build the iteration variable and its initialization before loop. 6330 ExprResult IV; 6331 ExprResult Init, CombInit; 6332 { 6333 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6334 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6335 Expr *RHS = 6336 (isOpenMPWorksharingDirective(DKind) || 6337 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6338 ? LB.get() 6339 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6340 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6341 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6342 6343 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6344 Expr *CombRHS = 6345 (isOpenMPWorksharingDirective(DKind) || 6346 isOpenMPTaskLoopDirective(DKind) || 6347 isOpenMPDistributeDirective(DKind)) 6348 ? CombLB.get() 6349 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6350 CombInit = 6351 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6352 CombInit = 6353 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6354 } 6355 } 6356 6357 bool UseStrictCompare = 6358 RealVType->hasUnsignedIntegerRepresentation() && 6359 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6360 return LIS.IsStrictCompare; 6361 }); 6362 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6363 // unsigned IV)) for worksharing loops. 6364 SourceLocation CondLoc = AStmt->getBeginLoc(); 6365 Expr *BoundUB = UB.get(); 6366 if (UseStrictCompare) { 6367 BoundUB = 6368 SemaRef 6369 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6370 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6371 .get(); 6372 BoundUB = 6373 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6374 } 6375 ExprResult Cond = 6376 (isOpenMPWorksharingDirective(DKind) || 6377 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6378 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6379 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6380 BoundUB) 6381 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6382 NumIterations.get()); 6383 ExprResult CombDistCond; 6384 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6385 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6386 NumIterations.get()); 6387 } 6388 6389 ExprResult CombCond; 6390 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6391 Expr *BoundCombUB = CombUB.get(); 6392 if (UseStrictCompare) { 6393 BoundCombUB = 6394 SemaRef 6395 .BuildBinOp( 6396 CurScope, CondLoc, BO_Add, BoundCombUB, 6397 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6398 .get(); 6399 BoundCombUB = 6400 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6401 .get(); 6402 } 6403 CombCond = 6404 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6405 IV.get(), BoundCombUB); 6406 } 6407 // Loop increment (IV = IV + 1) 6408 SourceLocation IncLoc = AStmt->getBeginLoc(); 6409 ExprResult Inc = 6410 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6411 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6412 if (!Inc.isUsable()) 6413 return 0; 6414 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6415 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6416 if (!Inc.isUsable()) 6417 return 0; 6418 6419 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6420 // Used for directives with static scheduling. 6421 // In combined construct, add combined version that use CombLB and CombUB 6422 // base variables for the update 6423 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6424 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6425 isOpenMPDistributeDirective(DKind)) { 6426 // LB + ST 6427 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6428 if (!NextLB.isUsable()) 6429 return 0; 6430 // LB = LB + ST 6431 NextLB = 6432 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6433 NextLB = 6434 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6435 if (!NextLB.isUsable()) 6436 return 0; 6437 // UB + ST 6438 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6439 if (!NextUB.isUsable()) 6440 return 0; 6441 // UB = UB + ST 6442 NextUB = 6443 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6444 NextUB = 6445 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6446 if (!NextUB.isUsable()) 6447 return 0; 6448 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6449 CombNextLB = 6450 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6451 if (!NextLB.isUsable()) 6452 return 0; 6453 // LB = LB + ST 6454 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 6455 CombNextLB.get()); 6456 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 6457 /*DiscardedValue*/ false); 6458 if (!CombNextLB.isUsable()) 6459 return 0; 6460 // UB + ST 6461 CombNextUB = 6462 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 6463 if (!CombNextUB.isUsable()) 6464 return 0; 6465 // UB = UB + ST 6466 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 6467 CombNextUB.get()); 6468 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 6469 /*DiscardedValue*/ false); 6470 if (!CombNextUB.isUsable()) 6471 return 0; 6472 } 6473 } 6474 6475 // Create increment expression for distribute loop when combined in a same 6476 // directive with for as IV = IV + ST; ensure upper bound expression based 6477 // on PrevUB instead of NumIterations - used to implement 'for' when found 6478 // in combination with 'distribute', like in 'distribute parallel for' 6479 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 6480 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 6481 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6482 DistCond = SemaRef.BuildBinOp( 6483 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 6484 assert(DistCond.isUsable() && "distribute cond expr was not built"); 6485 6486 DistInc = 6487 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 6488 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6489 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 6490 DistInc.get()); 6491 DistInc = 6492 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 6493 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6494 6495 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 6496 // construct 6497 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 6498 ExprResult IsUBGreater = 6499 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 6500 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6501 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 6502 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 6503 CondOp.get()); 6504 PrevEUB = 6505 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 6506 6507 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 6508 // parallel for is in combination with a distribute directive with 6509 // schedule(static, 1) 6510 Expr *BoundPrevUB = PrevUB.get(); 6511 if (UseStrictCompare) { 6512 BoundPrevUB = 6513 SemaRef 6514 .BuildBinOp( 6515 CurScope, CondLoc, BO_Add, BoundPrevUB, 6516 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6517 .get(); 6518 BoundPrevUB = 6519 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 6520 .get(); 6521 } 6522 ParForInDistCond = 6523 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6524 IV.get(), BoundPrevUB); 6525 } 6526 6527 // Build updates and final values of the loop counters. 6528 bool HasErrors = false; 6529 Built.Counters.resize(NestedLoopCount); 6530 Built.Inits.resize(NestedLoopCount); 6531 Built.Updates.resize(NestedLoopCount); 6532 Built.Finals.resize(NestedLoopCount); 6533 { 6534 // We implement the following algorithm for obtaining the 6535 // original loop iteration variable values based on the 6536 // value of the collapsed loop iteration variable IV. 6537 // 6538 // Let n+1 be the number of collapsed loops in the nest. 6539 // Iteration variables (I0, I1, .... In) 6540 // Iteration counts (N0, N1, ... Nn) 6541 // 6542 // Acc = IV; 6543 // 6544 // To compute Ik for loop k, 0 <= k <= n, generate: 6545 // Prod = N(k+1) * N(k+2) * ... * Nn; 6546 // Ik = Acc / Prod; 6547 // Acc -= Ik * Prod; 6548 // 6549 ExprResult Acc = IV; 6550 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6551 LoopIterationSpace &IS = IterSpaces[Cnt]; 6552 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 6553 ExprResult Iter; 6554 6555 // Compute prod 6556 ExprResult Prod = 6557 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 6558 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 6559 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 6560 IterSpaces[K].NumIterations); 6561 6562 // Iter = Acc / Prod 6563 // If there is at least one more inner loop to avoid 6564 // multiplication by 1. 6565 if (Cnt + 1 < NestedLoopCount) 6566 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 6567 Acc.get(), Prod.get()); 6568 else 6569 Iter = Acc; 6570 if (!Iter.isUsable()) { 6571 HasErrors = true; 6572 break; 6573 } 6574 6575 // Update Acc: 6576 // Acc -= Iter * Prod 6577 // Check if there is at least one more inner loop to avoid 6578 // multiplication by 1. 6579 if (Cnt + 1 < NestedLoopCount) 6580 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 6581 Iter.get(), Prod.get()); 6582 else 6583 Prod = Iter; 6584 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 6585 Acc.get(), Prod.get()); 6586 6587 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 6588 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 6589 DeclRefExpr *CounterVar = buildDeclRefExpr( 6590 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 6591 /*RefersToCapture=*/true); 6592 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 6593 IS.CounterInit, Captures); 6594 if (!Init.isUsable()) { 6595 HasErrors = true; 6596 break; 6597 } 6598 ExprResult Update = buildCounterUpdate( 6599 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 6600 IS.CounterStep, IS.Subtract, &Captures); 6601 if (!Update.isUsable()) { 6602 HasErrors = true; 6603 break; 6604 } 6605 6606 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 6607 ExprResult Final = buildCounterUpdate( 6608 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 6609 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 6610 if (!Final.isUsable()) { 6611 HasErrors = true; 6612 break; 6613 } 6614 6615 if (!Update.isUsable() || !Final.isUsable()) { 6616 HasErrors = true; 6617 break; 6618 } 6619 // Save results 6620 Built.Counters[Cnt] = IS.CounterVar; 6621 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 6622 Built.Inits[Cnt] = Init.get(); 6623 Built.Updates[Cnt] = Update.get(); 6624 Built.Finals[Cnt] = Final.get(); 6625 } 6626 } 6627 6628 if (HasErrors) 6629 return 0; 6630 6631 // Save results 6632 Built.IterationVarRef = IV.get(); 6633 Built.LastIteration = LastIteration.get(); 6634 Built.NumIterations = NumIterations.get(); 6635 Built.CalcLastIteration = SemaRef 6636 .ActOnFinishFullExpr(CalcLastIteration.get(), 6637 /*DiscardedValue*/ false) 6638 .get(); 6639 Built.PreCond = PreCond.get(); 6640 Built.PreInits = buildPreInits(C, Captures); 6641 Built.Cond = Cond.get(); 6642 Built.Init = Init.get(); 6643 Built.Inc = Inc.get(); 6644 Built.LB = LB.get(); 6645 Built.UB = UB.get(); 6646 Built.IL = IL.get(); 6647 Built.ST = ST.get(); 6648 Built.EUB = EUB.get(); 6649 Built.NLB = NextLB.get(); 6650 Built.NUB = NextUB.get(); 6651 Built.PrevLB = PrevLB.get(); 6652 Built.PrevUB = PrevUB.get(); 6653 Built.DistInc = DistInc.get(); 6654 Built.PrevEUB = PrevEUB.get(); 6655 Built.DistCombinedFields.LB = CombLB.get(); 6656 Built.DistCombinedFields.UB = CombUB.get(); 6657 Built.DistCombinedFields.EUB = CombEUB.get(); 6658 Built.DistCombinedFields.Init = CombInit.get(); 6659 Built.DistCombinedFields.Cond = CombCond.get(); 6660 Built.DistCombinedFields.NLB = CombNextLB.get(); 6661 Built.DistCombinedFields.NUB = CombNextUB.get(); 6662 Built.DistCombinedFields.DistCond = CombDistCond.get(); 6663 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 6664 6665 return NestedLoopCount; 6666 } 6667 6668 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 6669 auto CollapseClauses = 6670 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 6671 if (CollapseClauses.begin() != CollapseClauses.end()) 6672 return (*CollapseClauses.begin())->getNumForLoops(); 6673 return nullptr; 6674 } 6675 6676 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 6677 auto OrderedClauses = 6678 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 6679 if (OrderedClauses.begin() != OrderedClauses.end()) 6680 return (*OrderedClauses.begin())->getNumForLoops(); 6681 return nullptr; 6682 } 6683 6684 static bool checkSimdlenSafelenSpecified(Sema &S, 6685 const ArrayRef<OMPClause *> Clauses) { 6686 const OMPSafelenClause *Safelen = nullptr; 6687 const OMPSimdlenClause *Simdlen = nullptr; 6688 6689 for (const OMPClause *Clause : Clauses) { 6690 if (Clause->getClauseKind() == OMPC_safelen) 6691 Safelen = cast<OMPSafelenClause>(Clause); 6692 else if (Clause->getClauseKind() == OMPC_simdlen) 6693 Simdlen = cast<OMPSimdlenClause>(Clause); 6694 if (Safelen && Simdlen) 6695 break; 6696 } 6697 6698 if (Simdlen && Safelen) { 6699 const Expr *SimdlenLength = Simdlen->getSimdlen(); 6700 const Expr *SafelenLength = Safelen->getSafelen(); 6701 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 6702 SimdlenLength->isInstantiationDependent() || 6703 SimdlenLength->containsUnexpandedParameterPack()) 6704 return false; 6705 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 6706 SafelenLength->isInstantiationDependent() || 6707 SafelenLength->containsUnexpandedParameterPack()) 6708 return false; 6709 Expr::EvalResult SimdlenResult, SafelenResult; 6710 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 6711 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 6712 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 6713 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 6714 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 6715 // If both simdlen and safelen clauses are specified, the value of the 6716 // simdlen parameter must be less than or equal to the value of the safelen 6717 // parameter. 6718 if (SimdlenRes > SafelenRes) { 6719 S.Diag(SimdlenLength->getExprLoc(), 6720 diag::err_omp_wrong_simdlen_safelen_values) 6721 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 6722 return true; 6723 } 6724 } 6725 return false; 6726 } 6727 6728 StmtResult 6729 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6730 SourceLocation StartLoc, SourceLocation EndLoc, 6731 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6732 if (!AStmt) 6733 return StmtError(); 6734 6735 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6736 OMPLoopDirective::HelperExprs B; 6737 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6738 // define the nested loops number. 6739 unsigned NestedLoopCount = checkOpenMPLoop( 6740 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6741 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6742 if (NestedLoopCount == 0) 6743 return StmtError(); 6744 6745 assert((CurContext->isDependentContext() || B.builtAll()) && 6746 "omp simd loop exprs were not built"); 6747 6748 if (!CurContext->isDependentContext()) { 6749 // Finalize the clauses that need pre-built expressions for CodeGen. 6750 for (OMPClause *C : Clauses) { 6751 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6752 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6753 B.NumIterations, *this, CurScope, 6754 DSAStack)) 6755 return StmtError(); 6756 } 6757 } 6758 6759 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6760 return StmtError(); 6761 6762 setFunctionHasBranchProtectedScope(); 6763 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6764 Clauses, AStmt, B); 6765 } 6766 6767 StmtResult 6768 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6769 SourceLocation StartLoc, SourceLocation EndLoc, 6770 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6771 if (!AStmt) 6772 return StmtError(); 6773 6774 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6775 OMPLoopDirective::HelperExprs B; 6776 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6777 // define the nested loops number. 6778 unsigned NestedLoopCount = checkOpenMPLoop( 6779 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6780 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6781 if (NestedLoopCount == 0) 6782 return StmtError(); 6783 6784 assert((CurContext->isDependentContext() || B.builtAll()) && 6785 "omp for loop exprs were not built"); 6786 6787 if (!CurContext->isDependentContext()) { 6788 // Finalize the clauses that need pre-built expressions for CodeGen. 6789 for (OMPClause *C : Clauses) { 6790 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6791 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6792 B.NumIterations, *this, CurScope, 6793 DSAStack)) 6794 return StmtError(); 6795 } 6796 } 6797 6798 setFunctionHasBranchProtectedScope(); 6799 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6800 Clauses, AStmt, B, DSAStack->isCancelRegion()); 6801 } 6802 6803 StmtResult Sema::ActOnOpenMPForSimdDirective( 6804 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6805 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6806 if (!AStmt) 6807 return StmtError(); 6808 6809 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6810 OMPLoopDirective::HelperExprs B; 6811 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6812 // define the nested loops number. 6813 unsigned NestedLoopCount = 6814 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 6815 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6816 VarsWithImplicitDSA, B); 6817 if (NestedLoopCount == 0) 6818 return StmtError(); 6819 6820 assert((CurContext->isDependentContext() || B.builtAll()) && 6821 "omp for simd loop exprs were not built"); 6822 6823 if (!CurContext->isDependentContext()) { 6824 // Finalize the clauses that need pre-built expressions for CodeGen. 6825 for (OMPClause *C : Clauses) { 6826 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6827 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6828 B.NumIterations, *this, CurScope, 6829 DSAStack)) 6830 return StmtError(); 6831 } 6832 } 6833 6834 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6835 return StmtError(); 6836 6837 setFunctionHasBranchProtectedScope(); 6838 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6839 Clauses, AStmt, B); 6840 } 6841 6842 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 6843 Stmt *AStmt, 6844 SourceLocation StartLoc, 6845 SourceLocation EndLoc) { 6846 if (!AStmt) 6847 return StmtError(); 6848 6849 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6850 auto BaseStmt = AStmt; 6851 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6852 BaseStmt = CS->getCapturedStmt(); 6853 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6854 auto S = C->children(); 6855 if (S.begin() == S.end()) 6856 return StmtError(); 6857 // All associated statements must be '#pragma omp section' except for 6858 // the first one. 6859 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6860 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6861 if (SectionStmt) 6862 Diag(SectionStmt->getBeginLoc(), 6863 diag::err_omp_sections_substmt_not_section); 6864 return StmtError(); 6865 } 6866 cast<OMPSectionDirective>(SectionStmt) 6867 ->setHasCancel(DSAStack->isCancelRegion()); 6868 } 6869 } else { 6870 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 6871 return StmtError(); 6872 } 6873 6874 setFunctionHasBranchProtectedScope(); 6875 6876 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6877 DSAStack->isCancelRegion()); 6878 } 6879 6880 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 6881 SourceLocation StartLoc, 6882 SourceLocation EndLoc) { 6883 if (!AStmt) 6884 return StmtError(); 6885 6886 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6887 6888 setFunctionHasBranchProtectedScope(); 6889 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 6890 6891 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 6892 DSAStack->isCancelRegion()); 6893 } 6894 6895 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 6896 Stmt *AStmt, 6897 SourceLocation StartLoc, 6898 SourceLocation EndLoc) { 6899 if (!AStmt) 6900 return StmtError(); 6901 6902 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6903 6904 setFunctionHasBranchProtectedScope(); 6905 6906 // OpenMP [2.7.3, single Construct, Restrictions] 6907 // The copyprivate clause must not be used with the nowait clause. 6908 const OMPClause *Nowait = nullptr; 6909 const OMPClause *Copyprivate = nullptr; 6910 for (const OMPClause *Clause : Clauses) { 6911 if (Clause->getClauseKind() == OMPC_nowait) 6912 Nowait = Clause; 6913 else if (Clause->getClauseKind() == OMPC_copyprivate) 6914 Copyprivate = Clause; 6915 if (Copyprivate && Nowait) { 6916 Diag(Copyprivate->getBeginLoc(), 6917 diag::err_omp_single_copyprivate_with_nowait); 6918 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 6919 return StmtError(); 6920 } 6921 } 6922 6923 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6924 } 6925 6926 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 6927 SourceLocation StartLoc, 6928 SourceLocation EndLoc) { 6929 if (!AStmt) 6930 return StmtError(); 6931 6932 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6933 6934 setFunctionHasBranchProtectedScope(); 6935 6936 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 6937 } 6938 6939 StmtResult Sema::ActOnOpenMPCriticalDirective( 6940 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 6941 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6942 if (!AStmt) 6943 return StmtError(); 6944 6945 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6946 6947 bool ErrorFound = false; 6948 llvm::APSInt Hint; 6949 SourceLocation HintLoc; 6950 bool DependentHint = false; 6951 for (const OMPClause *C : Clauses) { 6952 if (C->getClauseKind() == OMPC_hint) { 6953 if (!DirName.getName()) { 6954 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 6955 ErrorFound = true; 6956 } 6957 Expr *E = cast<OMPHintClause>(C)->getHint(); 6958 if (E->isTypeDependent() || E->isValueDependent() || 6959 E->isInstantiationDependent()) { 6960 DependentHint = true; 6961 } else { 6962 Hint = E->EvaluateKnownConstInt(Context); 6963 HintLoc = C->getBeginLoc(); 6964 } 6965 } 6966 } 6967 if (ErrorFound) 6968 return StmtError(); 6969 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6970 if (Pair.first && DirName.getName() && !DependentHint) { 6971 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6972 Diag(StartLoc, diag::err_omp_critical_with_hint); 6973 if (HintLoc.isValid()) 6974 Diag(HintLoc, diag::note_omp_critical_hint_here) 6975 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6976 else 6977 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6978 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6979 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6980 << 1 6981 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6982 /*Radix=*/10, /*Signed=*/false); 6983 } else { 6984 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6985 } 6986 } 6987 } 6988 6989 setFunctionHasBranchProtectedScope(); 6990 6991 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6992 Clauses, AStmt); 6993 if (!Pair.first && DirName.getName() && !DependentHint) 6994 DSAStack->addCriticalWithHint(Dir, Hint); 6995 return Dir; 6996 } 6997 6998 StmtResult Sema::ActOnOpenMPParallelForDirective( 6999 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7000 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7001 if (!AStmt) 7002 return StmtError(); 7003 7004 auto *CS = cast<CapturedStmt>(AStmt); 7005 // 1.2.2 OpenMP Language Terminology 7006 // Structured block - An executable statement with a single entry at the 7007 // top and a single exit at the bottom. 7008 // The point of exit cannot be a branch out of the structured block. 7009 // longjmp() and throw() must not violate the entry/exit criteria. 7010 CS->getCapturedDecl()->setNothrow(); 7011 7012 OMPLoopDirective::HelperExprs B; 7013 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7014 // define the nested loops number. 7015 unsigned NestedLoopCount = 7016 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7017 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7018 VarsWithImplicitDSA, B); 7019 if (NestedLoopCount == 0) 7020 return StmtError(); 7021 7022 assert((CurContext->isDependentContext() || B.builtAll()) && 7023 "omp parallel for loop exprs were not built"); 7024 7025 if (!CurContext->isDependentContext()) { 7026 // Finalize the clauses that need pre-built expressions for CodeGen. 7027 for (OMPClause *C : Clauses) { 7028 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7029 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7030 B.NumIterations, *this, CurScope, 7031 DSAStack)) 7032 return StmtError(); 7033 } 7034 } 7035 7036 setFunctionHasBranchProtectedScope(); 7037 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7038 NestedLoopCount, Clauses, AStmt, B, 7039 DSAStack->isCancelRegion()); 7040 } 7041 7042 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7043 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7044 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7045 if (!AStmt) 7046 return StmtError(); 7047 7048 auto *CS = cast<CapturedStmt>(AStmt); 7049 // 1.2.2 OpenMP Language Terminology 7050 // Structured block - An executable statement with a single entry at the 7051 // top and a single exit at the bottom. 7052 // The point of exit cannot be a branch out of the structured block. 7053 // longjmp() and throw() must not violate the entry/exit criteria. 7054 CS->getCapturedDecl()->setNothrow(); 7055 7056 OMPLoopDirective::HelperExprs B; 7057 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7058 // define the nested loops number. 7059 unsigned NestedLoopCount = 7060 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7061 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7062 VarsWithImplicitDSA, B); 7063 if (NestedLoopCount == 0) 7064 return StmtError(); 7065 7066 if (!CurContext->isDependentContext()) { 7067 // Finalize the clauses that need pre-built expressions for CodeGen. 7068 for (OMPClause *C : Clauses) { 7069 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7070 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7071 B.NumIterations, *this, CurScope, 7072 DSAStack)) 7073 return StmtError(); 7074 } 7075 } 7076 7077 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7078 return StmtError(); 7079 7080 setFunctionHasBranchProtectedScope(); 7081 return OMPParallelForSimdDirective::Create( 7082 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7083 } 7084 7085 StmtResult 7086 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7087 Stmt *AStmt, SourceLocation StartLoc, 7088 SourceLocation EndLoc) { 7089 if (!AStmt) 7090 return StmtError(); 7091 7092 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7093 auto BaseStmt = AStmt; 7094 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7095 BaseStmt = CS->getCapturedStmt(); 7096 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7097 auto S = C->children(); 7098 if (S.begin() == S.end()) 7099 return StmtError(); 7100 // All associated statements must be '#pragma omp section' except for 7101 // the first one. 7102 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7103 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7104 if (SectionStmt) 7105 Diag(SectionStmt->getBeginLoc(), 7106 diag::err_omp_parallel_sections_substmt_not_section); 7107 return StmtError(); 7108 } 7109 cast<OMPSectionDirective>(SectionStmt) 7110 ->setHasCancel(DSAStack->isCancelRegion()); 7111 } 7112 } else { 7113 Diag(AStmt->getBeginLoc(), 7114 diag::err_omp_parallel_sections_not_compound_stmt); 7115 return StmtError(); 7116 } 7117 7118 setFunctionHasBranchProtectedScope(); 7119 7120 return OMPParallelSectionsDirective::Create( 7121 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7122 } 7123 7124 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7125 Stmt *AStmt, SourceLocation StartLoc, 7126 SourceLocation EndLoc) { 7127 if (!AStmt) 7128 return StmtError(); 7129 7130 auto *CS = cast<CapturedStmt>(AStmt); 7131 // 1.2.2 OpenMP Language Terminology 7132 // Structured block - An executable statement with a single entry at the 7133 // top and a single exit at the bottom. 7134 // The point of exit cannot be a branch out of the structured block. 7135 // longjmp() and throw() must not violate the entry/exit criteria. 7136 CS->getCapturedDecl()->setNothrow(); 7137 7138 setFunctionHasBranchProtectedScope(); 7139 7140 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7141 DSAStack->isCancelRegion()); 7142 } 7143 7144 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7145 SourceLocation EndLoc) { 7146 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7147 } 7148 7149 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7150 SourceLocation EndLoc) { 7151 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7152 } 7153 7154 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7155 SourceLocation EndLoc) { 7156 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7157 } 7158 7159 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7160 Stmt *AStmt, 7161 SourceLocation StartLoc, 7162 SourceLocation EndLoc) { 7163 if (!AStmt) 7164 return StmtError(); 7165 7166 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7167 7168 setFunctionHasBranchProtectedScope(); 7169 7170 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7171 AStmt, 7172 DSAStack->getTaskgroupReductionRef()); 7173 } 7174 7175 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7176 SourceLocation StartLoc, 7177 SourceLocation EndLoc) { 7178 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7179 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7180 } 7181 7182 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7183 Stmt *AStmt, 7184 SourceLocation StartLoc, 7185 SourceLocation EndLoc) { 7186 const OMPClause *DependFound = nullptr; 7187 const OMPClause *DependSourceClause = nullptr; 7188 const OMPClause *DependSinkClause = nullptr; 7189 bool ErrorFound = false; 7190 const OMPThreadsClause *TC = nullptr; 7191 const OMPSIMDClause *SC = nullptr; 7192 for (const OMPClause *C : Clauses) { 7193 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7194 DependFound = C; 7195 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7196 if (DependSourceClause) { 7197 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7198 << getOpenMPDirectiveName(OMPD_ordered) 7199 << getOpenMPClauseName(OMPC_depend) << 2; 7200 ErrorFound = true; 7201 } else { 7202 DependSourceClause = C; 7203 } 7204 if (DependSinkClause) { 7205 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7206 << 0; 7207 ErrorFound = true; 7208 } 7209 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7210 if (DependSourceClause) { 7211 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7212 << 1; 7213 ErrorFound = true; 7214 } 7215 DependSinkClause = C; 7216 } 7217 } else if (C->getClauseKind() == OMPC_threads) { 7218 TC = cast<OMPThreadsClause>(C); 7219 } else if (C->getClauseKind() == OMPC_simd) { 7220 SC = cast<OMPSIMDClause>(C); 7221 } 7222 } 7223 if (!ErrorFound && !SC && 7224 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7225 // OpenMP [2.8.1,simd Construct, Restrictions] 7226 // An ordered construct with the simd clause is the only OpenMP construct 7227 // that can appear in the simd region. 7228 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7229 ErrorFound = true; 7230 } else if (DependFound && (TC || SC)) { 7231 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7232 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7233 ErrorFound = true; 7234 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7235 Diag(DependFound->getBeginLoc(), 7236 diag::err_omp_ordered_directive_without_param); 7237 ErrorFound = true; 7238 } else if (TC || Clauses.empty()) { 7239 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 7240 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 7241 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 7242 << (TC != nullptr); 7243 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7244 ErrorFound = true; 7245 } 7246 } 7247 if ((!AStmt && !DependFound) || ErrorFound) 7248 return StmtError(); 7249 7250 if (AStmt) { 7251 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7252 7253 setFunctionHasBranchProtectedScope(); 7254 } 7255 7256 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7257 } 7258 7259 namespace { 7260 /// Helper class for checking expression in 'omp atomic [update]' 7261 /// construct. 7262 class OpenMPAtomicUpdateChecker { 7263 /// Error results for atomic update expressions. 7264 enum ExprAnalysisErrorCode { 7265 /// A statement is not an expression statement. 7266 NotAnExpression, 7267 /// Expression is not builtin binary or unary operation. 7268 NotABinaryOrUnaryExpression, 7269 /// Unary operation is not post-/pre- increment/decrement operation. 7270 NotAnUnaryIncDecExpression, 7271 /// An expression is not of scalar type. 7272 NotAScalarType, 7273 /// A binary operation is not an assignment operation. 7274 NotAnAssignmentOp, 7275 /// RHS part of the binary operation is not a binary expression. 7276 NotABinaryExpression, 7277 /// RHS part is not additive/multiplicative/shift/biwise binary 7278 /// expression. 7279 NotABinaryOperator, 7280 /// RHS binary operation does not have reference to the updated LHS 7281 /// part. 7282 NotAnUpdateExpression, 7283 /// No errors is found. 7284 NoError 7285 }; 7286 /// Reference to Sema. 7287 Sema &SemaRef; 7288 /// A location for note diagnostics (when error is found). 7289 SourceLocation NoteLoc; 7290 /// 'x' lvalue part of the source atomic expression. 7291 Expr *X; 7292 /// 'expr' rvalue part of the source atomic expression. 7293 Expr *E; 7294 /// Helper expression of the form 7295 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7296 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7297 Expr *UpdateExpr; 7298 /// Is 'x' a LHS in a RHS part of full update expression. It is 7299 /// important for non-associative operations. 7300 bool IsXLHSInRHSPart; 7301 BinaryOperatorKind Op; 7302 SourceLocation OpLoc; 7303 /// true if the source expression is a postfix unary operation, false 7304 /// if it is a prefix unary operation. 7305 bool IsPostfixUpdate; 7306 7307 public: 7308 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7309 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7310 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7311 /// Check specified statement that it is suitable for 'atomic update' 7312 /// constructs and extract 'x', 'expr' and Operation from the original 7313 /// expression. If DiagId and NoteId == 0, then only check is performed 7314 /// without error notification. 7315 /// \param DiagId Diagnostic which should be emitted if error is found. 7316 /// \param NoteId Diagnostic note for the main error message. 7317 /// \return true if statement is not an update expression, false otherwise. 7318 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7319 /// Return the 'x' lvalue part of the source atomic expression. 7320 Expr *getX() const { return X; } 7321 /// Return the 'expr' rvalue part of the source atomic expression. 7322 Expr *getExpr() const { return E; } 7323 /// Return the update expression used in calculation of the updated 7324 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7325 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7326 Expr *getUpdateExpr() const { return UpdateExpr; } 7327 /// Return true if 'x' is LHS in RHS part of full update expression, 7328 /// false otherwise. 7329 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7330 7331 /// true if the source expression is a postfix unary operation, false 7332 /// if it is a prefix unary operation. 7333 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7334 7335 private: 7336 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7337 unsigned NoteId = 0); 7338 }; 7339 } // namespace 7340 7341 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7342 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7343 ExprAnalysisErrorCode ErrorFound = NoError; 7344 SourceLocation ErrorLoc, NoteLoc; 7345 SourceRange ErrorRange, NoteRange; 7346 // Allowed constructs are: 7347 // x = x binop expr; 7348 // x = expr binop x; 7349 if (AtomicBinOp->getOpcode() == BO_Assign) { 7350 X = AtomicBinOp->getLHS(); 7351 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7352 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7353 if (AtomicInnerBinOp->isMultiplicativeOp() || 7354 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7355 AtomicInnerBinOp->isBitwiseOp()) { 7356 Op = AtomicInnerBinOp->getOpcode(); 7357 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7358 Expr *LHS = AtomicInnerBinOp->getLHS(); 7359 Expr *RHS = AtomicInnerBinOp->getRHS(); 7360 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7361 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7362 /*Canonical=*/true); 7363 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7364 /*Canonical=*/true); 7365 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7366 /*Canonical=*/true); 7367 if (XId == LHSId) { 7368 E = RHS; 7369 IsXLHSInRHSPart = true; 7370 } else if (XId == RHSId) { 7371 E = LHS; 7372 IsXLHSInRHSPart = false; 7373 } else { 7374 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7375 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7376 NoteLoc = X->getExprLoc(); 7377 NoteRange = X->getSourceRange(); 7378 ErrorFound = NotAnUpdateExpression; 7379 } 7380 } else { 7381 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7382 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7383 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7384 NoteRange = SourceRange(NoteLoc, NoteLoc); 7385 ErrorFound = NotABinaryOperator; 7386 } 7387 } else { 7388 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7389 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7390 ErrorFound = NotABinaryExpression; 7391 } 7392 } else { 7393 ErrorLoc = AtomicBinOp->getExprLoc(); 7394 ErrorRange = AtomicBinOp->getSourceRange(); 7395 NoteLoc = AtomicBinOp->getOperatorLoc(); 7396 NoteRange = SourceRange(NoteLoc, NoteLoc); 7397 ErrorFound = NotAnAssignmentOp; 7398 } 7399 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7400 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7401 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7402 return true; 7403 } 7404 if (SemaRef.CurContext->isDependentContext()) 7405 E = X = UpdateExpr = nullptr; 7406 return ErrorFound != NoError; 7407 } 7408 7409 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7410 unsigned NoteId) { 7411 ExprAnalysisErrorCode ErrorFound = NoError; 7412 SourceLocation ErrorLoc, NoteLoc; 7413 SourceRange ErrorRange, NoteRange; 7414 // Allowed constructs are: 7415 // x++; 7416 // x--; 7417 // ++x; 7418 // --x; 7419 // x binop= expr; 7420 // x = x binop expr; 7421 // x = expr binop x; 7422 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7423 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7424 if (AtomicBody->getType()->isScalarType() || 7425 AtomicBody->isInstantiationDependent()) { 7426 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7427 AtomicBody->IgnoreParenImpCasts())) { 7428 // Check for Compound Assignment Operation 7429 Op = BinaryOperator::getOpForCompoundAssignment( 7430 AtomicCompAssignOp->getOpcode()); 7431 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7432 E = AtomicCompAssignOp->getRHS(); 7433 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7434 IsXLHSInRHSPart = true; 7435 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7436 AtomicBody->IgnoreParenImpCasts())) { 7437 // Check for Binary Operation 7438 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 7439 return true; 7440 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 7441 AtomicBody->IgnoreParenImpCasts())) { 7442 // Check for Unary Operation 7443 if (AtomicUnaryOp->isIncrementDecrementOp()) { 7444 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 7445 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 7446 OpLoc = AtomicUnaryOp->getOperatorLoc(); 7447 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 7448 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 7449 IsXLHSInRHSPart = true; 7450 } else { 7451 ErrorFound = NotAnUnaryIncDecExpression; 7452 ErrorLoc = AtomicUnaryOp->getExprLoc(); 7453 ErrorRange = AtomicUnaryOp->getSourceRange(); 7454 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 7455 NoteRange = SourceRange(NoteLoc, NoteLoc); 7456 } 7457 } else if (!AtomicBody->isInstantiationDependent()) { 7458 ErrorFound = NotABinaryOrUnaryExpression; 7459 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 7460 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 7461 } 7462 } else { 7463 ErrorFound = NotAScalarType; 7464 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 7465 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7466 } 7467 } else { 7468 ErrorFound = NotAnExpression; 7469 NoteLoc = ErrorLoc = S->getBeginLoc(); 7470 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7471 } 7472 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7473 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7474 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7475 return true; 7476 } 7477 if (SemaRef.CurContext->isDependentContext()) 7478 E = X = UpdateExpr = nullptr; 7479 if (ErrorFound == NoError && E && X) { 7480 // Build an update expression of form 'OpaqueValueExpr(x) binop 7481 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 7482 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 7483 auto *OVEX = new (SemaRef.getASTContext()) 7484 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 7485 auto *OVEExpr = new (SemaRef.getASTContext()) 7486 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 7487 ExprResult Update = 7488 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 7489 IsXLHSInRHSPart ? OVEExpr : OVEX); 7490 if (Update.isInvalid()) 7491 return true; 7492 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 7493 Sema::AA_Casting); 7494 if (Update.isInvalid()) 7495 return true; 7496 UpdateExpr = Update.get(); 7497 } 7498 return ErrorFound != NoError; 7499 } 7500 7501 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 7502 Stmt *AStmt, 7503 SourceLocation StartLoc, 7504 SourceLocation EndLoc) { 7505 if (!AStmt) 7506 return StmtError(); 7507 7508 auto *CS = cast<CapturedStmt>(AStmt); 7509 // 1.2.2 OpenMP Language Terminology 7510 // Structured block - An executable statement with a single entry at the 7511 // top and a single exit at the bottom. 7512 // The point of exit cannot be a branch out of the structured block. 7513 // longjmp() and throw() must not violate the entry/exit criteria. 7514 OpenMPClauseKind AtomicKind = OMPC_unknown; 7515 SourceLocation AtomicKindLoc; 7516 for (const OMPClause *C : Clauses) { 7517 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 7518 C->getClauseKind() == OMPC_update || 7519 C->getClauseKind() == OMPC_capture) { 7520 if (AtomicKind != OMPC_unknown) { 7521 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 7522 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 7523 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 7524 << getOpenMPClauseName(AtomicKind); 7525 } else { 7526 AtomicKind = C->getClauseKind(); 7527 AtomicKindLoc = C->getBeginLoc(); 7528 } 7529 } 7530 } 7531 7532 Stmt *Body = CS->getCapturedStmt(); 7533 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 7534 Body = EWC->getSubExpr(); 7535 7536 Expr *X = nullptr; 7537 Expr *V = nullptr; 7538 Expr *E = nullptr; 7539 Expr *UE = nullptr; 7540 bool IsXLHSInRHSPart = false; 7541 bool IsPostfixUpdate = false; 7542 // OpenMP [2.12.6, atomic Construct] 7543 // In the next expressions: 7544 // * x and v (as applicable) are both l-value expressions with scalar type. 7545 // * During the execution of an atomic region, multiple syntactic 7546 // occurrences of x must designate the same storage location. 7547 // * Neither of v and expr (as applicable) may access the storage location 7548 // designated by x. 7549 // * Neither of x and expr (as applicable) may access the storage location 7550 // designated by v. 7551 // * expr is an expression with scalar type. 7552 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 7553 // * binop, binop=, ++, and -- are not overloaded operators. 7554 // * The expression x binop expr must be numerically equivalent to x binop 7555 // (expr). This requirement is satisfied if the operators in expr have 7556 // precedence greater than binop, or by using parentheses around expr or 7557 // subexpressions of expr. 7558 // * The expression expr binop x must be numerically equivalent to (expr) 7559 // binop x. This requirement is satisfied if the operators in expr have 7560 // precedence equal to or greater than binop, or by using parentheses around 7561 // expr or subexpressions of expr. 7562 // * For forms that allow multiple occurrences of x, the number of times 7563 // that x is evaluated is unspecified. 7564 if (AtomicKind == OMPC_read) { 7565 enum { 7566 NotAnExpression, 7567 NotAnAssignmentOp, 7568 NotAScalarType, 7569 NotAnLValue, 7570 NoError 7571 } ErrorFound = NoError; 7572 SourceLocation ErrorLoc, NoteLoc; 7573 SourceRange ErrorRange, NoteRange; 7574 // If clause is read: 7575 // v = x; 7576 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7577 const auto *AtomicBinOp = 7578 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7579 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7580 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7581 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 7582 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7583 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 7584 if (!X->isLValue() || !V->isLValue()) { 7585 const Expr *NotLValueExpr = X->isLValue() ? V : X; 7586 ErrorFound = NotAnLValue; 7587 ErrorLoc = AtomicBinOp->getExprLoc(); 7588 ErrorRange = AtomicBinOp->getSourceRange(); 7589 NoteLoc = NotLValueExpr->getExprLoc(); 7590 NoteRange = NotLValueExpr->getSourceRange(); 7591 } 7592 } else if (!X->isInstantiationDependent() || 7593 !V->isInstantiationDependent()) { 7594 const Expr *NotScalarExpr = 7595 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7596 ? V 7597 : X; 7598 ErrorFound = NotAScalarType; 7599 ErrorLoc = AtomicBinOp->getExprLoc(); 7600 ErrorRange = AtomicBinOp->getSourceRange(); 7601 NoteLoc = NotScalarExpr->getExprLoc(); 7602 NoteRange = NotScalarExpr->getSourceRange(); 7603 } 7604 } else if (!AtomicBody->isInstantiationDependent()) { 7605 ErrorFound = NotAnAssignmentOp; 7606 ErrorLoc = AtomicBody->getExprLoc(); 7607 ErrorRange = AtomicBody->getSourceRange(); 7608 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7609 : AtomicBody->getExprLoc(); 7610 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7611 : AtomicBody->getSourceRange(); 7612 } 7613 } else { 7614 ErrorFound = NotAnExpression; 7615 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7616 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7617 } 7618 if (ErrorFound != NoError) { 7619 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 7620 << ErrorRange; 7621 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7622 << NoteRange; 7623 return StmtError(); 7624 } 7625 if (CurContext->isDependentContext()) 7626 V = X = nullptr; 7627 } else if (AtomicKind == OMPC_write) { 7628 enum { 7629 NotAnExpression, 7630 NotAnAssignmentOp, 7631 NotAScalarType, 7632 NotAnLValue, 7633 NoError 7634 } ErrorFound = NoError; 7635 SourceLocation ErrorLoc, NoteLoc; 7636 SourceRange ErrorRange, NoteRange; 7637 // If clause is write: 7638 // x = expr; 7639 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7640 const auto *AtomicBinOp = 7641 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7642 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7643 X = AtomicBinOp->getLHS(); 7644 E = AtomicBinOp->getRHS(); 7645 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7646 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 7647 if (!X->isLValue()) { 7648 ErrorFound = NotAnLValue; 7649 ErrorLoc = AtomicBinOp->getExprLoc(); 7650 ErrorRange = AtomicBinOp->getSourceRange(); 7651 NoteLoc = X->getExprLoc(); 7652 NoteRange = X->getSourceRange(); 7653 } 7654 } else if (!X->isInstantiationDependent() || 7655 !E->isInstantiationDependent()) { 7656 const Expr *NotScalarExpr = 7657 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7658 ? E 7659 : X; 7660 ErrorFound = NotAScalarType; 7661 ErrorLoc = AtomicBinOp->getExprLoc(); 7662 ErrorRange = AtomicBinOp->getSourceRange(); 7663 NoteLoc = NotScalarExpr->getExprLoc(); 7664 NoteRange = NotScalarExpr->getSourceRange(); 7665 } 7666 } else if (!AtomicBody->isInstantiationDependent()) { 7667 ErrorFound = NotAnAssignmentOp; 7668 ErrorLoc = AtomicBody->getExprLoc(); 7669 ErrorRange = AtomicBody->getSourceRange(); 7670 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7671 : AtomicBody->getExprLoc(); 7672 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7673 : AtomicBody->getSourceRange(); 7674 } 7675 } else { 7676 ErrorFound = NotAnExpression; 7677 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7678 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7679 } 7680 if (ErrorFound != NoError) { 7681 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 7682 << ErrorRange; 7683 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7684 << NoteRange; 7685 return StmtError(); 7686 } 7687 if (CurContext->isDependentContext()) 7688 E = X = nullptr; 7689 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 7690 // If clause is update: 7691 // x++; 7692 // x--; 7693 // ++x; 7694 // --x; 7695 // x binop= expr; 7696 // x = x binop expr; 7697 // x = expr binop x; 7698 OpenMPAtomicUpdateChecker Checker(*this); 7699 if (Checker.checkStatement( 7700 Body, (AtomicKind == OMPC_update) 7701 ? diag::err_omp_atomic_update_not_expression_statement 7702 : diag::err_omp_atomic_not_expression_statement, 7703 diag::note_omp_atomic_update)) 7704 return StmtError(); 7705 if (!CurContext->isDependentContext()) { 7706 E = Checker.getExpr(); 7707 X = Checker.getX(); 7708 UE = Checker.getUpdateExpr(); 7709 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7710 } 7711 } else if (AtomicKind == OMPC_capture) { 7712 enum { 7713 NotAnAssignmentOp, 7714 NotACompoundStatement, 7715 NotTwoSubstatements, 7716 NotASpecificExpression, 7717 NoError 7718 } ErrorFound = NoError; 7719 SourceLocation ErrorLoc, NoteLoc; 7720 SourceRange ErrorRange, NoteRange; 7721 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7722 // If clause is a capture: 7723 // v = x++; 7724 // v = x--; 7725 // v = ++x; 7726 // v = --x; 7727 // v = x binop= expr; 7728 // v = x = x binop expr; 7729 // v = x = expr binop x; 7730 const auto *AtomicBinOp = 7731 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7732 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7733 V = AtomicBinOp->getLHS(); 7734 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7735 OpenMPAtomicUpdateChecker Checker(*this); 7736 if (Checker.checkStatement( 7737 Body, diag::err_omp_atomic_capture_not_expression_statement, 7738 diag::note_omp_atomic_update)) 7739 return StmtError(); 7740 E = Checker.getExpr(); 7741 X = Checker.getX(); 7742 UE = Checker.getUpdateExpr(); 7743 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7744 IsPostfixUpdate = Checker.isPostfixUpdate(); 7745 } else if (!AtomicBody->isInstantiationDependent()) { 7746 ErrorLoc = AtomicBody->getExprLoc(); 7747 ErrorRange = AtomicBody->getSourceRange(); 7748 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7749 : AtomicBody->getExprLoc(); 7750 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7751 : AtomicBody->getSourceRange(); 7752 ErrorFound = NotAnAssignmentOp; 7753 } 7754 if (ErrorFound != NoError) { 7755 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 7756 << ErrorRange; 7757 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7758 return StmtError(); 7759 } 7760 if (CurContext->isDependentContext()) 7761 UE = V = E = X = nullptr; 7762 } else { 7763 // If clause is a capture: 7764 // { v = x; x = expr; } 7765 // { v = x; x++; } 7766 // { v = x; x--; } 7767 // { v = x; ++x; } 7768 // { v = x; --x; } 7769 // { v = x; x binop= expr; } 7770 // { v = x; x = x binop expr; } 7771 // { v = x; x = expr binop x; } 7772 // { x++; v = x; } 7773 // { x--; v = x; } 7774 // { ++x; v = x; } 7775 // { --x; v = x; } 7776 // { x binop= expr; v = x; } 7777 // { x = x binop expr; v = x; } 7778 // { x = expr binop x; v = x; } 7779 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 7780 // Check that this is { expr1; expr2; } 7781 if (CS->size() == 2) { 7782 Stmt *First = CS->body_front(); 7783 Stmt *Second = CS->body_back(); 7784 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 7785 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 7786 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 7787 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 7788 // Need to find what subexpression is 'v' and what is 'x'. 7789 OpenMPAtomicUpdateChecker Checker(*this); 7790 bool IsUpdateExprFound = !Checker.checkStatement(Second); 7791 BinaryOperator *BinOp = nullptr; 7792 if (IsUpdateExprFound) { 7793 BinOp = dyn_cast<BinaryOperator>(First); 7794 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7795 } 7796 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7797 // { v = x; x++; } 7798 // { v = x; x--; } 7799 // { v = x; ++x; } 7800 // { v = x; --x; } 7801 // { v = x; x binop= expr; } 7802 // { v = x; x = x binop expr; } 7803 // { v = x; x = expr binop x; } 7804 // Check that the first expression has form v = x. 7805 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7806 llvm::FoldingSetNodeID XId, PossibleXId; 7807 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7808 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7809 IsUpdateExprFound = XId == PossibleXId; 7810 if (IsUpdateExprFound) { 7811 V = BinOp->getLHS(); 7812 X = Checker.getX(); 7813 E = Checker.getExpr(); 7814 UE = Checker.getUpdateExpr(); 7815 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7816 IsPostfixUpdate = true; 7817 } 7818 } 7819 if (!IsUpdateExprFound) { 7820 IsUpdateExprFound = !Checker.checkStatement(First); 7821 BinOp = nullptr; 7822 if (IsUpdateExprFound) { 7823 BinOp = dyn_cast<BinaryOperator>(Second); 7824 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7825 } 7826 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7827 // { x++; v = x; } 7828 // { x--; v = x; } 7829 // { ++x; v = x; } 7830 // { --x; v = x; } 7831 // { x binop= expr; v = x; } 7832 // { x = x binop expr; v = x; } 7833 // { x = expr binop x; v = x; } 7834 // Check that the second expression has form v = x. 7835 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7836 llvm::FoldingSetNodeID XId, PossibleXId; 7837 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7838 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7839 IsUpdateExprFound = XId == PossibleXId; 7840 if (IsUpdateExprFound) { 7841 V = BinOp->getLHS(); 7842 X = Checker.getX(); 7843 E = Checker.getExpr(); 7844 UE = Checker.getUpdateExpr(); 7845 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7846 IsPostfixUpdate = false; 7847 } 7848 } 7849 } 7850 if (!IsUpdateExprFound) { 7851 // { v = x; x = expr; } 7852 auto *FirstExpr = dyn_cast<Expr>(First); 7853 auto *SecondExpr = dyn_cast<Expr>(Second); 7854 if (!FirstExpr || !SecondExpr || 7855 !(FirstExpr->isInstantiationDependent() || 7856 SecondExpr->isInstantiationDependent())) { 7857 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 7858 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 7859 ErrorFound = NotAnAssignmentOp; 7860 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 7861 : First->getBeginLoc(); 7862 NoteRange = ErrorRange = FirstBinOp 7863 ? FirstBinOp->getSourceRange() 7864 : SourceRange(ErrorLoc, ErrorLoc); 7865 } else { 7866 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 7867 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 7868 ErrorFound = NotAnAssignmentOp; 7869 NoteLoc = ErrorLoc = SecondBinOp 7870 ? SecondBinOp->getOperatorLoc() 7871 : Second->getBeginLoc(); 7872 NoteRange = ErrorRange = 7873 SecondBinOp ? SecondBinOp->getSourceRange() 7874 : SourceRange(ErrorLoc, ErrorLoc); 7875 } else { 7876 Expr *PossibleXRHSInFirst = 7877 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 7878 Expr *PossibleXLHSInSecond = 7879 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 7880 llvm::FoldingSetNodeID X1Id, X2Id; 7881 PossibleXRHSInFirst->Profile(X1Id, Context, 7882 /*Canonical=*/true); 7883 PossibleXLHSInSecond->Profile(X2Id, Context, 7884 /*Canonical=*/true); 7885 IsUpdateExprFound = X1Id == X2Id; 7886 if (IsUpdateExprFound) { 7887 V = FirstBinOp->getLHS(); 7888 X = SecondBinOp->getLHS(); 7889 E = SecondBinOp->getRHS(); 7890 UE = nullptr; 7891 IsXLHSInRHSPart = false; 7892 IsPostfixUpdate = true; 7893 } else { 7894 ErrorFound = NotASpecificExpression; 7895 ErrorLoc = FirstBinOp->getExprLoc(); 7896 ErrorRange = FirstBinOp->getSourceRange(); 7897 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 7898 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 7899 } 7900 } 7901 } 7902 } 7903 } 7904 } else { 7905 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7906 NoteRange = ErrorRange = 7907 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7908 ErrorFound = NotTwoSubstatements; 7909 } 7910 } else { 7911 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7912 NoteRange = ErrorRange = 7913 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7914 ErrorFound = NotACompoundStatement; 7915 } 7916 if (ErrorFound != NoError) { 7917 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 7918 << ErrorRange; 7919 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7920 return StmtError(); 7921 } 7922 if (CurContext->isDependentContext()) 7923 UE = V = E = X = nullptr; 7924 } 7925 } 7926 7927 setFunctionHasBranchProtectedScope(); 7928 7929 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7930 X, V, E, UE, IsXLHSInRHSPart, 7931 IsPostfixUpdate); 7932 } 7933 7934 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 7935 Stmt *AStmt, 7936 SourceLocation StartLoc, 7937 SourceLocation EndLoc) { 7938 if (!AStmt) 7939 return StmtError(); 7940 7941 auto *CS = cast<CapturedStmt>(AStmt); 7942 // 1.2.2 OpenMP Language Terminology 7943 // Structured block - An executable statement with a single entry at the 7944 // top and a single exit at the bottom. 7945 // The point of exit cannot be a branch out of the structured block. 7946 // longjmp() and throw() must not violate the entry/exit criteria. 7947 CS->getCapturedDecl()->setNothrow(); 7948 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 7949 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7950 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7951 // 1.2.2 OpenMP Language Terminology 7952 // Structured block - An executable statement with a single entry at the 7953 // top and a single exit at the bottom. 7954 // The point of exit cannot be a branch out of the structured block. 7955 // longjmp() and throw() must not violate the entry/exit criteria. 7956 CS->getCapturedDecl()->setNothrow(); 7957 } 7958 7959 // OpenMP [2.16, Nesting of Regions] 7960 // If specified, a teams construct must be contained within a target 7961 // construct. That target construct must contain no statements or directives 7962 // outside of the teams construct. 7963 if (DSAStack->hasInnerTeamsRegion()) { 7964 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 7965 bool OMPTeamsFound = true; 7966 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 7967 auto I = CS->body_begin(); 7968 while (I != CS->body_end()) { 7969 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7970 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 7971 OMPTeamsFound) { 7972 7973 OMPTeamsFound = false; 7974 break; 7975 } 7976 ++I; 7977 } 7978 assert(I != CS->body_end() && "Not found statement"); 7979 S = *I; 7980 } else { 7981 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7982 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7983 } 7984 if (!OMPTeamsFound) { 7985 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7986 Diag(DSAStack->getInnerTeamsRegionLoc(), 7987 diag::note_omp_nested_teams_construct_here); 7988 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7989 << isa<OMPExecutableDirective>(S); 7990 return StmtError(); 7991 } 7992 } 7993 7994 setFunctionHasBranchProtectedScope(); 7995 7996 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7997 } 7998 7999 StmtResult 8000 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8001 Stmt *AStmt, SourceLocation StartLoc, 8002 SourceLocation EndLoc) { 8003 if (!AStmt) 8004 return StmtError(); 8005 8006 auto *CS = cast<CapturedStmt>(AStmt); 8007 // 1.2.2 OpenMP Language Terminology 8008 // Structured block - An executable statement with a single entry at the 8009 // top and a single exit at the bottom. 8010 // The point of exit cannot be a branch out of the structured block. 8011 // longjmp() and throw() must not violate the entry/exit criteria. 8012 CS->getCapturedDecl()->setNothrow(); 8013 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8014 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8015 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8016 // 1.2.2 OpenMP Language Terminology 8017 // Structured block - An executable statement with a single entry at the 8018 // top and a single exit at the bottom. 8019 // The point of exit cannot be a branch out of the structured block. 8020 // longjmp() and throw() must not violate the entry/exit criteria. 8021 CS->getCapturedDecl()->setNothrow(); 8022 } 8023 8024 setFunctionHasBranchProtectedScope(); 8025 8026 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8027 AStmt); 8028 } 8029 8030 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8031 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8032 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8033 if (!AStmt) 8034 return StmtError(); 8035 8036 auto *CS = cast<CapturedStmt>(AStmt); 8037 // 1.2.2 OpenMP Language Terminology 8038 // Structured block - An executable statement with a single entry at the 8039 // top and a single exit at the bottom. 8040 // The point of exit cannot be a branch out of the structured block. 8041 // longjmp() and throw() must not violate the entry/exit criteria. 8042 CS->getCapturedDecl()->setNothrow(); 8043 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8044 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8045 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8046 // 1.2.2 OpenMP Language Terminology 8047 // Structured block - An executable statement with a single entry at the 8048 // top and a single exit at the bottom. 8049 // The point of exit cannot be a branch out of the structured block. 8050 // longjmp() and throw() must not violate the entry/exit criteria. 8051 CS->getCapturedDecl()->setNothrow(); 8052 } 8053 8054 OMPLoopDirective::HelperExprs B; 8055 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8056 // define the nested loops number. 8057 unsigned NestedLoopCount = 8058 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8059 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8060 VarsWithImplicitDSA, B); 8061 if (NestedLoopCount == 0) 8062 return StmtError(); 8063 8064 assert((CurContext->isDependentContext() || B.builtAll()) && 8065 "omp target parallel for loop exprs were not built"); 8066 8067 if (!CurContext->isDependentContext()) { 8068 // Finalize the clauses that need pre-built expressions for CodeGen. 8069 for (OMPClause *C : Clauses) { 8070 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8071 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8072 B.NumIterations, *this, CurScope, 8073 DSAStack)) 8074 return StmtError(); 8075 } 8076 } 8077 8078 setFunctionHasBranchProtectedScope(); 8079 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8080 NestedLoopCount, Clauses, AStmt, 8081 B, DSAStack->isCancelRegion()); 8082 } 8083 8084 /// Check for existence of a map clause in the list of clauses. 8085 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8086 const OpenMPClauseKind K) { 8087 return llvm::any_of( 8088 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8089 } 8090 8091 template <typename... Params> 8092 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8093 const Params... ClauseTypes) { 8094 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8095 } 8096 8097 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8098 Stmt *AStmt, 8099 SourceLocation StartLoc, 8100 SourceLocation EndLoc) { 8101 if (!AStmt) 8102 return StmtError(); 8103 8104 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8105 8106 // OpenMP [2.10.1, Restrictions, p. 97] 8107 // At least one map clause must appear on the directive. 8108 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8109 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8110 << "'map' or 'use_device_ptr'" 8111 << getOpenMPDirectiveName(OMPD_target_data); 8112 return StmtError(); 8113 } 8114 8115 setFunctionHasBranchProtectedScope(); 8116 8117 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8118 AStmt); 8119 } 8120 8121 StmtResult 8122 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8123 SourceLocation StartLoc, 8124 SourceLocation EndLoc, Stmt *AStmt) { 8125 if (!AStmt) 8126 return StmtError(); 8127 8128 auto *CS = cast<CapturedStmt>(AStmt); 8129 // 1.2.2 OpenMP Language Terminology 8130 // Structured block - An executable statement with a single entry at the 8131 // top and a single exit at the bottom. 8132 // The point of exit cannot be a branch out of the structured block. 8133 // longjmp() and throw() must not violate the entry/exit criteria. 8134 CS->getCapturedDecl()->setNothrow(); 8135 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8136 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8137 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8138 // 1.2.2 OpenMP Language Terminology 8139 // Structured block - An executable statement with a single entry at the 8140 // top and a single exit at the bottom. 8141 // The point of exit cannot be a branch out of the structured block. 8142 // longjmp() and throw() must not violate the entry/exit criteria. 8143 CS->getCapturedDecl()->setNothrow(); 8144 } 8145 8146 // OpenMP [2.10.2, Restrictions, p. 99] 8147 // At least one map clause must appear on the directive. 8148 if (!hasClauses(Clauses, OMPC_map)) { 8149 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8150 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8151 return StmtError(); 8152 } 8153 8154 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8155 AStmt); 8156 } 8157 8158 StmtResult 8159 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8160 SourceLocation StartLoc, 8161 SourceLocation EndLoc, Stmt *AStmt) { 8162 if (!AStmt) 8163 return StmtError(); 8164 8165 auto *CS = cast<CapturedStmt>(AStmt); 8166 // 1.2.2 OpenMP Language Terminology 8167 // Structured block - An executable statement with a single entry at the 8168 // top and a single exit at the bottom. 8169 // The point of exit cannot be a branch out of the structured block. 8170 // longjmp() and throw() must not violate the entry/exit criteria. 8171 CS->getCapturedDecl()->setNothrow(); 8172 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8173 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8174 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8175 // 1.2.2 OpenMP Language Terminology 8176 // Structured block - An executable statement with a single entry at the 8177 // top and a single exit at the bottom. 8178 // The point of exit cannot be a branch out of the structured block. 8179 // longjmp() and throw() must not violate the entry/exit criteria. 8180 CS->getCapturedDecl()->setNothrow(); 8181 } 8182 8183 // OpenMP [2.10.3, Restrictions, p. 102] 8184 // At least one map clause must appear on the directive. 8185 if (!hasClauses(Clauses, OMPC_map)) { 8186 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8187 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8188 return StmtError(); 8189 } 8190 8191 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8192 AStmt); 8193 } 8194 8195 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8196 SourceLocation StartLoc, 8197 SourceLocation EndLoc, 8198 Stmt *AStmt) { 8199 if (!AStmt) 8200 return StmtError(); 8201 8202 auto *CS = cast<CapturedStmt>(AStmt); 8203 // 1.2.2 OpenMP Language Terminology 8204 // Structured block - An executable statement with a single entry at the 8205 // top and a single exit at the bottom. 8206 // The point of exit cannot be a branch out of the structured block. 8207 // longjmp() and throw() must not violate the entry/exit criteria. 8208 CS->getCapturedDecl()->setNothrow(); 8209 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8210 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8211 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8212 // 1.2.2 OpenMP Language Terminology 8213 // Structured block - An executable statement with a single entry at the 8214 // top and a single exit at the bottom. 8215 // The point of exit cannot be a branch out of the structured block. 8216 // longjmp() and throw() must not violate the entry/exit criteria. 8217 CS->getCapturedDecl()->setNothrow(); 8218 } 8219 8220 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8221 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8222 return StmtError(); 8223 } 8224 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8225 AStmt); 8226 } 8227 8228 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8229 Stmt *AStmt, SourceLocation StartLoc, 8230 SourceLocation EndLoc) { 8231 if (!AStmt) 8232 return StmtError(); 8233 8234 auto *CS = cast<CapturedStmt>(AStmt); 8235 // 1.2.2 OpenMP Language Terminology 8236 // Structured block - An executable statement with a single entry at the 8237 // top and a single exit at the bottom. 8238 // The point of exit cannot be a branch out of the structured block. 8239 // longjmp() and throw() must not violate the entry/exit criteria. 8240 CS->getCapturedDecl()->setNothrow(); 8241 8242 setFunctionHasBranchProtectedScope(); 8243 8244 DSAStack->setParentTeamsRegionLoc(StartLoc); 8245 8246 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8247 } 8248 8249 StmtResult 8250 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8251 SourceLocation EndLoc, 8252 OpenMPDirectiveKind CancelRegion) { 8253 if (DSAStack->isParentNowaitRegion()) { 8254 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8255 return StmtError(); 8256 } 8257 if (DSAStack->isParentOrderedRegion()) { 8258 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8259 return StmtError(); 8260 } 8261 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8262 CancelRegion); 8263 } 8264 8265 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8266 SourceLocation StartLoc, 8267 SourceLocation EndLoc, 8268 OpenMPDirectiveKind CancelRegion) { 8269 if (DSAStack->isParentNowaitRegion()) { 8270 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8271 return StmtError(); 8272 } 8273 if (DSAStack->isParentOrderedRegion()) { 8274 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8275 return StmtError(); 8276 } 8277 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8278 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8279 CancelRegion); 8280 } 8281 8282 static bool checkGrainsizeNumTasksClauses(Sema &S, 8283 ArrayRef<OMPClause *> Clauses) { 8284 const OMPClause *PrevClause = nullptr; 8285 bool ErrorFound = false; 8286 for (const OMPClause *C : Clauses) { 8287 if (C->getClauseKind() == OMPC_grainsize || 8288 C->getClauseKind() == OMPC_num_tasks) { 8289 if (!PrevClause) 8290 PrevClause = C; 8291 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8292 S.Diag(C->getBeginLoc(), 8293 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8294 << getOpenMPClauseName(C->getClauseKind()) 8295 << getOpenMPClauseName(PrevClause->getClauseKind()); 8296 S.Diag(PrevClause->getBeginLoc(), 8297 diag::note_omp_previous_grainsize_num_tasks) 8298 << getOpenMPClauseName(PrevClause->getClauseKind()); 8299 ErrorFound = true; 8300 } 8301 } 8302 } 8303 return ErrorFound; 8304 } 8305 8306 static bool checkReductionClauseWithNogroup(Sema &S, 8307 ArrayRef<OMPClause *> Clauses) { 8308 const OMPClause *ReductionClause = nullptr; 8309 const OMPClause *NogroupClause = nullptr; 8310 for (const OMPClause *C : Clauses) { 8311 if (C->getClauseKind() == OMPC_reduction) { 8312 ReductionClause = C; 8313 if (NogroupClause) 8314 break; 8315 continue; 8316 } 8317 if (C->getClauseKind() == OMPC_nogroup) { 8318 NogroupClause = C; 8319 if (ReductionClause) 8320 break; 8321 continue; 8322 } 8323 } 8324 if (ReductionClause && NogroupClause) { 8325 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8326 << SourceRange(NogroupClause->getBeginLoc(), 8327 NogroupClause->getEndLoc()); 8328 return true; 8329 } 8330 return false; 8331 } 8332 8333 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8334 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8335 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8336 if (!AStmt) 8337 return StmtError(); 8338 8339 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8340 OMPLoopDirective::HelperExprs B; 8341 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8342 // define the nested loops number. 8343 unsigned NestedLoopCount = 8344 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8345 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8346 VarsWithImplicitDSA, B); 8347 if (NestedLoopCount == 0) 8348 return StmtError(); 8349 8350 assert((CurContext->isDependentContext() || B.builtAll()) && 8351 "omp for loop exprs were not built"); 8352 8353 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8354 // The grainsize clause and num_tasks clause are mutually exclusive and may 8355 // not appear on the same taskloop directive. 8356 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8357 return StmtError(); 8358 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8359 // If a reduction clause is present on the taskloop directive, the nogroup 8360 // clause must not be specified. 8361 if (checkReductionClauseWithNogroup(*this, Clauses)) 8362 return StmtError(); 8363 8364 setFunctionHasBranchProtectedScope(); 8365 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8366 NestedLoopCount, Clauses, AStmt, B); 8367 } 8368 8369 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8370 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8371 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8372 if (!AStmt) 8373 return StmtError(); 8374 8375 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8376 OMPLoopDirective::HelperExprs B; 8377 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8378 // define the nested loops number. 8379 unsigned NestedLoopCount = 8380 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8381 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8382 VarsWithImplicitDSA, B); 8383 if (NestedLoopCount == 0) 8384 return StmtError(); 8385 8386 assert((CurContext->isDependentContext() || B.builtAll()) && 8387 "omp for loop exprs were not built"); 8388 8389 if (!CurContext->isDependentContext()) { 8390 // Finalize the clauses that need pre-built expressions for CodeGen. 8391 for (OMPClause *C : Clauses) { 8392 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8393 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8394 B.NumIterations, *this, CurScope, 8395 DSAStack)) 8396 return StmtError(); 8397 } 8398 } 8399 8400 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8401 // The grainsize clause and num_tasks clause are mutually exclusive and may 8402 // not appear on the same taskloop directive. 8403 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8404 return StmtError(); 8405 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8406 // If a reduction clause is present on the taskloop directive, the nogroup 8407 // clause must not be specified. 8408 if (checkReductionClauseWithNogroup(*this, Clauses)) 8409 return StmtError(); 8410 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8411 return StmtError(); 8412 8413 setFunctionHasBranchProtectedScope(); 8414 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8415 NestedLoopCount, Clauses, AStmt, B); 8416 } 8417 8418 StmtResult Sema::ActOnOpenMPDistributeDirective( 8419 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8420 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8421 if (!AStmt) 8422 return StmtError(); 8423 8424 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8425 OMPLoopDirective::HelperExprs B; 8426 // In presence of clause 'collapse' with number of loops, it will 8427 // define the nested loops number. 8428 unsigned NestedLoopCount = 8429 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8430 nullptr /*ordered not a clause on distribute*/, AStmt, 8431 *this, *DSAStack, VarsWithImplicitDSA, B); 8432 if (NestedLoopCount == 0) 8433 return StmtError(); 8434 8435 assert((CurContext->isDependentContext() || B.builtAll()) && 8436 "omp for loop exprs were not built"); 8437 8438 setFunctionHasBranchProtectedScope(); 8439 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 8440 NestedLoopCount, Clauses, AStmt, B); 8441 } 8442 8443 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 8444 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8445 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8446 if (!AStmt) 8447 return StmtError(); 8448 8449 auto *CS = cast<CapturedStmt>(AStmt); 8450 // 1.2.2 OpenMP Language Terminology 8451 // Structured block - An executable statement with a single entry at the 8452 // top and a single exit at the bottom. 8453 // The point of exit cannot be a branch out of the structured block. 8454 // longjmp() and throw() must not violate the entry/exit criteria. 8455 CS->getCapturedDecl()->setNothrow(); 8456 for (int ThisCaptureLevel = 8457 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 8458 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8459 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8460 // 1.2.2 OpenMP Language Terminology 8461 // Structured block - An executable statement with a single entry at the 8462 // top and a single exit at the bottom. 8463 // The point of exit cannot be a branch out of the structured block. 8464 // longjmp() and throw() must not violate the entry/exit criteria. 8465 CS->getCapturedDecl()->setNothrow(); 8466 } 8467 8468 OMPLoopDirective::HelperExprs B; 8469 // In presence of clause 'collapse' with number of loops, it will 8470 // define the nested loops number. 8471 unsigned NestedLoopCount = checkOpenMPLoop( 8472 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8473 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8474 VarsWithImplicitDSA, B); 8475 if (NestedLoopCount == 0) 8476 return StmtError(); 8477 8478 assert((CurContext->isDependentContext() || B.builtAll()) && 8479 "omp for loop exprs were not built"); 8480 8481 setFunctionHasBranchProtectedScope(); 8482 return OMPDistributeParallelForDirective::Create( 8483 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8484 DSAStack->isCancelRegion()); 8485 } 8486 8487 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 8488 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8489 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8490 if (!AStmt) 8491 return StmtError(); 8492 8493 auto *CS = cast<CapturedStmt>(AStmt); 8494 // 1.2.2 OpenMP Language Terminology 8495 // Structured block - An executable statement with a single entry at the 8496 // top and a single exit at the bottom. 8497 // The point of exit cannot be a branch out of the structured block. 8498 // longjmp() and throw() must not violate the entry/exit criteria. 8499 CS->getCapturedDecl()->setNothrow(); 8500 for (int ThisCaptureLevel = 8501 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 8502 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8503 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8504 // 1.2.2 OpenMP Language Terminology 8505 // Structured block - An executable statement with a single entry at the 8506 // top and a single exit at the bottom. 8507 // The point of exit cannot be a branch out of the structured block. 8508 // longjmp() and throw() must not violate the entry/exit criteria. 8509 CS->getCapturedDecl()->setNothrow(); 8510 } 8511 8512 OMPLoopDirective::HelperExprs B; 8513 // In presence of clause 'collapse' with number of loops, it will 8514 // define the nested loops number. 8515 unsigned NestedLoopCount = checkOpenMPLoop( 8516 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8517 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8518 VarsWithImplicitDSA, B); 8519 if (NestedLoopCount == 0) 8520 return StmtError(); 8521 8522 assert((CurContext->isDependentContext() || B.builtAll()) && 8523 "omp for loop exprs were not built"); 8524 8525 if (!CurContext->isDependentContext()) { 8526 // Finalize the clauses that need pre-built expressions for CodeGen. 8527 for (OMPClause *C : Clauses) { 8528 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8529 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8530 B.NumIterations, *this, CurScope, 8531 DSAStack)) 8532 return StmtError(); 8533 } 8534 } 8535 8536 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8537 return StmtError(); 8538 8539 setFunctionHasBranchProtectedScope(); 8540 return OMPDistributeParallelForSimdDirective::Create( 8541 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8542 } 8543 8544 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 8545 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8546 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8547 if (!AStmt) 8548 return StmtError(); 8549 8550 auto *CS = cast<CapturedStmt>(AStmt); 8551 // 1.2.2 OpenMP Language Terminology 8552 // Structured block - An executable statement with a single entry at the 8553 // top and a single exit at the bottom. 8554 // The point of exit cannot be a branch out of the structured block. 8555 // longjmp() and throw() must not violate the entry/exit criteria. 8556 CS->getCapturedDecl()->setNothrow(); 8557 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 8558 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8559 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8560 // 1.2.2 OpenMP Language Terminology 8561 // Structured block - An executable statement with a single entry at the 8562 // top and a single exit at the bottom. 8563 // The point of exit cannot be a branch out of the structured block. 8564 // longjmp() and throw() must not violate the entry/exit criteria. 8565 CS->getCapturedDecl()->setNothrow(); 8566 } 8567 8568 OMPLoopDirective::HelperExprs B; 8569 // In presence of clause 'collapse' with number of loops, it will 8570 // define the nested loops number. 8571 unsigned NestedLoopCount = 8572 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 8573 nullptr /*ordered not a clause on distribute*/, CS, *this, 8574 *DSAStack, VarsWithImplicitDSA, B); 8575 if (NestedLoopCount == 0) 8576 return StmtError(); 8577 8578 assert((CurContext->isDependentContext() || B.builtAll()) && 8579 "omp for loop exprs were not built"); 8580 8581 if (!CurContext->isDependentContext()) { 8582 // Finalize the clauses that need pre-built expressions for CodeGen. 8583 for (OMPClause *C : Clauses) { 8584 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8585 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8586 B.NumIterations, *this, CurScope, 8587 DSAStack)) 8588 return StmtError(); 8589 } 8590 } 8591 8592 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8593 return StmtError(); 8594 8595 setFunctionHasBranchProtectedScope(); 8596 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 8597 NestedLoopCount, Clauses, AStmt, B); 8598 } 8599 8600 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 8601 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8602 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8603 if (!AStmt) 8604 return StmtError(); 8605 8606 auto *CS = cast<CapturedStmt>(AStmt); 8607 // 1.2.2 OpenMP Language Terminology 8608 // Structured block - An executable statement with a single entry at the 8609 // top and a single exit at the bottom. 8610 // The point of exit cannot be a branch out of the structured block. 8611 // longjmp() and throw() must not violate the entry/exit criteria. 8612 CS->getCapturedDecl()->setNothrow(); 8613 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8614 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8615 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8616 // 1.2.2 OpenMP Language Terminology 8617 // Structured block - An executable statement with a single entry at the 8618 // top and a single exit at the bottom. 8619 // The point of exit cannot be a branch out of the structured block. 8620 // longjmp() and throw() must not violate the entry/exit criteria. 8621 CS->getCapturedDecl()->setNothrow(); 8622 } 8623 8624 OMPLoopDirective::HelperExprs B; 8625 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8626 // define the nested loops number. 8627 unsigned NestedLoopCount = checkOpenMPLoop( 8628 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8629 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8630 VarsWithImplicitDSA, B); 8631 if (NestedLoopCount == 0) 8632 return StmtError(); 8633 8634 assert((CurContext->isDependentContext() || B.builtAll()) && 8635 "omp target parallel for simd loop exprs were not built"); 8636 8637 if (!CurContext->isDependentContext()) { 8638 // Finalize the clauses that need pre-built expressions for CodeGen. 8639 for (OMPClause *C : Clauses) { 8640 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8641 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8642 B.NumIterations, *this, CurScope, 8643 DSAStack)) 8644 return StmtError(); 8645 } 8646 } 8647 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8648 return StmtError(); 8649 8650 setFunctionHasBranchProtectedScope(); 8651 return OMPTargetParallelForSimdDirective::Create( 8652 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8653 } 8654 8655 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 8656 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8657 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8658 if (!AStmt) 8659 return StmtError(); 8660 8661 auto *CS = cast<CapturedStmt>(AStmt); 8662 // 1.2.2 OpenMP Language Terminology 8663 // Structured block - An executable statement with a single entry at the 8664 // top and a single exit at the bottom. 8665 // The point of exit cannot be a branch out of the structured block. 8666 // longjmp() and throw() must not violate the entry/exit criteria. 8667 CS->getCapturedDecl()->setNothrow(); 8668 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 8669 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8670 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8671 // 1.2.2 OpenMP Language Terminology 8672 // Structured block - An executable statement with a single entry at the 8673 // top and a single exit at the bottom. 8674 // The point of exit cannot be a branch out of the structured block. 8675 // longjmp() and throw() must not violate the entry/exit criteria. 8676 CS->getCapturedDecl()->setNothrow(); 8677 } 8678 8679 OMPLoopDirective::HelperExprs B; 8680 // In presence of clause 'collapse' with number of loops, it will define the 8681 // nested loops number. 8682 unsigned NestedLoopCount = 8683 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 8684 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8685 VarsWithImplicitDSA, B); 8686 if (NestedLoopCount == 0) 8687 return StmtError(); 8688 8689 assert((CurContext->isDependentContext() || B.builtAll()) && 8690 "omp target simd loop exprs were not built"); 8691 8692 if (!CurContext->isDependentContext()) { 8693 // Finalize the clauses that need pre-built expressions for CodeGen. 8694 for (OMPClause *C : Clauses) { 8695 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8696 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8697 B.NumIterations, *this, CurScope, 8698 DSAStack)) 8699 return StmtError(); 8700 } 8701 } 8702 8703 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8704 return StmtError(); 8705 8706 setFunctionHasBranchProtectedScope(); 8707 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 8708 NestedLoopCount, Clauses, AStmt, B); 8709 } 8710 8711 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 8712 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8713 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8714 if (!AStmt) 8715 return StmtError(); 8716 8717 auto *CS = cast<CapturedStmt>(AStmt); 8718 // 1.2.2 OpenMP Language Terminology 8719 // Structured block - An executable statement with a single entry at the 8720 // top and a single exit at the bottom. 8721 // The point of exit cannot be a branch out of the structured block. 8722 // longjmp() and throw() must not violate the entry/exit criteria. 8723 CS->getCapturedDecl()->setNothrow(); 8724 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 8725 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8726 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8727 // 1.2.2 OpenMP Language Terminology 8728 // Structured block - An executable statement with a single entry at the 8729 // top and a single exit at the bottom. 8730 // The point of exit cannot be a branch out of the structured block. 8731 // longjmp() and throw() must not violate the entry/exit criteria. 8732 CS->getCapturedDecl()->setNothrow(); 8733 } 8734 8735 OMPLoopDirective::HelperExprs B; 8736 // In presence of clause 'collapse' with number of loops, it will 8737 // define the nested loops number. 8738 unsigned NestedLoopCount = 8739 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 8740 nullptr /*ordered not a clause on distribute*/, CS, *this, 8741 *DSAStack, VarsWithImplicitDSA, B); 8742 if (NestedLoopCount == 0) 8743 return StmtError(); 8744 8745 assert((CurContext->isDependentContext() || B.builtAll()) && 8746 "omp teams distribute loop exprs were not built"); 8747 8748 setFunctionHasBranchProtectedScope(); 8749 8750 DSAStack->setParentTeamsRegionLoc(StartLoc); 8751 8752 return OMPTeamsDistributeDirective::Create( 8753 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8754 } 8755 8756 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 8757 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8758 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8759 if (!AStmt) 8760 return StmtError(); 8761 8762 auto *CS = cast<CapturedStmt>(AStmt); 8763 // 1.2.2 OpenMP Language Terminology 8764 // Structured block - An executable statement with a single entry at the 8765 // top and a single exit at the bottom. 8766 // The point of exit cannot be a branch out of the structured block. 8767 // longjmp() and throw() must not violate the entry/exit criteria. 8768 CS->getCapturedDecl()->setNothrow(); 8769 for (int ThisCaptureLevel = 8770 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 8771 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8772 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8773 // 1.2.2 OpenMP Language Terminology 8774 // Structured block - An executable statement with a single entry at the 8775 // top and a single exit at the bottom. 8776 // The point of exit cannot be a branch out of the structured block. 8777 // longjmp() and throw() must not violate the entry/exit criteria. 8778 CS->getCapturedDecl()->setNothrow(); 8779 } 8780 8781 8782 OMPLoopDirective::HelperExprs B; 8783 // In presence of clause 'collapse' with number of loops, it will 8784 // define the nested loops number. 8785 unsigned NestedLoopCount = checkOpenMPLoop( 8786 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8787 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8788 VarsWithImplicitDSA, B); 8789 8790 if (NestedLoopCount == 0) 8791 return StmtError(); 8792 8793 assert((CurContext->isDependentContext() || B.builtAll()) && 8794 "omp teams distribute simd loop exprs were not built"); 8795 8796 if (!CurContext->isDependentContext()) { 8797 // Finalize the clauses that need pre-built expressions for CodeGen. 8798 for (OMPClause *C : Clauses) { 8799 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8800 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8801 B.NumIterations, *this, CurScope, 8802 DSAStack)) 8803 return StmtError(); 8804 } 8805 } 8806 8807 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8808 return StmtError(); 8809 8810 setFunctionHasBranchProtectedScope(); 8811 8812 DSAStack->setParentTeamsRegionLoc(StartLoc); 8813 8814 return OMPTeamsDistributeSimdDirective::Create( 8815 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8816 } 8817 8818 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 8819 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8820 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8821 if (!AStmt) 8822 return StmtError(); 8823 8824 auto *CS = cast<CapturedStmt>(AStmt); 8825 // 1.2.2 OpenMP Language Terminology 8826 // Structured block - An executable statement with a single entry at the 8827 // top and a single exit at the bottom. 8828 // The point of exit cannot be a branch out of the structured block. 8829 // longjmp() and throw() must not violate the entry/exit criteria. 8830 CS->getCapturedDecl()->setNothrow(); 8831 8832 for (int ThisCaptureLevel = 8833 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 8834 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8835 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8836 // 1.2.2 OpenMP Language Terminology 8837 // Structured block - An executable statement with a single entry at the 8838 // top and a single exit at the bottom. 8839 // The point of exit cannot be a branch out of the structured block. 8840 // longjmp() and throw() must not violate the entry/exit criteria. 8841 CS->getCapturedDecl()->setNothrow(); 8842 } 8843 8844 OMPLoopDirective::HelperExprs B; 8845 // In presence of clause 'collapse' with number of loops, it will 8846 // define the nested loops number. 8847 unsigned NestedLoopCount = checkOpenMPLoop( 8848 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8849 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8850 VarsWithImplicitDSA, B); 8851 8852 if (NestedLoopCount == 0) 8853 return StmtError(); 8854 8855 assert((CurContext->isDependentContext() || B.builtAll()) && 8856 "omp for loop exprs were not built"); 8857 8858 if (!CurContext->isDependentContext()) { 8859 // Finalize the clauses that need pre-built expressions for CodeGen. 8860 for (OMPClause *C : Clauses) { 8861 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8862 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8863 B.NumIterations, *this, CurScope, 8864 DSAStack)) 8865 return StmtError(); 8866 } 8867 } 8868 8869 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8870 return StmtError(); 8871 8872 setFunctionHasBranchProtectedScope(); 8873 8874 DSAStack->setParentTeamsRegionLoc(StartLoc); 8875 8876 return OMPTeamsDistributeParallelForSimdDirective::Create( 8877 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8878 } 8879 8880 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 8881 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8882 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8883 if (!AStmt) 8884 return StmtError(); 8885 8886 auto *CS = cast<CapturedStmt>(AStmt); 8887 // 1.2.2 OpenMP Language Terminology 8888 // Structured block - An executable statement with a single entry at the 8889 // top and a single exit at the bottom. 8890 // The point of exit cannot be a branch out of the structured block. 8891 // longjmp() and throw() must not violate the entry/exit criteria. 8892 CS->getCapturedDecl()->setNothrow(); 8893 8894 for (int ThisCaptureLevel = 8895 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 8896 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8897 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8898 // 1.2.2 OpenMP Language Terminology 8899 // Structured block - An executable statement with a single entry at the 8900 // top and a single exit at the bottom. 8901 // The point of exit cannot be a branch out of the structured block. 8902 // longjmp() and throw() must not violate the entry/exit criteria. 8903 CS->getCapturedDecl()->setNothrow(); 8904 } 8905 8906 OMPLoopDirective::HelperExprs B; 8907 // In presence of clause 'collapse' with number of loops, it will 8908 // define the nested loops number. 8909 unsigned NestedLoopCount = checkOpenMPLoop( 8910 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8911 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8912 VarsWithImplicitDSA, B); 8913 8914 if (NestedLoopCount == 0) 8915 return StmtError(); 8916 8917 assert((CurContext->isDependentContext() || B.builtAll()) && 8918 "omp for loop exprs were not built"); 8919 8920 setFunctionHasBranchProtectedScope(); 8921 8922 DSAStack->setParentTeamsRegionLoc(StartLoc); 8923 8924 return OMPTeamsDistributeParallelForDirective::Create( 8925 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8926 DSAStack->isCancelRegion()); 8927 } 8928 8929 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 8930 Stmt *AStmt, 8931 SourceLocation StartLoc, 8932 SourceLocation EndLoc) { 8933 if (!AStmt) 8934 return StmtError(); 8935 8936 auto *CS = cast<CapturedStmt>(AStmt); 8937 // 1.2.2 OpenMP Language Terminology 8938 // Structured block - An executable statement with a single entry at the 8939 // top and a single exit at the bottom. 8940 // The point of exit cannot be a branch out of the structured block. 8941 // longjmp() and throw() must not violate the entry/exit criteria. 8942 CS->getCapturedDecl()->setNothrow(); 8943 8944 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 8945 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8946 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8947 // 1.2.2 OpenMP Language Terminology 8948 // Structured block - An executable statement with a single entry at the 8949 // top and a single exit at the bottom. 8950 // The point of exit cannot be a branch out of the structured block. 8951 // longjmp() and throw() must not violate the entry/exit criteria. 8952 CS->getCapturedDecl()->setNothrow(); 8953 } 8954 setFunctionHasBranchProtectedScope(); 8955 8956 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 8957 AStmt); 8958 } 8959 8960 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 8961 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8962 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 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 = 8974 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8975 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8976 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8977 // 1.2.2 OpenMP Language Terminology 8978 // Structured block - An executable statement with a single entry at the 8979 // top and a single exit at the bottom. 8980 // The point of exit cannot be a branch out of the structured block. 8981 // longjmp() and throw() must not violate the entry/exit criteria. 8982 CS->getCapturedDecl()->setNothrow(); 8983 } 8984 8985 OMPLoopDirective::HelperExprs B; 8986 // In presence of clause 'collapse' with number of loops, it will 8987 // define the nested loops number. 8988 unsigned NestedLoopCount = checkOpenMPLoop( 8989 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8990 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8991 VarsWithImplicitDSA, B); 8992 if (NestedLoopCount == 0) 8993 return StmtError(); 8994 8995 assert((CurContext->isDependentContext() || B.builtAll()) && 8996 "omp target teams distribute loop exprs were not built"); 8997 8998 setFunctionHasBranchProtectedScope(); 8999 return OMPTargetTeamsDistributeDirective::Create( 9000 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9001 } 9002 9003 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 9004 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9005 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9006 if (!AStmt) 9007 return StmtError(); 9008 9009 auto *CS = cast<CapturedStmt>(AStmt); 9010 // 1.2.2 OpenMP Language Terminology 9011 // Structured block - An executable statement with a single entry at the 9012 // top and a single exit at the bottom. 9013 // The point of exit cannot be a branch out of the structured block. 9014 // longjmp() and throw() must not violate the entry/exit criteria. 9015 CS->getCapturedDecl()->setNothrow(); 9016 for (int ThisCaptureLevel = 9017 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 9018 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9019 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9020 // 1.2.2 OpenMP Language Terminology 9021 // Structured block - An executable statement with a single entry at the 9022 // top and a single exit at the bottom. 9023 // The point of exit cannot be a branch out of the structured block. 9024 // longjmp() and throw() must not violate the entry/exit criteria. 9025 CS->getCapturedDecl()->setNothrow(); 9026 } 9027 9028 OMPLoopDirective::HelperExprs B; 9029 // In presence of clause 'collapse' with number of loops, it will 9030 // define the nested loops number. 9031 unsigned NestedLoopCount = checkOpenMPLoop( 9032 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9033 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9034 VarsWithImplicitDSA, B); 9035 if (NestedLoopCount == 0) 9036 return StmtError(); 9037 9038 assert((CurContext->isDependentContext() || B.builtAll()) && 9039 "omp target teams distribute parallel for loop exprs were not built"); 9040 9041 if (!CurContext->isDependentContext()) { 9042 // Finalize the clauses that need pre-built expressions for CodeGen. 9043 for (OMPClause *C : Clauses) { 9044 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9045 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9046 B.NumIterations, *this, CurScope, 9047 DSAStack)) 9048 return StmtError(); 9049 } 9050 } 9051 9052 setFunctionHasBranchProtectedScope(); 9053 return OMPTargetTeamsDistributeParallelForDirective::Create( 9054 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9055 DSAStack->isCancelRegion()); 9056 } 9057 9058 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9059 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9060 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9061 if (!AStmt) 9062 return StmtError(); 9063 9064 auto *CS = cast<CapturedStmt>(AStmt); 9065 // 1.2.2 OpenMP Language Terminology 9066 // Structured block - An executable statement with a single entry at the 9067 // top and a single exit at the bottom. 9068 // The point of exit cannot be a branch out of the structured block. 9069 // longjmp() and throw() must not violate the entry/exit criteria. 9070 CS->getCapturedDecl()->setNothrow(); 9071 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9072 OMPD_target_teams_distribute_parallel_for_simd); 9073 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9074 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9075 // 1.2.2 OpenMP Language Terminology 9076 // Structured block - An executable statement with a single entry at the 9077 // top and a single exit at the bottom. 9078 // The point of exit cannot be a branch out of the structured block. 9079 // longjmp() and throw() must not violate the entry/exit criteria. 9080 CS->getCapturedDecl()->setNothrow(); 9081 } 9082 9083 OMPLoopDirective::HelperExprs B; 9084 // In presence of clause 'collapse' with number of loops, it will 9085 // define the nested loops number. 9086 unsigned NestedLoopCount = 9087 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9088 getCollapseNumberExpr(Clauses), 9089 nullptr /*ordered not a clause on distribute*/, CS, *this, 9090 *DSAStack, VarsWithImplicitDSA, B); 9091 if (NestedLoopCount == 0) 9092 return StmtError(); 9093 9094 assert((CurContext->isDependentContext() || B.builtAll()) && 9095 "omp target teams distribute parallel for simd loop exprs were not " 9096 "built"); 9097 9098 if (!CurContext->isDependentContext()) { 9099 // Finalize the clauses that need pre-built expressions for CodeGen. 9100 for (OMPClause *C : Clauses) { 9101 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9102 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9103 B.NumIterations, *this, CurScope, 9104 DSAStack)) 9105 return StmtError(); 9106 } 9107 } 9108 9109 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9110 return StmtError(); 9111 9112 setFunctionHasBranchProtectedScope(); 9113 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9114 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9115 } 9116 9117 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9118 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9119 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9120 if (!AStmt) 9121 return StmtError(); 9122 9123 auto *CS = cast<CapturedStmt>(AStmt); 9124 // 1.2.2 OpenMP Language Terminology 9125 // Structured block - An executable statement with a single entry at the 9126 // top and a single exit at the bottom. 9127 // The point of exit cannot be a branch out of the structured block. 9128 // longjmp() and throw() must not violate the entry/exit criteria. 9129 CS->getCapturedDecl()->setNothrow(); 9130 for (int ThisCaptureLevel = 9131 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9132 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9133 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9134 // 1.2.2 OpenMP Language Terminology 9135 // Structured block - An executable statement with a single entry at the 9136 // top and a single exit at the bottom. 9137 // The point of exit cannot be a branch out of the structured block. 9138 // longjmp() and throw() must not violate the entry/exit criteria. 9139 CS->getCapturedDecl()->setNothrow(); 9140 } 9141 9142 OMPLoopDirective::HelperExprs B; 9143 // In presence of clause 'collapse' with number of loops, it will 9144 // define the nested loops number. 9145 unsigned NestedLoopCount = checkOpenMPLoop( 9146 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9147 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9148 VarsWithImplicitDSA, B); 9149 if (NestedLoopCount == 0) 9150 return StmtError(); 9151 9152 assert((CurContext->isDependentContext() || B.builtAll()) && 9153 "omp target teams distribute simd loop exprs were not built"); 9154 9155 if (!CurContext->isDependentContext()) { 9156 // Finalize the clauses that need pre-built expressions for CodeGen. 9157 for (OMPClause *C : Clauses) { 9158 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9159 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9160 B.NumIterations, *this, CurScope, 9161 DSAStack)) 9162 return StmtError(); 9163 } 9164 } 9165 9166 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9167 return StmtError(); 9168 9169 setFunctionHasBranchProtectedScope(); 9170 return OMPTargetTeamsDistributeSimdDirective::Create( 9171 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9172 } 9173 9174 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9175 SourceLocation StartLoc, 9176 SourceLocation LParenLoc, 9177 SourceLocation EndLoc) { 9178 OMPClause *Res = nullptr; 9179 switch (Kind) { 9180 case OMPC_final: 9181 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9182 break; 9183 case OMPC_num_threads: 9184 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9185 break; 9186 case OMPC_safelen: 9187 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9188 break; 9189 case OMPC_simdlen: 9190 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9191 break; 9192 case OMPC_allocator: 9193 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9194 break; 9195 case OMPC_collapse: 9196 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9197 break; 9198 case OMPC_ordered: 9199 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9200 break; 9201 case OMPC_device: 9202 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9203 break; 9204 case OMPC_num_teams: 9205 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9206 break; 9207 case OMPC_thread_limit: 9208 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9209 break; 9210 case OMPC_priority: 9211 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9212 break; 9213 case OMPC_grainsize: 9214 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9215 break; 9216 case OMPC_num_tasks: 9217 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9218 break; 9219 case OMPC_hint: 9220 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9221 break; 9222 case OMPC_if: 9223 case OMPC_default: 9224 case OMPC_proc_bind: 9225 case OMPC_schedule: 9226 case OMPC_private: 9227 case OMPC_firstprivate: 9228 case OMPC_lastprivate: 9229 case OMPC_shared: 9230 case OMPC_reduction: 9231 case OMPC_task_reduction: 9232 case OMPC_in_reduction: 9233 case OMPC_linear: 9234 case OMPC_aligned: 9235 case OMPC_copyin: 9236 case OMPC_copyprivate: 9237 case OMPC_nowait: 9238 case OMPC_untied: 9239 case OMPC_mergeable: 9240 case OMPC_threadprivate: 9241 case OMPC_allocate: 9242 case OMPC_flush: 9243 case OMPC_read: 9244 case OMPC_write: 9245 case OMPC_update: 9246 case OMPC_capture: 9247 case OMPC_seq_cst: 9248 case OMPC_depend: 9249 case OMPC_threads: 9250 case OMPC_simd: 9251 case OMPC_map: 9252 case OMPC_nogroup: 9253 case OMPC_dist_schedule: 9254 case OMPC_defaultmap: 9255 case OMPC_unknown: 9256 case OMPC_uniform: 9257 case OMPC_to: 9258 case OMPC_from: 9259 case OMPC_use_device_ptr: 9260 case OMPC_is_device_ptr: 9261 case OMPC_unified_address: 9262 case OMPC_unified_shared_memory: 9263 case OMPC_reverse_offload: 9264 case OMPC_dynamic_allocators: 9265 case OMPC_atomic_default_mem_order: 9266 llvm_unreachable("Clause is not allowed."); 9267 } 9268 return Res; 9269 } 9270 9271 // An OpenMP directive such as 'target parallel' has two captured regions: 9272 // for the 'target' and 'parallel' respectively. This function returns 9273 // the region in which to capture expressions associated with a clause. 9274 // A return value of OMPD_unknown signifies that the expression should not 9275 // be captured. 9276 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9277 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9278 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9279 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9280 switch (CKind) { 9281 case OMPC_if: 9282 switch (DKind) { 9283 case OMPD_target_parallel: 9284 case OMPD_target_parallel_for: 9285 case OMPD_target_parallel_for_simd: 9286 // If this clause applies to the nested 'parallel' region, capture within 9287 // the 'target' region, otherwise do not capture. 9288 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9289 CaptureRegion = OMPD_target; 9290 break; 9291 case OMPD_target_teams_distribute_parallel_for: 9292 case OMPD_target_teams_distribute_parallel_for_simd: 9293 // If this clause applies to the nested 'parallel' region, capture within 9294 // the 'teams' region, otherwise do not capture. 9295 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9296 CaptureRegion = OMPD_teams; 9297 break; 9298 case OMPD_teams_distribute_parallel_for: 9299 case OMPD_teams_distribute_parallel_for_simd: 9300 CaptureRegion = OMPD_teams; 9301 break; 9302 case OMPD_target_update: 9303 case OMPD_target_enter_data: 9304 case OMPD_target_exit_data: 9305 CaptureRegion = OMPD_task; 9306 break; 9307 case OMPD_cancel: 9308 case OMPD_parallel: 9309 case OMPD_parallel_sections: 9310 case OMPD_parallel_for: 9311 case OMPD_parallel_for_simd: 9312 case OMPD_target: 9313 case OMPD_target_simd: 9314 case OMPD_target_teams: 9315 case OMPD_target_teams_distribute: 9316 case OMPD_target_teams_distribute_simd: 9317 case OMPD_distribute_parallel_for: 9318 case OMPD_distribute_parallel_for_simd: 9319 case OMPD_task: 9320 case OMPD_taskloop: 9321 case OMPD_taskloop_simd: 9322 case OMPD_target_data: 9323 // Do not capture if-clause expressions. 9324 break; 9325 case OMPD_threadprivate: 9326 case OMPD_allocate: 9327 case OMPD_taskyield: 9328 case OMPD_barrier: 9329 case OMPD_taskwait: 9330 case OMPD_cancellation_point: 9331 case OMPD_flush: 9332 case OMPD_declare_reduction: 9333 case OMPD_declare_mapper: 9334 case OMPD_declare_simd: 9335 case OMPD_declare_target: 9336 case OMPD_end_declare_target: 9337 case OMPD_teams: 9338 case OMPD_simd: 9339 case OMPD_for: 9340 case OMPD_for_simd: 9341 case OMPD_sections: 9342 case OMPD_section: 9343 case OMPD_single: 9344 case OMPD_master: 9345 case OMPD_critical: 9346 case OMPD_taskgroup: 9347 case OMPD_distribute: 9348 case OMPD_ordered: 9349 case OMPD_atomic: 9350 case OMPD_distribute_simd: 9351 case OMPD_teams_distribute: 9352 case OMPD_teams_distribute_simd: 9353 case OMPD_requires: 9354 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9355 case OMPD_unknown: 9356 llvm_unreachable("Unknown OpenMP directive"); 9357 } 9358 break; 9359 case OMPC_num_threads: 9360 switch (DKind) { 9361 case OMPD_target_parallel: 9362 case OMPD_target_parallel_for: 9363 case OMPD_target_parallel_for_simd: 9364 CaptureRegion = OMPD_target; 9365 break; 9366 case OMPD_teams_distribute_parallel_for: 9367 case OMPD_teams_distribute_parallel_for_simd: 9368 case OMPD_target_teams_distribute_parallel_for: 9369 case OMPD_target_teams_distribute_parallel_for_simd: 9370 CaptureRegion = OMPD_teams; 9371 break; 9372 case OMPD_parallel: 9373 case OMPD_parallel_sections: 9374 case OMPD_parallel_for: 9375 case OMPD_parallel_for_simd: 9376 case OMPD_distribute_parallel_for: 9377 case OMPD_distribute_parallel_for_simd: 9378 // Do not capture num_threads-clause expressions. 9379 break; 9380 case OMPD_target_data: 9381 case OMPD_target_enter_data: 9382 case OMPD_target_exit_data: 9383 case OMPD_target_update: 9384 case OMPD_target: 9385 case OMPD_target_simd: 9386 case OMPD_target_teams: 9387 case OMPD_target_teams_distribute: 9388 case OMPD_target_teams_distribute_simd: 9389 case OMPD_cancel: 9390 case OMPD_task: 9391 case OMPD_taskloop: 9392 case OMPD_taskloop_simd: 9393 case OMPD_threadprivate: 9394 case OMPD_allocate: 9395 case OMPD_taskyield: 9396 case OMPD_barrier: 9397 case OMPD_taskwait: 9398 case OMPD_cancellation_point: 9399 case OMPD_flush: 9400 case OMPD_declare_reduction: 9401 case OMPD_declare_mapper: 9402 case OMPD_declare_simd: 9403 case OMPD_declare_target: 9404 case OMPD_end_declare_target: 9405 case OMPD_teams: 9406 case OMPD_simd: 9407 case OMPD_for: 9408 case OMPD_for_simd: 9409 case OMPD_sections: 9410 case OMPD_section: 9411 case OMPD_single: 9412 case OMPD_master: 9413 case OMPD_critical: 9414 case OMPD_taskgroup: 9415 case OMPD_distribute: 9416 case OMPD_ordered: 9417 case OMPD_atomic: 9418 case OMPD_distribute_simd: 9419 case OMPD_teams_distribute: 9420 case OMPD_teams_distribute_simd: 9421 case OMPD_requires: 9422 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9423 case OMPD_unknown: 9424 llvm_unreachable("Unknown OpenMP directive"); 9425 } 9426 break; 9427 case OMPC_num_teams: 9428 switch (DKind) { 9429 case OMPD_target_teams: 9430 case OMPD_target_teams_distribute: 9431 case OMPD_target_teams_distribute_simd: 9432 case OMPD_target_teams_distribute_parallel_for: 9433 case OMPD_target_teams_distribute_parallel_for_simd: 9434 CaptureRegion = OMPD_target; 9435 break; 9436 case OMPD_teams_distribute_parallel_for: 9437 case OMPD_teams_distribute_parallel_for_simd: 9438 case OMPD_teams: 9439 case OMPD_teams_distribute: 9440 case OMPD_teams_distribute_simd: 9441 // Do not capture num_teams-clause expressions. 9442 break; 9443 case OMPD_distribute_parallel_for: 9444 case OMPD_distribute_parallel_for_simd: 9445 case OMPD_task: 9446 case OMPD_taskloop: 9447 case OMPD_taskloop_simd: 9448 case OMPD_target_data: 9449 case OMPD_target_enter_data: 9450 case OMPD_target_exit_data: 9451 case OMPD_target_update: 9452 case OMPD_cancel: 9453 case OMPD_parallel: 9454 case OMPD_parallel_sections: 9455 case OMPD_parallel_for: 9456 case OMPD_parallel_for_simd: 9457 case OMPD_target: 9458 case OMPD_target_simd: 9459 case OMPD_target_parallel: 9460 case OMPD_target_parallel_for: 9461 case OMPD_target_parallel_for_simd: 9462 case OMPD_threadprivate: 9463 case OMPD_allocate: 9464 case OMPD_taskyield: 9465 case OMPD_barrier: 9466 case OMPD_taskwait: 9467 case OMPD_cancellation_point: 9468 case OMPD_flush: 9469 case OMPD_declare_reduction: 9470 case OMPD_declare_mapper: 9471 case OMPD_declare_simd: 9472 case OMPD_declare_target: 9473 case OMPD_end_declare_target: 9474 case OMPD_simd: 9475 case OMPD_for: 9476 case OMPD_for_simd: 9477 case OMPD_sections: 9478 case OMPD_section: 9479 case OMPD_single: 9480 case OMPD_master: 9481 case OMPD_critical: 9482 case OMPD_taskgroup: 9483 case OMPD_distribute: 9484 case OMPD_ordered: 9485 case OMPD_atomic: 9486 case OMPD_distribute_simd: 9487 case OMPD_requires: 9488 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9489 case OMPD_unknown: 9490 llvm_unreachable("Unknown OpenMP directive"); 9491 } 9492 break; 9493 case OMPC_thread_limit: 9494 switch (DKind) { 9495 case OMPD_target_teams: 9496 case OMPD_target_teams_distribute: 9497 case OMPD_target_teams_distribute_simd: 9498 case OMPD_target_teams_distribute_parallel_for: 9499 case OMPD_target_teams_distribute_parallel_for_simd: 9500 CaptureRegion = OMPD_target; 9501 break; 9502 case OMPD_teams_distribute_parallel_for: 9503 case OMPD_teams_distribute_parallel_for_simd: 9504 case OMPD_teams: 9505 case OMPD_teams_distribute: 9506 case OMPD_teams_distribute_simd: 9507 // Do not capture thread_limit-clause expressions. 9508 break; 9509 case OMPD_distribute_parallel_for: 9510 case OMPD_distribute_parallel_for_simd: 9511 case OMPD_task: 9512 case OMPD_taskloop: 9513 case OMPD_taskloop_simd: 9514 case OMPD_target_data: 9515 case OMPD_target_enter_data: 9516 case OMPD_target_exit_data: 9517 case OMPD_target_update: 9518 case OMPD_cancel: 9519 case OMPD_parallel: 9520 case OMPD_parallel_sections: 9521 case OMPD_parallel_for: 9522 case OMPD_parallel_for_simd: 9523 case OMPD_target: 9524 case OMPD_target_simd: 9525 case OMPD_target_parallel: 9526 case OMPD_target_parallel_for: 9527 case OMPD_target_parallel_for_simd: 9528 case OMPD_threadprivate: 9529 case OMPD_allocate: 9530 case OMPD_taskyield: 9531 case OMPD_barrier: 9532 case OMPD_taskwait: 9533 case OMPD_cancellation_point: 9534 case OMPD_flush: 9535 case OMPD_declare_reduction: 9536 case OMPD_declare_mapper: 9537 case OMPD_declare_simd: 9538 case OMPD_declare_target: 9539 case OMPD_end_declare_target: 9540 case OMPD_simd: 9541 case OMPD_for: 9542 case OMPD_for_simd: 9543 case OMPD_sections: 9544 case OMPD_section: 9545 case OMPD_single: 9546 case OMPD_master: 9547 case OMPD_critical: 9548 case OMPD_taskgroup: 9549 case OMPD_distribute: 9550 case OMPD_ordered: 9551 case OMPD_atomic: 9552 case OMPD_distribute_simd: 9553 case OMPD_requires: 9554 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 9555 case OMPD_unknown: 9556 llvm_unreachable("Unknown OpenMP directive"); 9557 } 9558 break; 9559 case OMPC_schedule: 9560 switch (DKind) { 9561 case OMPD_parallel_for: 9562 case OMPD_parallel_for_simd: 9563 case OMPD_distribute_parallel_for: 9564 case OMPD_distribute_parallel_for_simd: 9565 case OMPD_teams_distribute_parallel_for: 9566 case OMPD_teams_distribute_parallel_for_simd: 9567 case OMPD_target_parallel_for: 9568 case OMPD_target_parallel_for_simd: 9569 case OMPD_target_teams_distribute_parallel_for: 9570 case OMPD_target_teams_distribute_parallel_for_simd: 9571 CaptureRegion = OMPD_parallel; 9572 break; 9573 case OMPD_for: 9574 case OMPD_for_simd: 9575 // Do not capture schedule-clause expressions. 9576 break; 9577 case OMPD_task: 9578 case OMPD_taskloop: 9579 case OMPD_taskloop_simd: 9580 case OMPD_target_data: 9581 case OMPD_target_enter_data: 9582 case OMPD_target_exit_data: 9583 case OMPD_target_update: 9584 case OMPD_teams: 9585 case OMPD_teams_distribute: 9586 case OMPD_teams_distribute_simd: 9587 case OMPD_target_teams_distribute: 9588 case OMPD_target_teams_distribute_simd: 9589 case OMPD_target: 9590 case OMPD_target_simd: 9591 case OMPD_target_parallel: 9592 case OMPD_cancel: 9593 case OMPD_parallel: 9594 case OMPD_parallel_sections: 9595 case OMPD_threadprivate: 9596 case OMPD_allocate: 9597 case OMPD_taskyield: 9598 case OMPD_barrier: 9599 case OMPD_taskwait: 9600 case OMPD_cancellation_point: 9601 case OMPD_flush: 9602 case OMPD_declare_reduction: 9603 case OMPD_declare_mapper: 9604 case OMPD_declare_simd: 9605 case OMPD_declare_target: 9606 case OMPD_end_declare_target: 9607 case OMPD_simd: 9608 case OMPD_sections: 9609 case OMPD_section: 9610 case OMPD_single: 9611 case OMPD_master: 9612 case OMPD_critical: 9613 case OMPD_taskgroup: 9614 case OMPD_distribute: 9615 case OMPD_ordered: 9616 case OMPD_atomic: 9617 case OMPD_distribute_simd: 9618 case OMPD_target_teams: 9619 case OMPD_requires: 9620 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9621 case OMPD_unknown: 9622 llvm_unreachable("Unknown OpenMP directive"); 9623 } 9624 break; 9625 case OMPC_dist_schedule: 9626 switch (DKind) { 9627 case OMPD_teams_distribute_parallel_for: 9628 case OMPD_teams_distribute_parallel_for_simd: 9629 case OMPD_teams_distribute: 9630 case OMPD_teams_distribute_simd: 9631 case OMPD_target_teams_distribute_parallel_for: 9632 case OMPD_target_teams_distribute_parallel_for_simd: 9633 case OMPD_target_teams_distribute: 9634 case OMPD_target_teams_distribute_simd: 9635 CaptureRegion = OMPD_teams; 9636 break; 9637 case OMPD_distribute_parallel_for: 9638 case OMPD_distribute_parallel_for_simd: 9639 case OMPD_distribute: 9640 case OMPD_distribute_simd: 9641 // Do not capture thread_limit-clause expressions. 9642 break; 9643 case OMPD_parallel_for: 9644 case OMPD_parallel_for_simd: 9645 case OMPD_target_parallel_for_simd: 9646 case OMPD_target_parallel_for: 9647 case OMPD_task: 9648 case OMPD_taskloop: 9649 case OMPD_taskloop_simd: 9650 case OMPD_target_data: 9651 case OMPD_target_enter_data: 9652 case OMPD_target_exit_data: 9653 case OMPD_target_update: 9654 case OMPD_teams: 9655 case OMPD_target: 9656 case OMPD_target_simd: 9657 case OMPD_target_parallel: 9658 case OMPD_cancel: 9659 case OMPD_parallel: 9660 case OMPD_parallel_sections: 9661 case OMPD_threadprivate: 9662 case OMPD_allocate: 9663 case OMPD_taskyield: 9664 case OMPD_barrier: 9665 case OMPD_taskwait: 9666 case OMPD_cancellation_point: 9667 case OMPD_flush: 9668 case OMPD_declare_reduction: 9669 case OMPD_declare_mapper: 9670 case OMPD_declare_simd: 9671 case OMPD_declare_target: 9672 case OMPD_end_declare_target: 9673 case OMPD_simd: 9674 case OMPD_for: 9675 case OMPD_for_simd: 9676 case OMPD_sections: 9677 case OMPD_section: 9678 case OMPD_single: 9679 case OMPD_master: 9680 case OMPD_critical: 9681 case OMPD_taskgroup: 9682 case OMPD_ordered: 9683 case OMPD_atomic: 9684 case OMPD_target_teams: 9685 case OMPD_requires: 9686 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9687 case OMPD_unknown: 9688 llvm_unreachable("Unknown OpenMP directive"); 9689 } 9690 break; 9691 case OMPC_device: 9692 switch (DKind) { 9693 case OMPD_target_update: 9694 case OMPD_target_enter_data: 9695 case OMPD_target_exit_data: 9696 case OMPD_target: 9697 case OMPD_target_simd: 9698 case OMPD_target_teams: 9699 case OMPD_target_parallel: 9700 case OMPD_target_teams_distribute: 9701 case OMPD_target_teams_distribute_simd: 9702 case OMPD_target_parallel_for: 9703 case OMPD_target_parallel_for_simd: 9704 case OMPD_target_teams_distribute_parallel_for: 9705 case OMPD_target_teams_distribute_parallel_for_simd: 9706 CaptureRegion = OMPD_task; 9707 break; 9708 case OMPD_target_data: 9709 // Do not capture device-clause expressions. 9710 break; 9711 case OMPD_teams_distribute_parallel_for: 9712 case OMPD_teams_distribute_parallel_for_simd: 9713 case OMPD_teams: 9714 case OMPD_teams_distribute: 9715 case OMPD_teams_distribute_simd: 9716 case OMPD_distribute_parallel_for: 9717 case OMPD_distribute_parallel_for_simd: 9718 case OMPD_task: 9719 case OMPD_taskloop: 9720 case OMPD_taskloop_simd: 9721 case OMPD_cancel: 9722 case OMPD_parallel: 9723 case OMPD_parallel_sections: 9724 case OMPD_parallel_for: 9725 case OMPD_parallel_for_simd: 9726 case OMPD_threadprivate: 9727 case OMPD_allocate: 9728 case OMPD_taskyield: 9729 case OMPD_barrier: 9730 case OMPD_taskwait: 9731 case OMPD_cancellation_point: 9732 case OMPD_flush: 9733 case OMPD_declare_reduction: 9734 case OMPD_declare_mapper: 9735 case OMPD_declare_simd: 9736 case OMPD_declare_target: 9737 case OMPD_end_declare_target: 9738 case OMPD_simd: 9739 case OMPD_for: 9740 case OMPD_for_simd: 9741 case OMPD_sections: 9742 case OMPD_section: 9743 case OMPD_single: 9744 case OMPD_master: 9745 case OMPD_critical: 9746 case OMPD_taskgroup: 9747 case OMPD_distribute: 9748 case OMPD_ordered: 9749 case OMPD_atomic: 9750 case OMPD_distribute_simd: 9751 case OMPD_requires: 9752 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9753 case OMPD_unknown: 9754 llvm_unreachable("Unknown OpenMP directive"); 9755 } 9756 break; 9757 case OMPC_firstprivate: 9758 case OMPC_lastprivate: 9759 case OMPC_reduction: 9760 case OMPC_task_reduction: 9761 case OMPC_in_reduction: 9762 case OMPC_linear: 9763 case OMPC_default: 9764 case OMPC_proc_bind: 9765 case OMPC_final: 9766 case OMPC_safelen: 9767 case OMPC_simdlen: 9768 case OMPC_allocator: 9769 case OMPC_collapse: 9770 case OMPC_private: 9771 case OMPC_shared: 9772 case OMPC_aligned: 9773 case OMPC_copyin: 9774 case OMPC_copyprivate: 9775 case OMPC_ordered: 9776 case OMPC_nowait: 9777 case OMPC_untied: 9778 case OMPC_mergeable: 9779 case OMPC_threadprivate: 9780 case OMPC_allocate: 9781 case OMPC_flush: 9782 case OMPC_read: 9783 case OMPC_write: 9784 case OMPC_update: 9785 case OMPC_capture: 9786 case OMPC_seq_cst: 9787 case OMPC_depend: 9788 case OMPC_threads: 9789 case OMPC_simd: 9790 case OMPC_map: 9791 case OMPC_priority: 9792 case OMPC_grainsize: 9793 case OMPC_nogroup: 9794 case OMPC_num_tasks: 9795 case OMPC_hint: 9796 case OMPC_defaultmap: 9797 case OMPC_unknown: 9798 case OMPC_uniform: 9799 case OMPC_to: 9800 case OMPC_from: 9801 case OMPC_use_device_ptr: 9802 case OMPC_is_device_ptr: 9803 case OMPC_unified_address: 9804 case OMPC_unified_shared_memory: 9805 case OMPC_reverse_offload: 9806 case OMPC_dynamic_allocators: 9807 case OMPC_atomic_default_mem_order: 9808 llvm_unreachable("Unexpected OpenMP clause."); 9809 } 9810 return CaptureRegion; 9811 } 9812 9813 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 9814 Expr *Condition, SourceLocation StartLoc, 9815 SourceLocation LParenLoc, 9816 SourceLocation NameModifierLoc, 9817 SourceLocation ColonLoc, 9818 SourceLocation EndLoc) { 9819 Expr *ValExpr = Condition; 9820 Stmt *HelperValStmt = nullptr; 9821 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9822 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9823 !Condition->isInstantiationDependent() && 9824 !Condition->containsUnexpandedParameterPack()) { 9825 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9826 if (Val.isInvalid()) 9827 return nullptr; 9828 9829 ValExpr = Val.get(); 9830 9831 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9832 CaptureRegion = 9833 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 9834 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9835 ValExpr = MakeFullExpr(ValExpr).get(); 9836 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9837 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9838 HelperValStmt = buildPreInits(Context, Captures); 9839 } 9840 } 9841 9842 return new (Context) 9843 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 9844 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 9845 } 9846 9847 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 9848 SourceLocation StartLoc, 9849 SourceLocation LParenLoc, 9850 SourceLocation EndLoc) { 9851 Expr *ValExpr = Condition; 9852 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9853 !Condition->isInstantiationDependent() && 9854 !Condition->containsUnexpandedParameterPack()) { 9855 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9856 if (Val.isInvalid()) 9857 return nullptr; 9858 9859 ValExpr = MakeFullExpr(Val.get()).get(); 9860 } 9861 9862 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9863 } 9864 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 9865 Expr *Op) { 9866 if (!Op) 9867 return ExprError(); 9868 9869 class IntConvertDiagnoser : public ICEConvertDiagnoser { 9870 public: 9871 IntConvertDiagnoser() 9872 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 9873 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 9874 QualType T) override { 9875 return S.Diag(Loc, diag::err_omp_not_integral) << T; 9876 } 9877 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 9878 QualType T) override { 9879 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 9880 } 9881 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 9882 QualType T, 9883 QualType ConvTy) override { 9884 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 9885 } 9886 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 9887 QualType ConvTy) override { 9888 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9889 << ConvTy->isEnumeralType() << ConvTy; 9890 } 9891 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 9892 QualType T) override { 9893 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 9894 } 9895 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 9896 QualType ConvTy) override { 9897 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9898 << ConvTy->isEnumeralType() << ConvTy; 9899 } 9900 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 9901 QualType) override { 9902 llvm_unreachable("conversion functions are permitted"); 9903 } 9904 } ConvertDiagnoser; 9905 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 9906 } 9907 9908 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 9909 OpenMPClauseKind CKind, 9910 bool StrictlyPositive) { 9911 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 9912 !ValExpr->isInstantiationDependent()) { 9913 SourceLocation Loc = ValExpr->getExprLoc(); 9914 ExprResult Value = 9915 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 9916 if (Value.isInvalid()) 9917 return false; 9918 9919 ValExpr = Value.get(); 9920 // The expression must evaluate to a non-negative integer value. 9921 llvm::APSInt Result; 9922 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 9923 Result.isSigned() && 9924 !((!StrictlyPositive && Result.isNonNegative()) || 9925 (StrictlyPositive && Result.isStrictlyPositive()))) { 9926 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 9927 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9928 << ValExpr->getSourceRange(); 9929 return false; 9930 } 9931 } 9932 return true; 9933 } 9934 9935 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 9936 SourceLocation StartLoc, 9937 SourceLocation LParenLoc, 9938 SourceLocation EndLoc) { 9939 Expr *ValExpr = NumThreads; 9940 Stmt *HelperValStmt = nullptr; 9941 9942 // OpenMP [2.5, Restrictions] 9943 // The num_threads expression must evaluate to a positive integer value. 9944 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 9945 /*StrictlyPositive=*/true)) 9946 return nullptr; 9947 9948 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9949 OpenMPDirectiveKind CaptureRegion = 9950 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 9951 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9952 ValExpr = MakeFullExpr(ValExpr).get(); 9953 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9954 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9955 HelperValStmt = buildPreInits(Context, Captures); 9956 } 9957 9958 return new (Context) OMPNumThreadsClause( 9959 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 9960 } 9961 9962 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 9963 OpenMPClauseKind CKind, 9964 bool StrictlyPositive) { 9965 if (!E) 9966 return ExprError(); 9967 if (E->isValueDependent() || E->isTypeDependent() || 9968 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 9969 return E; 9970 llvm::APSInt Result; 9971 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 9972 if (ICE.isInvalid()) 9973 return ExprError(); 9974 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 9975 (!StrictlyPositive && !Result.isNonNegative())) { 9976 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 9977 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9978 << E->getSourceRange(); 9979 return ExprError(); 9980 } 9981 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 9982 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 9983 << E->getSourceRange(); 9984 return ExprError(); 9985 } 9986 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 9987 DSAStack->setAssociatedLoops(Result.getExtValue()); 9988 else if (CKind == OMPC_ordered) 9989 DSAStack->setAssociatedLoops(Result.getExtValue()); 9990 return ICE; 9991 } 9992 9993 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9994 SourceLocation LParenLoc, 9995 SourceLocation EndLoc) { 9996 // OpenMP [2.8.1, simd construct, Description] 9997 // The parameter of the safelen clause must be a constant 9998 // positive integer expression. 9999 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 10000 if (Safelen.isInvalid()) 10001 return nullptr; 10002 return new (Context) 10003 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 10004 } 10005 10006 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 10007 SourceLocation LParenLoc, 10008 SourceLocation EndLoc) { 10009 // OpenMP [2.8.1, simd construct, Description] 10010 // The parameter of the simdlen clause must be a constant 10011 // positive integer expression. 10012 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 10013 if (Simdlen.isInvalid()) 10014 return nullptr; 10015 return new (Context) 10016 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 10017 } 10018 10019 /// Tries to find omp_allocator_handle_t type. 10020 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 10021 DSAStackTy *Stack) { 10022 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 10023 if (!OMPAllocatorHandleT.isNull()) 10024 return true; 10025 // Build the predefined allocator expressions. 10026 bool ErrorFound = false; 10027 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 10028 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 10029 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 10030 StringRef Allocator = 10031 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 10032 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 10033 auto *VD = dyn_cast_or_null<ValueDecl>( 10034 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 10035 if (!VD) { 10036 ErrorFound = true; 10037 break; 10038 } 10039 QualType AllocatorType = 10040 VD->getType().getNonLValueExprType(S.getASTContext()); 10041 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10042 if (!Res.isUsable()) { 10043 ErrorFound = true; 10044 break; 10045 } 10046 if (OMPAllocatorHandleT.isNull()) 10047 OMPAllocatorHandleT = AllocatorType; 10048 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10049 ErrorFound = true; 10050 break; 10051 } 10052 Stack->setAllocator(AllocatorKind, Res.get()); 10053 } 10054 if (ErrorFound) { 10055 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10056 return false; 10057 } 10058 OMPAllocatorHandleT.addConst(); 10059 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10060 return true; 10061 } 10062 10063 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10064 SourceLocation LParenLoc, 10065 SourceLocation EndLoc) { 10066 // OpenMP [2.11.3, allocate Directive, Description] 10067 // allocator is an expression of omp_allocator_handle_t type. 10068 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10069 return nullptr; 10070 10071 ExprResult Allocator = DefaultLvalueConversion(A); 10072 if (Allocator.isInvalid()) 10073 return nullptr; 10074 Allocator = PerformImplicitConversion(Allocator.get(), 10075 DSAStack->getOMPAllocatorHandleT(), 10076 Sema::AA_Initializing, 10077 /*AllowExplicit=*/true); 10078 if (Allocator.isInvalid()) 10079 return nullptr; 10080 return new (Context) 10081 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10082 } 10083 10084 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10085 SourceLocation StartLoc, 10086 SourceLocation LParenLoc, 10087 SourceLocation EndLoc) { 10088 // OpenMP [2.7.1, loop construct, Description] 10089 // OpenMP [2.8.1, simd construct, Description] 10090 // OpenMP [2.9.6, distribute construct, Description] 10091 // The parameter of the collapse clause must be a constant 10092 // positive integer expression. 10093 ExprResult NumForLoopsResult = 10094 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10095 if (NumForLoopsResult.isInvalid()) 10096 return nullptr; 10097 return new (Context) 10098 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10099 } 10100 10101 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10102 SourceLocation EndLoc, 10103 SourceLocation LParenLoc, 10104 Expr *NumForLoops) { 10105 // OpenMP [2.7.1, loop construct, Description] 10106 // OpenMP [2.8.1, simd construct, Description] 10107 // OpenMP [2.9.6, distribute construct, Description] 10108 // The parameter of the ordered clause must be a constant 10109 // positive integer expression if any. 10110 if (NumForLoops && LParenLoc.isValid()) { 10111 ExprResult NumForLoopsResult = 10112 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10113 if (NumForLoopsResult.isInvalid()) 10114 return nullptr; 10115 NumForLoops = NumForLoopsResult.get(); 10116 } else { 10117 NumForLoops = nullptr; 10118 } 10119 auto *Clause = OMPOrderedClause::Create( 10120 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10121 StartLoc, LParenLoc, EndLoc); 10122 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10123 return Clause; 10124 } 10125 10126 OMPClause *Sema::ActOnOpenMPSimpleClause( 10127 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10128 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10129 OMPClause *Res = nullptr; 10130 switch (Kind) { 10131 case OMPC_default: 10132 Res = 10133 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10134 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10135 break; 10136 case OMPC_proc_bind: 10137 Res = ActOnOpenMPProcBindClause( 10138 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10139 LParenLoc, EndLoc); 10140 break; 10141 case OMPC_atomic_default_mem_order: 10142 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10143 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10144 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10145 break; 10146 case OMPC_if: 10147 case OMPC_final: 10148 case OMPC_num_threads: 10149 case OMPC_safelen: 10150 case OMPC_simdlen: 10151 case OMPC_allocator: 10152 case OMPC_collapse: 10153 case OMPC_schedule: 10154 case OMPC_private: 10155 case OMPC_firstprivate: 10156 case OMPC_lastprivate: 10157 case OMPC_shared: 10158 case OMPC_reduction: 10159 case OMPC_task_reduction: 10160 case OMPC_in_reduction: 10161 case OMPC_linear: 10162 case OMPC_aligned: 10163 case OMPC_copyin: 10164 case OMPC_copyprivate: 10165 case OMPC_ordered: 10166 case OMPC_nowait: 10167 case OMPC_untied: 10168 case OMPC_mergeable: 10169 case OMPC_threadprivate: 10170 case OMPC_allocate: 10171 case OMPC_flush: 10172 case OMPC_read: 10173 case OMPC_write: 10174 case OMPC_update: 10175 case OMPC_capture: 10176 case OMPC_seq_cst: 10177 case OMPC_depend: 10178 case OMPC_device: 10179 case OMPC_threads: 10180 case OMPC_simd: 10181 case OMPC_map: 10182 case OMPC_num_teams: 10183 case OMPC_thread_limit: 10184 case OMPC_priority: 10185 case OMPC_grainsize: 10186 case OMPC_nogroup: 10187 case OMPC_num_tasks: 10188 case OMPC_hint: 10189 case OMPC_dist_schedule: 10190 case OMPC_defaultmap: 10191 case OMPC_unknown: 10192 case OMPC_uniform: 10193 case OMPC_to: 10194 case OMPC_from: 10195 case OMPC_use_device_ptr: 10196 case OMPC_is_device_ptr: 10197 case OMPC_unified_address: 10198 case OMPC_unified_shared_memory: 10199 case OMPC_reverse_offload: 10200 case OMPC_dynamic_allocators: 10201 llvm_unreachable("Clause is not allowed."); 10202 } 10203 return Res; 10204 } 10205 10206 static std::string 10207 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10208 ArrayRef<unsigned> Exclude = llvm::None) { 10209 SmallString<256> Buffer; 10210 llvm::raw_svector_ostream Out(Buffer); 10211 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10212 unsigned Skipped = Exclude.size(); 10213 auto S = Exclude.begin(), E = Exclude.end(); 10214 for (unsigned I = First; I < Last; ++I) { 10215 if (std::find(S, E, I) != E) { 10216 --Skipped; 10217 continue; 10218 } 10219 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10220 if (I == Bound - Skipped) 10221 Out << " or "; 10222 else if (I != Bound + 1 - Skipped) 10223 Out << ", "; 10224 } 10225 return Out.str(); 10226 } 10227 10228 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 10229 SourceLocation KindKwLoc, 10230 SourceLocation StartLoc, 10231 SourceLocation LParenLoc, 10232 SourceLocation EndLoc) { 10233 if (Kind == OMPC_DEFAULT_unknown) { 10234 static_assert(OMPC_DEFAULT_unknown > 0, 10235 "OMPC_DEFAULT_unknown not greater than 0"); 10236 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10237 << getListOfPossibleValues(OMPC_default, /*First=*/0, 10238 /*Last=*/OMPC_DEFAULT_unknown) 10239 << getOpenMPClauseName(OMPC_default); 10240 return nullptr; 10241 } 10242 switch (Kind) { 10243 case OMPC_DEFAULT_none: 10244 DSAStack->setDefaultDSANone(KindKwLoc); 10245 break; 10246 case OMPC_DEFAULT_shared: 10247 DSAStack->setDefaultDSAShared(KindKwLoc); 10248 break; 10249 case OMPC_DEFAULT_unknown: 10250 llvm_unreachable("Clause kind is not allowed."); 10251 break; 10252 } 10253 return new (Context) 10254 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10255 } 10256 10257 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10258 SourceLocation KindKwLoc, 10259 SourceLocation StartLoc, 10260 SourceLocation LParenLoc, 10261 SourceLocation EndLoc) { 10262 if (Kind == OMPC_PROC_BIND_unknown) { 10263 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10264 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10265 /*Last=*/OMPC_PROC_BIND_unknown) 10266 << getOpenMPClauseName(OMPC_proc_bind); 10267 return nullptr; 10268 } 10269 return new (Context) 10270 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10271 } 10272 10273 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10274 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10275 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10276 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10277 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10278 << getListOfPossibleValues( 10279 OMPC_atomic_default_mem_order, /*First=*/0, 10280 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10281 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10282 return nullptr; 10283 } 10284 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10285 LParenLoc, EndLoc); 10286 } 10287 10288 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10289 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10290 SourceLocation StartLoc, SourceLocation LParenLoc, 10291 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10292 SourceLocation EndLoc) { 10293 OMPClause *Res = nullptr; 10294 switch (Kind) { 10295 case OMPC_schedule: 10296 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10297 assert(Argument.size() == NumberOfElements && 10298 ArgumentLoc.size() == NumberOfElements); 10299 Res = ActOnOpenMPScheduleClause( 10300 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10301 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10302 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10303 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10304 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10305 break; 10306 case OMPC_if: 10307 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10308 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10309 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10310 DelimLoc, EndLoc); 10311 break; 10312 case OMPC_dist_schedule: 10313 Res = ActOnOpenMPDistScheduleClause( 10314 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10315 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10316 break; 10317 case OMPC_defaultmap: 10318 enum { Modifier, DefaultmapKind }; 10319 Res = ActOnOpenMPDefaultmapClause( 10320 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10321 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10322 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10323 EndLoc); 10324 break; 10325 case OMPC_final: 10326 case OMPC_num_threads: 10327 case OMPC_safelen: 10328 case OMPC_simdlen: 10329 case OMPC_allocator: 10330 case OMPC_collapse: 10331 case OMPC_default: 10332 case OMPC_proc_bind: 10333 case OMPC_private: 10334 case OMPC_firstprivate: 10335 case OMPC_lastprivate: 10336 case OMPC_shared: 10337 case OMPC_reduction: 10338 case OMPC_task_reduction: 10339 case OMPC_in_reduction: 10340 case OMPC_linear: 10341 case OMPC_aligned: 10342 case OMPC_copyin: 10343 case OMPC_copyprivate: 10344 case OMPC_ordered: 10345 case OMPC_nowait: 10346 case OMPC_untied: 10347 case OMPC_mergeable: 10348 case OMPC_threadprivate: 10349 case OMPC_allocate: 10350 case OMPC_flush: 10351 case OMPC_read: 10352 case OMPC_write: 10353 case OMPC_update: 10354 case OMPC_capture: 10355 case OMPC_seq_cst: 10356 case OMPC_depend: 10357 case OMPC_device: 10358 case OMPC_threads: 10359 case OMPC_simd: 10360 case OMPC_map: 10361 case OMPC_num_teams: 10362 case OMPC_thread_limit: 10363 case OMPC_priority: 10364 case OMPC_grainsize: 10365 case OMPC_nogroup: 10366 case OMPC_num_tasks: 10367 case OMPC_hint: 10368 case OMPC_unknown: 10369 case OMPC_uniform: 10370 case OMPC_to: 10371 case OMPC_from: 10372 case OMPC_use_device_ptr: 10373 case OMPC_is_device_ptr: 10374 case OMPC_unified_address: 10375 case OMPC_unified_shared_memory: 10376 case OMPC_reverse_offload: 10377 case OMPC_dynamic_allocators: 10378 case OMPC_atomic_default_mem_order: 10379 llvm_unreachable("Clause is not allowed."); 10380 } 10381 return Res; 10382 } 10383 10384 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10385 OpenMPScheduleClauseModifier M2, 10386 SourceLocation M1Loc, SourceLocation M2Loc) { 10387 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10388 SmallVector<unsigned, 2> Excluded; 10389 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10390 Excluded.push_back(M2); 10391 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10392 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10393 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10394 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10395 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10396 << getListOfPossibleValues(OMPC_schedule, 10397 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10398 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10399 Excluded) 10400 << getOpenMPClauseName(OMPC_schedule); 10401 return true; 10402 } 10403 return false; 10404 } 10405 10406 OMPClause *Sema::ActOnOpenMPScheduleClause( 10407 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10408 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10409 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10410 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10411 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10412 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10413 return nullptr; 10414 // OpenMP, 2.7.1, Loop Construct, Restrictions 10415 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10416 // but not both. 10417 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10418 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10419 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10420 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10421 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10422 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10423 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10424 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10425 return nullptr; 10426 } 10427 if (Kind == OMPC_SCHEDULE_unknown) { 10428 std::string Values; 10429 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10430 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10431 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10432 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10433 Exclude); 10434 } else { 10435 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10436 /*Last=*/OMPC_SCHEDULE_unknown); 10437 } 10438 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10439 << Values << getOpenMPClauseName(OMPC_schedule); 10440 return nullptr; 10441 } 10442 // OpenMP, 2.7.1, Loop Construct, Restrictions 10443 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 10444 // schedule(guided). 10445 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 10446 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 10447 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 10448 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 10449 diag::err_omp_schedule_nonmonotonic_static); 10450 return nullptr; 10451 } 10452 Expr *ValExpr = ChunkSize; 10453 Stmt *HelperValStmt = nullptr; 10454 if (ChunkSize) { 10455 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10456 !ChunkSize->isInstantiationDependent() && 10457 !ChunkSize->containsUnexpandedParameterPack()) { 10458 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 10459 ExprResult Val = 10460 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10461 if (Val.isInvalid()) 10462 return nullptr; 10463 10464 ValExpr = Val.get(); 10465 10466 // OpenMP [2.7.1, Restrictions] 10467 // chunk_size must be a loop invariant integer expression with a positive 10468 // value. 10469 llvm::APSInt Result; 10470 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10471 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10472 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10473 << "schedule" << 1 << ChunkSize->getSourceRange(); 10474 return nullptr; 10475 } 10476 } else if (getOpenMPCaptureRegionForClause( 10477 DSAStack->getCurrentDirective(), OMPC_schedule) != 10478 OMPD_unknown && 10479 !CurContext->isDependentContext()) { 10480 ValExpr = MakeFullExpr(ValExpr).get(); 10481 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10482 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10483 HelperValStmt = buildPreInits(Context, Captures); 10484 } 10485 } 10486 } 10487 10488 return new (Context) 10489 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 10490 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 10491 } 10492 10493 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 10494 SourceLocation StartLoc, 10495 SourceLocation EndLoc) { 10496 OMPClause *Res = nullptr; 10497 switch (Kind) { 10498 case OMPC_ordered: 10499 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 10500 break; 10501 case OMPC_nowait: 10502 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 10503 break; 10504 case OMPC_untied: 10505 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 10506 break; 10507 case OMPC_mergeable: 10508 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 10509 break; 10510 case OMPC_read: 10511 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 10512 break; 10513 case OMPC_write: 10514 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 10515 break; 10516 case OMPC_update: 10517 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 10518 break; 10519 case OMPC_capture: 10520 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 10521 break; 10522 case OMPC_seq_cst: 10523 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 10524 break; 10525 case OMPC_threads: 10526 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 10527 break; 10528 case OMPC_simd: 10529 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 10530 break; 10531 case OMPC_nogroup: 10532 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 10533 break; 10534 case OMPC_unified_address: 10535 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 10536 break; 10537 case OMPC_unified_shared_memory: 10538 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10539 break; 10540 case OMPC_reverse_offload: 10541 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 10542 break; 10543 case OMPC_dynamic_allocators: 10544 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 10545 break; 10546 case OMPC_if: 10547 case OMPC_final: 10548 case OMPC_num_threads: 10549 case OMPC_safelen: 10550 case OMPC_simdlen: 10551 case OMPC_allocator: 10552 case OMPC_collapse: 10553 case OMPC_schedule: 10554 case OMPC_private: 10555 case OMPC_firstprivate: 10556 case OMPC_lastprivate: 10557 case OMPC_shared: 10558 case OMPC_reduction: 10559 case OMPC_task_reduction: 10560 case OMPC_in_reduction: 10561 case OMPC_linear: 10562 case OMPC_aligned: 10563 case OMPC_copyin: 10564 case OMPC_copyprivate: 10565 case OMPC_default: 10566 case OMPC_proc_bind: 10567 case OMPC_threadprivate: 10568 case OMPC_allocate: 10569 case OMPC_flush: 10570 case OMPC_depend: 10571 case OMPC_device: 10572 case OMPC_map: 10573 case OMPC_num_teams: 10574 case OMPC_thread_limit: 10575 case OMPC_priority: 10576 case OMPC_grainsize: 10577 case OMPC_num_tasks: 10578 case OMPC_hint: 10579 case OMPC_dist_schedule: 10580 case OMPC_defaultmap: 10581 case OMPC_unknown: 10582 case OMPC_uniform: 10583 case OMPC_to: 10584 case OMPC_from: 10585 case OMPC_use_device_ptr: 10586 case OMPC_is_device_ptr: 10587 case OMPC_atomic_default_mem_order: 10588 llvm_unreachable("Clause is not allowed."); 10589 } 10590 return Res; 10591 } 10592 10593 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 10594 SourceLocation EndLoc) { 10595 DSAStack->setNowaitRegion(); 10596 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 10597 } 10598 10599 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 10600 SourceLocation EndLoc) { 10601 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 10602 } 10603 10604 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 10605 SourceLocation EndLoc) { 10606 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 10607 } 10608 10609 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 10610 SourceLocation EndLoc) { 10611 return new (Context) OMPReadClause(StartLoc, EndLoc); 10612 } 10613 10614 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 10615 SourceLocation EndLoc) { 10616 return new (Context) OMPWriteClause(StartLoc, EndLoc); 10617 } 10618 10619 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 10620 SourceLocation EndLoc) { 10621 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 10622 } 10623 10624 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10625 SourceLocation EndLoc) { 10626 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10627 } 10628 10629 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10630 SourceLocation EndLoc) { 10631 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10632 } 10633 10634 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 10635 SourceLocation EndLoc) { 10636 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 10637 } 10638 10639 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 10640 SourceLocation EndLoc) { 10641 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 10642 } 10643 10644 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 10645 SourceLocation EndLoc) { 10646 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 10647 } 10648 10649 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 10650 SourceLocation EndLoc) { 10651 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 10652 } 10653 10654 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 10655 SourceLocation EndLoc) { 10656 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10657 } 10658 10659 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 10660 SourceLocation EndLoc) { 10661 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 10662 } 10663 10664 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 10665 SourceLocation EndLoc) { 10666 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 10667 } 10668 10669 OMPClause *Sema::ActOnOpenMPVarListClause( 10670 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 10671 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 10672 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 10673 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 10674 OpenMPLinearClauseKind LinKind, 10675 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 10676 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 10677 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 10678 SourceLocation StartLoc = Locs.StartLoc; 10679 SourceLocation LParenLoc = Locs.LParenLoc; 10680 SourceLocation EndLoc = Locs.EndLoc; 10681 OMPClause *Res = nullptr; 10682 switch (Kind) { 10683 case OMPC_private: 10684 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10685 break; 10686 case OMPC_firstprivate: 10687 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10688 break; 10689 case OMPC_lastprivate: 10690 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10691 break; 10692 case OMPC_shared: 10693 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 10694 break; 10695 case OMPC_reduction: 10696 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10697 EndLoc, ReductionOrMapperIdScopeSpec, 10698 ReductionOrMapperId); 10699 break; 10700 case OMPC_task_reduction: 10701 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10702 EndLoc, ReductionOrMapperIdScopeSpec, 10703 ReductionOrMapperId); 10704 break; 10705 case OMPC_in_reduction: 10706 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10707 EndLoc, ReductionOrMapperIdScopeSpec, 10708 ReductionOrMapperId); 10709 break; 10710 case OMPC_linear: 10711 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 10712 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 10713 break; 10714 case OMPC_aligned: 10715 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 10716 ColonLoc, EndLoc); 10717 break; 10718 case OMPC_copyin: 10719 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 10720 break; 10721 case OMPC_copyprivate: 10722 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10723 break; 10724 case OMPC_flush: 10725 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 10726 break; 10727 case OMPC_depend: 10728 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 10729 StartLoc, LParenLoc, EndLoc); 10730 break; 10731 case OMPC_map: 10732 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 10733 ReductionOrMapperIdScopeSpec, 10734 ReductionOrMapperId, MapType, IsMapTypeImplicit, 10735 DepLinMapLoc, ColonLoc, VarList, Locs); 10736 break; 10737 case OMPC_to: 10738 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 10739 ReductionOrMapperId, Locs); 10740 break; 10741 case OMPC_from: 10742 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 10743 ReductionOrMapperId, Locs); 10744 break; 10745 case OMPC_use_device_ptr: 10746 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 10747 break; 10748 case OMPC_is_device_ptr: 10749 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 10750 break; 10751 case OMPC_allocate: 10752 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 10753 ColonLoc, EndLoc); 10754 break; 10755 case OMPC_if: 10756 case OMPC_final: 10757 case OMPC_num_threads: 10758 case OMPC_safelen: 10759 case OMPC_simdlen: 10760 case OMPC_allocator: 10761 case OMPC_collapse: 10762 case OMPC_default: 10763 case OMPC_proc_bind: 10764 case OMPC_schedule: 10765 case OMPC_ordered: 10766 case OMPC_nowait: 10767 case OMPC_untied: 10768 case OMPC_mergeable: 10769 case OMPC_threadprivate: 10770 case OMPC_read: 10771 case OMPC_write: 10772 case OMPC_update: 10773 case OMPC_capture: 10774 case OMPC_seq_cst: 10775 case OMPC_device: 10776 case OMPC_threads: 10777 case OMPC_simd: 10778 case OMPC_num_teams: 10779 case OMPC_thread_limit: 10780 case OMPC_priority: 10781 case OMPC_grainsize: 10782 case OMPC_nogroup: 10783 case OMPC_num_tasks: 10784 case OMPC_hint: 10785 case OMPC_dist_schedule: 10786 case OMPC_defaultmap: 10787 case OMPC_unknown: 10788 case OMPC_uniform: 10789 case OMPC_unified_address: 10790 case OMPC_unified_shared_memory: 10791 case OMPC_reverse_offload: 10792 case OMPC_dynamic_allocators: 10793 case OMPC_atomic_default_mem_order: 10794 llvm_unreachable("Clause is not allowed."); 10795 } 10796 return Res; 10797 } 10798 10799 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 10800 ExprObjectKind OK, SourceLocation Loc) { 10801 ExprResult Res = BuildDeclRefExpr( 10802 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 10803 if (!Res.isUsable()) 10804 return ExprError(); 10805 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 10806 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 10807 if (!Res.isUsable()) 10808 return ExprError(); 10809 } 10810 if (VK != VK_LValue && Res.get()->isGLValue()) { 10811 Res = DefaultLvalueConversion(Res.get()); 10812 if (!Res.isUsable()) 10813 return ExprError(); 10814 } 10815 return Res; 10816 } 10817 10818 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 10819 SourceLocation StartLoc, 10820 SourceLocation LParenLoc, 10821 SourceLocation EndLoc) { 10822 SmallVector<Expr *, 8> Vars; 10823 SmallVector<Expr *, 8> PrivateCopies; 10824 for (Expr *RefExpr : VarList) { 10825 assert(RefExpr && "NULL expr in OpenMP private clause."); 10826 SourceLocation ELoc; 10827 SourceRange ERange; 10828 Expr *SimpleRefExpr = RefExpr; 10829 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10830 if (Res.second) { 10831 // It will be analyzed later. 10832 Vars.push_back(RefExpr); 10833 PrivateCopies.push_back(nullptr); 10834 } 10835 ValueDecl *D = Res.first; 10836 if (!D) 10837 continue; 10838 10839 QualType Type = D->getType(); 10840 auto *VD = dyn_cast<VarDecl>(D); 10841 10842 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10843 // A variable that appears in a private clause must not have an incomplete 10844 // type or a reference type. 10845 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 10846 continue; 10847 Type = Type.getNonReferenceType(); 10848 10849 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10850 // A variable that is privatized must not have a const-qualified type 10851 // unless it is of class type with a mutable member. This restriction does 10852 // not apply to the firstprivate clause. 10853 // 10854 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 10855 // A variable that appears in a private clause must not have a 10856 // const-qualified type unless it is of class type with a mutable member. 10857 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 10858 continue; 10859 10860 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10861 // in a Construct] 10862 // Variables with the predetermined data-sharing attributes may not be 10863 // listed in data-sharing attributes clauses, except for the cases 10864 // listed below. For these exceptions only, listing a predetermined 10865 // variable in a data-sharing attribute clause is allowed and overrides 10866 // the variable's predetermined data-sharing attributes. 10867 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10868 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 10869 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10870 << getOpenMPClauseName(OMPC_private); 10871 reportOriginalDsa(*this, DSAStack, D, DVar); 10872 continue; 10873 } 10874 10875 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10876 // Variably modified types are not supported for tasks. 10877 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10878 isOpenMPTaskingDirective(CurrDir)) { 10879 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10880 << getOpenMPClauseName(OMPC_private) << Type 10881 << getOpenMPDirectiveName(CurrDir); 10882 bool IsDecl = 10883 !VD || 10884 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10885 Diag(D->getLocation(), 10886 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10887 << D; 10888 continue; 10889 } 10890 10891 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10892 // A list item cannot appear in both a map clause and a data-sharing 10893 // attribute clause on the same construct 10894 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10895 OpenMPClauseKind ConflictKind; 10896 if (DSAStack->checkMappableExprComponentListsForDecl( 10897 VD, /*CurrentRegionOnly=*/true, 10898 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 10899 OpenMPClauseKind WhereFoundClauseKind) -> bool { 10900 ConflictKind = WhereFoundClauseKind; 10901 return true; 10902 })) { 10903 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10904 << getOpenMPClauseName(OMPC_private) 10905 << getOpenMPClauseName(ConflictKind) 10906 << getOpenMPDirectiveName(CurrDir); 10907 reportOriginalDsa(*this, DSAStack, D, DVar); 10908 continue; 10909 } 10910 } 10911 10912 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 10913 // A variable of class type (or array thereof) that appears in a private 10914 // clause requires an accessible, unambiguous default constructor for the 10915 // class type. 10916 // Generate helper private variable and initialize it with the default 10917 // value. The address of the original variable is replaced by the address of 10918 // the new private variable in CodeGen. This new variable is not added to 10919 // IdResolver, so the code in the OpenMP region uses original variable for 10920 // proper diagnostics. 10921 Type = Type.getUnqualifiedType(); 10922 VarDecl *VDPrivate = 10923 buildVarDecl(*this, ELoc, Type, D->getName(), 10924 D->hasAttrs() ? &D->getAttrs() : nullptr, 10925 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10926 ActOnUninitializedDecl(VDPrivate); 10927 if (VDPrivate->isInvalidDecl()) 10928 continue; 10929 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10930 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 10931 10932 DeclRefExpr *Ref = nullptr; 10933 if (!VD && !CurContext->isDependentContext()) 10934 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10935 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 10936 Vars.push_back((VD || CurContext->isDependentContext()) 10937 ? RefExpr->IgnoreParens() 10938 : Ref); 10939 PrivateCopies.push_back(VDPrivateRefExpr); 10940 } 10941 10942 if (Vars.empty()) 10943 return nullptr; 10944 10945 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10946 PrivateCopies); 10947 } 10948 10949 namespace { 10950 class DiagsUninitializedSeveretyRAII { 10951 private: 10952 DiagnosticsEngine &Diags; 10953 SourceLocation SavedLoc; 10954 bool IsIgnored = false; 10955 10956 public: 10957 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 10958 bool IsIgnored) 10959 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 10960 if (!IsIgnored) { 10961 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 10962 /*Map*/ diag::Severity::Ignored, Loc); 10963 } 10964 } 10965 ~DiagsUninitializedSeveretyRAII() { 10966 if (!IsIgnored) 10967 Diags.popMappings(SavedLoc); 10968 } 10969 }; 10970 } 10971 10972 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 10973 SourceLocation StartLoc, 10974 SourceLocation LParenLoc, 10975 SourceLocation EndLoc) { 10976 SmallVector<Expr *, 8> Vars; 10977 SmallVector<Expr *, 8> PrivateCopies; 10978 SmallVector<Expr *, 8> Inits; 10979 SmallVector<Decl *, 4> ExprCaptures; 10980 bool IsImplicitClause = 10981 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 10982 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 10983 10984 for (Expr *RefExpr : VarList) { 10985 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 10986 SourceLocation ELoc; 10987 SourceRange ERange; 10988 Expr *SimpleRefExpr = RefExpr; 10989 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10990 if (Res.second) { 10991 // It will be analyzed later. 10992 Vars.push_back(RefExpr); 10993 PrivateCopies.push_back(nullptr); 10994 Inits.push_back(nullptr); 10995 } 10996 ValueDecl *D = Res.first; 10997 if (!D) 10998 continue; 10999 11000 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 11001 QualType Type = D->getType(); 11002 auto *VD = dyn_cast<VarDecl>(D); 11003 11004 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11005 // A variable that appears in a private clause must not have an incomplete 11006 // type or a reference type. 11007 if (RequireCompleteType(ELoc, Type, 11008 diag::err_omp_firstprivate_incomplete_type)) 11009 continue; 11010 Type = Type.getNonReferenceType(); 11011 11012 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 11013 // A variable of class type (or array thereof) that appears in a private 11014 // clause requires an accessible, unambiguous copy constructor for the 11015 // class type. 11016 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11017 11018 // If an implicit firstprivate variable found it was checked already. 11019 DSAStackTy::DSAVarData TopDVar; 11020 if (!IsImplicitClause) { 11021 DSAStackTy::DSAVarData DVar = 11022 DSAStack->getTopDSA(D, /*FromParent=*/false); 11023 TopDVar = DVar; 11024 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11025 bool IsConstant = ElemType.isConstant(Context); 11026 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 11027 // A list item that specifies a given variable may not appear in more 11028 // than one clause on the same directive, except that a variable may be 11029 // specified in both firstprivate and lastprivate clauses. 11030 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11031 // A list item may appear in a firstprivate or lastprivate clause but not 11032 // both. 11033 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 11034 (isOpenMPDistributeDirective(CurrDir) || 11035 DVar.CKind != OMPC_lastprivate) && 11036 DVar.RefExpr) { 11037 Diag(ELoc, diag::err_omp_wrong_dsa) 11038 << getOpenMPClauseName(DVar.CKind) 11039 << getOpenMPClauseName(OMPC_firstprivate); 11040 reportOriginalDsa(*this, DSAStack, D, DVar); 11041 continue; 11042 } 11043 11044 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11045 // in a Construct] 11046 // Variables with the predetermined data-sharing attributes may not be 11047 // listed in data-sharing attributes clauses, except for the cases 11048 // listed below. For these exceptions only, listing a predetermined 11049 // variable in a data-sharing attribute clause is allowed and overrides 11050 // the variable's predetermined data-sharing attributes. 11051 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11052 // in a Construct, C/C++, p.2] 11053 // Variables with const-qualified type having no mutable member may be 11054 // listed in a firstprivate clause, even if they are static data members. 11055 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11056 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11057 Diag(ELoc, diag::err_omp_wrong_dsa) 11058 << getOpenMPClauseName(DVar.CKind) 11059 << getOpenMPClauseName(OMPC_firstprivate); 11060 reportOriginalDsa(*this, DSAStack, D, DVar); 11061 continue; 11062 } 11063 11064 // OpenMP [2.9.3.4, Restrictions, p.2] 11065 // A list item that is private within a parallel region must not appear 11066 // in a firstprivate clause on a worksharing construct if any of the 11067 // worksharing regions arising from the worksharing construct ever bind 11068 // to any of the parallel regions arising from the parallel construct. 11069 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11070 // A list item that is private within a teams region must not appear in a 11071 // firstprivate clause on a distribute construct if any of the distribute 11072 // regions arising from the distribute construct ever bind to any of the 11073 // teams regions arising from the teams construct. 11074 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11075 // A list item that appears in a reduction clause of a teams construct 11076 // must not appear in a firstprivate clause on a distribute construct if 11077 // any of the distribute regions arising from the distribute construct 11078 // ever bind to any of the teams regions arising from the teams construct. 11079 if ((isOpenMPWorksharingDirective(CurrDir) || 11080 isOpenMPDistributeDirective(CurrDir)) && 11081 !isOpenMPParallelDirective(CurrDir) && 11082 !isOpenMPTeamsDirective(CurrDir)) { 11083 DVar = DSAStack->getImplicitDSA(D, true); 11084 if (DVar.CKind != OMPC_shared && 11085 (isOpenMPParallelDirective(DVar.DKind) || 11086 isOpenMPTeamsDirective(DVar.DKind) || 11087 DVar.DKind == OMPD_unknown)) { 11088 Diag(ELoc, diag::err_omp_required_access) 11089 << getOpenMPClauseName(OMPC_firstprivate) 11090 << getOpenMPClauseName(OMPC_shared); 11091 reportOriginalDsa(*this, DSAStack, D, DVar); 11092 continue; 11093 } 11094 } 11095 // OpenMP [2.9.3.4, Restrictions, p.3] 11096 // A list item that appears in a reduction clause of a parallel construct 11097 // must not appear in a firstprivate clause on a worksharing or task 11098 // construct if any of the worksharing or task regions arising from the 11099 // worksharing or task construct ever bind to any of the parallel regions 11100 // arising from the parallel construct. 11101 // OpenMP [2.9.3.4, Restrictions, p.4] 11102 // A list item that appears in a reduction clause in worksharing 11103 // construct must not appear in a firstprivate clause in a task construct 11104 // encountered during execution of any of the worksharing regions arising 11105 // from the worksharing construct. 11106 if (isOpenMPTaskingDirective(CurrDir)) { 11107 DVar = DSAStack->hasInnermostDSA( 11108 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11109 [](OpenMPDirectiveKind K) { 11110 return isOpenMPParallelDirective(K) || 11111 isOpenMPWorksharingDirective(K) || 11112 isOpenMPTeamsDirective(K); 11113 }, 11114 /*FromParent=*/true); 11115 if (DVar.CKind == OMPC_reduction && 11116 (isOpenMPParallelDirective(DVar.DKind) || 11117 isOpenMPWorksharingDirective(DVar.DKind) || 11118 isOpenMPTeamsDirective(DVar.DKind))) { 11119 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11120 << getOpenMPDirectiveName(DVar.DKind); 11121 reportOriginalDsa(*this, DSAStack, D, DVar); 11122 continue; 11123 } 11124 } 11125 11126 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11127 // A list item cannot appear in both a map clause and a data-sharing 11128 // attribute clause on the same construct 11129 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11130 OpenMPClauseKind ConflictKind; 11131 if (DSAStack->checkMappableExprComponentListsForDecl( 11132 VD, /*CurrentRegionOnly=*/true, 11133 [&ConflictKind]( 11134 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11135 OpenMPClauseKind WhereFoundClauseKind) { 11136 ConflictKind = WhereFoundClauseKind; 11137 return true; 11138 })) { 11139 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11140 << getOpenMPClauseName(OMPC_firstprivate) 11141 << getOpenMPClauseName(ConflictKind) 11142 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11143 reportOriginalDsa(*this, DSAStack, D, DVar); 11144 continue; 11145 } 11146 } 11147 } 11148 11149 // Variably modified types are not supported for tasks. 11150 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11151 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11152 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11153 << getOpenMPClauseName(OMPC_firstprivate) << Type 11154 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11155 bool IsDecl = 11156 !VD || 11157 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11158 Diag(D->getLocation(), 11159 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11160 << D; 11161 continue; 11162 } 11163 11164 Type = Type.getUnqualifiedType(); 11165 VarDecl *VDPrivate = 11166 buildVarDecl(*this, ELoc, Type, D->getName(), 11167 D->hasAttrs() ? &D->getAttrs() : nullptr, 11168 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11169 // Generate helper private variable and initialize it with the value of the 11170 // original variable. The address of the original variable is replaced by 11171 // the address of the new private variable in the CodeGen. This new variable 11172 // is not added to IdResolver, so the code in the OpenMP region uses 11173 // original variable for proper diagnostics and variable capturing. 11174 Expr *VDInitRefExpr = nullptr; 11175 // For arrays generate initializer for single element and replace it by the 11176 // original array element in CodeGen. 11177 if (Type->isArrayType()) { 11178 VarDecl *VDInit = 11179 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11180 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11181 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11182 ElemType = ElemType.getUnqualifiedType(); 11183 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11184 ".firstprivate.temp"); 11185 InitializedEntity Entity = 11186 InitializedEntity::InitializeVariable(VDInitTemp); 11187 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11188 11189 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11190 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11191 if (Result.isInvalid()) 11192 VDPrivate->setInvalidDecl(); 11193 else 11194 VDPrivate->setInit(Result.getAs<Expr>()); 11195 // Remove temp variable declaration. 11196 Context.Deallocate(VDInitTemp); 11197 } else { 11198 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11199 ".firstprivate.temp"); 11200 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11201 RefExpr->getExprLoc()); 11202 AddInitializerToDecl(VDPrivate, 11203 DefaultLvalueConversion(VDInitRefExpr).get(), 11204 /*DirectInit=*/false); 11205 } 11206 if (VDPrivate->isInvalidDecl()) { 11207 if (IsImplicitClause) { 11208 Diag(RefExpr->getExprLoc(), 11209 diag::note_omp_task_predetermined_firstprivate_here); 11210 } 11211 continue; 11212 } 11213 CurContext->addDecl(VDPrivate); 11214 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11215 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 11216 RefExpr->getExprLoc()); 11217 DeclRefExpr *Ref = nullptr; 11218 if (!VD && !CurContext->isDependentContext()) { 11219 if (TopDVar.CKind == OMPC_lastprivate) { 11220 Ref = TopDVar.PrivateCopy; 11221 } else { 11222 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11223 if (!isOpenMPCapturedDecl(D)) 11224 ExprCaptures.push_back(Ref->getDecl()); 11225 } 11226 } 11227 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11228 Vars.push_back((VD || CurContext->isDependentContext()) 11229 ? RefExpr->IgnoreParens() 11230 : Ref); 11231 PrivateCopies.push_back(VDPrivateRefExpr); 11232 Inits.push_back(VDInitRefExpr); 11233 } 11234 11235 if (Vars.empty()) 11236 return nullptr; 11237 11238 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11239 Vars, PrivateCopies, Inits, 11240 buildPreInits(Context, ExprCaptures)); 11241 } 11242 11243 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11244 SourceLocation StartLoc, 11245 SourceLocation LParenLoc, 11246 SourceLocation EndLoc) { 11247 SmallVector<Expr *, 8> Vars; 11248 SmallVector<Expr *, 8> SrcExprs; 11249 SmallVector<Expr *, 8> DstExprs; 11250 SmallVector<Expr *, 8> AssignmentOps; 11251 SmallVector<Decl *, 4> ExprCaptures; 11252 SmallVector<Expr *, 4> ExprPostUpdates; 11253 for (Expr *RefExpr : VarList) { 11254 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11255 SourceLocation ELoc; 11256 SourceRange ERange; 11257 Expr *SimpleRefExpr = RefExpr; 11258 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11259 if (Res.second) { 11260 // It will be analyzed later. 11261 Vars.push_back(RefExpr); 11262 SrcExprs.push_back(nullptr); 11263 DstExprs.push_back(nullptr); 11264 AssignmentOps.push_back(nullptr); 11265 } 11266 ValueDecl *D = Res.first; 11267 if (!D) 11268 continue; 11269 11270 QualType Type = D->getType(); 11271 auto *VD = dyn_cast<VarDecl>(D); 11272 11273 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11274 // A variable that appears in a lastprivate clause must not have an 11275 // incomplete type or a reference type. 11276 if (RequireCompleteType(ELoc, Type, 11277 diag::err_omp_lastprivate_incomplete_type)) 11278 continue; 11279 Type = Type.getNonReferenceType(); 11280 11281 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11282 // A variable that is privatized must not have a const-qualified type 11283 // unless it is of class type with a mutable member. This restriction does 11284 // not apply to the firstprivate clause. 11285 // 11286 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11287 // A variable that appears in a lastprivate clause must not have a 11288 // const-qualified type unless it is of class type with a mutable member. 11289 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11290 continue; 11291 11292 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11293 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11294 // in a Construct] 11295 // Variables with the predetermined data-sharing attributes may not be 11296 // listed in data-sharing attributes clauses, except for the cases 11297 // listed below. 11298 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11299 // A list item may appear in a firstprivate or lastprivate clause but not 11300 // both. 11301 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11302 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11303 (isOpenMPDistributeDirective(CurrDir) || 11304 DVar.CKind != OMPC_firstprivate) && 11305 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11306 Diag(ELoc, diag::err_omp_wrong_dsa) 11307 << getOpenMPClauseName(DVar.CKind) 11308 << getOpenMPClauseName(OMPC_lastprivate); 11309 reportOriginalDsa(*this, DSAStack, D, DVar); 11310 continue; 11311 } 11312 11313 // OpenMP [2.14.3.5, Restrictions, p.2] 11314 // A list item that is private within a parallel region, or that appears in 11315 // the reduction clause of a parallel construct, must not appear in a 11316 // lastprivate clause on a worksharing construct if any of the corresponding 11317 // worksharing regions ever binds to any of the corresponding parallel 11318 // regions. 11319 DSAStackTy::DSAVarData TopDVar = DVar; 11320 if (isOpenMPWorksharingDirective(CurrDir) && 11321 !isOpenMPParallelDirective(CurrDir) && 11322 !isOpenMPTeamsDirective(CurrDir)) { 11323 DVar = DSAStack->getImplicitDSA(D, true); 11324 if (DVar.CKind != OMPC_shared) { 11325 Diag(ELoc, diag::err_omp_required_access) 11326 << getOpenMPClauseName(OMPC_lastprivate) 11327 << getOpenMPClauseName(OMPC_shared); 11328 reportOriginalDsa(*this, DSAStack, D, DVar); 11329 continue; 11330 } 11331 } 11332 11333 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11334 // A variable of class type (or array thereof) that appears in a 11335 // lastprivate clause requires an accessible, unambiguous default 11336 // constructor for the class type, unless the list item is also specified 11337 // in a firstprivate clause. 11338 // A variable of class type (or array thereof) that appears in a 11339 // lastprivate clause requires an accessible, unambiguous copy assignment 11340 // operator for the class type. 11341 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11342 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11343 Type.getUnqualifiedType(), ".lastprivate.src", 11344 D->hasAttrs() ? &D->getAttrs() : nullptr); 11345 DeclRefExpr *PseudoSrcExpr = 11346 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11347 VarDecl *DstVD = 11348 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11349 D->hasAttrs() ? &D->getAttrs() : nullptr); 11350 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11351 // For arrays generate assignment operation for single element and replace 11352 // it by the original array element in CodeGen. 11353 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11354 PseudoDstExpr, PseudoSrcExpr); 11355 if (AssignmentOp.isInvalid()) 11356 continue; 11357 AssignmentOp = 11358 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11359 if (AssignmentOp.isInvalid()) 11360 continue; 11361 11362 DeclRefExpr *Ref = nullptr; 11363 if (!VD && !CurContext->isDependentContext()) { 11364 if (TopDVar.CKind == OMPC_firstprivate) { 11365 Ref = TopDVar.PrivateCopy; 11366 } else { 11367 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11368 if (!isOpenMPCapturedDecl(D)) 11369 ExprCaptures.push_back(Ref->getDecl()); 11370 } 11371 if (TopDVar.CKind == OMPC_firstprivate || 11372 (!isOpenMPCapturedDecl(D) && 11373 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11374 ExprResult RefRes = DefaultLvalueConversion(Ref); 11375 if (!RefRes.isUsable()) 11376 continue; 11377 ExprResult PostUpdateRes = 11378 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11379 RefRes.get()); 11380 if (!PostUpdateRes.isUsable()) 11381 continue; 11382 ExprPostUpdates.push_back( 11383 IgnoredValueConversions(PostUpdateRes.get()).get()); 11384 } 11385 } 11386 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11387 Vars.push_back((VD || CurContext->isDependentContext()) 11388 ? RefExpr->IgnoreParens() 11389 : Ref); 11390 SrcExprs.push_back(PseudoSrcExpr); 11391 DstExprs.push_back(PseudoDstExpr); 11392 AssignmentOps.push_back(AssignmentOp.get()); 11393 } 11394 11395 if (Vars.empty()) 11396 return nullptr; 11397 11398 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11399 Vars, SrcExprs, DstExprs, AssignmentOps, 11400 buildPreInits(Context, ExprCaptures), 11401 buildPostUpdate(*this, ExprPostUpdates)); 11402 } 11403 11404 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11405 SourceLocation StartLoc, 11406 SourceLocation LParenLoc, 11407 SourceLocation EndLoc) { 11408 SmallVector<Expr *, 8> Vars; 11409 for (Expr *RefExpr : VarList) { 11410 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11411 SourceLocation ELoc; 11412 SourceRange ERange; 11413 Expr *SimpleRefExpr = RefExpr; 11414 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11415 if (Res.second) { 11416 // It will be analyzed later. 11417 Vars.push_back(RefExpr); 11418 } 11419 ValueDecl *D = Res.first; 11420 if (!D) 11421 continue; 11422 11423 auto *VD = dyn_cast<VarDecl>(D); 11424 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11425 // in a Construct] 11426 // Variables with the predetermined data-sharing attributes may not be 11427 // listed in data-sharing attributes clauses, except for the cases 11428 // listed below. For these exceptions only, listing a predetermined 11429 // variable in a data-sharing attribute clause is allowed and overrides 11430 // the variable's predetermined data-sharing attributes. 11431 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11432 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 11433 DVar.RefExpr) { 11434 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11435 << getOpenMPClauseName(OMPC_shared); 11436 reportOriginalDsa(*this, DSAStack, D, DVar); 11437 continue; 11438 } 11439 11440 DeclRefExpr *Ref = nullptr; 11441 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 11442 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11443 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 11444 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 11445 ? RefExpr->IgnoreParens() 11446 : Ref); 11447 } 11448 11449 if (Vars.empty()) 11450 return nullptr; 11451 11452 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 11453 } 11454 11455 namespace { 11456 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 11457 DSAStackTy *Stack; 11458 11459 public: 11460 bool VisitDeclRefExpr(DeclRefExpr *E) { 11461 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 11462 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 11463 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 11464 return false; 11465 if (DVar.CKind != OMPC_unknown) 11466 return true; 11467 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 11468 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 11469 /*FromParent=*/true); 11470 return DVarPrivate.CKind != OMPC_unknown; 11471 } 11472 return false; 11473 } 11474 bool VisitStmt(Stmt *S) { 11475 for (Stmt *Child : S->children()) { 11476 if (Child && Visit(Child)) 11477 return true; 11478 } 11479 return false; 11480 } 11481 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 11482 }; 11483 } // namespace 11484 11485 namespace { 11486 // Transform MemberExpression for specified FieldDecl of current class to 11487 // DeclRefExpr to specified OMPCapturedExprDecl. 11488 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 11489 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 11490 ValueDecl *Field = nullptr; 11491 DeclRefExpr *CapturedExpr = nullptr; 11492 11493 public: 11494 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 11495 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 11496 11497 ExprResult TransformMemberExpr(MemberExpr *E) { 11498 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 11499 E->getMemberDecl() == Field) { 11500 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 11501 return CapturedExpr; 11502 } 11503 return BaseTransform::TransformMemberExpr(E); 11504 } 11505 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 11506 }; 11507 } // namespace 11508 11509 template <typename T, typename U> 11510 static T filterLookupForUDReductionAndMapper( 11511 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 11512 for (U &Set : Lookups) { 11513 for (auto *D : Set) { 11514 if (T Res = Gen(cast<ValueDecl>(D))) 11515 return Res; 11516 } 11517 } 11518 return T(); 11519 } 11520 11521 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 11522 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 11523 11524 for (auto RD : D->redecls()) { 11525 // Don't bother with extra checks if we already know this one isn't visible. 11526 if (RD == D) 11527 continue; 11528 11529 auto ND = cast<NamedDecl>(RD); 11530 if (LookupResult::isVisible(SemaRef, ND)) 11531 return ND; 11532 } 11533 11534 return nullptr; 11535 } 11536 11537 static void 11538 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 11539 SourceLocation Loc, QualType Ty, 11540 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 11541 // Find all of the associated namespaces and classes based on the 11542 // arguments we have. 11543 Sema::AssociatedNamespaceSet AssociatedNamespaces; 11544 Sema::AssociatedClassSet AssociatedClasses; 11545 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 11546 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 11547 AssociatedClasses); 11548 11549 // C++ [basic.lookup.argdep]p3: 11550 // Let X be the lookup set produced by unqualified lookup (3.4.1) 11551 // and let Y be the lookup set produced by argument dependent 11552 // lookup (defined as follows). If X contains [...] then Y is 11553 // empty. Otherwise Y is the set of declarations found in the 11554 // namespaces associated with the argument types as described 11555 // below. The set of declarations found by the lookup of the name 11556 // is the union of X and Y. 11557 // 11558 // Here, we compute Y and add its members to the overloaded 11559 // candidate set. 11560 for (auto *NS : AssociatedNamespaces) { 11561 // When considering an associated namespace, the lookup is the 11562 // same as the lookup performed when the associated namespace is 11563 // used as a qualifier (3.4.3.2) except that: 11564 // 11565 // -- Any using-directives in the associated namespace are 11566 // ignored. 11567 // 11568 // -- Any namespace-scope friend functions declared in 11569 // associated classes are visible within their respective 11570 // namespaces even if they are not visible during an ordinary 11571 // lookup (11.4). 11572 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11573 for (auto *D : R) { 11574 auto *Underlying = D; 11575 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11576 Underlying = USD->getTargetDecl(); 11577 11578 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11579 !isa<OMPDeclareMapperDecl>(Underlying)) 11580 continue; 11581 11582 if (!SemaRef.isVisible(D)) { 11583 D = findAcceptableDecl(SemaRef, D); 11584 if (!D) 11585 continue; 11586 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11587 Underlying = USD->getTargetDecl(); 11588 } 11589 Lookups.emplace_back(); 11590 Lookups.back().addDecl(Underlying); 11591 } 11592 } 11593 } 11594 11595 static ExprResult 11596 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11597 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11598 const DeclarationNameInfo &ReductionId, QualType Ty, 11599 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11600 if (ReductionIdScopeSpec.isInvalid()) 11601 return ExprError(); 11602 SmallVector<UnresolvedSet<8>, 4> Lookups; 11603 if (S) { 11604 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11605 Lookup.suppressDiagnostics(); 11606 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11607 NamedDecl *D = Lookup.getRepresentativeDecl(); 11608 do { 11609 S = S->getParent(); 11610 } while (S && !S->isDeclScope(D)); 11611 if (S) 11612 S = S->getParent(); 11613 Lookups.emplace_back(); 11614 Lookups.back().append(Lookup.begin(), Lookup.end()); 11615 Lookup.clear(); 11616 } 11617 } else if (auto *ULE = 11618 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11619 Lookups.push_back(UnresolvedSet<8>()); 11620 Decl *PrevD = nullptr; 11621 for (NamedDecl *D : ULE->decls()) { 11622 if (D == PrevD) 11623 Lookups.push_back(UnresolvedSet<8>()); 11624 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11625 Lookups.back().addDecl(DRD); 11626 PrevD = D; 11627 } 11628 } 11629 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11630 Ty->isInstantiationDependentType() || 11631 Ty->containsUnexpandedParameterPack() || 11632 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11633 return !D->isInvalidDecl() && 11634 (D->getType()->isDependentType() || 11635 D->getType()->isInstantiationDependentType() || 11636 D->getType()->containsUnexpandedParameterPack()); 11637 })) { 11638 UnresolvedSet<8> ResSet; 11639 for (const UnresolvedSet<8> &Set : Lookups) { 11640 if (Set.empty()) 11641 continue; 11642 ResSet.append(Set.begin(), Set.end()); 11643 // The last item marks the end of all declarations at the specified scope. 11644 ResSet.addDecl(Set[Set.size() - 1]); 11645 } 11646 return UnresolvedLookupExpr::Create( 11647 SemaRef.Context, /*NamingClass=*/nullptr, 11648 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 11649 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 11650 } 11651 // Lookup inside the classes. 11652 // C++ [over.match.oper]p3: 11653 // For a unary operator @ with an operand of a type whose 11654 // cv-unqualified version is T1, and for a binary operator @ with 11655 // a left operand of a type whose cv-unqualified version is T1 and 11656 // a right operand of a type whose cv-unqualified version is T2, 11657 // three sets of candidate functions, designated member 11658 // candidates, non-member candidates and built-in candidates, are 11659 // constructed as follows: 11660 // -- If T1 is a complete class type or a class currently being 11661 // defined, the set of member candidates is the result of the 11662 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 11663 // the set of member candidates is empty. 11664 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11665 Lookup.suppressDiagnostics(); 11666 if (const auto *TyRec = Ty->getAs<RecordType>()) { 11667 // Complete the type if it can be completed. 11668 // If the type is neither complete nor being defined, bail out now. 11669 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 11670 TyRec->getDecl()->getDefinition()) { 11671 Lookup.clear(); 11672 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 11673 if (Lookup.empty()) { 11674 Lookups.emplace_back(); 11675 Lookups.back().append(Lookup.begin(), Lookup.end()); 11676 } 11677 } 11678 } 11679 // Perform ADL. 11680 if (SemaRef.getLangOpts().CPlusPlus) 11681 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 11682 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11683 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 11684 if (!D->isInvalidDecl() && 11685 SemaRef.Context.hasSameType(D->getType(), Ty)) 11686 return D; 11687 return nullptr; 11688 })) 11689 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 11690 VK_LValue, Loc); 11691 if (SemaRef.getLangOpts().CPlusPlus) { 11692 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11693 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 11694 if (!D->isInvalidDecl() && 11695 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 11696 !Ty.isMoreQualifiedThan(D->getType())) 11697 return D; 11698 return nullptr; 11699 })) { 11700 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 11701 /*DetectVirtual=*/false); 11702 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 11703 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 11704 VD->getType().getUnqualifiedType()))) { 11705 if (SemaRef.CheckBaseClassAccess( 11706 Loc, VD->getType(), Ty, Paths.front(), 11707 /*DiagID=*/0) != Sema::AR_inaccessible) { 11708 SemaRef.BuildBasePathArray(Paths, BasePath); 11709 return SemaRef.BuildDeclRefExpr( 11710 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 11711 } 11712 } 11713 } 11714 } 11715 } 11716 if (ReductionIdScopeSpec.isSet()) { 11717 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 11718 return ExprError(); 11719 } 11720 return ExprEmpty(); 11721 } 11722 11723 namespace { 11724 /// Data for the reduction-based clauses. 11725 struct ReductionData { 11726 /// List of original reduction items. 11727 SmallVector<Expr *, 8> Vars; 11728 /// List of private copies of the reduction items. 11729 SmallVector<Expr *, 8> Privates; 11730 /// LHS expressions for the reduction_op expressions. 11731 SmallVector<Expr *, 8> LHSs; 11732 /// RHS expressions for the reduction_op expressions. 11733 SmallVector<Expr *, 8> RHSs; 11734 /// Reduction operation expression. 11735 SmallVector<Expr *, 8> ReductionOps; 11736 /// Taskgroup descriptors for the corresponding reduction items in 11737 /// in_reduction clauses. 11738 SmallVector<Expr *, 8> TaskgroupDescriptors; 11739 /// List of captures for clause. 11740 SmallVector<Decl *, 4> ExprCaptures; 11741 /// List of postupdate expressions. 11742 SmallVector<Expr *, 4> ExprPostUpdates; 11743 ReductionData() = delete; 11744 /// Reserves required memory for the reduction data. 11745 ReductionData(unsigned Size) { 11746 Vars.reserve(Size); 11747 Privates.reserve(Size); 11748 LHSs.reserve(Size); 11749 RHSs.reserve(Size); 11750 ReductionOps.reserve(Size); 11751 TaskgroupDescriptors.reserve(Size); 11752 ExprCaptures.reserve(Size); 11753 ExprPostUpdates.reserve(Size); 11754 } 11755 /// Stores reduction item and reduction operation only (required for dependent 11756 /// reduction item). 11757 void push(Expr *Item, Expr *ReductionOp) { 11758 Vars.emplace_back(Item); 11759 Privates.emplace_back(nullptr); 11760 LHSs.emplace_back(nullptr); 11761 RHSs.emplace_back(nullptr); 11762 ReductionOps.emplace_back(ReductionOp); 11763 TaskgroupDescriptors.emplace_back(nullptr); 11764 } 11765 /// Stores reduction data. 11766 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 11767 Expr *TaskgroupDescriptor) { 11768 Vars.emplace_back(Item); 11769 Privates.emplace_back(Private); 11770 LHSs.emplace_back(LHS); 11771 RHSs.emplace_back(RHS); 11772 ReductionOps.emplace_back(ReductionOp); 11773 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 11774 } 11775 }; 11776 } // namespace 11777 11778 static bool checkOMPArraySectionConstantForReduction( 11779 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 11780 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 11781 const Expr *Length = OASE->getLength(); 11782 if (Length == nullptr) { 11783 // For array sections of the form [1:] or [:], we would need to analyze 11784 // the lower bound... 11785 if (OASE->getColonLoc().isValid()) 11786 return false; 11787 11788 // This is an array subscript which has implicit length 1! 11789 SingleElement = true; 11790 ArraySizes.push_back(llvm::APSInt::get(1)); 11791 } else { 11792 Expr::EvalResult Result; 11793 if (!Length->EvaluateAsInt(Result, Context)) 11794 return false; 11795 11796 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11797 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 11798 ArraySizes.push_back(ConstantLengthValue); 11799 } 11800 11801 // Get the base of this array section and walk up from there. 11802 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 11803 11804 // We require length = 1 for all array sections except the right-most to 11805 // guarantee that the memory region is contiguous and has no holes in it. 11806 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 11807 Length = TempOASE->getLength(); 11808 if (Length == nullptr) { 11809 // For array sections of the form [1:] or [:], we would need to analyze 11810 // the lower bound... 11811 if (OASE->getColonLoc().isValid()) 11812 return false; 11813 11814 // This is an array subscript which has implicit length 1! 11815 ArraySizes.push_back(llvm::APSInt::get(1)); 11816 } else { 11817 Expr::EvalResult Result; 11818 if (!Length->EvaluateAsInt(Result, Context)) 11819 return false; 11820 11821 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11822 if (ConstantLengthValue.getSExtValue() != 1) 11823 return false; 11824 11825 ArraySizes.push_back(ConstantLengthValue); 11826 } 11827 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 11828 } 11829 11830 // If we have a single element, we don't need to add the implicit lengths. 11831 if (!SingleElement) { 11832 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 11833 // Has implicit length 1! 11834 ArraySizes.push_back(llvm::APSInt::get(1)); 11835 Base = TempASE->getBase()->IgnoreParenImpCasts(); 11836 } 11837 } 11838 11839 // This array section can be privatized as a single value or as a constant 11840 // sized array. 11841 return true; 11842 } 11843 11844 static bool actOnOMPReductionKindClause( 11845 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 11846 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11847 SourceLocation ColonLoc, SourceLocation EndLoc, 11848 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11849 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 11850 DeclarationName DN = ReductionId.getName(); 11851 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 11852 BinaryOperatorKind BOK = BO_Comma; 11853 11854 ASTContext &Context = S.Context; 11855 // OpenMP [2.14.3.6, reduction clause] 11856 // C 11857 // reduction-identifier is either an identifier or one of the following 11858 // operators: +, -, *, &, |, ^, && and || 11859 // C++ 11860 // reduction-identifier is either an id-expression or one of the following 11861 // operators: +, -, *, &, |, ^, && and || 11862 switch (OOK) { 11863 case OO_Plus: 11864 case OO_Minus: 11865 BOK = BO_Add; 11866 break; 11867 case OO_Star: 11868 BOK = BO_Mul; 11869 break; 11870 case OO_Amp: 11871 BOK = BO_And; 11872 break; 11873 case OO_Pipe: 11874 BOK = BO_Or; 11875 break; 11876 case OO_Caret: 11877 BOK = BO_Xor; 11878 break; 11879 case OO_AmpAmp: 11880 BOK = BO_LAnd; 11881 break; 11882 case OO_PipePipe: 11883 BOK = BO_LOr; 11884 break; 11885 case OO_New: 11886 case OO_Delete: 11887 case OO_Array_New: 11888 case OO_Array_Delete: 11889 case OO_Slash: 11890 case OO_Percent: 11891 case OO_Tilde: 11892 case OO_Exclaim: 11893 case OO_Equal: 11894 case OO_Less: 11895 case OO_Greater: 11896 case OO_LessEqual: 11897 case OO_GreaterEqual: 11898 case OO_PlusEqual: 11899 case OO_MinusEqual: 11900 case OO_StarEqual: 11901 case OO_SlashEqual: 11902 case OO_PercentEqual: 11903 case OO_CaretEqual: 11904 case OO_AmpEqual: 11905 case OO_PipeEqual: 11906 case OO_LessLess: 11907 case OO_GreaterGreater: 11908 case OO_LessLessEqual: 11909 case OO_GreaterGreaterEqual: 11910 case OO_EqualEqual: 11911 case OO_ExclaimEqual: 11912 case OO_Spaceship: 11913 case OO_PlusPlus: 11914 case OO_MinusMinus: 11915 case OO_Comma: 11916 case OO_ArrowStar: 11917 case OO_Arrow: 11918 case OO_Call: 11919 case OO_Subscript: 11920 case OO_Conditional: 11921 case OO_Coawait: 11922 case NUM_OVERLOADED_OPERATORS: 11923 llvm_unreachable("Unexpected reduction identifier"); 11924 case OO_None: 11925 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 11926 if (II->isStr("max")) 11927 BOK = BO_GT; 11928 else if (II->isStr("min")) 11929 BOK = BO_LT; 11930 } 11931 break; 11932 } 11933 SourceRange ReductionIdRange; 11934 if (ReductionIdScopeSpec.isValid()) 11935 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 11936 else 11937 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 11938 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 11939 11940 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 11941 bool FirstIter = true; 11942 for (Expr *RefExpr : VarList) { 11943 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 11944 // OpenMP [2.1, C/C++] 11945 // A list item is a variable or array section, subject to the restrictions 11946 // specified in Section 2.4 on page 42 and in each of the sections 11947 // describing clauses and directives for which a list appears. 11948 // OpenMP [2.14.3.3, Restrictions, p.1] 11949 // A variable that is part of another variable (as an array or 11950 // structure element) cannot appear in a private clause. 11951 if (!FirstIter && IR != ER) 11952 ++IR; 11953 FirstIter = false; 11954 SourceLocation ELoc; 11955 SourceRange ERange; 11956 Expr *SimpleRefExpr = RefExpr; 11957 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 11958 /*AllowArraySection=*/true); 11959 if (Res.second) { 11960 // Try to find 'declare reduction' corresponding construct before using 11961 // builtin/overloaded operators. 11962 QualType Type = Context.DependentTy; 11963 CXXCastPath BasePath; 11964 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11965 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11966 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11967 Expr *ReductionOp = nullptr; 11968 if (S.CurContext->isDependentContext() && 11969 (DeclareReductionRef.isUnset() || 11970 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 11971 ReductionOp = DeclareReductionRef.get(); 11972 // It will be analyzed later. 11973 RD.push(RefExpr, ReductionOp); 11974 } 11975 ValueDecl *D = Res.first; 11976 if (!D) 11977 continue; 11978 11979 Expr *TaskgroupDescriptor = nullptr; 11980 QualType Type; 11981 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 11982 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 11983 if (ASE) { 11984 Type = ASE->getType().getNonReferenceType(); 11985 } else if (OASE) { 11986 QualType BaseType = 11987 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 11988 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 11989 Type = ATy->getElementType(); 11990 else 11991 Type = BaseType->getPointeeType(); 11992 Type = Type.getNonReferenceType(); 11993 } else { 11994 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 11995 } 11996 auto *VD = dyn_cast<VarDecl>(D); 11997 11998 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11999 // A variable that appears in a private clause must not have an incomplete 12000 // type or a reference type. 12001 if (S.RequireCompleteType(ELoc, D->getType(), 12002 diag::err_omp_reduction_incomplete_type)) 12003 continue; 12004 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12005 // A list item that appears in a reduction clause must not be 12006 // const-qualified. 12007 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 12008 /*AcceptIfMutable*/ false, ASE || OASE)) 12009 continue; 12010 12011 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 12012 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 12013 // If a list-item is a reference type then it must bind to the same object 12014 // for all threads of the team. 12015 if (!ASE && !OASE) { 12016 if (VD) { 12017 VarDecl *VDDef = VD->getDefinition(); 12018 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 12019 DSARefChecker Check(Stack); 12020 if (Check.Visit(VDDef->getInit())) { 12021 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 12022 << getOpenMPClauseName(ClauseKind) << ERange; 12023 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 12024 continue; 12025 } 12026 } 12027 } 12028 12029 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12030 // in a Construct] 12031 // Variables with the predetermined data-sharing attributes may not be 12032 // listed in data-sharing attributes clauses, except for the cases 12033 // listed below. For these exceptions only, listing a predetermined 12034 // variable in a data-sharing attribute clause is allowed and overrides 12035 // the variable's predetermined data-sharing attributes. 12036 // OpenMP [2.14.3.6, Restrictions, p.3] 12037 // Any number of reduction clauses can be specified on the directive, 12038 // but a list item can appear only once in the reduction clauses for that 12039 // directive. 12040 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 12041 if (DVar.CKind == OMPC_reduction) { 12042 S.Diag(ELoc, diag::err_omp_once_referenced) 12043 << getOpenMPClauseName(ClauseKind); 12044 if (DVar.RefExpr) 12045 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12046 continue; 12047 } 12048 if (DVar.CKind != OMPC_unknown) { 12049 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12050 << getOpenMPClauseName(DVar.CKind) 12051 << getOpenMPClauseName(OMPC_reduction); 12052 reportOriginalDsa(S, Stack, D, DVar); 12053 continue; 12054 } 12055 12056 // OpenMP [2.14.3.6, Restrictions, p.1] 12057 // A list item that appears in a reduction clause of a worksharing 12058 // construct must be shared in the parallel regions to which any of the 12059 // worksharing regions arising from the worksharing construct bind. 12060 if (isOpenMPWorksharingDirective(CurrDir) && 12061 !isOpenMPParallelDirective(CurrDir) && 12062 !isOpenMPTeamsDirective(CurrDir)) { 12063 DVar = Stack->getImplicitDSA(D, true); 12064 if (DVar.CKind != OMPC_shared) { 12065 S.Diag(ELoc, diag::err_omp_required_access) 12066 << getOpenMPClauseName(OMPC_reduction) 12067 << getOpenMPClauseName(OMPC_shared); 12068 reportOriginalDsa(S, Stack, D, DVar); 12069 continue; 12070 } 12071 } 12072 } 12073 12074 // Try to find 'declare reduction' corresponding construct before using 12075 // builtin/overloaded operators. 12076 CXXCastPath BasePath; 12077 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12078 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12079 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12080 if (DeclareReductionRef.isInvalid()) 12081 continue; 12082 if (S.CurContext->isDependentContext() && 12083 (DeclareReductionRef.isUnset() || 12084 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12085 RD.push(RefExpr, DeclareReductionRef.get()); 12086 continue; 12087 } 12088 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12089 // Not allowed reduction identifier is found. 12090 S.Diag(ReductionId.getBeginLoc(), 12091 diag::err_omp_unknown_reduction_identifier) 12092 << Type << ReductionIdRange; 12093 continue; 12094 } 12095 12096 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12097 // The type of a list item that appears in a reduction clause must be valid 12098 // for the reduction-identifier. For a max or min reduction in C, the type 12099 // of the list item must be an allowed arithmetic data type: char, int, 12100 // float, double, or _Bool, possibly modified with long, short, signed, or 12101 // unsigned. For a max or min reduction in C++, the type of the list item 12102 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12103 // double, or bool, possibly modified with long, short, signed, or unsigned. 12104 if (DeclareReductionRef.isUnset()) { 12105 if ((BOK == BO_GT || BOK == BO_LT) && 12106 !(Type->isScalarType() || 12107 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12108 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12109 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12110 if (!ASE && !OASE) { 12111 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12112 VarDecl::DeclarationOnly; 12113 S.Diag(D->getLocation(), 12114 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12115 << D; 12116 } 12117 continue; 12118 } 12119 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12120 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12121 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12122 << getOpenMPClauseName(ClauseKind); 12123 if (!ASE && !OASE) { 12124 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12125 VarDecl::DeclarationOnly; 12126 S.Diag(D->getLocation(), 12127 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12128 << D; 12129 } 12130 continue; 12131 } 12132 } 12133 12134 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12135 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12136 D->hasAttrs() ? &D->getAttrs() : nullptr); 12137 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12138 D->hasAttrs() ? &D->getAttrs() : nullptr); 12139 QualType PrivateTy = Type; 12140 12141 // Try if we can determine constant lengths for all array sections and avoid 12142 // the VLA. 12143 bool ConstantLengthOASE = false; 12144 if (OASE) { 12145 bool SingleElement; 12146 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12147 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12148 Context, OASE, SingleElement, ArraySizes); 12149 12150 // If we don't have a single element, we must emit a constant array type. 12151 if (ConstantLengthOASE && !SingleElement) { 12152 for (llvm::APSInt &Size : ArraySizes) 12153 PrivateTy = Context.getConstantArrayType( 12154 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12155 } 12156 } 12157 12158 if ((OASE && !ConstantLengthOASE) || 12159 (!OASE && !ASE && 12160 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12161 if (!Context.getTargetInfo().isVLASupported()) { 12162 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 12163 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12164 S.Diag(ELoc, diag::note_vla_unsupported); 12165 } else { 12166 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12167 S.targetDiag(ELoc, diag::note_vla_unsupported); 12168 } 12169 continue; 12170 } 12171 // For arrays/array sections only: 12172 // Create pseudo array type for private copy. The size for this array will 12173 // be generated during codegen. 12174 // For array subscripts or single variables Private Ty is the same as Type 12175 // (type of the variable or single array element). 12176 PrivateTy = Context.getVariableArrayType( 12177 Type, 12178 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12179 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12180 } else if (!ASE && !OASE && 12181 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12182 PrivateTy = D->getType().getNonReferenceType(); 12183 } 12184 // Private copy. 12185 VarDecl *PrivateVD = 12186 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12187 D->hasAttrs() ? &D->getAttrs() : nullptr, 12188 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12189 // Add initializer for private variable. 12190 Expr *Init = nullptr; 12191 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12192 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12193 if (DeclareReductionRef.isUsable()) { 12194 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12195 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12196 if (DRD->getInitializer()) { 12197 Init = DRDRef; 12198 RHSVD->setInit(DRDRef); 12199 RHSVD->setInitStyle(VarDecl::CallInit); 12200 } 12201 } else { 12202 switch (BOK) { 12203 case BO_Add: 12204 case BO_Xor: 12205 case BO_Or: 12206 case BO_LOr: 12207 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12208 if (Type->isScalarType() || Type->isAnyComplexType()) 12209 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 12210 break; 12211 case BO_Mul: 12212 case BO_LAnd: 12213 if (Type->isScalarType() || Type->isAnyComplexType()) { 12214 // '*' and '&&' reduction ops - initializer is '1'. 12215 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 12216 } 12217 break; 12218 case BO_And: { 12219 // '&' reduction op - initializer is '~0'. 12220 QualType OrigType = Type; 12221 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 12222 Type = ComplexTy->getElementType(); 12223 if (Type->isRealFloatingType()) { 12224 llvm::APFloat InitValue = 12225 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 12226 /*isIEEE=*/true); 12227 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12228 Type, ELoc); 12229 } else if (Type->isScalarType()) { 12230 uint64_t Size = Context.getTypeSize(Type); 12231 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 12232 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 12233 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12234 } 12235 if (Init && OrigType->isAnyComplexType()) { 12236 // Init = 0xFFFF + 0xFFFFi; 12237 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 12238 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 12239 } 12240 Type = OrigType; 12241 break; 12242 } 12243 case BO_LT: 12244 case BO_GT: { 12245 // 'min' reduction op - initializer is 'Largest representable number in 12246 // the reduction list item type'. 12247 // 'max' reduction op - initializer is 'Least representable number in 12248 // the reduction list item type'. 12249 if (Type->isIntegerType() || Type->isPointerType()) { 12250 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12251 uint64_t Size = Context.getTypeSize(Type); 12252 QualType IntTy = 12253 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12254 llvm::APInt InitValue = 12255 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12256 : llvm::APInt::getMinValue(Size) 12257 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12258 : llvm::APInt::getMaxValue(Size); 12259 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12260 if (Type->isPointerType()) { 12261 // Cast to pointer type. 12262 ExprResult CastExpr = S.BuildCStyleCastExpr( 12263 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12264 if (CastExpr.isInvalid()) 12265 continue; 12266 Init = CastExpr.get(); 12267 } 12268 } else if (Type->isRealFloatingType()) { 12269 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12270 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12271 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12272 Type, ELoc); 12273 } 12274 break; 12275 } 12276 case BO_PtrMemD: 12277 case BO_PtrMemI: 12278 case BO_MulAssign: 12279 case BO_Div: 12280 case BO_Rem: 12281 case BO_Sub: 12282 case BO_Shl: 12283 case BO_Shr: 12284 case BO_LE: 12285 case BO_GE: 12286 case BO_EQ: 12287 case BO_NE: 12288 case BO_Cmp: 12289 case BO_AndAssign: 12290 case BO_XorAssign: 12291 case BO_OrAssign: 12292 case BO_Assign: 12293 case BO_AddAssign: 12294 case BO_SubAssign: 12295 case BO_DivAssign: 12296 case BO_RemAssign: 12297 case BO_ShlAssign: 12298 case BO_ShrAssign: 12299 case BO_Comma: 12300 llvm_unreachable("Unexpected reduction operation"); 12301 } 12302 } 12303 if (Init && DeclareReductionRef.isUnset()) 12304 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12305 else if (!Init) 12306 S.ActOnUninitializedDecl(RHSVD); 12307 if (RHSVD->isInvalidDecl()) 12308 continue; 12309 if (!RHSVD->hasInit() && 12310 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12311 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12312 << Type << ReductionIdRange; 12313 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12314 VarDecl::DeclarationOnly; 12315 S.Diag(D->getLocation(), 12316 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12317 << D; 12318 continue; 12319 } 12320 // Store initializer for single element in private copy. Will be used during 12321 // codegen. 12322 PrivateVD->setInit(RHSVD->getInit()); 12323 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12324 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12325 ExprResult ReductionOp; 12326 if (DeclareReductionRef.isUsable()) { 12327 QualType RedTy = DeclareReductionRef.get()->getType(); 12328 QualType PtrRedTy = Context.getPointerType(RedTy); 12329 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12330 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12331 if (!BasePath.empty()) { 12332 LHS = S.DefaultLvalueConversion(LHS.get()); 12333 RHS = S.DefaultLvalueConversion(RHS.get()); 12334 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12335 CK_UncheckedDerivedToBase, LHS.get(), 12336 &BasePath, LHS.get()->getValueKind()); 12337 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12338 CK_UncheckedDerivedToBase, RHS.get(), 12339 &BasePath, RHS.get()->getValueKind()); 12340 } 12341 FunctionProtoType::ExtProtoInfo EPI; 12342 QualType Params[] = {PtrRedTy, PtrRedTy}; 12343 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12344 auto *OVE = new (Context) OpaqueValueExpr( 12345 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12346 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12347 Expr *Args[] = {LHS.get(), RHS.get()}; 12348 ReductionOp = 12349 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12350 } else { 12351 ReductionOp = S.BuildBinOp( 12352 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12353 if (ReductionOp.isUsable()) { 12354 if (BOK != BO_LT && BOK != BO_GT) { 12355 ReductionOp = 12356 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12357 BO_Assign, LHSDRE, ReductionOp.get()); 12358 } else { 12359 auto *ConditionalOp = new (Context) 12360 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12361 Type, VK_LValue, OK_Ordinary); 12362 ReductionOp = 12363 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12364 BO_Assign, LHSDRE, ConditionalOp); 12365 } 12366 if (ReductionOp.isUsable()) 12367 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12368 /*DiscardedValue*/ false); 12369 } 12370 if (!ReductionOp.isUsable()) 12371 continue; 12372 } 12373 12374 // OpenMP [2.15.4.6, Restrictions, p.2] 12375 // A list item that appears in an in_reduction clause of a task construct 12376 // must appear in a task_reduction clause of a construct associated with a 12377 // taskgroup region that includes the participating task in its taskgroup 12378 // set. The construct associated with the innermost region that meets this 12379 // condition must specify the same reduction-identifier as the in_reduction 12380 // clause. 12381 if (ClauseKind == OMPC_in_reduction) { 12382 SourceRange ParentSR; 12383 BinaryOperatorKind ParentBOK; 12384 const Expr *ParentReductionOp; 12385 Expr *ParentBOKTD, *ParentReductionOpTD; 12386 DSAStackTy::DSAVarData ParentBOKDSA = 12387 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12388 ParentBOKTD); 12389 DSAStackTy::DSAVarData ParentReductionOpDSA = 12390 Stack->getTopMostTaskgroupReductionData( 12391 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12392 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12393 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12394 if (!IsParentBOK && !IsParentReductionOp) { 12395 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12396 continue; 12397 } 12398 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12399 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12400 IsParentReductionOp) { 12401 bool EmitError = true; 12402 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12403 llvm::FoldingSetNodeID RedId, ParentRedId; 12404 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12405 DeclareReductionRef.get()->Profile(RedId, Context, 12406 /*Canonical=*/true); 12407 EmitError = RedId != ParentRedId; 12408 } 12409 if (EmitError) { 12410 S.Diag(ReductionId.getBeginLoc(), 12411 diag::err_omp_reduction_identifier_mismatch) 12412 << ReductionIdRange << RefExpr->getSourceRange(); 12413 S.Diag(ParentSR.getBegin(), 12414 diag::note_omp_previous_reduction_identifier) 12415 << ParentSR 12416 << (IsParentBOK ? ParentBOKDSA.RefExpr 12417 : ParentReductionOpDSA.RefExpr) 12418 ->getSourceRange(); 12419 continue; 12420 } 12421 } 12422 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 12423 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 12424 } 12425 12426 DeclRefExpr *Ref = nullptr; 12427 Expr *VarsExpr = RefExpr->IgnoreParens(); 12428 if (!VD && !S.CurContext->isDependentContext()) { 12429 if (ASE || OASE) { 12430 TransformExprToCaptures RebuildToCapture(S, D); 12431 VarsExpr = 12432 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 12433 Ref = RebuildToCapture.getCapturedExpr(); 12434 } else { 12435 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 12436 } 12437 if (!S.isOpenMPCapturedDecl(D)) { 12438 RD.ExprCaptures.emplace_back(Ref->getDecl()); 12439 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12440 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 12441 if (!RefRes.isUsable()) 12442 continue; 12443 ExprResult PostUpdateRes = 12444 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12445 RefRes.get()); 12446 if (!PostUpdateRes.isUsable()) 12447 continue; 12448 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 12449 Stack->getCurrentDirective() == OMPD_taskgroup) { 12450 S.Diag(RefExpr->getExprLoc(), 12451 diag::err_omp_reduction_non_addressable_expression) 12452 << RefExpr->getSourceRange(); 12453 continue; 12454 } 12455 RD.ExprPostUpdates.emplace_back( 12456 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 12457 } 12458 } 12459 } 12460 // All reduction items are still marked as reduction (to do not increase 12461 // code base size). 12462 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 12463 if (CurrDir == OMPD_taskgroup) { 12464 if (DeclareReductionRef.isUsable()) 12465 Stack->addTaskgroupReductionData(D, ReductionIdRange, 12466 DeclareReductionRef.get()); 12467 else 12468 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 12469 } 12470 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 12471 TaskgroupDescriptor); 12472 } 12473 return RD.Vars.empty(); 12474 } 12475 12476 OMPClause *Sema::ActOnOpenMPReductionClause( 12477 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12478 SourceLocation ColonLoc, SourceLocation EndLoc, 12479 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12480 ArrayRef<Expr *> UnresolvedReductions) { 12481 ReductionData RD(VarList.size()); 12482 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 12483 StartLoc, LParenLoc, ColonLoc, EndLoc, 12484 ReductionIdScopeSpec, ReductionId, 12485 UnresolvedReductions, RD)) 12486 return nullptr; 12487 12488 return OMPReductionClause::Create( 12489 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12490 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12491 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12492 buildPreInits(Context, RD.ExprCaptures), 12493 buildPostUpdate(*this, RD.ExprPostUpdates)); 12494 } 12495 12496 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 12497 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12498 SourceLocation ColonLoc, SourceLocation EndLoc, 12499 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12500 ArrayRef<Expr *> UnresolvedReductions) { 12501 ReductionData RD(VarList.size()); 12502 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 12503 StartLoc, LParenLoc, ColonLoc, EndLoc, 12504 ReductionIdScopeSpec, ReductionId, 12505 UnresolvedReductions, RD)) 12506 return nullptr; 12507 12508 return OMPTaskReductionClause::Create( 12509 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12510 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12511 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12512 buildPreInits(Context, RD.ExprCaptures), 12513 buildPostUpdate(*this, RD.ExprPostUpdates)); 12514 } 12515 12516 OMPClause *Sema::ActOnOpenMPInReductionClause( 12517 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12518 SourceLocation ColonLoc, SourceLocation EndLoc, 12519 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12520 ArrayRef<Expr *> UnresolvedReductions) { 12521 ReductionData RD(VarList.size()); 12522 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 12523 StartLoc, LParenLoc, ColonLoc, EndLoc, 12524 ReductionIdScopeSpec, ReductionId, 12525 UnresolvedReductions, RD)) 12526 return nullptr; 12527 12528 return OMPInReductionClause::Create( 12529 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12530 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12531 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 12532 buildPreInits(Context, RD.ExprCaptures), 12533 buildPostUpdate(*this, RD.ExprPostUpdates)); 12534 } 12535 12536 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 12537 SourceLocation LinLoc) { 12538 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 12539 LinKind == OMPC_LINEAR_unknown) { 12540 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 12541 return true; 12542 } 12543 return false; 12544 } 12545 12546 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 12547 OpenMPLinearClauseKind LinKind, 12548 QualType Type) { 12549 const auto *VD = dyn_cast_or_null<VarDecl>(D); 12550 // A variable must not have an incomplete type or a reference type. 12551 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 12552 return true; 12553 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 12554 !Type->isReferenceType()) { 12555 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 12556 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 12557 return true; 12558 } 12559 Type = Type.getNonReferenceType(); 12560 12561 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12562 // A variable that is privatized must not have a const-qualified type 12563 // unless it is of class type with a mutable member. This restriction does 12564 // not apply to the firstprivate clause. 12565 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 12566 return true; 12567 12568 // A list item must be of integral or pointer type. 12569 Type = Type.getUnqualifiedType().getCanonicalType(); 12570 const auto *Ty = Type.getTypePtrOrNull(); 12571 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 12572 !Ty->isPointerType())) { 12573 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12574 if (D) { 12575 bool IsDecl = 12576 !VD || 12577 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12578 Diag(D->getLocation(), 12579 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12580 << D; 12581 } 12582 return true; 12583 } 12584 return false; 12585 } 12586 12587 OMPClause *Sema::ActOnOpenMPLinearClause( 12588 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12589 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12590 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12591 SmallVector<Expr *, 8> Vars; 12592 SmallVector<Expr *, 8> Privates; 12593 SmallVector<Expr *, 8> Inits; 12594 SmallVector<Decl *, 4> ExprCaptures; 12595 SmallVector<Expr *, 4> ExprPostUpdates; 12596 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12597 LinKind = OMPC_LINEAR_val; 12598 for (Expr *RefExpr : VarList) { 12599 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12600 SourceLocation ELoc; 12601 SourceRange ERange; 12602 Expr *SimpleRefExpr = RefExpr; 12603 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12604 if (Res.second) { 12605 // It will be analyzed later. 12606 Vars.push_back(RefExpr); 12607 Privates.push_back(nullptr); 12608 Inits.push_back(nullptr); 12609 } 12610 ValueDecl *D = Res.first; 12611 if (!D) 12612 continue; 12613 12614 QualType Type = D->getType(); 12615 auto *VD = dyn_cast<VarDecl>(D); 12616 12617 // OpenMP [2.14.3.7, linear clause] 12618 // A list-item cannot appear in more than one linear clause. 12619 // A list-item that appears in a linear clause cannot appear in any 12620 // other data-sharing attribute clause. 12621 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12622 if (DVar.RefExpr) { 12623 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12624 << getOpenMPClauseName(OMPC_linear); 12625 reportOriginalDsa(*this, DSAStack, D, DVar); 12626 continue; 12627 } 12628 12629 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12630 continue; 12631 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12632 12633 // Build private copy of original var. 12634 VarDecl *Private = 12635 buildVarDecl(*this, ELoc, Type, D->getName(), 12636 D->hasAttrs() ? &D->getAttrs() : nullptr, 12637 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12638 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 12639 // Build var to save initial value. 12640 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 12641 Expr *InitExpr; 12642 DeclRefExpr *Ref = nullptr; 12643 if (!VD && !CurContext->isDependentContext()) { 12644 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12645 if (!isOpenMPCapturedDecl(D)) { 12646 ExprCaptures.push_back(Ref->getDecl()); 12647 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12648 ExprResult RefRes = DefaultLvalueConversion(Ref); 12649 if (!RefRes.isUsable()) 12650 continue; 12651 ExprResult PostUpdateRes = 12652 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 12653 SimpleRefExpr, RefRes.get()); 12654 if (!PostUpdateRes.isUsable()) 12655 continue; 12656 ExprPostUpdates.push_back( 12657 IgnoredValueConversions(PostUpdateRes.get()).get()); 12658 } 12659 } 12660 } 12661 if (LinKind == OMPC_LINEAR_uval) 12662 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 12663 else 12664 InitExpr = VD ? SimpleRefExpr : Ref; 12665 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 12666 /*DirectInit=*/false); 12667 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 12668 12669 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 12670 Vars.push_back((VD || CurContext->isDependentContext()) 12671 ? RefExpr->IgnoreParens() 12672 : Ref); 12673 Privates.push_back(PrivateRef); 12674 Inits.push_back(InitRef); 12675 } 12676 12677 if (Vars.empty()) 12678 return nullptr; 12679 12680 Expr *StepExpr = Step; 12681 Expr *CalcStepExpr = nullptr; 12682 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 12683 !Step->isInstantiationDependent() && 12684 !Step->containsUnexpandedParameterPack()) { 12685 SourceLocation StepLoc = Step->getBeginLoc(); 12686 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 12687 if (Val.isInvalid()) 12688 return nullptr; 12689 StepExpr = Val.get(); 12690 12691 // Build var to save the step value. 12692 VarDecl *SaveVar = 12693 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 12694 ExprResult SaveRef = 12695 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 12696 ExprResult CalcStep = 12697 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 12698 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 12699 12700 // Warn about zero linear step (it would be probably better specified as 12701 // making corresponding variables 'const'). 12702 llvm::APSInt Result; 12703 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 12704 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 12705 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 12706 << (Vars.size() > 1); 12707 if (!IsConstant && CalcStep.isUsable()) { 12708 // Calculate the step beforehand instead of doing this on each iteration. 12709 // (This is not used if the number of iterations may be kfold-ed). 12710 CalcStepExpr = CalcStep.get(); 12711 } 12712 } 12713 12714 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 12715 ColonLoc, EndLoc, Vars, Privates, Inits, 12716 StepExpr, CalcStepExpr, 12717 buildPreInits(Context, ExprCaptures), 12718 buildPostUpdate(*this, ExprPostUpdates)); 12719 } 12720 12721 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 12722 Expr *NumIterations, Sema &SemaRef, 12723 Scope *S, DSAStackTy *Stack) { 12724 // Walk the vars and build update/final expressions for the CodeGen. 12725 SmallVector<Expr *, 8> Updates; 12726 SmallVector<Expr *, 8> Finals; 12727 Expr *Step = Clause.getStep(); 12728 Expr *CalcStep = Clause.getCalcStep(); 12729 // OpenMP [2.14.3.7, linear clause] 12730 // If linear-step is not specified it is assumed to be 1. 12731 if (!Step) 12732 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 12733 else if (CalcStep) 12734 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 12735 bool HasErrors = false; 12736 auto CurInit = Clause.inits().begin(); 12737 auto CurPrivate = Clause.privates().begin(); 12738 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 12739 for (Expr *RefExpr : Clause.varlists()) { 12740 SourceLocation ELoc; 12741 SourceRange ERange; 12742 Expr *SimpleRefExpr = RefExpr; 12743 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 12744 ValueDecl *D = Res.first; 12745 if (Res.second || !D) { 12746 Updates.push_back(nullptr); 12747 Finals.push_back(nullptr); 12748 HasErrors = true; 12749 continue; 12750 } 12751 auto &&Info = Stack->isLoopControlVariable(D); 12752 // OpenMP [2.15.11, distribute simd Construct] 12753 // A list item may not appear in a linear clause, unless it is the loop 12754 // iteration variable. 12755 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 12756 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 12757 SemaRef.Diag(ELoc, 12758 diag::err_omp_linear_distribute_var_non_loop_iteration); 12759 Updates.push_back(nullptr); 12760 Finals.push_back(nullptr); 12761 HasErrors = true; 12762 continue; 12763 } 12764 Expr *InitExpr = *CurInit; 12765 12766 // Build privatized reference to the current linear var. 12767 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 12768 Expr *CapturedRef; 12769 if (LinKind == OMPC_LINEAR_uval) 12770 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 12771 else 12772 CapturedRef = 12773 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 12774 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 12775 /*RefersToCapture=*/true); 12776 12777 // Build update: Var = InitExpr + IV * Step 12778 ExprResult Update; 12779 if (!Info.first) 12780 Update = 12781 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 12782 InitExpr, IV, Step, /* Subtract */ false); 12783 else 12784 Update = *CurPrivate; 12785 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 12786 /*DiscardedValue*/ false); 12787 12788 // Build final: Var = InitExpr + NumIterations * Step 12789 ExprResult Final; 12790 if (!Info.first) 12791 Final = 12792 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 12793 InitExpr, NumIterations, Step, /*Subtract=*/false); 12794 else 12795 Final = *CurPrivate; 12796 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 12797 /*DiscardedValue*/ false); 12798 12799 if (!Update.isUsable() || !Final.isUsable()) { 12800 Updates.push_back(nullptr); 12801 Finals.push_back(nullptr); 12802 HasErrors = true; 12803 } else { 12804 Updates.push_back(Update.get()); 12805 Finals.push_back(Final.get()); 12806 } 12807 ++CurInit; 12808 ++CurPrivate; 12809 } 12810 Clause.setUpdates(Updates); 12811 Clause.setFinals(Finals); 12812 return HasErrors; 12813 } 12814 12815 OMPClause *Sema::ActOnOpenMPAlignedClause( 12816 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 12817 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12818 SmallVector<Expr *, 8> Vars; 12819 for (Expr *RefExpr : VarList) { 12820 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12821 SourceLocation ELoc; 12822 SourceRange ERange; 12823 Expr *SimpleRefExpr = RefExpr; 12824 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12825 if (Res.second) { 12826 // It will be analyzed later. 12827 Vars.push_back(RefExpr); 12828 } 12829 ValueDecl *D = Res.first; 12830 if (!D) 12831 continue; 12832 12833 QualType QType = D->getType(); 12834 auto *VD = dyn_cast<VarDecl>(D); 12835 12836 // OpenMP [2.8.1, simd construct, Restrictions] 12837 // The type of list items appearing in the aligned clause must be 12838 // array, pointer, reference to array, or reference to pointer. 12839 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12840 const Type *Ty = QType.getTypePtrOrNull(); 12841 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 12842 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 12843 << QType << getLangOpts().CPlusPlus << ERange; 12844 bool IsDecl = 12845 !VD || 12846 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12847 Diag(D->getLocation(), 12848 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12849 << D; 12850 continue; 12851 } 12852 12853 // OpenMP [2.8.1, simd construct, Restrictions] 12854 // A list-item cannot appear in more than one aligned clause. 12855 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 12856 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 12857 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 12858 << getOpenMPClauseName(OMPC_aligned); 12859 continue; 12860 } 12861 12862 DeclRefExpr *Ref = nullptr; 12863 if (!VD && isOpenMPCapturedDecl(D)) 12864 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12865 Vars.push_back(DefaultFunctionArrayConversion( 12866 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 12867 .get()); 12868 } 12869 12870 // OpenMP [2.8.1, simd construct, Description] 12871 // The parameter of the aligned clause, alignment, must be a constant 12872 // positive integer expression. 12873 // If no optional parameter is specified, implementation-defined default 12874 // alignments for SIMD instructions on the target platforms are assumed. 12875 if (Alignment != nullptr) { 12876 ExprResult AlignResult = 12877 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 12878 if (AlignResult.isInvalid()) 12879 return nullptr; 12880 Alignment = AlignResult.get(); 12881 } 12882 if (Vars.empty()) 12883 return nullptr; 12884 12885 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 12886 EndLoc, Vars, Alignment); 12887 } 12888 12889 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 12890 SourceLocation StartLoc, 12891 SourceLocation LParenLoc, 12892 SourceLocation EndLoc) { 12893 SmallVector<Expr *, 8> Vars; 12894 SmallVector<Expr *, 8> SrcExprs; 12895 SmallVector<Expr *, 8> DstExprs; 12896 SmallVector<Expr *, 8> AssignmentOps; 12897 for (Expr *RefExpr : VarList) { 12898 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 12899 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12900 // It will be analyzed later. 12901 Vars.push_back(RefExpr); 12902 SrcExprs.push_back(nullptr); 12903 DstExprs.push_back(nullptr); 12904 AssignmentOps.push_back(nullptr); 12905 continue; 12906 } 12907 12908 SourceLocation ELoc = RefExpr->getExprLoc(); 12909 // OpenMP [2.1, C/C++] 12910 // A list item is a variable name. 12911 // OpenMP [2.14.4.1, Restrictions, p.1] 12912 // A list item that appears in a copyin clause must be threadprivate. 12913 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 12914 if (!DE || !isa<VarDecl>(DE->getDecl())) { 12915 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 12916 << 0 << RefExpr->getSourceRange(); 12917 continue; 12918 } 12919 12920 Decl *D = DE->getDecl(); 12921 auto *VD = cast<VarDecl>(D); 12922 12923 QualType Type = VD->getType(); 12924 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 12925 // It will be analyzed later. 12926 Vars.push_back(DE); 12927 SrcExprs.push_back(nullptr); 12928 DstExprs.push_back(nullptr); 12929 AssignmentOps.push_back(nullptr); 12930 continue; 12931 } 12932 12933 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 12934 // A list item that appears in a copyin clause must be threadprivate. 12935 if (!DSAStack->isThreadPrivate(VD)) { 12936 Diag(ELoc, diag::err_omp_required_access) 12937 << getOpenMPClauseName(OMPC_copyin) 12938 << getOpenMPDirectiveName(OMPD_threadprivate); 12939 continue; 12940 } 12941 12942 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12943 // A variable of class type (or array thereof) that appears in a 12944 // copyin clause requires an accessible, unambiguous copy assignment 12945 // operator for the class type. 12946 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12947 VarDecl *SrcVD = 12948 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 12949 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12950 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 12951 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 12952 VarDecl *DstVD = 12953 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 12954 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12955 DeclRefExpr *PseudoDstExpr = 12956 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 12957 // For arrays generate assignment operation for single element and replace 12958 // it by the original array element in CodeGen. 12959 ExprResult AssignmentOp = 12960 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 12961 PseudoSrcExpr); 12962 if (AssignmentOp.isInvalid()) 12963 continue; 12964 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 12965 /*DiscardedValue*/ false); 12966 if (AssignmentOp.isInvalid()) 12967 continue; 12968 12969 DSAStack->addDSA(VD, DE, OMPC_copyin); 12970 Vars.push_back(DE); 12971 SrcExprs.push_back(PseudoSrcExpr); 12972 DstExprs.push_back(PseudoDstExpr); 12973 AssignmentOps.push_back(AssignmentOp.get()); 12974 } 12975 12976 if (Vars.empty()) 12977 return nullptr; 12978 12979 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12980 SrcExprs, DstExprs, AssignmentOps); 12981 } 12982 12983 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 12984 SourceLocation StartLoc, 12985 SourceLocation LParenLoc, 12986 SourceLocation EndLoc) { 12987 SmallVector<Expr *, 8> Vars; 12988 SmallVector<Expr *, 8> SrcExprs; 12989 SmallVector<Expr *, 8> DstExprs; 12990 SmallVector<Expr *, 8> AssignmentOps; 12991 for (Expr *RefExpr : VarList) { 12992 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12993 SourceLocation ELoc; 12994 SourceRange ERange; 12995 Expr *SimpleRefExpr = RefExpr; 12996 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12997 if (Res.second) { 12998 // It will be analyzed later. 12999 Vars.push_back(RefExpr); 13000 SrcExprs.push_back(nullptr); 13001 DstExprs.push_back(nullptr); 13002 AssignmentOps.push_back(nullptr); 13003 } 13004 ValueDecl *D = Res.first; 13005 if (!D) 13006 continue; 13007 13008 QualType Type = D->getType(); 13009 auto *VD = dyn_cast<VarDecl>(D); 13010 13011 // OpenMP [2.14.4.2, Restrictions, p.2] 13012 // A list item that appears in a copyprivate clause may not appear in a 13013 // private or firstprivate clause on the single construct. 13014 if (!VD || !DSAStack->isThreadPrivate(VD)) { 13015 DSAStackTy::DSAVarData DVar = 13016 DSAStack->getTopDSA(D, /*FromParent=*/false); 13017 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 13018 DVar.RefExpr) { 13019 Diag(ELoc, diag::err_omp_wrong_dsa) 13020 << getOpenMPClauseName(DVar.CKind) 13021 << getOpenMPClauseName(OMPC_copyprivate); 13022 reportOriginalDsa(*this, DSAStack, D, DVar); 13023 continue; 13024 } 13025 13026 // OpenMP [2.11.4.2, Restrictions, p.1] 13027 // All list items that appear in a copyprivate clause must be either 13028 // threadprivate or private in the enclosing context. 13029 if (DVar.CKind == OMPC_unknown) { 13030 DVar = DSAStack->getImplicitDSA(D, false); 13031 if (DVar.CKind == OMPC_shared) { 13032 Diag(ELoc, diag::err_omp_required_access) 13033 << getOpenMPClauseName(OMPC_copyprivate) 13034 << "threadprivate or private in the enclosing context"; 13035 reportOriginalDsa(*this, DSAStack, D, DVar); 13036 continue; 13037 } 13038 } 13039 } 13040 13041 // Variably modified types are not supported. 13042 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 13043 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13044 << getOpenMPClauseName(OMPC_copyprivate) << Type 13045 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13046 bool IsDecl = 13047 !VD || 13048 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13049 Diag(D->getLocation(), 13050 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13051 << D; 13052 continue; 13053 } 13054 13055 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13056 // A variable of class type (or array thereof) that appears in a 13057 // copyin clause requires an accessible, unambiguous copy assignment 13058 // operator for the class type. 13059 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13060 .getUnqualifiedType(); 13061 VarDecl *SrcVD = 13062 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13063 D->hasAttrs() ? &D->getAttrs() : nullptr); 13064 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13065 VarDecl *DstVD = 13066 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13067 D->hasAttrs() ? &D->getAttrs() : nullptr); 13068 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13069 ExprResult AssignmentOp = BuildBinOp( 13070 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13071 if (AssignmentOp.isInvalid()) 13072 continue; 13073 AssignmentOp = 13074 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13075 if (AssignmentOp.isInvalid()) 13076 continue; 13077 13078 // No need to mark vars as copyprivate, they are already threadprivate or 13079 // implicitly private. 13080 assert(VD || isOpenMPCapturedDecl(D)); 13081 Vars.push_back( 13082 VD ? RefExpr->IgnoreParens() 13083 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13084 SrcExprs.push_back(PseudoSrcExpr); 13085 DstExprs.push_back(PseudoDstExpr); 13086 AssignmentOps.push_back(AssignmentOp.get()); 13087 } 13088 13089 if (Vars.empty()) 13090 return nullptr; 13091 13092 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13093 Vars, SrcExprs, DstExprs, AssignmentOps); 13094 } 13095 13096 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13097 SourceLocation StartLoc, 13098 SourceLocation LParenLoc, 13099 SourceLocation EndLoc) { 13100 if (VarList.empty()) 13101 return nullptr; 13102 13103 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13104 } 13105 13106 OMPClause * 13107 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13108 SourceLocation DepLoc, SourceLocation ColonLoc, 13109 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13110 SourceLocation LParenLoc, SourceLocation EndLoc) { 13111 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13112 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13113 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13114 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13115 return nullptr; 13116 } 13117 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13118 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13119 DepKind == OMPC_DEPEND_sink)) { 13120 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13121 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13122 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13123 /*Last=*/OMPC_DEPEND_unknown, Except) 13124 << getOpenMPClauseName(OMPC_depend); 13125 return nullptr; 13126 } 13127 SmallVector<Expr *, 8> Vars; 13128 DSAStackTy::OperatorOffsetTy OpsOffs; 13129 llvm::APSInt DepCounter(/*BitWidth=*/32); 13130 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13131 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13132 if (const Expr *OrderedCountExpr = 13133 DSAStack->getParentOrderedRegionParam().first) { 13134 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13135 TotalDepCount.setIsUnsigned(/*Val=*/true); 13136 } 13137 } 13138 for (Expr *RefExpr : VarList) { 13139 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13140 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13141 // It will be analyzed later. 13142 Vars.push_back(RefExpr); 13143 continue; 13144 } 13145 13146 SourceLocation ELoc = RefExpr->getExprLoc(); 13147 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13148 if (DepKind == OMPC_DEPEND_sink) { 13149 if (DSAStack->getParentOrderedRegionParam().first && 13150 DepCounter >= TotalDepCount) { 13151 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13152 continue; 13153 } 13154 ++DepCounter; 13155 // OpenMP [2.13.9, Summary] 13156 // depend(dependence-type : vec), where dependence-type is: 13157 // 'sink' and where vec is the iteration vector, which has the form: 13158 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13159 // where n is the value specified by the ordered clause in the loop 13160 // directive, xi denotes the loop iteration variable of the i-th nested 13161 // loop associated with the loop directive, and di is a constant 13162 // non-negative integer. 13163 if (CurContext->isDependentContext()) { 13164 // It will be analyzed later. 13165 Vars.push_back(RefExpr); 13166 continue; 13167 } 13168 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13169 OverloadedOperatorKind OOK = OO_None; 13170 SourceLocation OOLoc; 13171 Expr *LHS = SimpleExpr; 13172 Expr *RHS = nullptr; 13173 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13174 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13175 OOLoc = BO->getOperatorLoc(); 13176 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13177 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13178 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13179 OOK = OCE->getOperator(); 13180 OOLoc = OCE->getOperatorLoc(); 13181 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13182 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13183 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13184 OOK = MCE->getMethodDecl() 13185 ->getNameInfo() 13186 .getName() 13187 .getCXXOverloadedOperator(); 13188 OOLoc = MCE->getCallee()->getExprLoc(); 13189 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13190 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13191 } 13192 SourceLocation ELoc; 13193 SourceRange ERange; 13194 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13195 if (Res.second) { 13196 // It will be analyzed later. 13197 Vars.push_back(RefExpr); 13198 } 13199 ValueDecl *D = Res.first; 13200 if (!D) 13201 continue; 13202 13203 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 13204 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 13205 continue; 13206 } 13207 if (RHS) { 13208 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 13209 RHS, OMPC_depend, /*StrictlyPositive=*/false); 13210 if (RHSRes.isInvalid()) 13211 continue; 13212 } 13213 if (!CurContext->isDependentContext() && 13214 DSAStack->getParentOrderedRegionParam().first && 13215 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 13216 const ValueDecl *VD = 13217 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 13218 if (VD) 13219 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 13220 << 1 << VD; 13221 else 13222 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 13223 continue; 13224 } 13225 OpsOffs.emplace_back(RHS, OOK); 13226 } else { 13227 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 13228 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 13229 (ASE && 13230 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 13231 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 13232 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13233 << RefExpr->getSourceRange(); 13234 continue; 13235 } 13236 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 13237 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 13238 ExprResult Res = 13239 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 13240 getDiagnostics().setSuppressAllDiagnostics(Suppress); 13241 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 13242 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13243 << RefExpr->getSourceRange(); 13244 continue; 13245 } 13246 } 13247 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13248 } 13249 13250 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13251 TotalDepCount > VarList.size() && 13252 DSAStack->getParentOrderedRegionParam().first && 13253 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13254 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13255 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13256 } 13257 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13258 Vars.empty()) 13259 return nullptr; 13260 13261 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13262 DepKind, DepLoc, ColonLoc, Vars, 13263 TotalDepCount.getZExtValue()); 13264 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13265 DSAStack->isParentOrderedRegion()) 13266 DSAStack->addDoacrossDependClause(C, OpsOffs); 13267 return C; 13268 } 13269 13270 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13271 SourceLocation LParenLoc, 13272 SourceLocation EndLoc) { 13273 Expr *ValExpr = Device; 13274 Stmt *HelperValStmt = nullptr; 13275 13276 // OpenMP [2.9.1, Restrictions] 13277 // The device expression must evaluate to a non-negative integer value. 13278 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13279 /*StrictlyPositive=*/false)) 13280 return nullptr; 13281 13282 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13283 OpenMPDirectiveKind CaptureRegion = 13284 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13285 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13286 ValExpr = MakeFullExpr(ValExpr).get(); 13287 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13288 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13289 HelperValStmt = buildPreInits(Context, Captures); 13290 } 13291 13292 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13293 StartLoc, LParenLoc, EndLoc); 13294 } 13295 13296 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13297 DSAStackTy *Stack, QualType QTy, 13298 bool FullCheck = true) { 13299 NamedDecl *ND; 13300 if (QTy->isIncompleteType(&ND)) { 13301 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13302 return false; 13303 } 13304 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13305 !QTy.isTrivialType(SemaRef.Context)) 13306 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13307 return true; 13308 } 13309 13310 /// Return true if it can be proven that the provided array expression 13311 /// (array section or array subscript) does NOT specify the whole size of the 13312 /// array whose base type is \a BaseQTy. 13313 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13314 const Expr *E, 13315 QualType BaseQTy) { 13316 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13317 13318 // If this is an array subscript, it refers to the whole size if the size of 13319 // the dimension is constant and equals 1. Also, an array section assumes the 13320 // format of an array subscript if no colon is used. 13321 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13322 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13323 return ATy->getSize().getSExtValue() != 1; 13324 // Size can't be evaluated statically. 13325 return false; 13326 } 13327 13328 assert(OASE && "Expecting array section if not an array subscript."); 13329 const Expr *LowerBound = OASE->getLowerBound(); 13330 const Expr *Length = OASE->getLength(); 13331 13332 // If there is a lower bound that does not evaluates to zero, we are not 13333 // covering the whole dimension. 13334 if (LowerBound) { 13335 Expr::EvalResult Result; 13336 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13337 return false; // Can't get the integer value as a constant. 13338 13339 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13340 if (ConstLowerBound.getSExtValue()) 13341 return true; 13342 } 13343 13344 // If we don't have a length we covering the whole dimension. 13345 if (!Length) 13346 return false; 13347 13348 // If the base is a pointer, we don't have a way to get the size of the 13349 // pointee. 13350 if (BaseQTy->isPointerType()) 13351 return false; 13352 13353 // We can only check if the length is the same as the size of the dimension 13354 // if we have a constant array. 13355 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13356 if (!CATy) 13357 return false; 13358 13359 Expr::EvalResult Result; 13360 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13361 return false; // Can't get the integer value as a constant. 13362 13363 llvm::APSInt ConstLength = Result.Val.getInt(); 13364 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13365 } 13366 13367 // Return true if it can be proven that the provided array expression (array 13368 // section or array subscript) does NOT specify a single element of the array 13369 // whose base type is \a BaseQTy. 13370 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13371 const Expr *E, 13372 QualType BaseQTy) { 13373 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13374 13375 // An array subscript always refer to a single element. Also, an array section 13376 // assumes the format of an array subscript if no colon is used. 13377 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13378 return false; 13379 13380 assert(OASE && "Expecting array section if not an array subscript."); 13381 const Expr *Length = OASE->getLength(); 13382 13383 // If we don't have a length we have to check if the array has unitary size 13384 // for this dimension. Also, we should always expect a length if the base type 13385 // is pointer. 13386 if (!Length) { 13387 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13388 return ATy->getSize().getSExtValue() != 1; 13389 // We cannot assume anything. 13390 return false; 13391 } 13392 13393 // Check if the length evaluates to 1. 13394 Expr::EvalResult Result; 13395 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13396 return false; // Can't get the integer value as a constant. 13397 13398 llvm::APSInt ConstLength = Result.Val.getInt(); 13399 return ConstLength.getSExtValue() != 1; 13400 } 13401 13402 // Return the expression of the base of the mappable expression or null if it 13403 // cannot be determined and do all the necessary checks to see if the expression 13404 // is valid as a standalone mappable expression. In the process, record all the 13405 // components of the expression. 13406 static const Expr *checkMapClauseExpressionBase( 13407 Sema &SemaRef, Expr *E, 13408 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 13409 OpenMPClauseKind CKind, bool NoDiagnose) { 13410 SourceLocation ELoc = E->getExprLoc(); 13411 SourceRange ERange = E->getSourceRange(); 13412 13413 // The base of elements of list in a map clause have to be either: 13414 // - a reference to variable or field. 13415 // - a member expression. 13416 // - an array expression. 13417 // 13418 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 13419 // reference to 'r'. 13420 // 13421 // If we have: 13422 // 13423 // struct SS { 13424 // Bla S; 13425 // foo() { 13426 // #pragma omp target map (S.Arr[:12]); 13427 // } 13428 // } 13429 // 13430 // We want to retrieve the member expression 'this->S'; 13431 13432 const Expr *RelevantExpr = nullptr; 13433 13434 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 13435 // If a list item is an array section, it must specify contiguous storage. 13436 // 13437 // For this restriction it is sufficient that we make sure only references 13438 // to variables or fields and array expressions, and that no array sections 13439 // exist except in the rightmost expression (unless they cover the whole 13440 // dimension of the array). E.g. these would be invalid: 13441 // 13442 // r.ArrS[3:5].Arr[6:7] 13443 // 13444 // r.ArrS[3:5].x 13445 // 13446 // but these would be valid: 13447 // r.ArrS[3].Arr[6:7] 13448 // 13449 // r.ArrS[3].x 13450 13451 bool AllowUnitySizeArraySection = true; 13452 bool AllowWholeSizeArraySection = true; 13453 13454 while (!RelevantExpr) { 13455 E = E->IgnoreParenImpCasts(); 13456 13457 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 13458 if (!isa<VarDecl>(CurE->getDecl())) 13459 return nullptr; 13460 13461 RelevantExpr = CurE; 13462 13463 // If we got a reference to a declaration, we should not expect any array 13464 // section before that. 13465 AllowUnitySizeArraySection = false; 13466 AllowWholeSizeArraySection = false; 13467 13468 // Record the component. 13469 CurComponents.emplace_back(CurE, CurE->getDecl()); 13470 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 13471 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 13472 13473 if (isa<CXXThisExpr>(BaseE)) 13474 // We found a base expression: this->Val. 13475 RelevantExpr = CurE; 13476 else 13477 E = BaseE; 13478 13479 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 13480 if (!NoDiagnose) { 13481 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 13482 << CurE->getSourceRange(); 13483 return nullptr; 13484 } 13485 if (RelevantExpr) 13486 return nullptr; 13487 continue; 13488 } 13489 13490 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 13491 13492 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 13493 // A bit-field cannot appear in a map clause. 13494 // 13495 if (FD->isBitField()) { 13496 if (!NoDiagnose) { 13497 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 13498 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 13499 return nullptr; 13500 } 13501 if (RelevantExpr) 13502 return nullptr; 13503 continue; 13504 } 13505 13506 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13507 // If the type of a list item is a reference to a type T then the type 13508 // will be considered to be T for all purposes of this clause. 13509 QualType CurType = BaseE->getType().getNonReferenceType(); 13510 13511 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 13512 // A list item cannot be a variable that is a member of a structure with 13513 // a union type. 13514 // 13515 if (CurType->isUnionType()) { 13516 if (!NoDiagnose) { 13517 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 13518 << CurE->getSourceRange(); 13519 return nullptr; 13520 } 13521 continue; 13522 } 13523 13524 // If we got a member expression, we should not expect any array section 13525 // before that: 13526 // 13527 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 13528 // If a list item is an element of a structure, only the rightmost symbol 13529 // of the variable reference can be an array section. 13530 // 13531 AllowUnitySizeArraySection = false; 13532 AllowWholeSizeArraySection = false; 13533 13534 // Record the component. 13535 CurComponents.emplace_back(CurE, FD); 13536 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 13537 E = CurE->getBase()->IgnoreParenImpCasts(); 13538 13539 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 13540 if (!NoDiagnose) { 13541 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13542 << 0 << CurE->getSourceRange(); 13543 return nullptr; 13544 } 13545 continue; 13546 } 13547 13548 // If we got an array subscript that express the whole dimension we 13549 // can have any array expressions before. If it only expressing part of 13550 // the dimension, we can only have unitary-size array expressions. 13551 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 13552 E->getType())) 13553 AllowWholeSizeArraySection = false; 13554 13555 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13556 Expr::EvalResult Result; 13557 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 13558 if (!Result.Val.getInt().isNullValue()) { 13559 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13560 diag::err_omp_invalid_map_this_expr); 13561 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13562 diag::note_omp_invalid_subscript_on_this_ptr_map); 13563 } 13564 } 13565 RelevantExpr = TE; 13566 } 13567 13568 // Record the component - we don't have any declaration associated. 13569 CurComponents.emplace_back(CurE, nullptr); 13570 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 13571 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 13572 E = CurE->getBase()->IgnoreParenImpCasts(); 13573 13574 QualType CurType = 13575 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13576 13577 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13578 // If the type of a list item is a reference to a type T then the type 13579 // will be considered to be T for all purposes of this clause. 13580 if (CurType->isReferenceType()) 13581 CurType = CurType->getPointeeType(); 13582 13583 bool IsPointer = CurType->isAnyPointerType(); 13584 13585 if (!IsPointer && !CurType->isArrayType()) { 13586 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13587 << 0 << CurE->getSourceRange(); 13588 return nullptr; 13589 } 13590 13591 bool NotWhole = 13592 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13593 bool NotUnity = 13594 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13595 13596 if (AllowWholeSizeArraySection) { 13597 // Any array section is currently allowed. Allowing a whole size array 13598 // section implies allowing a unity array section as well. 13599 // 13600 // If this array section refers to the whole dimension we can still 13601 // accept other array sections before this one, except if the base is a 13602 // pointer. Otherwise, only unitary sections are accepted. 13603 if (NotWhole || IsPointer) 13604 AllowWholeSizeArraySection = false; 13605 } else if (AllowUnitySizeArraySection && NotUnity) { 13606 // A unity or whole array section is not allowed and that is not 13607 // compatible with the properties of the current array section. 13608 SemaRef.Diag( 13609 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13610 << CurE->getSourceRange(); 13611 return nullptr; 13612 } 13613 13614 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13615 Expr::EvalResult ResultR; 13616 Expr::EvalResult ResultL; 13617 if (CurE->getLength()->EvaluateAsInt(ResultR, 13618 SemaRef.getASTContext())) { 13619 if (!ResultR.Val.getInt().isOneValue()) { 13620 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13621 diag::err_omp_invalid_map_this_expr); 13622 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13623 diag::note_omp_invalid_length_on_this_ptr_mapping); 13624 } 13625 } 13626 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 13627 ResultL, SemaRef.getASTContext())) { 13628 if (!ResultL.Val.getInt().isNullValue()) { 13629 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13630 diag::err_omp_invalid_map_this_expr); 13631 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13632 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 13633 } 13634 } 13635 RelevantExpr = TE; 13636 } 13637 13638 // Record the component - we don't have any declaration associated. 13639 CurComponents.emplace_back(CurE, nullptr); 13640 } else { 13641 if (!NoDiagnose) { 13642 // If nothing else worked, this is not a valid map clause expression. 13643 SemaRef.Diag( 13644 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 13645 << ERange; 13646 } 13647 return nullptr; 13648 } 13649 } 13650 13651 return RelevantExpr; 13652 } 13653 13654 // Return true if expression E associated with value VD has conflicts with other 13655 // map information. 13656 static bool checkMapConflicts( 13657 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 13658 bool CurrentRegionOnly, 13659 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 13660 OpenMPClauseKind CKind) { 13661 assert(VD && E); 13662 SourceLocation ELoc = E->getExprLoc(); 13663 SourceRange ERange = E->getSourceRange(); 13664 13665 // In order to easily check the conflicts we need to match each component of 13666 // the expression under test with the components of the expressions that are 13667 // already in the stack. 13668 13669 assert(!CurComponents.empty() && "Map clause expression with no components!"); 13670 assert(CurComponents.back().getAssociatedDeclaration() == VD && 13671 "Map clause expression with unexpected base!"); 13672 13673 // Variables to help detecting enclosing problems in data environment nests. 13674 bool IsEnclosedByDataEnvironmentExpr = false; 13675 const Expr *EnclosingExpr = nullptr; 13676 13677 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 13678 VD, CurrentRegionOnly, 13679 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 13680 ERange, CKind, &EnclosingExpr, 13681 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 13682 StackComponents, 13683 OpenMPClauseKind) { 13684 assert(!StackComponents.empty() && 13685 "Map clause expression with no components!"); 13686 assert(StackComponents.back().getAssociatedDeclaration() == VD && 13687 "Map clause expression with unexpected base!"); 13688 (void)VD; 13689 13690 // The whole expression in the stack. 13691 const Expr *RE = StackComponents.front().getAssociatedExpression(); 13692 13693 // Expressions must start from the same base. Here we detect at which 13694 // point both expressions diverge from each other and see if we can 13695 // detect if the memory referred to both expressions is contiguous and 13696 // do not overlap. 13697 auto CI = CurComponents.rbegin(); 13698 auto CE = CurComponents.rend(); 13699 auto SI = StackComponents.rbegin(); 13700 auto SE = StackComponents.rend(); 13701 for (; CI != CE && SI != SE; ++CI, ++SI) { 13702 13703 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 13704 // At most one list item can be an array item derived from a given 13705 // variable in map clauses of the same construct. 13706 if (CurrentRegionOnly && 13707 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 13708 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 13709 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 13710 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 13711 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 13712 diag::err_omp_multiple_array_items_in_map_clause) 13713 << CI->getAssociatedExpression()->getSourceRange(); 13714 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 13715 diag::note_used_here) 13716 << SI->getAssociatedExpression()->getSourceRange(); 13717 return true; 13718 } 13719 13720 // Do both expressions have the same kind? 13721 if (CI->getAssociatedExpression()->getStmtClass() != 13722 SI->getAssociatedExpression()->getStmtClass()) 13723 break; 13724 13725 // Are we dealing with different variables/fields? 13726 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 13727 break; 13728 } 13729 // Check if the extra components of the expressions in the enclosing 13730 // data environment are redundant for the current base declaration. 13731 // If they are, the maps completely overlap, which is legal. 13732 for (; SI != SE; ++SI) { 13733 QualType Type; 13734 if (const auto *ASE = 13735 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 13736 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 13737 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 13738 SI->getAssociatedExpression())) { 13739 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 13740 Type = 13741 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13742 } 13743 if (Type.isNull() || Type->isAnyPointerType() || 13744 checkArrayExpressionDoesNotReferToWholeSize( 13745 SemaRef, SI->getAssociatedExpression(), Type)) 13746 break; 13747 } 13748 13749 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13750 // List items of map clauses in the same construct must not share 13751 // original storage. 13752 // 13753 // If the expressions are exactly the same or one is a subset of the 13754 // other, it means they are sharing storage. 13755 if (CI == CE && SI == SE) { 13756 if (CurrentRegionOnly) { 13757 if (CKind == OMPC_map) { 13758 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13759 } else { 13760 assert(CKind == OMPC_to || CKind == OMPC_from); 13761 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13762 << ERange; 13763 } 13764 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13765 << RE->getSourceRange(); 13766 return true; 13767 } 13768 // If we find the same expression in the enclosing data environment, 13769 // that is legal. 13770 IsEnclosedByDataEnvironmentExpr = true; 13771 return false; 13772 } 13773 13774 QualType DerivedType = 13775 std::prev(CI)->getAssociatedDeclaration()->getType(); 13776 SourceLocation DerivedLoc = 13777 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 13778 13779 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13780 // If the type of a list item is a reference to a type T then the type 13781 // will be considered to be T for all purposes of this clause. 13782 DerivedType = DerivedType.getNonReferenceType(); 13783 13784 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 13785 // A variable for which the type is pointer and an array section 13786 // derived from that variable must not appear as list items of map 13787 // clauses of the same construct. 13788 // 13789 // Also, cover one of the cases in: 13790 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13791 // If any part of the original storage of a list item has corresponding 13792 // storage in the device data environment, all of the original storage 13793 // must have corresponding storage in the device data environment. 13794 // 13795 if (DerivedType->isAnyPointerType()) { 13796 if (CI == CE || SI == SE) { 13797 SemaRef.Diag( 13798 DerivedLoc, 13799 diag::err_omp_pointer_mapped_along_with_derived_section) 13800 << DerivedLoc; 13801 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13802 << RE->getSourceRange(); 13803 return true; 13804 } 13805 if (CI->getAssociatedExpression()->getStmtClass() != 13806 SI->getAssociatedExpression()->getStmtClass() || 13807 CI->getAssociatedDeclaration()->getCanonicalDecl() == 13808 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 13809 assert(CI != CE && SI != SE); 13810 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 13811 << DerivedLoc; 13812 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13813 << RE->getSourceRange(); 13814 return true; 13815 } 13816 } 13817 13818 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13819 // List items of map clauses in the same construct must not share 13820 // original storage. 13821 // 13822 // An expression is a subset of the other. 13823 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 13824 if (CKind == OMPC_map) { 13825 if (CI != CE || SI != SE) { 13826 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 13827 // a pointer. 13828 auto Begin = 13829 CI != CE ? CurComponents.begin() : StackComponents.begin(); 13830 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 13831 auto It = Begin; 13832 while (It != End && !It->getAssociatedDeclaration()) 13833 std::advance(It, 1); 13834 assert(It != End && 13835 "Expected at least one component with the declaration."); 13836 if (It != Begin && It->getAssociatedDeclaration() 13837 ->getType() 13838 .getCanonicalType() 13839 ->isAnyPointerType()) { 13840 IsEnclosedByDataEnvironmentExpr = false; 13841 EnclosingExpr = nullptr; 13842 return false; 13843 } 13844 } 13845 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13846 } else { 13847 assert(CKind == OMPC_to || CKind == OMPC_from); 13848 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13849 << ERange; 13850 } 13851 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13852 << RE->getSourceRange(); 13853 return true; 13854 } 13855 13856 // The current expression uses the same base as other expression in the 13857 // data environment but does not contain it completely. 13858 if (!CurrentRegionOnly && SI != SE) 13859 EnclosingExpr = RE; 13860 13861 // The current expression is a subset of the expression in the data 13862 // environment. 13863 IsEnclosedByDataEnvironmentExpr |= 13864 (!CurrentRegionOnly && CI != CE && SI == SE); 13865 13866 return false; 13867 }); 13868 13869 if (CurrentRegionOnly) 13870 return FoundError; 13871 13872 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13873 // If any part of the original storage of a list item has corresponding 13874 // storage in the device data environment, all of the original storage must 13875 // have corresponding storage in the device data environment. 13876 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 13877 // If a list item is an element of a structure, and a different element of 13878 // the structure has a corresponding list item in the device data environment 13879 // prior to a task encountering the construct associated with the map clause, 13880 // then the list item must also have a corresponding list item in the device 13881 // data environment prior to the task encountering the construct. 13882 // 13883 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 13884 SemaRef.Diag(ELoc, 13885 diag::err_omp_original_storage_is_shared_and_does_not_contain) 13886 << ERange; 13887 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 13888 << EnclosingExpr->getSourceRange(); 13889 return true; 13890 } 13891 13892 return FoundError; 13893 } 13894 13895 // Look up the user-defined mapper given the mapper name and mapped type, and 13896 // build a reference to it. 13897 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 13898 CXXScopeSpec &MapperIdScopeSpec, 13899 const DeclarationNameInfo &MapperId, 13900 QualType Type, 13901 Expr *UnresolvedMapper) { 13902 if (MapperIdScopeSpec.isInvalid()) 13903 return ExprError(); 13904 // Find all user-defined mappers with the given MapperId. 13905 SmallVector<UnresolvedSet<8>, 4> Lookups; 13906 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 13907 Lookup.suppressDiagnostics(); 13908 if (S) { 13909 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 13910 NamedDecl *D = Lookup.getRepresentativeDecl(); 13911 while (S && !S->isDeclScope(D)) 13912 S = S->getParent(); 13913 if (S) 13914 S = S->getParent(); 13915 Lookups.emplace_back(); 13916 Lookups.back().append(Lookup.begin(), Lookup.end()); 13917 Lookup.clear(); 13918 } 13919 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 13920 // Extract the user-defined mappers with the given MapperId. 13921 Lookups.push_back(UnresolvedSet<8>()); 13922 for (NamedDecl *D : ULE->decls()) { 13923 auto *DMD = cast<OMPDeclareMapperDecl>(D); 13924 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 13925 Lookups.back().addDecl(DMD); 13926 } 13927 } 13928 // Defer the lookup for dependent types. The results will be passed through 13929 // UnresolvedMapper on instantiation. 13930 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 13931 Type->isInstantiationDependentType() || 13932 Type->containsUnexpandedParameterPack() || 13933 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13934 return !D->isInvalidDecl() && 13935 (D->getType()->isDependentType() || 13936 D->getType()->isInstantiationDependentType() || 13937 D->getType()->containsUnexpandedParameterPack()); 13938 })) { 13939 UnresolvedSet<8> URS; 13940 for (const UnresolvedSet<8> &Set : Lookups) { 13941 if (Set.empty()) 13942 continue; 13943 URS.append(Set.begin(), Set.end()); 13944 } 13945 return UnresolvedLookupExpr::Create( 13946 SemaRef.Context, /*NamingClass=*/nullptr, 13947 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 13948 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 13949 } 13950 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13951 // The type must be of struct, union or class type in C and C++ 13952 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 13953 return ExprEmpty(); 13954 SourceLocation Loc = MapperId.getLoc(); 13955 // Perform argument dependent lookup. 13956 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 13957 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 13958 // Return the first user-defined mapper with the desired type. 13959 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13960 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 13961 if (!D->isInvalidDecl() && 13962 SemaRef.Context.hasSameType(D->getType(), Type)) 13963 return D; 13964 return nullptr; 13965 })) 13966 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13967 // Find the first user-defined mapper with a type derived from the desired 13968 // type. 13969 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13970 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 13971 if (!D->isInvalidDecl() && 13972 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 13973 !Type.isMoreQualifiedThan(D->getType())) 13974 return D; 13975 return nullptr; 13976 })) { 13977 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13978 /*DetectVirtual=*/false); 13979 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 13980 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13981 VD->getType().getUnqualifiedType()))) { 13982 if (SemaRef.CheckBaseClassAccess( 13983 Loc, VD->getType(), Type, Paths.front(), 13984 /*DiagID=*/0) != Sema::AR_inaccessible) { 13985 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13986 } 13987 } 13988 } 13989 } 13990 // Report error if a mapper is specified, but cannot be found. 13991 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 13992 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 13993 << Type << MapperId.getName(); 13994 return ExprError(); 13995 } 13996 return ExprEmpty(); 13997 } 13998 13999 namespace { 14000 // Utility struct that gathers all the related lists associated with a mappable 14001 // expression. 14002 struct MappableVarListInfo { 14003 // The list of expressions. 14004 ArrayRef<Expr *> VarList; 14005 // The list of processed expressions. 14006 SmallVector<Expr *, 16> ProcessedVarList; 14007 // The mappble components for each expression. 14008 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 14009 // The base declaration of the variable. 14010 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 14011 // The reference to the user-defined mapper associated with every expression. 14012 SmallVector<Expr *, 16> UDMapperList; 14013 14014 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 14015 // We have a list of components and base declarations for each entry in the 14016 // variable list. 14017 VarComponents.reserve(VarList.size()); 14018 VarBaseDeclarations.reserve(VarList.size()); 14019 } 14020 }; 14021 } 14022 14023 // Check the validity of the provided variable list for the provided clause kind 14024 // \a CKind. In the check process the valid expressions, mappable expression 14025 // components, variables, and user-defined mappers are extracted and used to 14026 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 14027 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 14028 // and \a MapperId are expected to be valid if the clause kind is 'map'. 14029 static void checkMappableExpressionList( 14030 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 14031 MappableVarListInfo &MVLI, SourceLocation StartLoc, 14032 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 14033 ArrayRef<Expr *> UnresolvedMappers, 14034 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 14035 bool IsMapTypeImplicit = false) { 14036 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 14037 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 14038 "Unexpected clause kind with mappable expressions!"); 14039 14040 // If the identifier of user-defined mapper is not specified, it is "default". 14041 // We do not change the actual name in this clause to distinguish whether a 14042 // mapper is specified explicitly, i.e., it is not explicitly specified when 14043 // MapperId.getName() is empty. 14044 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 14045 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14046 MapperId.setName(DeclNames.getIdentifier( 14047 &SemaRef.getASTContext().Idents.get("default"))); 14048 } 14049 14050 // Iterators to find the current unresolved mapper expression. 14051 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14052 bool UpdateUMIt = false; 14053 Expr *UnresolvedMapper = nullptr; 14054 14055 // Keep track of the mappable components and base declarations in this clause. 14056 // Each entry in the list is going to have a list of components associated. We 14057 // record each set of the components so that we can build the clause later on. 14058 // In the end we should have the same amount of declarations and component 14059 // lists. 14060 14061 for (Expr *RE : MVLI.VarList) { 14062 assert(RE && "Null expr in omp to/from/map clause"); 14063 SourceLocation ELoc = RE->getExprLoc(); 14064 14065 // Find the current unresolved mapper expression. 14066 if (UpdateUMIt && UMIt != UMEnd) { 14067 UMIt++; 14068 assert( 14069 UMIt != UMEnd && 14070 "Expect the size of UnresolvedMappers to match with that of VarList"); 14071 } 14072 UpdateUMIt = true; 14073 if (UMIt != UMEnd) 14074 UnresolvedMapper = *UMIt; 14075 14076 const Expr *VE = RE->IgnoreParenLValueCasts(); 14077 14078 if (VE->isValueDependent() || VE->isTypeDependent() || 14079 VE->isInstantiationDependent() || 14080 VE->containsUnexpandedParameterPack()) { 14081 // Try to find the associated user-defined mapper. 14082 ExprResult ER = buildUserDefinedMapperRef( 14083 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14084 VE->getType().getCanonicalType(), UnresolvedMapper); 14085 if (ER.isInvalid()) 14086 continue; 14087 MVLI.UDMapperList.push_back(ER.get()); 14088 // We can only analyze this information once the missing information is 14089 // resolved. 14090 MVLI.ProcessedVarList.push_back(RE); 14091 continue; 14092 } 14093 14094 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14095 14096 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14097 SemaRef.Diag(ELoc, 14098 diag::err_omp_expected_named_var_member_or_array_expression) 14099 << RE->getSourceRange(); 14100 continue; 14101 } 14102 14103 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14104 ValueDecl *CurDeclaration = nullptr; 14105 14106 // Obtain the array or member expression bases if required. Also, fill the 14107 // components array with all the components identified in the process. 14108 const Expr *BE = checkMapClauseExpressionBase( 14109 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14110 if (!BE) 14111 continue; 14112 14113 assert(!CurComponents.empty() && 14114 "Invalid mappable expression information."); 14115 14116 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14117 // Add store "this" pointer to class in DSAStackTy for future checking 14118 DSAS->addMappedClassesQualTypes(TE->getType()); 14119 // Try to find the associated user-defined mapper. 14120 ExprResult ER = buildUserDefinedMapperRef( 14121 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14122 VE->getType().getCanonicalType(), UnresolvedMapper); 14123 if (ER.isInvalid()) 14124 continue; 14125 MVLI.UDMapperList.push_back(ER.get()); 14126 // Skip restriction checking for variable or field declarations 14127 MVLI.ProcessedVarList.push_back(RE); 14128 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14129 MVLI.VarComponents.back().append(CurComponents.begin(), 14130 CurComponents.end()); 14131 MVLI.VarBaseDeclarations.push_back(nullptr); 14132 continue; 14133 } 14134 14135 // For the following checks, we rely on the base declaration which is 14136 // expected to be associated with the last component. The declaration is 14137 // expected to be a variable or a field (if 'this' is being mapped). 14138 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14139 assert(CurDeclaration && "Null decl on map clause."); 14140 assert( 14141 CurDeclaration->isCanonicalDecl() && 14142 "Expecting components to have associated only canonical declarations."); 14143 14144 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14145 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14146 14147 assert((VD || FD) && "Only variables or fields are expected here!"); 14148 (void)FD; 14149 14150 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14151 // threadprivate variables cannot appear in a map clause. 14152 // OpenMP 4.5 [2.10.5, target update Construct] 14153 // threadprivate variables cannot appear in a from clause. 14154 if (VD && DSAS->isThreadPrivate(VD)) { 14155 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14156 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14157 << getOpenMPClauseName(CKind); 14158 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14159 continue; 14160 } 14161 14162 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14163 // A list item cannot appear in both a map clause and a data-sharing 14164 // attribute clause on the same construct. 14165 14166 // Check conflicts with other map clause expressions. We check the conflicts 14167 // with the current construct separately from the enclosing data 14168 // environment, because the restrictions are different. We only have to 14169 // check conflicts across regions for the map clauses. 14170 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14171 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14172 break; 14173 if (CKind == OMPC_map && 14174 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14175 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14176 break; 14177 14178 // OpenMP 4.5 [2.10.5, target update Construct] 14179 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14180 // If the type of a list item is a reference to a type T then the type will 14181 // be considered to be T for all purposes of this clause. 14182 auto I = llvm::find_if( 14183 CurComponents, 14184 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14185 return MC.getAssociatedDeclaration(); 14186 }); 14187 assert(I != CurComponents.end() && "Null decl on map clause."); 14188 QualType Type = 14189 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14190 14191 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14192 // A list item in a to or from clause must have a mappable type. 14193 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14194 // A list item must have a mappable type. 14195 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14196 DSAS, Type)) 14197 continue; 14198 14199 if (CKind == OMPC_map) { 14200 // target enter data 14201 // OpenMP [2.10.2, Restrictions, p. 99] 14202 // A map-type must be specified in all map clauses and must be either 14203 // to or alloc. 14204 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 14205 if (DKind == OMPD_target_enter_data && 14206 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 14207 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14208 << (IsMapTypeImplicit ? 1 : 0) 14209 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14210 << getOpenMPDirectiveName(DKind); 14211 continue; 14212 } 14213 14214 // target exit_data 14215 // OpenMP [2.10.3, Restrictions, p. 102] 14216 // A map-type must be specified in all map clauses and must be either 14217 // from, release, or delete. 14218 if (DKind == OMPD_target_exit_data && 14219 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 14220 MapType == OMPC_MAP_delete)) { 14221 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14222 << (IsMapTypeImplicit ? 1 : 0) 14223 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14224 << getOpenMPDirectiveName(DKind); 14225 continue; 14226 } 14227 14228 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14229 // A list item cannot appear in both a map clause and a data-sharing 14230 // attribute clause on the same construct 14231 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 14232 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14233 if (isOpenMPPrivate(DVar.CKind)) { 14234 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14235 << getOpenMPClauseName(DVar.CKind) 14236 << getOpenMPClauseName(OMPC_map) 14237 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 14238 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 14239 continue; 14240 } 14241 } 14242 } 14243 14244 // Try to find the associated user-defined mapper. 14245 ExprResult ER = buildUserDefinedMapperRef( 14246 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14247 Type.getCanonicalType(), UnresolvedMapper); 14248 if (ER.isInvalid()) 14249 continue; 14250 MVLI.UDMapperList.push_back(ER.get()); 14251 14252 // Save the current expression. 14253 MVLI.ProcessedVarList.push_back(RE); 14254 14255 // Store the components in the stack so that they can be used to check 14256 // against other clauses later on. 14257 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14258 /*WhereFoundClauseKind=*/OMPC_map); 14259 14260 // Save the components and declaration to create the clause. For purposes of 14261 // the clause creation, any component list that has has base 'this' uses 14262 // null as base declaration. 14263 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14264 MVLI.VarComponents.back().append(CurComponents.begin(), 14265 CurComponents.end()); 14266 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14267 : CurDeclaration); 14268 } 14269 } 14270 14271 OMPClause *Sema::ActOnOpenMPMapClause( 14272 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14273 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14274 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14275 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14276 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14277 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14278 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14279 OMPC_MAP_MODIFIER_unknown, 14280 OMPC_MAP_MODIFIER_unknown}; 14281 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14282 14283 // Process map-type-modifiers, flag errors for duplicate modifiers. 14284 unsigned Count = 0; 14285 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14286 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14287 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14288 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14289 continue; 14290 } 14291 assert(Count < OMPMapClause::NumberOfModifiers && 14292 "Modifiers exceed the allowed number of map type modifiers"); 14293 Modifiers[Count] = MapTypeModifiers[I]; 14294 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14295 ++Count; 14296 } 14297 14298 MappableVarListInfo MVLI(VarList); 14299 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14300 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14301 MapType, IsMapTypeImplicit); 14302 14303 // We need to produce a map clause even if we don't have variables so that 14304 // other diagnostics related with non-existing map clauses are accurate. 14305 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14306 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14307 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14308 MapperIdScopeSpec.getWithLocInContext(Context), 14309 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14310 } 14311 14312 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14313 TypeResult ParsedType) { 14314 assert(ParsedType.isUsable()); 14315 14316 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14317 if (ReductionType.isNull()) 14318 return QualType(); 14319 14320 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14321 // A type name in a declare reduction directive cannot be a function type, an 14322 // array type, a reference type, or a type qualified with const, volatile or 14323 // restrict. 14324 if (ReductionType.hasQualifiers()) { 14325 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14326 return QualType(); 14327 } 14328 14329 if (ReductionType->isFunctionType()) { 14330 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14331 return QualType(); 14332 } 14333 if (ReductionType->isReferenceType()) { 14334 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14335 return QualType(); 14336 } 14337 if (ReductionType->isArrayType()) { 14338 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14339 return QualType(); 14340 } 14341 return ReductionType; 14342 } 14343 14344 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14345 Scope *S, DeclContext *DC, DeclarationName Name, 14346 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14347 AccessSpecifier AS, Decl *PrevDeclInScope) { 14348 SmallVector<Decl *, 8> Decls; 14349 Decls.reserve(ReductionTypes.size()); 14350 14351 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14352 forRedeclarationInCurContext()); 14353 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14354 // A reduction-identifier may not be re-declared in the current scope for the 14355 // same type or for a type that is compatible according to the base language 14356 // rules. 14357 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14358 OMPDeclareReductionDecl *PrevDRD = nullptr; 14359 bool InCompoundScope = true; 14360 if (S != nullptr) { 14361 // Find previous declaration with the same name not referenced in other 14362 // declarations. 14363 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14364 InCompoundScope = 14365 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14366 LookupName(Lookup, S); 14367 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14368 /*AllowInlineNamespace=*/false); 14369 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14370 LookupResult::Filter Filter = Lookup.makeFilter(); 14371 while (Filter.hasNext()) { 14372 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14373 if (InCompoundScope) { 14374 auto I = UsedAsPrevious.find(PrevDecl); 14375 if (I == UsedAsPrevious.end()) 14376 UsedAsPrevious[PrevDecl] = false; 14377 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14378 UsedAsPrevious[D] = true; 14379 } 14380 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14381 PrevDecl->getLocation(); 14382 } 14383 Filter.done(); 14384 if (InCompoundScope) { 14385 for (const auto &PrevData : UsedAsPrevious) { 14386 if (!PrevData.second) { 14387 PrevDRD = PrevData.first; 14388 break; 14389 } 14390 } 14391 } 14392 } else if (PrevDeclInScope != nullptr) { 14393 auto *PrevDRDInScope = PrevDRD = 14394 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14395 do { 14396 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14397 PrevDRDInScope->getLocation(); 14398 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14399 } while (PrevDRDInScope != nullptr); 14400 } 14401 for (const auto &TyData : ReductionTypes) { 14402 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 14403 bool Invalid = false; 14404 if (I != PreviousRedeclTypes.end()) { 14405 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 14406 << TyData.first; 14407 Diag(I->second, diag::note_previous_definition); 14408 Invalid = true; 14409 } 14410 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 14411 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 14412 Name, TyData.first, PrevDRD); 14413 DC->addDecl(DRD); 14414 DRD->setAccess(AS); 14415 Decls.push_back(DRD); 14416 if (Invalid) 14417 DRD->setInvalidDecl(); 14418 else 14419 PrevDRD = DRD; 14420 } 14421 14422 return DeclGroupPtrTy::make( 14423 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 14424 } 14425 14426 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 14427 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14428 14429 // Enter new function scope. 14430 PushFunctionScope(); 14431 setFunctionHasBranchProtectedScope(); 14432 getCurFunction()->setHasOMPDeclareReductionCombiner(); 14433 14434 if (S != nullptr) 14435 PushDeclContext(S, DRD); 14436 else 14437 CurContext = DRD; 14438 14439 PushExpressionEvaluationContext( 14440 ExpressionEvaluationContext::PotentiallyEvaluated); 14441 14442 QualType ReductionType = DRD->getType(); 14443 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 14444 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 14445 // uses semantics of argument handles by value, but it should be passed by 14446 // reference. C lang does not support references, so pass all parameters as 14447 // pointers. 14448 // Create 'T omp_in;' variable. 14449 VarDecl *OmpInParm = 14450 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 14451 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 14452 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 14453 // uses semantics of argument handles by value, but it should be passed by 14454 // reference. C lang does not support references, so pass all parameters as 14455 // pointers. 14456 // Create 'T omp_out;' variable. 14457 VarDecl *OmpOutParm = 14458 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 14459 if (S != nullptr) { 14460 PushOnScopeChains(OmpInParm, S); 14461 PushOnScopeChains(OmpOutParm, S); 14462 } else { 14463 DRD->addDecl(OmpInParm); 14464 DRD->addDecl(OmpOutParm); 14465 } 14466 Expr *InE = 14467 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 14468 Expr *OutE = 14469 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 14470 DRD->setCombinerData(InE, OutE); 14471 } 14472 14473 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 14474 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14475 DiscardCleanupsInEvaluationContext(); 14476 PopExpressionEvaluationContext(); 14477 14478 PopDeclContext(); 14479 PopFunctionScopeInfo(); 14480 14481 if (Combiner != nullptr) 14482 DRD->setCombiner(Combiner); 14483 else 14484 DRD->setInvalidDecl(); 14485 } 14486 14487 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 14488 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14489 14490 // Enter new function scope. 14491 PushFunctionScope(); 14492 setFunctionHasBranchProtectedScope(); 14493 14494 if (S != nullptr) 14495 PushDeclContext(S, DRD); 14496 else 14497 CurContext = DRD; 14498 14499 PushExpressionEvaluationContext( 14500 ExpressionEvaluationContext::PotentiallyEvaluated); 14501 14502 QualType ReductionType = DRD->getType(); 14503 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 14504 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 14505 // uses semantics of argument handles by value, but it should be passed by 14506 // reference. C lang does not support references, so pass all parameters as 14507 // pointers. 14508 // Create 'T omp_priv;' variable. 14509 VarDecl *OmpPrivParm = 14510 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 14511 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 14512 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 14513 // uses semantics of argument handles by value, but it should be passed by 14514 // reference. C lang does not support references, so pass all parameters as 14515 // pointers. 14516 // Create 'T omp_orig;' variable. 14517 VarDecl *OmpOrigParm = 14518 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 14519 if (S != nullptr) { 14520 PushOnScopeChains(OmpPrivParm, S); 14521 PushOnScopeChains(OmpOrigParm, S); 14522 } else { 14523 DRD->addDecl(OmpPrivParm); 14524 DRD->addDecl(OmpOrigParm); 14525 } 14526 Expr *OrigE = 14527 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 14528 Expr *PrivE = 14529 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 14530 DRD->setInitializerData(OrigE, PrivE); 14531 return OmpPrivParm; 14532 } 14533 14534 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 14535 VarDecl *OmpPrivParm) { 14536 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14537 DiscardCleanupsInEvaluationContext(); 14538 PopExpressionEvaluationContext(); 14539 14540 PopDeclContext(); 14541 PopFunctionScopeInfo(); 14542 14543 if (Initializer != nullptr) { 14544 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 14545 } else if (OmpPrivParm->hasInit()) { 14546 DRD->setInitializer(OmpPrivParm->getInit(), 14547 OmpPrivParm->isDirectInit() 14548 ? OMPDeclareReductionDecl::DirectInit 14549 : OMPDeclareReductionDecl::CopyInit); 14550 } else { 14551 DRD->setInvalidDecl(); 14552 } 14553 } 14554 14555 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 14556 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 14557 for (Decl *D : DeclReductions.get()) { 14558 if (IsValid) { 14559 if (S) 14560 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 14561 /*AddToContext=*/false); 14562 } else { 14563 D->setInvalidDecl(); 14564 } 14565 } 14566 return DeclReductions; 14567 } 14568 14569 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 14570 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 14571 QualType T = TInfo->getType(); 14572 if (D.isInvalidType()) 14573 return true; 14574 14575 if (getLangOpts().CPlusPlus) { 14576 // Check that there are no default arguments (C++ only). 14577 CheckExtraCXXDefaultArguments(D); 14578 } 14579 14580 return CreateParsedType(T, TInfo); 14581 } 14582 14583 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14584 TypeResult ParsedType) { 14585 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14586 14587 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14588 assert(!MapperType.isNull() && "Expect valid mapper type"); 14589 14590 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14591 // The type must be of struct, union or class type in C and C++ 14592 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14593 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14594 return QualType(); 14595 } 14596 return MapperType; 14597 } 14598 14599 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14600 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14601 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14602 Decl *PrevDeclInScope) { 14603 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14604 forRedeclarationInCurContext()); 14605 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14606 // A mapper-identifier may not be redeclared in the current scope for the 14607 // same type or for a type that is compatible according to the base language 14608 // rules. 14609 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14610 OMPDeclareMapperDecl *PrevDMD = nullptr; 14611 bool InCompoundScope = true; 14612 if (S != nullptr) { 14613 // Find previous declaration with the same name not referenced in other 14614 // declarations. 14615 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14616 InCompoundScope = 14617 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14618 LookupName(Lookup, S); 14619 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14620 /*AllowInlineNamespace=*/false); 14621 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 14622 LookupResult::Filter Filter = Lookup.makeFilter(); 14623 while (Filter.hasNext()) { 14624 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 14625 if (InCompoundScope) { 14626 auto I = UsedAsPrevious.find(PrevDecl); 14627 if (I == UsedAsPrevious.end()) 14628 UsedAsPrevious[PrevDecl] = false; 14629 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 14630 UsedAsPrevious[D] = true; 14631 } 14632 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14633 PrevDecl->getLocation(); 14634 } 14635 Filter.done(); 14636 if (InCompoundScope) { 14637 for (const auto &PrevData : UsedAsPrevious) { 14638 if (!PrevData.second) { 14639 PrevDMD = PrevData.first; 14640 break; 14641 } 14642 } 14643 } 14644 } else if (PrevDeclInScope) { 14645 auto *PrevDMDInScope = PrevDMD = 14646 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 14647 do { 14648 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 14649 PrevDMDInScope->getLocation(); 14650 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 14651 } while (PrevDMDInScope != nullptr); 14652 } 14653 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 14654 bool Invalid = false; 14655 if (I != PreviousRedeclTypes.end()) { 14656 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 14657 << MapperType << Name; 14658 Diag(I->second, diag::note_previous_definition); 14659 Invalid = true; 14660 } 14661 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 14662 MapperType, VN, PrevDMD); 14663 DC->addDecl(DMD); 14664 DMD->setAccess(AS); 14665 if (Invalid) 14666 DMD->setInvalidDecl(); 14667 14668 // Enter new function scope. 14669 PushFunctionScope(); 14670 setFunctionHasBranchProtectedScope(); 14671 14672 CurContext = DMD; 14673 14674 return DMD; 14675 } 14676 14677 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 14678 Scope *S, 14679 QualType MapperType, 14680 SourceLocation StartLoc, 14681 DeclarationName VN) { 14682 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 14683 if (S) 14684 PushOnScopeChains(VD, S); 14685 else 14686 DMD->addDecl(VD); 14687 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 14688 DMD->setMapperVarRef(MapperVarRefExpr); 14689 } 14690 14691 Sema::DeclGroupPtrTy 14692 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 14693 ArrayRef<OMPClause *> ClauseList) { 14694 PopDeclContext(); 14695 PopFunctionScopeInfo(); 14696 14697 if (D) { 14698 if (S) 14699 PushOnScopeChains(D, S, /*AddToContext=*/false); 14700 D->CreateClauses(Context, ClauseList); 14701 } 14702 14703 return DeclGroupPtrTy::make(DeclGroupRef(D)); 14704 } 14705 14706 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 14707 SourceLocation StartLoc, 14708 SourceLocation LParenLoc, 14709 SourceLocation EndLoc) { 14710 Expr *ValExpr = NumTeams; 14711 Stmt *HelperValStmt = nullptr; 14712 14713 // OpenMP [teams Constrcut, Restrictions] 14714 // The num_teams expression must evaluate to a positive integer value. 14715 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 14716 /*StrictlyPositive=*/true)) 14717 return nullptr; 14718 14719 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14720 OpenMPDirectiveKind CaptureRegion = 14721 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 14722 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14723 ValExpr = MakeFullExpr(ValExpr).get(); 14724 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14725 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14726 HelperValStmt = buildPreInits(Context, Captures); 14727 } 14728 14729 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 14730 StartLoc, LParenLoc, EndLoc); 14731 } 14732 14733 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 14734 SourceLocation StartLoc, 14735 SourceLocation LParenLoc, 14736 SourceLocation EndLoc) { 14737 Expr *ValExpr = ThreadLimit; 14738 Stmt *HelperValStmt = nullptr; 14739 14740 // OpenMP [teams Constrcut, Restrictions] 14741 // The thread_limit expression must evaluate to a positive integer value. 14742 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 14743 /*StrictlyPositive=*/true)) 14744 return nullptr; 14745 14746 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14747 OpenMPDirectiveKind CaptureRegion = 14748 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 14749 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14750 ValExpr = MakeFullExpr(ValExpr).get(); 14751 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14752 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14753 HelperValStmt = buildPreInits(Context, Captures); 14754 } 14755 14756 return new (Context) OMPThreadLimitClause( 14757 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14758 } 14759 14760 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 14761 SourceLocation StartLoc, 14762 SourceLocation LParenLoc, 14763 SourceLocation EndLoc) { 14764 Expr *ValExpr = Priority; 14765 14766 // OpenMP [2.9.1, task Constrcut] 14767 // The priority-value is a non-negative numerical scalar expression. 14768 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 14769 /*StrictlyPositive=*/false)) 14770 return nullptr; 14771 14772 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14773 } 14774 14775 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 14776 SourceLocation StartLoc, 14777 SourceLocation LParenLoc, 14778 SourceLocation EndLoc) { 14779 Expr *ValExpr = Grainsize; 14780 14781 // OpenMP [2.9.2, taskloop Constrcut] 14782 // The parameter of the grainsize clause must be a positive integer 14783 // expression. 14784 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 14785 /*StrictlyPositive=*/true)) 14786 return nullptr; 14787 14788 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14789 } 14790 14791 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 14792 SourceLocation StartLoc, 14793 SourceLocation LParenLoc, 14794 SourceLocation EndLoc) { 14795 Expr *ValExpr = NumTasks; 14796 14797 // OpenMP [2.9.2, taskloop Constrcut] 14798 // The parameter of the num_tasks clause must be a positive integer 14799 // expression. 14800 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 14801 /*StrictlyPositive=*/true)) 14802 return nullptr; 14803 14804 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14805 } 14806 14807 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 14808 SourceLocation LParenLoc, 14809 SourceLocation EndLoc) { 14810 // OpenMP [2.13.2, critical construct, Description] 14811 // ... where hint-expression is an integer constant expression that evaluates 14812 // to a valid lock hint. 14813 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 14814 if (HintExpr.isInvalid()) 14815 return nullptr; 14816 return new (Context) 14817 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 14818 } 14819 14820 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 14821 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14822 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 14823 SourceLocation EndLoc) { 14824 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 14825 std::string Values; 14826 Values += "'"; 14827 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 14828 Values += "'"; 14829 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14830 << Values << getOpenMPClauseName(OMPC_dist_schedule); 14831 return nullptr; 14832 } 14833 Expr *ValExpr = ChunkSize; 14834 Stmt *HelperValStmt = nullptr; 14835 if (ChunkSize) { 14836 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14837 !ChunkSize->isInstantiationDependent() && 14838 !ChunkSize->containsUnexpandedParameterPack()) { 14839 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14840 ExprResult Val = 14841 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14842 if (Val.isInvalid()) 14843 return nullptr; 14844 14845 ValExpr = Val.get(); 14846 14847 // OpenMP [2.7.1, Restrictions] 14848 // chunk_size must be a loop invariant integer expression with a positive 14849 // value. 14850 llvm::APSInt Result; 14851 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 14852 if (Result.isSigned() && !Result.isStrictlyPositive()) { 14853 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14854 << "dist_schedule" << ChunkSize->getSourceRange(); 14855 return nullptr; 14856 } 14857 } else if (getOpenMPCaptureRegionForClause( 14858 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 14859 OMPD_unknown && 14860 !CurContext->isDependentContext()) { 14861 ValExpr = MakeFullExpr(ValExpr).get(); 14862 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14863 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14864 HelperValStmt = buildPreInits(Context, Captures); 14865 } 14866 } 14867 } 14868 14869 return new (Context) 14870 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 14871 Kind, ValExpr, HelperValStmt); 14872 } 14873 14874 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 14875 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 14876 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 14877 SourceLocation KindLoc, SourceLocation EndLoc) { 14878 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 14879 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 14880 std::string Value; 14881 SourceLocation Loc; 14882 Value += "'"; 14883 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 14884 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14885 OMPC_DEFAULTMAP_MODIFIER_tofrom); 14886 Loc = MLoc; 14887 } else { 14888 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14889 OMPC_DEFAULTMAP_scalar); 14890 Loc = KindLoc; 14891 } 14892 Value += "'"; 14893 Diag(Loc, diag::err_omp_unexpected_clause_value) 14894 << Value << getOpenMPClauseName(OMPC_defaultmap); 14895 return nullptr; 14896 } 14897 DSAStack->setDefaultDMAToFromScalar(StartLoc); 14898 14899 return new (Context) 14900 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 14901 } 14902 14903 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 14904 DeclContext *CurLexicalContext = getCurLexicalContext(); 14905 if (!CurLexicalContext->isFileContext() && 14906 !CurLexicalContext->isExternCContext() && 14907 !CurLexicalContext->isExternCXXContext() && 14908 !isa<CXXRecordDecl>(CurLexicalContext) && 14909 !isa<ClassTemplateDecl>(CurLexicalContext) && 14910 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 14911 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 14912 Diag(Loc, diag::err_omp_region_not_file_context); 14913 return false; 14914 } 14915 ++DeclareTargetNestingLevel; 14916 return true; 14917 } 14918 14919 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 14920 assert(DeclareTargetNestingLevel > 0 && 14921 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 14922 --DeclareTargetNestingLevel; 14923 } 14924 14925 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 14926 CXXScopeSpec &ScopeSpec, 14927 const DeclarationNameInfo &Id, 14928 OMPDeclareTargetDeclAttr::MapTypeTy MT, 14929 NamedDeclSetType &SameDirectiveDecls) { 14930 LookupResult Lookup(*this, Id, LookupOrdinaryName); 14931 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 14932 14933 if (Lookup.isAmbiguous()) 14934 return; 14935 Lookup.suppressDiagnostics(); 14936 14937 if (!Lookup.isSingleResult()) { 14938 VarOrFuncDeclFilterCCC CCC(*this); 14939 if (TypoCorrection Corrected = 14940 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 14941 CTK_ErrorRecovery)) { 14942 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 14943 << Id.getName()); 14944 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 14945 return; 14946 } 14947 14948 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 14949 return; 14950 } 14951 14952 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 14953 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 14954 isa<FunctionTemplateDecl>(ND)) { 14955 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 14956 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 14957 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14958 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 14959 cast<ValueDecl>(ND)); 14960 if (!Res) { 14961 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 14962 ND->addAttr(A); 14963 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14964 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 14965 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 14966 } else if (*Res != MT) { 14967 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 14968 << Id.getName(); 14969 } 14970 } else { 14971 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 14972 } 14973 } 14974 14975 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 14976 Sema &SemaRef, Decl *D) { 14977 if (!D || !isa<VarDecl>(D)) 14978 return; 14979 auto *VD = cast<VarDecl>(D); 14980 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 14981 return; 14982 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 14983 SemaRef.Diag(SL, diag::note_used_here) << SR; 14984 } 14985 14986 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 14987 Sema &SemaRef, DSAStackTy *Stack, 14988 ValueDecl *VD) { 14989 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 14990 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 14991 /*FullCheck=*/false); 14992 } 14993 14994 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 14995 SourceLocation IdLoc) { 14996 if (!D || D->isInvalidDecl()) 14997 return; 14998 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 14999 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 15000 if (auto *VD = dyn_cast<VarDecl>(D)) { 15001 // Only global variables can be marked as declare target. 15002 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 15003 !VD->isStaticDataMember()) 15004 return; 15005 // 2.10.6: threadprivate variable cannot appear in a declare target 15006 // directive. 15007 if (DSAStack->isThreadPrivate(VD)) { 15008 Diag(SL, diag::err_omp_threadprivate_in_target); 15009 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 15010 return; 15011 } 15012 } 15013 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 15014 D = FTD->getTemplatedDecl(); 15015 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 15016 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15017 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 15018 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 15019 assert(IdLoc.isValid() && "Source location is expected"); 15020 Diag(IdLoc, diag::err_omp_function_in_link_clause); 15021 Diag(FD->getLocation(), diag::note_defined_here) << FD; 15022 return; 15023 } 15024 } 15025 if (auto *VD = dyn_cast<ValueDecl>(D)) { 15026 // Problem if any with var declared with incomplete type will be reported 15027 // as normal, so no need to check it here. 15028 if ((E || !VD->getType()->isIncompleteType()) && 15029 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 15030 return; 15031 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 15032 // Checking declaration inside declare target region. 15033 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 15034 isa<FunctionTemplateDecl>(D)) { 15035 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 15036 Context, OMPDeclareTargetDeclAttr::MT_To); 15037 D->addAttr(A); 15038 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15039 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 15040 } 15041 return; 15042 } 15043 } 15044 if (!E) 15045 return; 15046 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 15047 } 15048 15049 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15050 CXXScopeSpec &MapperIdScopeSpec, 15051 DeclarationNameInfo &MapperId, 15052 const OMPVarListLocTy &Locs, 15053 ArrayRef<Expr *> UnresolvedMappers) { 15054 MappableVarListInfo MVLI(VarList); 15055 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15056 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15057 if (MVLI.ProcessedVarList.empty()) 15058 return nullptr; 15059 15060 return OMPToClause::Create( 15061 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15062 MVLI.VarComponents, MVLI.UDMapperList, 15063 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15064 } 15065 15066 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15067 CXXScopeSpec &MapperIdScopeSpec, 15068 DeclarationNameInfo &MapperId, 15069 const OMPVarListLocTy &Locs, 15070 ArrayRef<Expr *> UnresolvedMappers) { 15071 MappableVarListInfo MVLI(VarList); 15072 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15073 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15074 if (MVLI.ProcessedVarList.empty()) 15075 return nullptr; 15076 15077 return OMPFromClause::Create( 15078 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15079 MVLI.VarComponents, MVLI.UDMapperList, 15080 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15081 } 15082 15083 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 15084 const OMPVarListLocTy &Locs) { 15085 MappableVarListInfo MVLI(VarList); 15086 SmallVector<Expr *, 8> PrivateCopies; 15087 SmallVector<Expr *, 8> Inits; 15088 15089 for (Expr *RefExpr : VarList) { 15090 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 15091 SourceLocation ELoc; 15092 SourceRange ERange; 15093 Expr *SimpleRefExpr = RefExpr; 15094 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15095 if (Res.second) { 15096 // It will be analyzed later. 15097 MVLI.ProcessedVarList.push_back(RefExpr); 15098 PrivateCopies.push_back(nullptr); 15099 Inits.push_back(nullptr); 15100 } 15101 ValueDecl *D = Res.first; 15102 if (!D) 15103 continue; 15104 15105 QualType Type = D->getType(); 15106 Type = Type.getNonReferenceType().getUnqualifiedType(); 15107 15108 auto *VD = dyn_cast<VarDecl>(D); 15109 15110 // Item should be a pointer or reference to pointer. 15111 if (!Type->isPointerType()) { 15112 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 15113 << 0 << RefExpr->getSourceRange(); 15114 continue; 15115 } 15116 15117 // Build the private variable and the expression that refers to it. 15118 auto VDPrivate = 15119 buildVarDecl(*this, ELoc, Type, D->getName(), 15120 D->hasAttrs() ? &D->getAttrs() : nullptr, 15121 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15122 if (VDPrivate->isInvalidDecl()) 15123 continue; 15124 15125 CurContext->addDecl(VDPrivate); 15126 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15127 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15128 15129 // Add temporary variable to initialize the private copy of the pointer. 15130 VarDecl *VDInit = 15131 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15132 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15133 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15134 AddInitializerToDecl(VDPrivate, 15135 DefaultLvalueConversion(VDInitRefExpr).get(), 15136 /*DirectInit=*/false); 15137 15138 // If required, build a capture to implement the privatization initialized 15139 // with the current list item value. 15140 DeclRefExpr *Ref = nullptr; 15141 if (!VD) 15142 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15143 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 15144 PrivateCopies.push_back(VDPrivateRefExpr); 15145 Inits.push_back(VDInitRefExpr); 15146 15147 // We need to add a data sharing attribute for this variable to make sure it 15148 // is correctly captured. A variable that shows up in a use_device_ptr has 15149 // similar properties of a first private variable. 15150 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15151 15152 // Create a mappable component for the list item. List items in this clause 15153 // only need a component. 15154 MVLI.VarBaseDeclarations.push_back(D); 15155 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15156 MVLI.VarComponents.back().push_back( 15157 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 15158 } 15159 15160 if (MVLI.ProcessedVarList.empty()) 15161 return nullptr; 15162 15163 return OMPUseDevicePtrClause::Create( 15164 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 15165 MVLI.VarBaseDeclarations, MVLI.VarComponents); 15166 } 15167 15168 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 15169 const OMPVarListLocTy &Locs) { 15170 MappableVarListInfo MVLI(VarList); 15171 for (Expr *RefExpr : VarList) { 15172 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 15173 SourceLocation ELoc; 15174 SourceRange ERange; 15175 Expr *SimpleRefExpr = RefExpr; 15176 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15177 if (Res.second) { 15178 // It will be analyzed later. 15179 MVLI.ProcessedVarList.push_back(RefExpr); 15180 } 15181 ValueDecl *D = Res.first; 15182 if (!D) 15183 continue; 15184 15185 QualType Type = D->getType(); 15186 // item should be a pointer or array or reference to pointer or array 15187 if (!Type.getNonReferenceType()->isPointerType() && 15188 !Type.getNonReferenceType()->isArrayType()) { 15189 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 15190 << 0 << RefExpr->getSourceRange(); 15191 continue; 15192 } 15193 15194 // Check if the declaration in the clause does not show up in any data 15195 // sharing attribute. 15196 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15197 if (isOpenMPPrivate(DVar.CKind)) { 15198 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15199 << getOpenMPClauseName(DVar.CKind) 15200 << getOpenMPClauseName(OMPC_is_device_ptr) 15201 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15202 reportOriginalDsa(*this, DSAStack, D, DVar); 15203 continue; 15204 } 15205 15206 const Expr *ConflictExpr; 15207 if (DSAStack->checkMappableExprComponentListsForDecl( 15208 D, /*CurrentRegionOnly=*/true, 15209 [&ConflictExpr]( 15210 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 15211 OpenMPClauseKind) -> bool { 15212 ConflictExpr = R.front().getAssociatedExpression(); 15213 return true; 15214 })) { 15215 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 15216 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 15217 << ConflictExpr->getSourceRange(); 15218 continue; 15219 } 15220 15221 // Store the components in the stack so that they can be used to check 15222 // against other clauses later on. 15223 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 15224 DSAStack->addMappableExpressionComponents( 15225 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 15226 15227 // Record the expression we've just processed. 15228 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 15229 15230 // Create a mappable component for the list item. List items in this clause 15231 // only need a component. We use a null declaration to signal fields in 15232 // 'this'. 15233 assert((isa<DeclRefExpr>(SimpleRefExpr) || 15234 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 15235 "Unexpected device pointer expression!"); 15236 MVLI.VarBaseDeclarations.push_back( 15237 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 15238 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15239 MVLI.VarComponents.back().push_back(MC); 15240 } 15241 15242 if (MVLI.ProcessedVarList.empty()) 15243 return nullptr; 15244 15245 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 15246 MVLI.VarBaseDeclarations, 15247 MVLI.VarComponents); 15248 } 15249 15250 OMPClause *Sema::ActOnOpenMPAllocateClause( 15251 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15252 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15253 if (Allocator) { 15254 // OpenMP [2.11.4 allocate Clause, Description] 15255 // allocator is an expression of omp_allocator_handle_t type. 15256 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15257 return nullptr; 15258 15259 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15260 if (AllocatorRes.isInvalid()) 15261 return nullptr; 15262 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15263 DSAStack->getOMPAllocatorHandleT(), 15264 Sema::AA_Initializing, 15265 /*AllowExplicit=*/true); 15266 if (AllocatorRes.isInvalid()) 15267 return nullptr; 15268 Allocator = AllocatorRes.get(); 15269 } else { 15270 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15271 // allocate clauses that appear on a target construct or on constructs in a 15272 // target region must specify an allocator expression unless a requires 15273 // directive with the dynamic_allocators clause is present in the same 15274 // compilation unit. 15275 if (LangOpts.OpenMPIsDevice && 15276 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15277 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15278 } 15279 // Analyze and build list of variables. 15280 SmallVector<Expr *, 8> Vars; 15281 for (Expr *RefExpr : VarList) { 15282 assert(RefExpr && "NULL expr in OpenMP private clause."); 15283 SourceLocation ELoc; 15284 SourceRange ERange; 15285 Expr *SimpleRefExpr = RefExpr; 15286 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15287 if (Res.second) { 15288 // It will be analyzed later. 15289 Vars.push_back(RefExpr); 15290 } 15291 ValueDecl *D = Res.first; 15292 if (!D) 15293 continue; 15294 15295 auto *VD = dyn_cast<VarDecl>(D); 15296 DeclRefExpr *Ref = nullptr; 15297 if (!VD && !CurContext->isDependentContext()) 15298 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15299 Vars.push_back((VD || CurContext->isDependentContext()) 15300 ? RefExpr->IgnoreParens() 15301 : Ref); 15302 } 15303 15304 if (Vars.empty()) 15305 return nullptr; 15306 15307 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15308 ColonLoc, EndLoc, Vars); 15309 } 15310