1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 bool HasMutipleLoops = false; 143 const Decl *PossiblyLoopCounter = nullptr; 144 bool NowaitRegion = false; 145 bool CancelRegion = false; 146 bool LoopStart = false; 147 bool BodyComplete = false; 148 SourceLocation InnerTeamsRegionLoc; 149 /// Reference to the taskgroup task_reduction reference expression. 150 Expr *TaskgroupReductionRef = nullptr; 151 llvm::DenseSet<QualType> MappedClassesQualTypes; 152 /// List of globals marked as declare target link in this target region 153 /// (isOpenMPTargetExecutionDirective(Directive) == true). 154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 156 Scope *CurScope, SourceLocation Loc) 157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 158 ConstructLoc(Loc) {} 159 SharingMapTy() = default; 160 }; 161 162 using StackTy = SmallVector<SharingMapTy, 4>; 163 164 /// Stack of used declaration and their data-sharing attributes. 165 DeclSAMapTy Threadprivates; 166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 168 /// true, if check for DSA must be from parent directive, false, if 169 /// from current directive. 170 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 171 Sema &SemaRef; 172 bool ForceCapturing = false; 173 /// true if all the vaiables in the target executable directives must be 174 /// captured by reference. 175 bool ForceCaptureByReferenceInTargetExecutable = false; 176 CriticalsWithHintsTy Criticals; 177 unsigned IgnoredStackElements = 0; 178 179 /// Iterators over the stack iterate in order from innermost to outermost 180 /// directive. 181 using const_iterator = StackTy::const_reverse_iterator; 182 const_iterator begin() const { 183 return Stack.empty() ? const_iterator() 184 : Stack.back().first.rbegin() + IgnoredStackElements; 185 } 186 const_iterator end() const { 187 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 188 } 189 using iterator = StackTy::reverse_iterator; 190 iterator begin() { 191 return Stack.empty() ? iterator() 192 : Stack.back().first.rbegin() + IgnoredStackElements; 193 } 194 iterator end() { 195 return Stack.empty() ? iterator() : Stack.back().first.rend(); 196 } 197 198 // Convenience operations to get at the elements of the stack. 199 200 bool isStackEmpty() const { 201 return Stack.empty() || 202 Stack.back().second != CurrentNonCapturingFunctionScope || 203 Stack.back().first.size() <= IgnoredStackElements; 204 } 205 size_t getStackSize() const { 206 return isStackEmpty() ? 0 207 : Stack.back().first.size() - IgnoredStackElements; 208 } 209 210 SharingMapTy *getTopOfStackOrNull() { 211 size_t Size = getStackSize(); 212 if (Size == 0) 213 return nullptr; 214 return &Stack.back().first[Size - 1]; 215 } 216 const SharingMapTy *getTopOfStackOrNull() const { 217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 218 } 219 SharingMapTy &getTopOfStack() { 220 assert(!isStackEmpty() && "no current directive"); 221 return *getTopOfStackOrNull(); 222 } 223 const SharingMapTy &getTopOfStack() const { 224 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 225 } 226 227 SharingMapTy *getSecondOnStackOrNull() { 228 size_t Size = getStackSize(); 229 if (Size <= 1) 230 return nullptr; 231 return &Stack.back().first[Size - 2]; 232 } 233 const SharingMapTy *getSecondOnStackOrNull() const { 234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 235 } 236 237 /// Get the stack element at a certain level (previously returned by 238 /// \c getNestingLevel). 239 /// 240 /// Note that nesting levels count from outermost to innermost, and this is 241 /// the reverse of our iteration order where new inner levels are pushed at 242 /// the front of the stack. 243 SharingMapTy &getStackElemAtLevel(unsigned Level) { 244 assert(Level < getStackSize() && "no such stack element"); 245 return Stack.back().first[Level]; 246 } 247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 249 } 250 251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 252 253 /// Checks if the variable is a local for OpenMP region. 254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 255 256 /// Vector of previously declared requires directives 257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 258 /// omp_allocator_handle_t type. 259 QualType OMPAllocatorHandleT; 260 /// Expression for the predefined allocators. 261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 262 nullptr}; 263 /// Vector of previously encountered target directives 264 SmallVector<SourceLocation, 2> TargetLocations; 265 266 public: 267 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 268 269 /// Sets omp_allocator_handle_t type. 270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 271 /// Gets omp_allocator_handle_t type. 272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 273 /// Sets the given default allocator. 274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 275 Expr *Allocator) { 276 OMPPredefinedAllocators[AllocatorKind] = Allocator; 277 } 278 /// Returns the specified default allocator. 279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 280 return OMPPredefinedAllocators[AllocatorKind]; 281 } 282 283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 284 OpenMPClauseKind getClauseParsingMode() const { 285 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 286 return ClauseKindMode; 287 } 288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 289 290 bool isBodyComplete() const { 291 const SharingMapTy *Top = getTopOfStackOrNull(); 292 return Top && Top->BodyComplete; 293 } 294 void setBodyComplete() { 295 getTopOfStack().BodyComplete = true; 296 } 297 298 bool isForceVarCapturing() const { return ForceCapturing; } 299 void setForceVarCapturing(bool V) { ForceCapturing = V; } 300 301 void setForceCaptureByReferenceInTargetExecutable(bool V) { 302 ForceCaptureByReferenceInTargetExecutable = V; 303 } 304 bool isForceCaptureByReferenceInTargetExecutable() const { 305 return ForceCaptureByReferenceInTargetExecutable; 306 } 307 308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 309 Scope *CurScope, SourceLocation Loc) { 310 assert(!IgnoredStackElements && 311 "cannot change stack while ignoring elements"); 312 if (Stack.empty() || 313 Stack.back().second != CurrentNonCapturingFunctionScope) 314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 316 Stack.back().first.back().DefaultAttrLoc = Loc; 317 } 318 319 void pop() { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 assert(!Stack.back().first.empty() && 323 "Data-sharing attributes stack is empty!"); 324 Stack.back().first.pop_back(); 325 } 326 327 /// RAII object to temporarily leave the scope of a directive when we want to 328 /// logically operate in its parent. 329 class ParentDirectiveScope { 330 DSAStackTy &Self; 331 bool Active; 332 public: 333 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 334 : Self(Self), Active(false) { 335 if (Activate) 336 enable(); 337 } 338 ~ParentDirectiveScope() { disable(); } 339 void disable() { 340 if (Active) { 341 --Self.IgnoredStackElements; 342 Active = false; 343 } 344 } 345 void enable() { 346 if (!Active) { 347 ++Self.IgnoredStackElements; 348 Active = true; 349 } 350 } 351 }; 352 353 /// Marks that we're started loop parsing. 354 void loopInit() { 355 assert(isOpenMPLoopDirective(getCurrentDirective()) && 356 "Expected loop-based directive."); 357 getTopOfStack().LoopStart = true; 358 } 359 /// Start capturing of the variables in the loop context. 360 void loopStart() { 361 assert(isOpenMPLoopDirective(getCurrentDirective()) && 362 "Expected loop-based directive."); 363 getTopOfStack().LoopStart = false; 364 } 365 /// true, if variables are captured, false otherwise. 366 bool isLoopStarted() const { 367 assert(isOpenMPLoopDirective(getCurrentDirective()) && 368 "Expected loop-based directive."); 369 return !getTopOfStack().LoopStart; 370 } 371 /// Marks (or clears) declaration as possibly loop counter. 372 void resetPossibleLoopCounter(const Decl *D = nullptr) { 373 getTopOfStack().PossiblyLoopCounter = 374 D ? D->getCanonicalDecl() : D; 375 } 376 /// Gets the possible loop counter decl. 377 const Decl *getPossiblyLoopCunter() const { 378 return getTopOfStack().PossiblyLoopCounter; 379 } 380 /// Start new OpenMP region stack in new non-capturing function. 381 void pushFunction() { 382 assert(!IgnoredStackElements && 383 "cannot change stack while ignoring elements"); 384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 385 assert(!isa<CapturingScopeInfo>(CurFnScope)); 386 CurrentNonCapturingFunctionScope = CurFnScope; 387 } 388 /// Pop region stack for non-capturing function. 389 void popFunction(const FunctionScopeInfo *OldFSI) { 390 assert(!IgnoredStackElements && 391 "cannot change stack while ignoring elements"); 392 if (!Stack.empty() && Stack.back().second == OldFSI) { 393 assert(Stack.back().first.empty()); 394 Stack.pop_back(); 395 } 396 CurrentNonCapturingFunctionScope = nullptr; 397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 398 if (!isa<CapturingScopeInfo>(FSI)) { 399 CurrentNonCapturingFunctionScope = FSI; 400 break; 401 } 402 } 403 } 404 405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 407 } 408 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 409 getCriticalWithHint(const DeclarationNameInfo &Name) const { 410 auto I = Criticals.find(Name.getAsString()); 411 if (I != Criticals.end()) 412 return I->second; 413 return std::make_pair(nullptr, llvm::APSInt()); 414 } 415 /// If 'aligned' declaration for given variable \a D was not seen yet, 416 /// add it and return NULL; otherwise return previous occurrence's expression 417 /// for diagnostics. 418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 419 420 /// Register specified variable as loop control variable. 421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 422 /// Check if the specified variable is a loop control variable for 423 /// current region. 424 /// \return The index of the loop control variable in the list of associated 425 /// for-loops (from outer to inner). 426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 427 /// Check if the specified variable is a loop control variable for 428 /// parent region. 429 /// \return The index of the loop control variable in the list of associated 430 /// for-loops (from outer to inner). 431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 432 /// Get the loop control variable for the I-th loop (or nullptr) in 433 /// parent directive. 434 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 435 436 /// Adds explicit data sharing attribute to the specified declaration. 437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 438 DeclRefExpr *PrivateCopy = nullptr); 439 440 /// Adds additional information for the reduction items with the reduction id 441 /// represented as an operator. 442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 443 BinaryOperatorKind BOK); 444 /// Adds additional information for the reduction items with the reduction id 445 /// represented as reduction identifier. 446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 447 const Expr *ReductionRef); 448 /// Returns the location and reduction operation from the innermost parent 449 /// region for the given \p D. 450 const DSAVarData 451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 452 BinaryOperatorKind &BOK, 453 Expr *&TaskgroupDescriptor) const; 454 /// Returns the location and reduction operation from the innermost parent 455 /// region for the given \p D. 456 const DSAVarData 457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 458 const Expr *&ReductionRef, 459 Expr *&TaskgroupDescriptor) const; 460 /// Return reduction reference expression for the current taskgroup. 461 Expr *getTaskgroupReductionRef() const { 462 assert(getTopOfStack().Directive == OMPD_taskgroup && 463 "taskgroup reference expression requested for non taskgroup " 464 "directive."); 465 return getTopOfStack().TaskgroupReductionRef; 466 } 467 /// Checks if the given \p VD declaration is actually a taskgroup reduction 468 /// descriptor variable at the \p Level of OpenMP regions. 469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 470 return getStackElemAtLevel(Level).TaskgroupReductionRef && 471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 472 ->getDecl() == VD; 473 } 474 475 /// Returns data sharing attributes from top of the stack for the 476 /// specified declaration. 477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 478 /// Returns data-sharing attributes for the specified declaration. 479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 480 /// Checks if the specified variables has data-sharing attributes which 481 /// match specified \a CPred predicate in any directive which matches \a DPred 482 /// predicate. 483 const DSAVarData 484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 486 bool FromParent) const; 487 /// Checks if the specified variables has data-sharing attributes which 488 /// match specified \a CPred predicate in any innermost directive which 489 /// matches \a DPred predicate. 490 const DSAVarData 491 hasInnermostDSA(ValueDecl *D, 492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 494 bool FromParent) const; 495 /// Checks if the specified variables has explicit data-sharing 496 /// attributes which match specified \a CPred predicate at the specified 497 /// OpenMP region. 498 bool hasExplicitDSA(const ValueDecl *D, 499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 500 unsigned Level, bool NotLastprivate = false) const; 501 502 /// Returns true if the directive at level \Level matches in the 503 /// specified \a DPred predicate. 504 bool hasExplicitDirective( 505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 506 unsigned Level) const; 507 508 /// Finds a directive which matches specified \a DPred predicate. 509 bool hasDirective( 510 const llvm::function_ref<bool( 511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 512 DPred, 513 bool FromParent) const; 514 515 /// Returns currently analyzed directive. 516 OpenMPDirectiveKind getCurrentDirective() const { 517 const SharingMapTy *Top = getTopOfStackOrNull(); 518 return Top ? Top->Directive : OMPD_unknown; 519 } 520 /// Returns directive kind at specified level. 521 OpenMPDirectiveKind getDirective(unsigned Level) const { 522 assert(!isStackEmpty() && "No directive at specified level."); 523 return getStackElemAtLevel(Level).Directive; 524 } 525 /// Returns the capture region at the specified level. 526 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 527 unsigned OpenMPCaptureLevel) const { 528 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 529 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 530 return CaptureRegions[OpenMPCaptureLevel]; 531 } 532 /// Returns parent directive. 533 OpenMPDirectiveKind getParentDirective() const { 534 const SharingMapTy *Parent = getSecondOnStackOrNull(); 535 return Parent ? Parent->Directive : OMPD_unknown; 536 } 537 538 /// Add requires decl to internal vector 539 void addRequiresDecl(OMPRequiresDecl *RD) { 540 RequiresDecls.push_back(RD); 541 } 542 543 /// Checks if the defined 'requires' directive has specified type of clause. 544 template <typename ClauseType> 545 bool hasRequiresDeclWithClause() { 546 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 547 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 548 return isa<ClauseType>(C); 549 }); 550 }); 551 } 552 553 /// Checks for a duplicate clause amongst previously declared requires 554 /// directives 555 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 556 bool IsDuplicate = false; 557 for (OMPClause *CNew : ClauseList) { 558 for (const OMPRequiresDecl *D : RequiresDecls) { 559 for (const OMPClause *CPrev : D->clauselists()) { 560 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 561 SemaRef.Diag(CNew->getBeginLoc(), 562 diag::err_omp_requires_clause_redeclaration) 563 << getOpenMPClauseName(CNew->getClauseKind()); 564 SemaRef.Diag(CPrev->getBeginLoc(), 565 diag::note_omp_requires_previous_clause) 566 << getOpenMPClauseName(CPrev->getClauseKind()); 567 IsDuplicate = true; 568 } 569 } 570 } 571 } 572 return IsDuplicate; 573 } 574 575 /// Add location of previously encountered target to internal vector 576 void addTargetDirLocation(SourceLocation LocStart) { 577 TargetLocations.push_back(LocStart); 578 } 579 580 // Return previously encountered target region locations. 581 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 582 return TargetLocations; 583 } 584 585 /// Set default data sharing attribute to none. 586 void setDefaultDSANone(SourceLocation Loc) { 587 getTopOfStack().DefaultAttr = DSA_none; 588 getTopOfStack().DefaultAttrLoc = Loc; 589 } 590 /// Set default data sharing attribute to shared. 591 void setDefaultDSAShared(SourceLocation Loc) { 592 getTopOfStack().DefaultAttr = DSA_shared; 593 getTopOfStack().DefaultAttrLoc = Loc; 594 } 595 /// Set default data mapping attribute to 'tofrom:scalar'. 596 void setDefaultDMAToFromScalar(SourceLocation Loc) { 597 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 598 getTopOfStack().DefaultMapAttrLoc = Loc; 599 } 600 601 DefaultDataSharingAttributes getDefaultDSA() const { 602 return isStackEmpty() ? DSA_unspecified 603 : getTopOfStack().DefaultAttr; 604 } 605 SourceLocation getDefaultDSALocation() const { 606 return isStackEmpty() ? SourceLocation() 607 : getTopOfStack().DefaultAttrLoc; 608 } 609 DefaultMapAttributes getDefaultDMA() const { 610 return isStackEmpty() ? DMA_unspecified 611 : getTopOfStack().DefaultMapAttr; 612 } 613 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 614 return getStackElemAtLevel(Level).DefaultMapAttr; 615 } 616 SourceLocation getDefaultDMALocation() const { 617 return isStackEmpty() ? SourceLocation() 618 : getTopOfStack().DefaultMapAttrLoc; 619 } 620 621 /// Checks if the specified variable is a threadprivate. 622 bool isThreadPrivate(VarDecl *D) { 623 const DSAVarData DVar = getTopDSA(D, false); 624 return isOpenMPThreadPrivate(DVar.CKind); 625 } 626 627 /// Marks current region as ordered (it has an 'ordered' clause). 628 void setOrderedRegion(bool IsOrdered, const Expr *Param, 629 OMPOrderedClause *Clause) { 630 if (IsOrdered) 631 getTopOfStack().OrderedRegion.emplace(Param, Clause); 632 else 633 getTopOfStack().OrderedRegion.reset(); 634 } 635 /// Returns true, if region is ordered (has associated 'ordered' clause), 636 /// false - otherwise. 637 bool isOrderedRegion() const { 638 if (const SharingMapTy *Top = getTopOfStackOrNull()) 639 return Top->OrderedRegion.hasValue(); 640 return false; 641 } 642 /// Returns optional parameter for the ordered region. 643 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 644 if (const SharingMapTy *Top = getTopOfStackOrNull()) 645 if (Top->OrderedRegion.hasValue()) 646 return Top->OrderedRegion.getValue(); 647 return std::make_pair(nullptr, nullptr); 648 } 649 /// Returns true, if parent region is ordered (has associated 650 /// 'ordered' clause), false - otherwise. 651 bool isParentOrderedRegion() const { 652 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 653 return Parent->OrderedRegion.hasValue(); 654 return false; 655 } 656 /// Returns optional parameter for the ordered region. 657 std::pair<const Expr *, OMPOrderedClause *> 658 getParentOrderedRegionParam() const { 659 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 660 if (Parent->OrderedRegion.hasValue()) 661 return Parent->OrderedRegion.getValue(); 662 return std::make_pair(nullptr, nullptr); 663 } 664 /// Marks current region as nowait (it has a 'nowait' clause). 665 void setNowaitRegion(bool IsNowait = true) { 666 getTopOfStack().NowaitRegion = IsNowait; 667 } 668 /// Returns true, if parent region is nowait (has associated 669 /// 'nowait' clause), false - otherwise. 670 bool isParentNowaitRegion() const { 671 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 672 return Parent->NowaitRegion; 673 return false; 674 } 675 /// Marks parent region as cancel region. 676 void setParentCancelRegion(bool Cancel = true) { 677 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 678 Parent->CancelRegion |= Cancel; 679 } 680 /// Return true if current region has inner cancel construct. 681 bool isCancelRegion() const { 682 const SharingMapTy *Top = getTopOfStackOrNull(); 683 return Top ? Top->CancelRegion : false; 684 } 685 686 /// Set collapse value for the region. 687 void setAssociatedLoops(unsigned Val) { 688 getTopOfStack().AssociatedLoops = Val; 689 if (Val > 1) 690 getTopOfStack().HasMutipleLoops = true; 691 } 692 /// Return collapse value for region. 693 unsigned getAssociatedLoops() const { 694 const SharingMapTy *Top = getTopOfStackOrNull(); 695 return Top ? Top->AssociatedLoops : 0; 696 } 697 /// Returns true if the construct is associated with multiple loops. 698 bool hasMutipleLoops() const { 699 const SharingMapTy *Top = getTopOfStackOrNull(); 700 return Top ? Top->HasMutipleLoops : false; 701 } 702 703 /// Marks current target region as one with closely nested teams 704 /// region. 705 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 706 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 707 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 708 } 709 /// Returns true, if current region has closely nested teams region. 710 bool hasInnerTeamsRegion() const { 711 return getInnerTeamsRegionLoc().isValid(); 712 } 713 /// Returns location of the nested teams region (if any). 714 SourceLocation getInnerTeamsRegionLoc() const { 715 const SharingMapTy *Top = getTopOfStackOrNull(); 716 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 717 } 718 719 Scope *getCurScope() const { 720 const SharingMapTy *Top = getTopOfStackOrNull(); 721 return Top ? Top->CurScope : nullptr; 722 } 723 SourceLocation getConstructLoc() const { 724 const SharingMapTy *Top = getTopOfStackOrNull(); 725 return Top ? Top->ConstructLoc : SourceLocation(); 726 } 727 728 /// Do the check specified in \a Check to all component lists and return true 729 /// if any issue is found. 730 bool checkMappableExprComponentListsForDecl( 731 const ValueDecl *VD, bool CurrentRegionOnly, 732 const llvm::function_ref< 733 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 734 OpenMPClauseKind)> 735 Check) const { 736 if (isStackEmpty()) 737 return false; 738 auto SI = begin(); 739 auto SE = end(); 740 741 if (SI == SE) 742 return false; 743 744 if (CurrentRegionOnly) 745 SE = std::next(SI); 746 else 747 std::advance(SI, 1); 748 749 for (; SI != SE; ++SI) { 750 auto MI = SI->MappedExprComponents.find(VD); 751 if (MI != SI->MappedExprComponents.end()) 752 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 753 MI->second.Components) 754 if (Check(L, MI->second.Kind)) 755 return true; 756 } 757 return false; 758 } 759 760 /// Do the check specified in \a Check to all component lists at a given level 761 /// and return true if any issue is found. 762 bool checkMappableExprComponentListsForDeclAtLevel( 763 const ValueDecl *VD, unsigned Level, 764 const llvm::function_ref< 765 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 766 OpenMPClauseKind)> 767 Check) const { 768 if (getStackSize() <= Level) 769 return false; 770 771 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 772 auto MI = StackElem.MappedExprComponents.find(VD); 773 if (MI != StackElem.MappedExprComponents.end()) 774 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 775 MI->second.Components) 776 if (Check(L, MI->second.Kind)) 777 return true; 778 return false; 779 } 780 781 /// Create a new mappable expression component list associated with a given 782 /// declaration and initialize it with the provided list of components. 783 void addMappableExpressionComponents( 784 const ValueDecl *VD, 785 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 786 OpenMPClauseKind WhereFoundClauseKind) { 787 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 788 // Create new entry and append the new components there. 789 MEC.Components.resize(MEC.Components.size() + 1); 790 MEC.Components.back().append(Components.begin(), Components.end()); 791 MEC.Kind = WhereFoundClauseKind; 792 } 793 794 unsigned getNestingLevel() const { 795 assert(!isStackEmpty()); 796 return getStackSize() - 1; 797 } 798 void addDoacrossDependClause(OMPDependClause *C, 799 const OperatorOffsetTy &OpsOffs) { 800 SharingMapTy *Parent = getSecondOnStackOrNull(); 801 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 802 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 803 } 804 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 805 getDoacrossDependClauses() const { 806 const SharingMapTy &StackElem = getTopOfStack(); 807 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 808 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 809 return llvm::make_range(Ref.begin(), Ref.end()); 810 } 811 return llvm::make_range(StackElem.DoacrossDepends.end(), 812 StackElem.DoacrossDepends.end()); 813 } 814 815 // Store types of classes which have been explicitly mapped 816 void addMappedClassesQualTypes(QualType QT) { 817 SharingMapTy &StackElem = getTopOfStack(); 818 StackElem.MappedClassesQualTypes.insert(QT); 819 } 820 821 // Return set of mapped classes types 822 bool isClassPreviouslyMapped(QualType QT) const { 823 const SharingMapTy &StackElem = getTopOfStack(); 824 return StackElem.MappedClassesQualTypes.count(QT) != 0; 825 } 826 827 /// Adds global declare target to the parent target region. 828 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 829 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 830 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 831 "Expected declare target link global."); 832 for (auto &Elem : *this) { 833 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 834 Elem.DeclareTargetLinkVarDecls.push_back(E); 835 return; 836 } 837 } 838 } 839 840 /// Returns the list of globals with declare target link if current directive 841 /// is target. 842 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 843 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 844 "Expected target executable directive."); 845 return getTopOfStack().DeclareTargetLinkVarDecls; 846 } 847 }; 848 849 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 850 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 851 } 852 853 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 854 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 855 DKind == OMPD_unknown; 856 } 857 858 } // namespace 859 860 static const Expr *getExprAsWritten(const Expr *E) { 861 if (const auto *FE = dyn_cast<FullExpr>(E)) 862 E = FE->getSubExpr(); 863 864 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 865 E = MTE->GetTemporaryExpr(); 866 867 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 868 E = Binder->getSubExpr(); 869 870 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 871 E = ICE->getSubExprAsWritten(); 872 return E->IgnoreParens(); 873 } 874 875 static Expr *getExprAsWritten(Expr *E) { 876 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 877 } 878 879 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 880 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 881 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 882 D = ME->getMemberDecl(); 883 const auto *VD = dyn_cast<VarDecl>(D); 884 const auto *FD = dyn_cast<FieldDecl>(D); 885 if (VD != nullptr) { 886 VD = VD->getCanonicalDecl(); 887 D = VD; 888 } else { 889 assert(FD); 890 FD = FD->getCanonicalDecl(); 891 D = FD; 892 } 893 return D; 894 } 895 896 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 897 return const_cast<ValueDecl *>( 898 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 899 } 900 901 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 902 ValueDecl *D) const { 903 D = getCanonicalDecl(D); 904 auto *VD = dyn_cast<VarDecl>(D); 905 const auto *FD = dyn_cast<FieldDecl>(D); 906 DSAVarData DVar; 907 if (Iter == end()) { 908 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 909 // in a region but not in construct] 910 // File-scope or namespace-scope variables referenced in called routines 911 // in the region are shared unless they appear in a threadprivate 912 // directive. 913 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 914 DVar.CKind = OMPC_shared; 915 916 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 917 // in a region but not in construct] 918 // Variables with static storage duration that are declared in called 919 // routines in the region are shared. 920 if (VD && VD->hasGlobalStorage()) 921 DVar.CKind = OMPC_shared; 922 923 // Non-static data members are shared by default. 924 if (FD) 925 DVar.CKind = OMPC_shared; 926 927 return DVar; 928 } 929 930 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 931 // in a Construct, C/C++, predetermined, p.1] 932 // Variables with automatic storage duration that are declared in a scope 933 // inside the construct are private. 934 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 935 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 936 DVar.CKind = OMPC_private; 937 return DVar; 938 } 939 940 DVar.DKind = Iter->Directive; 941 // Explicitly specified attributes and local variables with predetermined 942 // attributes. 943 if (Iter->SharingMap.count(D)) { 944 const DSAInfo &Data = Iter->SharingMap.lookup(D); 945 DVar.RefExpr = Data.RefExpr.getPointer(); 946 DVar.PrivateCopy = Data.PrivateCopy; 947 DVar.CKind = Data.Attributes; 948 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 949 return DVar; 950 } 951 952 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 953 // in a Construct, C/C++, implicitly determined, p.1] 954 // In a parallel or task construct, the data-sharing attributes of these 955 // variables are determined by the default clause, if present. 956 switch (Iter->DefaultAttr) { 957 case DSA_shared: 958 DVar.CKind = OMPC_shared; 959 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 960 return DVar; 961 case DSA_none: 962 return DVar; 963 case DSA_unspecified: 964 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 965 // in a Construct, implicitly determined, p.2] 966 // In a parallel construct, if no default clause is present, these 967 // variables are shared. 968 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 969 if (isOpenMPParallelDirective(DVar.DKind) || 970 isOpenMPTeamsDirective(DVar.DKind)) { 971 DVar.CKind = OMPC_shared; 972 return DVar; 973 } 974 975 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 976 // in a Construct, implicitly determined, p.4] 977 // In a task construct, if no default clause is present, a variable that in 978 // the enclosing context is determined to be shared by all implicit tasks 979 // bound to the current team is shared. 980 if (isOpenMPTaskingDirective(DVar.DKind)) { 981 DSAVarData DVarTemp; 982 const_iterator I = Iter, E = end(); 983 do { 984 ++I; 985 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 986 // Referenced in a Construct, implicitly determined, p.6] 987 // In a task construct, if no default clause is present, a variable 988 // whose data-sharing attribute is not determined by the rules above is 989 // firstprivate. 990 DVarTemp = getDSA(I, D); 991 if (DVarTemp.CKind != OMPC_shared) { 992 DVar.RefExpr = nullptr; 993 DVar.CKind = OMPC_firstprivate; 994 return DVar; 995 } 996 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 997 DVar.CKind = 998 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 999 return DVar; 1000 } 1001 } 1002 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1003 // in a Construct, implicitly determined, p.3] 1004 // For constructs other than task, if no default clause is present, these 1005 // variables inherit their data-sharing attributes from the enclosing 1006 // context. 1007 return getDSA(++Iter, D); 1008 } 1009 1010 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1011 const Expr *NewDE) { 1012 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1013 D = getCanonicalDecl(D); 1014 SharingMapTy &StackElem = getTopOfStack(); 1015 auto It = StackElem.AlignedMap.find(D); 1016 if (It == StackElem.AlignedMap.end()) { 1017 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1018 StackElem.AlignedMap[D] = NewDE; 1019 return nullptr; 1020 } 1021 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1022 return It->second; 1023 } 1024 1025 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1026 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1027 D = getCanonicalDecl(D); 1028 SharingMapTy &StackElem = getTopOfStack(); 1029 StackElem.LCVMap.try_emplace( 1030 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1031 } 1032 1033 const DSAStackTy::LCDeclInfo 1034 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1035 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1036 D = getCanonicalDecl(D); 1037 const SharingMapTy &StackElem = getTopOfStack(); 1038 auto It = StackElem.LCVMap.find(D); 1039 if (It != StackElem.LCVMap.end()) 1040 return It->second; 1041 return {0, nullptr}; 1042 } 1043 1044 const DSAStackTy::LCDeclInfo 1045 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1046 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1047 assert(Parent && "Data-sharing attributes stack is empty"); 1048 D = getCanonicalDecl(D); 1049 auto It = Parent->LCVMap.find(D); 1050 if (It != Parent->LCVMap.end()) 1051 return It->second; 1052 return {0, nullptr}; 1053 } 1054 1055 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1056 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1057 assert(Parent && "Data-sharing attributes stack is empty"); 1058 if (Parent->LCVMap.size() < I) 1059 return nullptr; 1060 for (const auto &Pair : Parent->LCVMap) 1061 if (Pair.second.first == I) 1062 return Pair.first; 1063 return nullptr; 1064 } 1065 1066 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1067 DeclRefExpr *PrivateCopy) { 1068 D = getCanonicalDecl(D); 1069 if (A == OMPC_threadprivate) { 1070 DSAInfo &Data = Threadprivates[D]; 1071 Data.Attributes = A; 1072 Data.RefExpr.setPointer(E); 1073 Data.PrivateCopy = nullptr; 1074 } else { 1075 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1076 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1077 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1078 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1079 (isLoopControlVariable(D).first && A == OMPC_private)); 1080 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1081 Data.RefExpr.setInt(/*IntVal=*/true); 1082 return; 1083 } 1084 const bool IsLastprivate = 1085 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1086 Data.Attributes = A; 1087 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1088 Data.PrivateCopy = PrivateCopy; 1089 if (PrivateCopy) { 1090 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1091 Data.Attributes = A; 1092 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1093 Data.PrivateCopy = nullptr; 1094 } 1095 } 1096 } 1097 1098 /// Build a variable declaration for OpenMP loop iteration variable. 1099 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1100 StringRef Name, const AttrVec *Attrs = nullptr, 1101 DeclRefExpr *OrigRef = nullptr) { 1102 DeclContext *DC = SemaRef.CurContext; 1103 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1104 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1105 auto *Decl = 1106 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1107 if (Attrs) { 1108 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1109 I != E; ++I) 1110 Decl->addAttr(*I); 1111 } 1112 Decl->setImplicit(); 1113 if (OrigRef) { 1114 Decl->addAttr( 1115 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1116 } 1117 return Decl; 1118 } 1119 1120 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1121 SourceLocation Loc, 1122 bool RefersToCapture = false) { 1123 D->setReferenced(); 1124 D->markUsed(S.Context); 1125 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1126 SourceLocation(), D, RefersToCapture, Loc, Ty, 1127 VK_LValue); 1128 } 1129 1130 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1131 BinaryOperatorKind BOK) { 1132 D = getCanonicalDecl(D); 1133 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1134 assert( 1135 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1136 "Additional reduction info may be specified only for reduction items."); 1137 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1138 assert(ReductionData.ReductionRange.isInvalid() && 1139 getTopOfStack().Directive == OMPD_taskgroup && 1140 "Additional reduction info may be specified only once for reduction " 1141 "items."); 1142 ReductionData.set(BOK, SR); 1143 Expr *&TaskgroupReductionRef = 1144 getTopOfStack().TaskgroupReductionRef; 1145 if (!TaskgroupReductionRef) { 1146 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1147 SemaRef.Context.VoidPtrTy, ".task_red."); 1148 TaskgroupReductionRef = 1149 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1150 } 1151 } 1152 1153 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1154 const Expr *ReductionRef) { 1155 D = getCanonicalDecl(D); 1156 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1157 assert( 1158 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1159 "Additional reduction info may be specified only for reduction items."); 1160 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1161 assert(ReductionData.ReductionRange.isInvalid() && 1162 getTopOfStack().Directive == OMPD_taskgroup && 1163 "Additional reduction info may be specified only once for reduction " 1164 "items."); 1165 ReductionData.set(ReductionRef, SR); 1166 Expr *&TaskgroupReductionRef = 1167 getTopOfStack().TaskgroupReductionRef; 1168 if (!TaskgroupReductionRef) { 1169 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1170 SemaRef.Context.VoidPtrTy, ".task_red."); 1171 TaskgroupReductionRef = 1172 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1173 } 1174 } 1175 1176 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1177 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1178 Expr *&TaskgroupDescriptor) const { 1179 D = getCanonicalDecl(D); 1180 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1181 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1182 const DSAInfo &Data = I->SharingMap.lookup(D); 1183 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1184 continue; 1185 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1186 if (!ReductionData.ReductionOp || 1187 ReductionData.ReductionOp.is<const Expr *>()) 1188 return DSAVarData(); 1189 SR = ReductionData.ReductionRange; 1190 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1191 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1192 "expression for the descriptor is not " 1193 "set."); 1194 TaskgroupDescriptor = I->TaskgroupReductionRef; 1195 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1196 Data.PrivateCopy, I->DefaultAttrLoc); 1197 } 1198 return DSAVarData(); 1199 } 1200 1201 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1202 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1203 Expr *&TaskgroupDescriptor) const { 1204 D = getCanonicalDecl(D); 1205 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1206 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1207 const DSAInfo &Data = I->SharingMap.lookup(D); 1208 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1209 continue; 1210 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1211 if (!ReductionData.ReductionOp || 1212 !ReductionData.ReductionOp.is<const Expr *>()) 1213 return DSAVarData(); 1214 SR = ReductionData.ReductionRange; 1215 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1216 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1217 "expression for the descriptor is not " 1218 "set."); 1219 TaskgroupDescriptor = I->TaskgroupReductionRef; 1220 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1221 Data.PrivateCopy, I->DefaultAttrLoc); 1222 } 1223 return DSAVarData(); 1224 } 1225 1226 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1227 D = D->getCanonicalDecl(); 1228 for (const_iterator E = end(); I != E; ++I) { 1229 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1230 isOpenMPTargetExecutionDirective(I->Directive)) { 1231 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1232 Scope *CurScope = getCurScope(); 1233 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1234 CurScope = CurScope->getParent(); 1235 return CurScope != TopScope; 1236 } 1237 } 1238 return false; 1239 } 1240 1241 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1242 bool AcceptIfMutable = true, 1243 bool *IsClassType = nullptr) { 1244 ASTContext &Context = SemaRef.getASTContext(); 1245 Type = Type.getNonReferenceType().getCanonicalType(); 1246 bool IsConstant = Type.isConstant(Context); 1247 Type = Context.getBaseElementType(Type); 1248 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1249 ? Type->getAsCXXRecordDecl() 1250 : nullptr; 1251 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1252 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1253 RD = CTD->getTemplatedDecl(); 1254 if (IsClassType) 1255 *IsClassType = RD; 1256 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1257 RD->hasDefinition() && RD->hasMutableFields()); 1258 } 1259 1260 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1261 QualType Type, OpenMPClauseKind CKind, 1262 SourceLocation ELoc, 1263 bool AcceptIfMutable = true, 1264 bool ListItemNotVar = false) { 1265 ASTContext &Context = SemaRef.getASTContext(); 1266 bool IsClassType; 1267 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1268 unsigned Diag = ListItemNotVar 1269 ? diag::err_omp_const_list_item 1270 : IsClassType ? diag::err_omp_const_not_mutable_variable 1271 : diag::err_omp_const_variable; 1272 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1273 if (!ListItemNotVar && D) { 1274 const VarDecl *VD = dyn_cast<VarDecl>(D); 1275 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1276 VarDecl::DeclarationOnly; 1277 SemaRef.Diag(D->getLocation(), 1278 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1279 << D; 1280 } 1281 return true; 1282 } 1283 return false; 1284 } 1285 1286 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1287 bool FromParent) { 1288 D = getCanonicalDecl(D); 1289 DSAVarData DVar; 1290 1291 auto *VD = dyn_cast<VarDecl>(D); 1292 auto TI = Threadprivates.find(D); 1293 if (TI != Threadprivates.end()) { 1294 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1295 DVar.CKind = OMPC_threadprivate; 1296 return DVar; 1297 } 1298 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1299 DVar.RefExpr = buildDeclRefExpr( 1300 SemaRef, VD, D->getType().getNonReferenceType(), 1301 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1302 DVar.CKind = OMPC_threadprivate; 1303 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1304 return DVar; 1305 } 1306 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1307 // in a Construct, C/C++, predetermined, p.1] 1308 // Variables appearing in threadprivate directives are threadprivate. 1309 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1310 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1311 SemaRef.getLangOpts().OpenMPUseTLS && 1312 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1313 (VD && VD->getStorageClass() == SC_Register && 1314 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1315 DVar.RefExpr = buildDeclRefExpr( 1316 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1317 DVar.CKind = OMPC_threadprivate; 1318 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1319 return DVar; 1320 } 1321 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1322 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1323 !isLoopControlVariable(D).first) { 1324 const_iterator IterTarget = 1325 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1326 return isOpenMPTargetExecutionDirective(Data.Directive); 1327 }); 1328 if (IterTarget != end()) { 1329 const_iterator ParentIterTarget = IterTarget + 1; 1330 for (const_iterator Iter = begin(); 1331 Iter != ParentIterTarget; ++Iter) { 1332 if (isOpenMPLocal(VD, Iter)) { 1333 DVar.RefExpr = 1334 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1335 D->getLocation()); 1336 DVar.CKind = OMPC_threadprivate; 1337 return DVar; 1338 } 1339 } 1340 if (!isClauseParsingMode() || IterTarget != begin()) { 1341 auto DSAIter = IterTarget->SharingMap.find(D); 1342 if (DSAIter != IterTarget->SharingMap.end() && 1343 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1344 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1345 DVar.CKind = OMPC_threadprivate; 1346 return DVar; 1347 } 1348 const_iterator End = end(); 1349 if (!SemaRef.isOpenMPCapturedByRef( 1350 D, std::distance(ParentIterTarget, End), 1351 /*OpenMPCaptureLevel=*/0)) { 1352 DVar.RefExpr = 1353 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1354 IterTarget->ConstructLoc); 1355 DVar.CKind = OMPC_threadprivate; 1356 return DVar; 1357 } 1358 } 1359 } 1360 } 1361 1362 if (isStackEmpty()) 1363 // Not in OpenMP execution region and top scope was already checked. 1364 return DVar; 1365 1366 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1367 // in a Construct, C/C++, predetermined, p.4] 1368 // Static data members are shared. 1369 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1370 // in a Construct, C/C++, predetermined, p.7] 1371 // Variables with static storage duration that are declared in a scope 1372 // inside the construct are shared. 1373 if (VD && VD->isStaticDataMember()) { 1374 // Check for explicitly specified attributes. 1375 const_iterator I = begin(); 1376 const_iterator EndI = end(); 1377 if (FromParent && I != EndI) 1378 ++I; 1379 auto It = I->SharingMap.find(D); 1380 if (It != I->SharingMap.end()) { 1381 const DSAInfo &Data = It->getSecond(); 1382 DVar.RefExpr = Data.RefExpr.getPointer(); 1383 DVar.PrivateCopy = Data.PrivateCopy; 1384 DVar.CKind = Data.Attributes; 1385 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1386 DVar.DKind = I->Directive; 1387 return DVar; 1388 } 1389 1390 DVar.CKind = OMPC_shared; 1391 return DVar; 1392 } 1393 1394 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1395 // The predetermined shared attribute for const-qualified types having no 1396 // mutable members was removed after OpenMP 3.1. 1397 if (SemaRef.LangOpts.OpenMP <= 31) { 1398 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1399 // in a Construct, C/C++, predetermined, p.6] 1400 // Variables with const qualified type having no mutable member are 1401 // shared. 1402 if (isConstNotMutableType(SemaRef, D->getType())) { 1403 // Variables with const-qualified type having no mutable member may be 1404 // listed in a firstprivate clause, even if they are static data members. 1405 DSAVarData DVarTemp = hasInnermostDSA( 1406 D, 1407 [](OpenMPClauseKind C) { 1408 return C == OMPC_firstprivate || C == OMPC_shared; 1409 }, 1410 MatchesAlways, FromParent); 1411 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1412 return DVarTemp; 1413 1414 DVar.CKind = OMPC_shared; 1415 return DVar; 1416 } 1417 } 1418 1419 // Explicitly specified attributes and local variables with predetermined 1420 // attributes. 1421 const_iterator I = begin(); 1422 const_iterator EndI = end(); 1423 if (FromParent && I != EndI) 1424 ++I; 1425 auto It = I->SharingMap.find(D); 1426 if (It != I->SharingMap.end()) { 1427 const DSAInfo &Data = It->getSecond(); 1428 DVar.RefExpr = Data.RefExpr.getPointer(); 1429 DVar.PrivateCopy = Data.PrivateCopy; 1430 DVar.CKind = Data.Attributes; 1431 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1432 DVar.DKind = I->Directive; 1433 } 1434 1435 return DVar; 1436 } 1437 1438 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1439 bool FromParent) const { 1440 if (isStackEmpty()) { 1441 const_iterator I; 1442 return getDSA(I, D); 1443 } 1444 D = getCanonicalDecl(D); 1445 const_iterator StartI = begin(); 1446 const_iterator EndI = end(); 1447 if (FromParent && StartI != EndI) 1448 ++StartI; 1449 return getDSA(StartI, D); 1450 } 1451 1452 const DSAStackTy::DSAVarData 1453 DSAStackTy::hasDSA(ValueDecl *D, 1454 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1455 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1456 bool FromParent) const { 1457 if (isStackEmpty()) 1458 return {}; 1459 D = getCanonicalDecl(D); 1460 const_iterator I = begin(); 1461 const_iterator EndI = end(); 1462 if (FromParent && I != EndI) 1463 ++I; 1464 for (; I != EndI; ++I) { 1465 if (!DPred(I->Directive) && 1466 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1467 continue; 1468 const_iterator NewI = I; 1469 DSAVarData DVar = getDSA(NewI, D); 1470 if (I == NewI && CPred(DVar.CKind)) 1471 return DVar; 1472 } 1473 return {}; 1474 } 1475 1476 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1477 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1478 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1479 bool FromParent) const { 1480 if (isStackEmpty()) 1481 return {}; 1482 D = getCanonicalDecl(D); 1483 const_iterator StartI = begin(); 1484 const_iterator EndI = end(); 1485 if (FromParent && StartI != EndI) 1486 ++StartI; 1487 if (StartI == EndI || !DPred(StartI->Directive)) 1488 return {}; 1489 const_iterator NewI = StartI; 1490 DSAVarData DVar = getDSA(NewI, D); 1491 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1492 } 1493 1494 bool DSAStackTy::hasExplicitDSA( 1495 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1496 unsigned Level, bool NotLastprivate) const { 1497 if (getStackSize() <= Level) 1498 return false; 1499 D = getCanonicalDecl(D); 1500 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1501 auto I = StackElem.SharingMap.find(D); 1502 if (I != StackElem.SharingMap.end() && 1503 I->getSecond().RefExpr.getPointer() && 1504 CPred(I->getSecond().Attributes) && 1505 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1506 return true; 1507 // Check predetermined rules for the loop control variables. 1508 auto LI = StackElem.LCVMap.find(D); 1509 if (LI != StackElem.LCVMap.end()) 1510 return CPred(OMPC_private); 1511 return false; 1512 } 1513 1514 bool DSAStackTy::hasExplicitDirective( 1515 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1516 unsigned Level) const { 1517 if (getStackSize() <= Level) 1518 return false; 1519 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1520 return DPred(StackElem.Directive); 1521 } 1522 1523 bool DSAStackTy::hasDirective( 1524 const llvm::function_ref<bool(OpenMPDirectiveKind, 1525 const DeclarationNameInfo &, SourceLocation)> 1526 DPred, 1527 bool FromParent) const { 1528 // We look only in the enclosing region. 1529 size_t Skip = FromParent ? 2 : 1; 1530 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1531 I != E; ++I) { 1532 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1533 return true; 1534 } 1535 return false; 1536 } 1537 1538 void Sema::InitDataSharingAttributesStack() { 1539 VarDataSharingAttributesStack = new DSAStackTy(*this); 1540 } 1541 1542 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1543 1544 void Sema::pushOpenMPFunctionRegion() { 1545 DSAStack->pushFunction(); 1546 } 1547 1548 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1549 DSAStack->popFunction(OldFSI); 1550 } 1551 1552 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1553 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1554 "Expected OpenMP device compilation."); 1555 return !S.isInOpenMPTargetExecutionDirective() && 1556 !S.isInOpenMPDeclareTargetContext(); 1557 } 1558 1559 namespace { 1560 /// Status of the function emission on the host/device. 1561 enum class FunctionEmissionStatus { 1562 Emitted, 1563 Discarded, 1564 Unknown, 1565 }; 1566 } // anonymous namespace 1567 1568 /// Do we know that we will eventually codegen the given function? 1569 static FunctionEmissionStatus isKnownDeviceEmitted(Sema &S, FunctionDecl *FD) { 1570 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1571 "Expected OpenMP device compilation."); 1572 // Templates are emitted when they're instantiated. 1573 if (FD->isDependentContext()) 1574 return FunctionEmissionStatus::Discarded; 1575 1576 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 1577 OMPDeclareTargetDeclAttr::getDeviceType(FD->getCanonicalDecl()); 1578 if (DevTy.hasValue()) 1579 return (*DevTy == OMPDeclareTargetDeclAttr::DT_Host) 1580 ? FunctionEmissionStatus::Discarded 1581 : FunctionEmissionStatus::Emitted; 1582 1583 // Otherwise, the function is known-emitted if it's in our set of 1584 // known-emitted functions. 1585 return (S.DeviceKnownEmittedFns.count(FD) > 0) 1586 ? FunctionEmissionStatus::Emitted 1587 : FunctionEmissionStatus::Unknown; 1588 } 1589 1590 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1591 unsigned DiagID) { 1592 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1593 "Expected OpenMP device compilation."); 1594 FunctionEmissionStatus FES = 1595 isKnownDeviceEmitted(*this, getCurFunctionDecl()); 1596 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1597 switch (FES) { 1598 case FunctionEmissionStatus::Emitted: 1599 Kind = DeviceDiagBuilder::K_Immediate; 1600 break; 1601 case FunctionEmissionStatus::Unknown: 1602 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1603 : DeviceDiagBuilder::K_Immediate; 1604 break; 1605 case FunctionEmissionStatus::Discarded: 1606 Kind = DeviceDiagBuilder::K_Nop; 1607 break; 1608 } 1609 1610 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1611 } 1612 1613 /// Do we know that we will eventually codegen the given function? 1614 static FunctionEmissionStatus isKnownHostEmitted(Sema &S, FunctionDecl *FD) { 1615 assert(S.LangOpts.OpenMP && !S.LangOpts.OpenMPIsDevice && 1616 "Expected OpenMP host compilation."); 1617 // In OpenMP 4.5 all the functions are host functions. 1618 if (S.LangOpts.OpenMP <= 45) 1619 return FunctionEmissionStatus::Emitted; 1620 1621 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 1622 OMPDeclareTargetDeclAttr::getDeviceType(FD->getCanonicalDecl()); 1623 if (DevTy.hasValue()) 1624 return (*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 1625 ? FunctionEmissionStatus::Discarded 1626 : FunctionEmissionStatus::Emitted; 1627 1628 // Otherwise, the function is known-emitted if it's in our set of 1629 // known-emitted functions. 1630 return (S.DeviceKnownEmittedFns.count(FD) > 0) 1631 ? FunctionEmissionStatus::Emitted 1632 : FunctionEmissionStatus::Unknown; 1633 } 1634 1635 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1636 unsigned DiagID) { 1637 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1638 "Expected OpenMP host compilation."); 1639 FunctionEmissionStatus FES = 1640 isKnownHostEmitted(*this, getCurFunctionDecl()); 1641 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1642 switch (FES) { 1643 case FunctionEmissionStatus::Emitted: 1644 Kind = DeviceDiagBuilder::K_Immediate; 1645 break; 1646 case FunctionEmissionStatus::Unknown: 1647 Kind = DeviceDiagBuilder::K_Deferred; 1648 break; 1649 case FunctionEmissionStatus::Discarded: 1650 Kind = DeviceDiagBuilder::K_Nop; 1651 break; 1652 } 1653 1654 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1655 } 1656 1657 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1658 bool CheckForDelayedContext) { 1659 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1660 "Expected OpenMP device compilation."); 1661 assert(Callee && "Callee may not be null."); 1662 Callee = Callee->getMostRecentDecl(); 1663 FunctionDecl *Caller = getCurFunctionDecl(); 1664 1665 // host only function are not available on the device. 1666 if (Caller && 1667 (isKnownDeviceEmitted(*this, Caller) == FunctionEmissionStatus::Emitted || 1668 (!isOpenMPDeviceDelayedContext(*this) && 1669 isKnownDeviceEmitted(*this, Caller) == 1670 FunctionEmissionStatus::Unknown)) && 1671 isKnownDeviceEmitted(*this, Callee) == 1672 FunctionEmissionStatus::Discarded) { 1673 StringRef HostDevTy = 1674 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 1675 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1676 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1677 diag::note_omp_marked_device_type_here) 1678 << HostDevTy; 1679 return; 1680 } 1681 // If the caller is known-emitted, mark the callee as known-emitted. 1682 // Otherwise, mark the call in our call graph so we can traverse it later. 1683 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1684 (!Caller && !CheckForDelayedContext) || 1685 (Caller && 1686 isKnownDeviceEmitted(*this, Caller) == FunctionEmissionStatus::Emitted)) 1687 markKnownEmitted(*this, Caller, Callee, Loc, 1688 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1689 return CheckForDelayedContext && 1690 isKnownDeviceEmitted(S, FD) == 1691 FunctionEmissionStatus::Emitted; 1692 }); 1693 else if (Caller) 1694 DeviceCallGraph[Caller].insert({Callee, Loc}); 1695 } 1696 1697 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1698 bool CheckCaller) { 1699 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1700 "Expected OpenMP host compilation."); 1701 assert(Callee && "Callee may not be null."); 1702 Callee = Callee->getMostRecentDecl(); 1703 FunctionDecl *Caller = getCurFunctionDecl(); 1704 1705 // device only function are not available on the host. 1706 if (Caller && 1707 isKnownHostEmitted(*this, Caller) == FunctionEmissionStatus::Emitted && 1708 isKnownHostEmitted(*this, Callee) == FunctionEmissionStatus::Discarded) { 1709 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1710 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1711 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1712 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1713 diag::note_omp_marked_device_type_here) 1714 << NoHostDevTy; 1715 return; 1716 } 1717 // If the caller is known-emitted, mark the callee as known-emitted. 1718 // Otherwise, mark the call in our call graph so we can traverse it later. 1719 if ((!CheckCaller && !Caller) || 1720 (Caller && 1721 isKnownHostEmitted(*this, Caller) == FunctionEmissionStatus::Emitted)) 1722 markKnownEmitted( 1723 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1724 return CheckCaller && 1725 isKnownHostEmitted(S, FD) == FunctionEmissionStatus::Emitted; 1726 }); 1727 else if (Caller) 1728 DeviceCallGraph[Caller].insert({Callee, Loc}); 1729 } 1730 1731 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1732 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1733 "OpenMP device compilation mode is expected."); 1734 QualType Ty = E->getType(); 1735 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1736 ((Ty->isFloat128Type() || 1737 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1738 !Context.getTargetInfo().hasFloat128Type()) || 1739 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1740 !Context.getTargetInfo().hasInt128Type())) 1741 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1742 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1743 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1744 } 1745 1746 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1747 unsigned OpenMPCaptureLevel) const { 1748 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1749 1750 ASTContext &Ctx = getASTContext(); 1751 bool IsByRef = true; 1752 1753 // Find the directive that is associated with the provided scope. 1754 D = cast<ValueDecl>(D->getCanonicalDecl()); 1755 QualType Ty = D->getType(); 1756 1757 bool IsVariableUsedInMapClause = false; 1758 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1759 // This table summarizes how a given variable should be passed to the device 1760 // given its type and the clauses where it appears. This table is based on 1761 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1762 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1763 // 1764 // ========================================================================= 1765 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1766 // | |(tofrom:scalar)| | pvt | | | | 1767 // ========================================================================= 1768 // | scl | | | | - | | bycopy| 1769 // | scl | | - | x | - | - | bycopy| 1770 // | scl | | x | - | - | - | null | 1771 // | scl | x | | | - | | byref | 1772 // | scl | x | - | x | - | - | bycopy| 1773 // | scl | x | x | - | - | - | null | 1774 // | scl | | - | - | - | x | byref | 1775 // | scl | x | - | - | - | x | byref | 1776 // 1777 // | agg | n.a. | | | - | | byref | 1778 // | agg | n.a. | - | x | - | - | byref | 1779 // | agg | n.a. | x | - | - | - | null | 1780 // | agg | n.a. | - | - | - | x | byref | 1781 // | agg | n.a. | - | - | - | x[] | byref | 1782 // 1783 // | ptr | n.a. | | | - | | bycopy| 1784 // | ptr | n.a. | - | x | - | - | bycopy| 1785 // | ptr | n.a. | x | - | - | - | null | 1786 // | ptr | n.a. | - | - | - | x | byref | 1787 // | ptr | n.a. | - | - | - | x[] | bycopy| 1788 // | ptr | n.a. | - | - | x | | bycopy| 1789 // | ptr | n.a. | - | - | x | x | bycopy| 1790 // | ptr | n.a. | - | - | x | x[] | bycopy| 1791 // ========================================================================= 1792 // Legend: 1793 // scl - scalar 1794 // ptr - pointer 1795 // agg - aggregate 1796 // x - applies 1797 // - - invalid in this combination 1798 // [] - mapped with an array section 1799 // byref - should be mapped by reference 1800 // byval - should be mapped by value 1801 // null - initialize a local variable to null on the device 1802 // 1803 // Observations: 1804 // - All scalar declarations that show up in a map clause have to be passed 1805 // by reference, because they may have been mapped in the enclosing data 1806 // environment. 1807 // - If the scalar value does not fit the size of uintptr, it has to be 1808 // passed by reference, regardless the result in the table above. 1809 // - For pointers mapped by value that have either an implicit map or an 1810 // array section, the runtime library may pass the NULL value to the 1811 // device instead of the value passed to it by the compiler. 1812 1813 if (Ty->isReferenceType()) 1814 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1815 1816 // Locate map clauses and see if the variable being captured is referred to 1817 // in any of those clauses. Here we only care about variables, not fields, 1818 // because fields are part of aggregates. 1819 bool IsVariableAssociatedWithSection = false; 1820 1821 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1822 D, Level, 1823 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1824 OMPClauseMappableExprCommon::MappableExprComponentListRef 1825 MapExprComponents, 1826 OpenMPClauseKind WhereFoundClauseKind) { 1827 // Only the map clause information influences how a variable is 1828 // captured. E.g. is_device_ptr does not require changing the default 1829 // behavior. 1830 if (WhereFoundClauseKind != OMPC_map) 1831 return false; 1832 1833 auto EI = MapExprComponents.rbegin(); 1834 auto EE = MapExprComponents.rend(); 1835 1836 assert(EI != EE && "Invalid map expression!"); 1837 1838 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1839 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1840 1841 ++EI; 1842 if (EI == EE) 1843 return false; 1844 1845 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1846 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1847 isa<MemberExpr>(EI->getAssociatedExpression())) { 1848 IsVariableAssociatedWithSection = true; 1849 // There is nothing more we need to know about this variable. 1850 return true; 1851 } 1852 1853 // Keep looking for more map info. 1854 return false; 1855 }); 1856 1857 if (IsVariableUsedInMapClause) { 1858 // If variable is identified in a map clause it is always captured by 1859 // reference except if it is a pointer that is dereferenced somehow. 1860 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1861 } else { 1862 // By default, all the data that has a scalar type is mapped by copy 1863 // (except for reduction variables). 1864 IsByRef = 1865 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1866 !Ty->isAnyPointerType()) || 1867 !Ty->isScalarType() || 1868 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1869 DSAStack->hasExplicitDSA( 1870 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1871 } 1872 } 1873 1874 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1875 IsByRef = 1876 ((IsVariableUsedInMapClause && 1877 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1878 OMPD_target) || 1879 !DSAStack->hasExplicitDSA( 1880 D, 1881 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1882 Level, /*NotLastprivate=*/true)) && 1883 // If the variable is artificial and must be captured by value - try to 1884 // capture by value. 1885 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1886 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1887 } 1888 1889 // When passing data by copy, we need to make sure it fits the uintptr size 1890 // and alignment, because the runtime library only deals with uintptr types. 1891 // If it does not fit the uintptr size, we need to pass the data by reference 1892 // instead. 1893 if (!IsByRef && 1894 (Ctx.getTypeSizeInChars(Ty) > 1895 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1896 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1897 IsByRef = true; 1898 } 1899 1900 return IsByRef; 1901 } 1902 1903 unsigned Sema::getOpenMPNestingLevel() const { 1904 assert(getLangOpts().OpenMP); 1905 return DSAStack->getNestingLevel(); 1906 } 1907 1908 bool Sema::isInOpenMPTargetExecutionDirective() const { 1909 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1910 !DSAStack->isClauseParsingMode()) || 1911 DSAStack->hasDirective( 1912 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1913 SourceLocation) -> bool { 1914 return isOpenMPTargetExecutionDirective(K); 1915 }, 1916 false); 1917 } 1918 1919 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1920 unsigned StopAt) { 1921 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1922 D = getCanonicalDecl(D); 1923 1924 // If we want to determine whether the variable should be captured from the 1925 // perspective of the current capturing scope, and we've already left all the 1926 // capturing scopes of the top directive on the stack, check from the 1927 // perspective of its parent directive (if any) instead. 1928 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1929 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1930 1931 // If we are attempting to capture a global variable in a directive with 1932 // 'target' we return true so that this global is also mapped to the device. 1933 // 1934 auto *VD = dyn_cast<VarDecl>(D); 1935 if (VD && !VD->hasLocalStorage() && 1936 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1937 if (isInOpenMPDeclareTargetContext()) { 1938 // Try to mark variable as declare target if it is used in capturing 1939 // regions. 1940 if (LangOpts.OpenMP <= 45 && 1941 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1942 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1943 return nullptr; 1944 } else if (isInOpenMPTargetExecutionDirective()) { 1945 // If the declaration is enclosed in a 'declare target' directive, 1946 // then it should not be captured. 1947 // 1948 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1949 return nullptr; 1950 return VD; 1951 } 1952 } 1953 1954 if (CheckScopeInfo) { 1955 bool OpenMPFound = false; 1956 for (unsigned I = StopAt + 1; I > 0; --I) { 1957 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1958 if(!isa<CapturingScopeInfo>(FSI)) 1959 return nullptr; 1960 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1961 if (RSI->CapRegionKind == CR_OpenMP) { 1962 OpenMPFound = true; 1963 break; 1964 } 1965 } 1966 if (!OpenMPFound) 1967 return nullptr; 1968 } 1969 1970 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1971 (!DSAStack->isClauseParsingMode() || 1972 DSAStack->getParentDirective() != OMPD_unknown)) { 1973 auto &&Info = DSAStack->isLoopControlVariable(D); 1974 if (Info.first || 1975 (VD && VD->hasLocalStorage() && 1976 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1977 (VD && DSAStack->isForceVarCapturing())) 1978 return VD ? VD : Info.second; 1979 DSAStackTy::DSAVarData DVarPrivate = 1980 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1981 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1982 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1983 // Threadprivate variables must not be captured. 1984 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1985 return nullptr; 1986 // The variable is not private or it is the variable in the directive with 1987 // default(none) clause and not used in any clause. 1988 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1989 [](OpenMPDirectiveKind) { return true; }, 1990 DSAStack->isClauseParsingMode()); 1991 if (DVarPrivate.CKind != OMPC_unknown || 1992 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1993 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1994 } 1995 return nullptr; 1996 } 1997 1998 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1999 unsigned Level) const { 2000 SmallVector<OpenMPDirectiveKind, 4> Regions; 2001 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2002 FunctionScopesIndex -= Regions.size(); 2003 } 2004 2005 void Sema::startOpenMPLoop() { 2006 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2007 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2008 DSAStack->loopInit(); 2009 } 2010 2011 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2012 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2013 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2014 if (DSAStack->getAssociatedLoops() > 0 && 2015 !DSAStack->isLoopStarted()) { 2016 DSAStack->resetPossibleLoopCounter(D); 2017 DSAStack->loopStart(); 2018 return true; 2019 } 2020 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2021 DSAStack->isLoopControlVariable(D).first) && 2022 !DSAStack->hasExplicitDSA( 2023 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2024 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2025 return true; 2026 } 2027 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2028 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2029 DSAStack->isForceVarCapturing() && 2030 !DSAStack->hasExplicitDSA( 2031 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2032 return true; 2033 } 2034 return DSAStack->hasExplicitDSA( 2035 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2036 (DSAStack->isClauseParsingMode() && 2037 DSAStack->getClauseParsingMode() == OMPC_private) || 2038 // Consider taskgroup reduction descriptor variable a private to avoid 2039 // possible capture in the region. 2040 (DSAStack->hasExplicitDirective( 2041 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2042 Level) && 2043 DSAStack->isTaskgroupReductionRef(D, Level)); 2044 } 2045 2046 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2047 unsigned Level) { 2048 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2049 D = getCanonicalDecl(D); 2050 OpenMPClauseKind OMPC = OMPC_unknown; 2051 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2052 const unsigned NewLevel = I - 1; 2053 if (DSAStack->hasExplicitDSA(D, 2054 [&OMPC](const OpenMPClauseKind K) { 2055 if (isOpenMPPrivate(K)) { 2056 OMPC = K; 2057 return true; 2058 } 2059 return false; 2060 }, 2061 NewLevel)) 2062 break; 2063 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2064 D, NewLevel, 2065 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2066 OpenMPClauseKind) { return true; })) { 2067 OMPC = OMPC_map; 2068 break; 2069 } 2070 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2071 NewLevel)) { 2072 OMPC = OMPC_map; 2073 if (D->getType()->isScalarType() && 2074 DSAStack->getDefaultDMAAtLevel(NewLevel) != 2075 DefaultMapAttributes::DMA_tofrom_scalar) 2076 OMPC = OMPC_firstprivate; 2077 break; 2078 } 2079 } 2080 if (OMPC != OMPC_unknown) 2081 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2082 } 2083 2084 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2085 unsigned Level) const { 2086 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2087 // Return true if the current level is no longer enclosed in a target region. 2088 2089 const auto *VD = dyn_cast<VarDecl>(D); 2090 return VD && !VD->hasLocalStorage() && 2091 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2092 Level); 2093 } 2094 2095 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2096 2097 void Sema::finalizeOpenMPDelayedAnalysis() { 2098 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2099 // Diagnose implicit declare target functions and their callees. 2100 for (const auto &CallerCallees : DeviceCallGraph) { 2101 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2102 OMPDeclareTargetDeclAttr::getDeviceType( 2103 CallerCallees.getFirst()->getMostRecentDecl()); 2104 // Ignore host functions during device analyzis. 2105 if (LangOpts.OpenMPIsDevice && DevTy && 2106 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2107 continue; 2108 // Ignore nohost functions during host analyzis. 2109 if (!LangOpts.OpenMPIsDevice && DevTy && 2110 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2111 continue; 2112 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2113 &Callee : CallerCallees.getSecond()) { 2114 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2115 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2116 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2117 if (LangOpts.OpenMPIsDevice && DevTy && 2118 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2119 // Diagnose host function called during device codegen. 2120 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2121 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2122 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2123 << HostDevTy << 0; 2124 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2125 diag::note_omp_marked_device_type_here) 2126 << HostDevTy; 2127 continue; 2128 } 2129 if (!LangOpts.OpenMPIsDevice && DevTy && 2130 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2131 // Diagnose nohost function called during host codegen. 2132 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2133 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2134 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2135 << NoHostDevTy << 1; 2136 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2137 diag::note_omp_marked_device_type_here) 2138 << NoHostDevTy; 2139 continue; 2140 } 2141 } 2142 } 2143 } 2144 2145 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2146 const DeclarationNameInfo &DirName, 2147 Scope *CurScope, SourceLocation Loc) { 2148 DSAStack->push(DKind, DirName, CurScope, Loc); 2149 PushExpressionEvaluationContext( 2150 ExpressionEvaluationContext::PotentiallyEvaluated); 2151 } 2152 2153 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2154 DSAStack->setClauseParsingMode(K); 2155 } 2156 2157 void Sema::EndOpenMPClause() { 2158 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2159 } 2160 2161 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2162 ArrayRef<OMPClause *> Clauses); 2163 2164 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2165 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2166 // A variable of class type (or array thereof) that appears in a lastprivate 2167 // clause requires an accessible, unambiguous default constructor for the 2168 // class type, unless the list item is also specified in a firstprivate 2169 // clause. 2170 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2171 for (OMPClause *C : D->clauses()) { 2172 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2173 SmallVector<Expr *, 8> PrivateCopies; 2174 for (Expr *DE : Clause->varlists()) { 2175 if (DE->isValueDependent() || DE->isTypeDependent()) { 2176 PrivateCopies.push_back(nullptr); 2177 continue; 2178 } 2179 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2180 auto *VD = cast<VarDecl>(DRE->getDecl()); 2181 QualType Type = VD->getType().getNonReferenceType(); 2182 const DSAStackTy::DSAVarData DVar = 2183 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2184 if (DVar.CKind == OMPC_lastprivate) { 2185 // Generate helper private variable and initialize it with the 2186 // default value. The address of the original variable is replaced 2187 // by the address of the new private variable in CodeGen. This new 2188 // variable is not added to IdResolver, so the code in the OpenMP 2189 // region uses original variable for proper diagnostics. 2190 VarDecl *VDPrivate = buildVarDecl( 2191 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2192 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2193 ActOnUninitializedDecl(VDPrivate); 2194 if (VDPrivate->isInvalidDecl()) { 2195 PrivateCopies.push_back(nullptr); 2196 continue; 2197 } 2198 PrivateCopies.push_back(buildDeclRefExpr( 2199 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2200 } else { 2201 // The variable is also a firstprivate, so initialization sequence 2202 // for private copy is generated already. 2203 PrivateCopies.push_back(nullptr); 2204 } 2205 } 2206 Clause->setPrivateCopies(PrivateCopies); 2207 } 2208 } 2209 // Check allocate clauses. 2210 if (!CurContext->isDependentContext()) 2211 checkAllocateClauses(*this, DSAStack, D->clauses()); 2212 } 2213 2214 DSAStack->pop(); 2215 DiscardCleanupsInEvaluationContext(); 2216 PopExpressionEvaluationContext(); 2217 } 2218 2219 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2220 Expr *NumIterations, Sema &SemaRef, 2221 Scope *S, DSAStackTy *Stack); 2222 2223 namespace { 2224 2225 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2226 private: 2227 Sema &SemaRef; 2228 2229 public: 2230 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2231 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2232 NamedDecl *ND = Candidate.getCorrectionDecl(); 2233 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2234 return VD->hasGlobalStorage() && 2235 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2236 SemaRef.getCurScope()); 2237 } 2238 return false; 2239 } 2240 2241 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2242 return std::make_unique<VarDeclFilterCCC>(*this); 2243 } 2244 2245 }; 2246 2247 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2248 private: 2249 Sema &SemaRef; 2250 2251 public: 2252 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2253 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2254 NamedDecl *ND = Candidate.getCorrectionDecl(); 2255 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2256 isa<FunctionDecl>(ND))) { 2257 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2258 SemaRef.getCurScope()); 2259 } 2260 return false; 2261 } 2262 2263 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2264 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2265 } 2266 }; 2267 2268 } // namespace 2269 2270 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2271 CXXScopeSpec &ScopeSpec, 2272 const DeclarationNameInfo &Id, 2273 OpenMPDirectiveKind Kind) { 2274 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2275 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2276 2277 if (Lookup.isAmbiguous()) 2278 return ExprError(); 2279 2280 VarDecl *VD; 2281 if (!Lookup.isSingleResult()) { 2282 VarDeclFilterCCC CCC(*this); 2283 if (TypoCorrection Corrected = 2284 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2285 CTK_ErrorRecovery)) { 2286 diagnoseTypo(Corrected, 2287 PDiag(Lookup.empty() 2288 ? diag::err_undeclared_var_use_suggest 2289 : diag::err_omp_expected_var_arg_suggest) 2290 << Id.getName()); 2291 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2292 } else { 2293 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2294 : diag::err_omp_expected_var_arg) 2295 << Id.getName(); 2296 return ExprError(); 2297 } 2298 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2299 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2300 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2301 return ExprError(); 2302 } 2303 Lookup.suppressDiagnostics(); 2304 2305 // OpenMP [2.9.2, Syntax, C/C++] 2306 // Variables must be file-scope, namespace-scope, or static block-scope. 2307 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2308 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2309 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2310 bool IsDecl = 2311 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2312 Diag(VD->getLocation(), 2313 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2314 << VD; 2315 return ExprError(); 2316 } 2317 2318 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2319 NamedDecl *ND = CanonicalVD; 2320 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2321 // A threadprivate directive for file-scope variables must appear outside 2322 // any definition or declaration. 2323 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2324 !getCurLexicalContext()->isTranslationUnit()) { 2325 Diag(Id.getLoc(), diag::err_omp_var_scope) 2326 << getOpenMPDirectiveName(Kind) << VD; 2327 bool IsDecl = 2328 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2329 Diag(VD->getLocation(), 2330 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2331 << VD; 2332 return ExprError(); 2333 } 2334 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2335 // A threadprivate directive for static class member variables must appear 2336 // in the class definition, in the same scope in which the member 2337 // variables are declared. 2338 if (CanonicalVD->isStaticDataMember() && 2339 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2340 Diag(Id.getLoc(), diag::err_omp_var_scope) 2341 << getOpenMPDirectiveName(Kind) << VD; 2342 bool IsDecl = 2343 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2344 Diag(VD->getLocation(), 2345 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2346 << VD; 2347 return ExprError(); 2348 } 2349 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2350 // A threadprivate directive for namespace-scope variables must appear 2351 // outside any definition or declaration other than the namespace 2352 // definition itself. 2353 if (CanonicalVD->getDeclContext()->isNamespace() && 2354 (!getCurLexicalContext()->isFileContext() || 2355 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2356 Diag(Id.getLoc(), diag::err_omp_var_scope) 2357 << getOpenMPDirectiveName(Kind) << VD; 2358 bool IsDecl = 2359 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2360 Diag(VD->getLocation(), 2361 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2362 << VD; 2363 return ExprError(); 2364 } 2365 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2366 // A threadprivate directive for static block-scope variables must appear 2367 // in the scope of the variable and not in a nested scope. 2368 if (CanonicalVD->isLocalVarDecl() && CurScope && 2369 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2370 Diag(Id.getLoc(), diag::err_omp_var_scope) 2371 << getOpenMPDirectiveName(Kind) << VD; 2372 bool IsDecl = 2373 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2374 Diag(VD->getLocation(), 2375 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2376 << VD; 2377 return ExprError(); 2378 } 2379 2380 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2381 // A threadprivate directive must lexically precede all references to any 2382 // of the variables in its list. 2383 if (Kind == OMPD_threadprivate && VD->isUsed() && 2384 !DSAStack->isThreadPrivate(VD)) { 2385 Diag(Id.getLoc(), diag::err_omp_var_used) 2386 << getOpenMPDirectiveName(Kind) << VD; 2387 return ExprError(); 2388 } 2389 2390 QualType ExprType = VD->getType().getNonReferenceType(); 2391 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2392 SourceLocation(), VD, 2393 /*RefersToEnclosingVariableOrCapture=*/false, 2394 Id.getLoc(), ExprType, VK_LValue); 2395 } 2396 2397 Sema::DeclGroupPtrTy 2398 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2399 ArrayRef<Expr *> VarList) { 2400 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2401 CurContext->addDecl(D); 2402 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2403 } 2404 return nullptr; 2405 } 2406 2407 namespace { 2408 class LocalVarRefChecker final 2409 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2410 Sema &SemaRef; 2411 2412 public: 2413 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2414 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2415 if (VD->hasLocalStorage()) { 2416 SemaRef.Diag(E->getBeginLoc(), 2417 diag::err_omp_local_var_in_threadprivate_init) 2418 << E->getSourceRange(); 2419 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2420 << VD << VD->getSourceRange(); 2421 return true; 2422 } 2423 } 2424 return false; 2425 } 2426 bool VisitStmt(const Stmt *S) { 2427 for (const Stmt *Child : S->children()) { 2428 if (Child && Visit(Child)) 2429 return true; 2430 } 2431 return false; 2432 } 2433 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2434 }; 2435 } // namespace 2436 2437 OMPThreadPrivateDecl * 2438 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2439 SmallVector<Expr *, 8> Vars; 2440 for (Expr *RefExpr : VarList) { 2441 auto *DE = cast<DeclRefExpr>(RefExpr); 2442 auto *VD = cast<VarDecl>(DE->getDecl()); 2443 SourceLocation ILoc = DE->getExprLoc(); 2444 2445 // Mark variable as used. 2446 VD->setReferenced(); 2447 VD->markUsed(Context); 2448 2449 QualType QType = VD->getType(); 2450 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2451 // It will be analyzed later. 2452 Vars.push_back(DE); 2453 continue; 2454 } 2455 2456 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2457 // A threadprivate variable must not have an incomplete type. 2458 if (RequireCompleteType(ILoc, VD->getType(), 2459 diag::err_omp_threadprivate_incomplete_type)) { 2460 continue; 2461 } 2462 2463 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2464 // A threadprivate variable must not have a reference type. 2465 if (VD->getType()->isReferenceType()) { 2466 Diag(ILoc, diag::err_omp_ref_type_arg) 2467 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2468 bool IsDecl = 2469 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2470 Diag(VD->getLocation(), 2471 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2472 << VD; 2473 continue; 2474 } 2475 2476 // Check if this is a TLS variable. If TLS is not being supported, produce 2477 // the corresponding diagnostic. 2478 if ((VD->getTLSKind() != VarDecl::TLS_None && 2479 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2480 getLangOpts().OpenMPUseTLS && 2481 getASTContext().getTargetInfo().isTLSSupported())) || 2482 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2483 !VD->isLocalVarDecl())) { 2484 Diag(ILoc, diag::err_omp_var_thread_local) 2485 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2486 bool IsDecl = 2487 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2488 Diag(VD->getLocation(), 2489 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2490 << VD; 2491 continue; 2492 } 2493 2494 // Check if initial value of threadprivate variable reference variable with 2495 // local storage (it is not supported by runtime). 2496 if (const Expr *Init = VD->getAnyInitializer()) { 2497 LocalVarRefChecker Checker(*this); 2498 if (Checker.Visit(Init)) 2499 continue; 2500 } 2501 2502 Vars.push_back(RefExpr); 2503 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2504 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2505 Context, SourceRange(Loc, Loc))); 2506 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2507 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2508 } 2509 OMPThreadPrivateDecl *D = nullptr; 2510 if (!Vars.empty()) { 2511 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2512 Vars); 2513 D->setAccess(AS_public); 2514 } 2515 return D; 2516 } 2517 2518 static OMPAllocateDeclAttr::AllocatorTypeTy 2519 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2520 if (!Allocator) 2521 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2522 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2523 Allocator->isInstantiationDependent() || 2524 Allocator->containsUnexpandedParameterPack()) 2525 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2526 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2527 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2528 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2529 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2530 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2531 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2532 llvm::FoldingSetNodeID AEId, DAEId; 2533 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2534 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2535 if (AEId == DAEId) { 2536 AllocatorKindRes = AllocatorKind; 2537 break; 2538 } 2539 } 2540 return AllocatorKindRes; 2541 } 2542 2543 static bool checkPreviousOMPAllocateAttribute( 2544 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2545 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2546 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2547 return false; 2548 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2549 Expr *PrevAllocator = A->getAllocator(); 2550 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2551 getAllocatorKind(S, Stack, PrevAllocator); 2552 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2553 if (AllocatorsMatch && 2554 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2555 Allocator && PrevAllocator) { 2556 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2557 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2558 llvm::FoldingSetNodeID AEId, PAEId; 2559 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2560 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2561 AllocatorsMatch = AEId == PAEId; 2562 } 2563 if (!AllocatorsMatch) { 2564 SmallString<256> AllocatorBuffer; 2565 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2566 if (Allocator) 2567 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2568 SmallString<256> PrevAllocatorBuffer; 2569 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2570 if (PrevAllocator) 2571 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2572 S.getPrintingPolicy()); 2573 2574 SourceLocation AllocatorLoc = 2575 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2576 SourceRange AllocatorRange = 2577 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2578 SourceLocation PrevAllocatorLoc = 2579 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2580 SourceRange PrevAllocatorRange = 2581 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2582 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2583 << (Allocator ? 1 : 0) << AllocatorStream.str() 2584 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2585 << AllocatorRange; 2586 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2587 << PrevAllocatorRange; 2588 return true; 2589 } 2590 return false; 2591 } 2592 2593 static void 2594 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2595 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2596 Expr *Allocator, SourceRange SR) { 2597 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2598 return; 2599 if (Allocator && 2600 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2601 Allocator->isInstantiationDependent() || 2602 Allocator->containsUnexpandedParameterPack())) 2603 return; 2604 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2605 Allocator, SR); 2606 VD->addAttr(A); 2607 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2608 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2609 } 2610 2611 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2612 SourceLocation Loc, ArrayRef<Expr *> VarList, 2613 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2614 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2615 Expr *Allocator = nullptr; 2616 if (Clauses.empty()) { 2617 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2618 // allocate directives that appear in a target region must specify an 2619 // allocator clause unless a requires directive with the dynamic_allocators 2620 // clause is present in the same compilation unit. 2621 if (LangOpts.OpenMPIsDevice && 2622 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2623 targetDiag(Loc, diag::err_expected_allocator_clause); 2624 } else { 2625 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2626 } 2627 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2628 getAllocatorKind(*this, DSAStack, Allocator); 2629 SmallVector<Expr *, 8> Vars; 2630 for (Expr *RefExpr : VarList) { 2631 auto *DE = cast<DeclRefExpr>(RefExpr); 2632 auto *VD = cast<VarDecl>(DE->getDecl()); 2633 2634 // Check if this is a TLS variable or global register. 2635 if (VD->getTLSKind() != VarDecl::TLS_None || 2636 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2637 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2638 !VD->isLocalVarDecl())) 2639 continue; 2640 2641 // If the used several times in the allocate directive, the same allocator 2642 // must be used. 2643 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2644 AllocatorKind, Allocator)) 2645 continue; 2646 2647 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2648 // If a list item has a static storage type, the allocator expression in the 2649 // allocator clause must be a constant expression that evaluates to one of 2650 // the predefined memory allocator values. 2651 if (Allocator && VD->hasGlobalStorage()) { 2652 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2653 Diag(Allocator->getExprLoc(), 2654 diag::err_omp_expected_predefined_allocator) 2655 << Allocator->getSourceRange(); 2656 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2657 VarDecl::DeclarationOnly; 2658 Diag(VD->getLocation(), 2659 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2660 << VD; 2661 continue; 2662 } 2663 } 2664 2665 Vars.push_back(RefExpr); 2666 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2667 DE->getSourceRange()); 2668 } 2669 if (Vars.empty()) 2670 return nullptr; 2671 if (!Owner) 2672 Owner = getCurLexicalContext(); 2673 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2674 D->setAccess(AS_public); 2675 Owner->addDecl(D); 2676 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2677 } 2678 2679 Sema::DeclGroupPtrTy 2680 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2681 ArrayRef<OMPClause *> ClauseList) { 2682 OMPRequiresDecl *D = nullptr; 2683 if (!CurContext->isFileContext()) { 2684 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2685 } else { 2686 D = CheckOMPRequiresDecl(Loc, ClauseList); 2687 if (D) { 2688 CurContext->addDecl(D); 2689 DSAStack->addRequiresDecl(D); 2690 } 2691 } 2692 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2693 } 2694 2695 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2696 ArrayRef<OMPClause *> ClauseList) { 2697 /// For target specific clauses, the requires directive cannot be 2698 /// specified after the handling of any of the target regions in the 2699 /// current compilation unit. 2700 ArrayRef<SourceLocation> TargetLocations = 2701 DSAStack->getEncounteredTargetLocs(); 2702 if (!TargetLocations.empty()) { 2703 for (const OMPClause *CNew : ClauseList) { 2704 // Check if any of the requires clauses affect target regions. 2705 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2706 isa<OMPUnifiedAddressClause>(CNew) || 2707 isa<OMPReverseOffloadClause>(CNew) || 2708 isa<OMPDynamicAllocatorsClause>(CNew)) { 2709 Diag(Loc, diag::err_omp_target_before_requires) 2710 << getOpenMPClauseName(CNew->getClauseKind()); 2711 for (SourceLocation TargetLoc : TargetLocations) { 2712 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2713 } 2714 } 2715 } 2716 } 2717 2718 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2719 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2720 ClauseList); 2721 return nullptr; 2722 } 2723 2724 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2725 const ValueDecl *D, 2726 const DSAStackTy::DSAVarData &DVar, 2727 bool IsLoopIterVar = false) { 2728 if (DVar.RefExpr) { 2729 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2730 << getOpenMPClauseName(DVar.CKind); 2731 return; 2732 } 2733 enum { 2734 PDSA_StaticMemberShared, 2735 PDSA_StaticLocalVarShared, 2736 PDSA_LoopIterVarPrivate, 2737 PDSA_LoopIterVarLinear, 2738 PDSA_LoopIterVarLastprivate, 2739 PDSA_ConstVarShared, 2740 PDSA_GlobalVarShared, 2741 PDSA_TaskVarFirstprivate, 2742 PDSA_LocalVarPrivate, 2743 PDSA_Implicit 2744 } Reason = PDSA_Implicit; 2745 bool ReportHint = false; 2746 auto ReportLoc = D->getLocation(); 2747 auto *VD = dyn_cast<VarDecl>(D); 2748 if (IsLoopIterVar) { 2749 if (DVar.CKind == OMPC_private) 2750 Reason = PDSA_LoopIterVarPrivate; 2751 else if (DVar.CKind == OMPC_lastprivate) 2752 Reason = PDSA_LoopIterVarLastprivate; 2753 else 2754 Reason = PDSA_LoopIterVarLinear; 2755 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2756 DVar.CKind == OMPC_firstprivate) { 2757 Reason = PDSA_TaskVarFirstprivate; 2758 ReportLoc = DVar.ImplicitDSALoc; 2759 } else if (VD && VD->isStaticLocal()) 2760 Reason = PDSA_StaticLocalVarShared; 2761 else if (VD && VD->isStaticDataMember()) 2762 Reason = PDSA_StaticMemberShared; 2763 else if (VD && VD->isFileVarDecl()) 2764 Reason = PDSA_GlobalVarShared; 2765 else if (D->getType().isConstant(SemaRef.getASTContext())) 2766 Reason = PDSA_ConstVarShared; 2767 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2768 ReportHint = true; 2769 Reason = PDSA_LocalVarPrivate; 2770 } 2771 if (Reason != PDSA_Implicit) { 2772 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2773 << Reason << ReportHint 2774 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2775 } else if (DVar.ImplicitDSALoc.isValid()) { 2776 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2777 << getOpenMPClauseName(DVar.CKind); 2778 } 2779 } 2780 2781 namespace { 2782 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2783 DSAStackTy *Stack; 2784 Sema &SemaRef; 2785 bool ErrorFound = false; 2786 CapturedStmt *CS = nullptr; 2787 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2788 llvm::SmallVector<Expr *, 4> ImplicitMap; 2789 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2790 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2791 2792 void VisitSubCaptures(OMPExecutableDirective *S) { 2793 // Check implicitly captured variables. 2794 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2795 return; 2796 visitSubCaptures(S->getInnermostCapturedStmt()); 2797 } 2798 2799 public: 2800 void VisitDeclRefExpr(DeclRefExpr *E) { 2801 if (E->isTypeDependent() || E->isValueDependent() || 2802 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2803 return; 2804 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2805 // Check the datasharing rules for the expressions in the clauses. 2806 if (!CS) { 2807 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2808 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2809 Visit(CED->getInit()); 2810 return; 2811 } 2812 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2813 // Do not analyze internal variables and do not enclose them into 2814 // implicit clauses. 2815 return; 2816 VD = VD->getCanonicalDecl(); 2817 // Skip internally declared variables. 2818 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2819 return; 2820 2821 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2822 // Check if the variable has explicit DSA set and stop analysis if it so. 2823 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2824 return; 2825 2826 // Skip internally declared static variables. 2827 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2828 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2829 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2830 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2831 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2832 return; 2833 2834 SourceLocation ELoc = E->getExprLoc(); 2835 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2836 // The default(none) clause requires that each variable that is referenced 2837 // in the construct, and does not have a predetermined data-sharing 2838 // attribute, must have its data-sharing attribute explicitly determined 2839 // by being listed in a data-sharing attribute clause. 2840 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2841 isImplicitOrExplicitTaskingRegion(DKind) && 2842 VarsWithInheritedDSA.count(VD) == 0) { 2843 VarsWithInheritedDSA[VD] = E; 2844 return; 2845 } 2846 2847 if (isOpenMPTargetExecutionDirective(DKind) && 2848 !Stack->isLoopControlVariable(VD).first) { 2849 if (!Stack->checkMappableExprComponentListsForDecl( 2850 VD, /*CurrentRegionOnly=*/true, 2851 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2852 StackComponents, 2853 OpenMPClauseKind) { 2854 // Variable is used if it has been marked as an array, array 2855 // section or the variable iself. 2856 return StackComponents.size() == 1 || 2857 std::all_of( 2858 std::next(StackComponents.rbegin()), 2859 StackComponents.rend(), 2860 [](const OMPClauseMappableExprCommon:: 2861 MappableComponent &MC) { 2862 return MC.getAssociatedDeclaration() == 2863 nullptr && 2864 (isa<OMPArraySectionExpr>( 2865 MC.getAssociatedExpression()) || 2866 isa<ArraySubscriptExpr>( 2867 MC.getAssociatedExpression())); 2868 }); 2869 })) { 2870 bool IsFirstprivate = false; 2871 // By default lambdas are captured as firstprivates. 2872 if (const auto *RD = 2873 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2874 IsFirstprivate = RD->isLambda(); 2875 IsFirstprivate = 2876 IsFirstprivate || 2877 (VD->getType().getNonReferenceType()->isScalarType() && 2878 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2879 if (IsFirstprivate) 2880 ImplicitFirstprivate.emplace_back(E); 2881 else 2882 ImplicitMap.emplace_back(E); 2883 return; 2884 } 2885 } 2886 2887 // OpenMP [2.9.3.6, Restrictions, p.2] 2888 // A list item that appears in a reduction clause of the innermost 2889 // enclosing worksharing or parallel construct may not be accessed in an 2890 // explicit task. 2891 DVar = Stack->hasInnermostDSA( 2892 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2893 [](OpenMPDirectiveKind K) { 2894 return isOpenMPParallelDirective(K) || 2895 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2896 }, 2897 /*FromParent=*/true); 2898 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2899 ErrorFound = true; 2900 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2901 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2902 return; 2903 } 2904 2905 // Define implicit data-sharing attributes for task. 2906 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2907 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2908 !Stack->isLoopControlVariable(VD).first) { 2909 ImplicitFirstprivate.push_back(E); 2910 return; 2911 } 2912 2913 // Store implicitly used globals with declare target link for parent 2914 // target. 2915 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2916 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2917 Stack->addToParentTargetRegionLinkGlobals(E); 2918 return; 2919 } 2920 } 2921 } 2922 void VisitMemberExpr(MemberExpr *E) { 2923 if (E->isTypeDependent() || E->isValueDependent() || 2924 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2925 return; 2926 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2927 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2928 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2929 if (!FD) 2930 return; 2931 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2932 // Check if the variable has explicit DSA set and stop analysis if it 2933 // so. 2934 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2935 return; 2936 2937 if (isOpenMPTargetExecutionDirective(DKind) && 2938 !Stack->isLoopControlVariable(FD).first && 2939 !Stack->checkMappableExprComponentListsForDecl( 2940 FD, /*CurrentRegionOnly=*/true, 2941 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2942 StackComponents, 2943 OpenMPClauseKind) { 2944 return isa<CXXThisExpr>( 2945 cast<MemberExpr>( 2946 StackComponents.back().getAssociatedExpression()) 2947 ->getBase() 2948 ->IgnoreParens()); 2949 })) { 2950 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2951 // A bit-field cannot appear in a map clause. 2952 // 2953 if (FD->isBitField()) 2954 return; 2955 2956 // Check to see if the member expression is referencing a class that 2957 // has already been explicitly mapped 2958 if (Stack->isClassPreviouslyMapped(TE->getType())) 2959 return; 2960 2961 ImplicitMap.emplace_back(E); 2962 return; 2963 } 2964 2965 SourceLocation ELoc = E->getExprLoc(); 2966 // OpenMP [2.9.3.6, Restrictions, p.2] 2967 // A list item that appears in a reduction clause of the innermost 2968 // enclosing worksharing or parallel construct may not be accessed in 2969 // an explicit task. 2970 DVar = Stack->hasInnermostDSA( 2971 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2972 [](OpenMPDirectiveKind K) { 2973 return isOpenMPParallelDirective(K) || 2974 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2975 }, 2976 /*FromParent=*/true); 2977 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2978 ErrorFound = true; 2979 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2980 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2981 return; 2982 } 2983 2984 // Define implicit data-sharing attributes for task. 2985 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2986 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2987 !Stack->isLoopControlVariable(FD).first) { 2988 // Check if there is a captured expression for the current field in the 2989 // region. Do not mark it as firstprivate unless there is no captured 2990 // expression. 2991 // TODO: try to make it firstprivate. 2992 if (DVar.CKind != OMPC_unknown) 2993 ImplicitFirstprivate.push_back(E); 2994 } 2995 return; 2996 } 2997 if (isOpenMPTargetExecutionDirective(DKind)) { 2998 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2999 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3000 /*NoDiagnose=*/true)) 3001 return; 3002 const auto *VD = cast<ValueDecl>( 3003 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3004 if (!Stack->checkMappableExprComponentListsForDecl( 3005 VD, /*CurrentRegionOnly=*/true, 3006 [&CurComponents]( 3007 OMPClauseMappableExprCommon::MappableExprComponentListRef 3008 StackComponents, 3009 OpenMPClauseKind) { 3010 auto CCI = CurComponents.rbegin(); 3011 auto CCE = CurComponents.rend(); 3012 for (const auto &SC : llvm::reverse(StackComponents)) { 3013 // Do both expressions have the same kind? 3014 if (CCI->getAssociatedExpression()->getStmtClass() != 3015 SC.getAssociatedExpression()->getStmtClass()) 3016 if (!(isa<OMPArraySectionExpr>( 3017 SC.getAssociatedExpression()) && 3018 isa<ArraySubscriptExpr>( 3019 CCI->getAssociatedExpression()))) 3020 return false; 3021 3022 const Decl *CCD = CCI->getAssociatedDeclaration(); 3023 const Decl *SCD = SC.getAssociatedDeclaration(); 3024 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3025 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3026 if (SCD != CCD) 3027 return false; 3028 std::advance(CCI, 1); 3029 if (CCI == CCE) 3030 break; 3031 } 3032 return true; 3033 })) { 3034 Visit(E->getBase()); 3035 } 3036 } else { 3037 Visit(E->getBase()); 3038 } 3039 } 3040 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3041 for (OMPClause *C : S->clauses()) { 3042 // Skip analysis of arguments of implicitly defined firstprivate clause 3043 // for task|target directives. 3044 // Skip analysis of arguments of implicitly defined map clause for target 3045 // directives. 3046 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3047 C->isImplicit())) { 3048 for (Stmt *CC : C->children()) { 3049 if (CC) 3050 Visit(CC); 3051 } 3052 } 3053 } 3054 // Check implicitly captured variables. 3055 VisitSubCaptures(S); 3056 } 3057 void VisitStmt(Stmt *S) { 3058 for (Stmt *C : S->children()) { 3059 if (C) { 3060 // Check implicitly captured variables in the task-based directives to 3061 // check if they must be firstprivatized. 3062 Visit(C); 3063 } 3064 } 3065 } 3066 3067 void visitSubCaptures(CapturedStmt *S) { 3068 for (const CapturedStmt::Capture &Cap : S->captures()) { 3069 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3070 continue; 3071 VarDecl *VD = Cap.getCapturedVar(); 3072 // Do not try to map the variable if it or its sub-component was mapped 3073 // already. 3074 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3075 Stack->checkMappableExprComponentListsForDecl( 3076 VD, /*CurrentRegionOnly=*/true, 3077 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3078 OpenMPClauseKind) { return true; })) 3079 continue; 3080 DeclRefExpr *DRE = buildDeclRefExpr( 3081 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3082 Cap.getLocation(), /*RefersToCapture=*/true); 3083 Visit(DRE); 3084 } 3085 } 3086 bool isErrorFound() const { return ErrorFound; } 3087 ArrayRef<Expr *> getImplicitFirstprivate() const { 3088 return ImplicitFirstprivate; 3089 } 3090 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 3091 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3092 return VarsWithInheritedDSA; 3093 } 3094 3095 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3096 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3097 // Process declare target link variables for the target directives. 3098 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3099 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3100 Visit(E); 3101 } 3102 } 3103 }; 3104 } // namespace 3105 3106 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3107 switch (DKind) { 3108 case OMPD_parallel: 3109 case OMPD_parallel_for: 3110 case OMPD_parallel_for_simd: 3111 case OMPD_parallel_sections: 3112 case OMPD_teams: 3113 case OMPD_teams_distribute: 3114 case OMPD_teams_distribute_simd: { 3115 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3116 QualType KmpInt32PtrTy = 3117 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3118 Sema::CapturedParamNameType Params[] = { 3119 std::make_pair(".global_tid.", KmpInt32PtrTy), 3120 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3121 std::make_pair(StringRef(), QualType()) // __context with shared vars 3122 }; 3123 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3124 Params); 3125 break; 3126 } 3127 case OMPD_target_teams: 3128 case OMPD_target_parallel: 3129 case OMPD_target_parallel_for: 3130 case OMPD_target_parallel_for_simd: 3131 case OMPD_target_teams_distribute: 3132 case OMPD_target_teams_distribute_simd: { 3133 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3134 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3135 QualType KmpInt32PtrTy = 3136 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3137 QualType Args[] = {VoidPtrTy}; 3138 FunctionProtoType::ExtProtoInfo EPI; 3139 EPI.Variadic = true; 3140 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3141 Sema::CapturedParamNameType Params[] = { 3142 std::make_pair(".global_tid.", KmpInt32Ty), 3143 std::make_pair(".part_id.", KmpInt32PtrTy), 3144 std::make_pair(".privates.", VoidPtrTy), 3145 std::make_pair( 3146 ".copy_fn.", 3147 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3148 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3149 std::make_pair(StringRef(), QualType()) // __context with shared vars 3150 }; 3151 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3152 Params, /*OpenMPCaptureLevel=*/0); 3153 // Mark this captured region as inlined, because we don't use outlined 3154 // function directly. 3155 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3156 AlwaysInlineAttr::CreateImplicit( 3157 Context, AlwaysInlineAttr::Keyword_forceinline)); 3158 Sema::CapturedParamNameType ParamsTarget[] = { 3159 std::make_pair(StringRef(), QualType()) // __context with shared vars 3160 }; 3161 // Start a captured region for 'target' with no implicit parameters. 3162 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3163 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3164 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3165 std::make_pair(".global_tid.", KmpInt32PtrTy), 3166 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3167 std::make_pair(StringRef(), QualType()) // __context with shared vars 3168 }; 3169 // Start a captured region for 'teams' or 'parallel'. Both regions have 3170 // the same implicit parameters. 3171 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3172 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3173 break; 3174 } 3175 case OMPD_target: 3176 case OMPD_target_simd: { 3177 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3178 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3179 QualType KmpInt32PtrTy = 3180 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3181 QualType Args[] = {VoidPtrTy}; 3182 FunctionProtoType::ExtProtoInfo EPI; 3183 EPI.Variadic = true; 3184 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3185 Sema::CapturedParamNameType Params[] = { 3186 std::make_pair(".global_tid.", KmpInt32Ty), 3187 std::make_pair(".part_id.", KmpInt32PtrTy), 3188 std::make_pair(".privates.", VoidPtrTy), 3189 std::make_pair( 3190 ".copy_fn.", 3191 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3192 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3193 std::make_pair(StringRef(), QualType()) // __context with shared vars 3194 }; 3195 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3196 Params, /*OpenMPCaptureLevel=*/0); 3197 // Mark this captured region as inlined, because we don't use outlined 3198 // function directly. 3199 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3200 AlwaysInlineAttr::CreateImplicit( 3201 Context, AlwaysInlineAttr::Keyword_forceinline)); 3202 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3203 std::make_pair(StringRef(), QualType()), 3204 /*OpenMPCaptureLevel=*/1); 3205 break; 3206 } 3207 case OMPD_simd: 3208 case OMPD_for: 3209 case OMPD_for_simd: 3210 case OMPD_sections: 3211 case OMPD_section: 3212 case OMPD_single: 3213 case OMPD_master: 3214 case OMPD_critical: 3215 case OMPD_taskgroup: 3216 case OMPD_distribute: 3217 case OMPD_distribute_simd: 3218 case OMPD_ordered: 3219 case OMPD_atomic: 3220 case OMPD_target_data: { 3221 Sema::CapturedParamNameType Params[] = { 3222 std::make_pair(StringRef(), QualType()) // __context with shared vars 3223 }; 3224 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3225 Params); 3226 break; 3227 } 3228 case OMPD_task: { 3229 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3230 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3231 QualType KmpInt32PtrTy = 3232 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3233 QualType Args[] = {VoidPtrTy}; 3234 FunctionProtoType::ExtProtoInfo EPI; 3235 EPI.Variadic = true; 3236 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3237 Sema::CapturedParamNameType Params[] = { 3238 std::make_pair(".global_tid.", KmpInt32Ty), 3239 std::make_pair(".part_id.", KmpInt32PtrTy), 3240 std::make_pair(".privates.", VoidPtrTy), 3241 std::make_pair( 3242 ".copy_fn.", 3243 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3244 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3245 std::make_pair(StringRef(), QualType()) // __context with shared vars 3246 }; 3247 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3248 Params); 3249 // Mark this captured region as inlined, because we don't use outlined 3250 // function directly. 3251 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3252 AlwaysInlineAttr::CreateImplicit( 3253 Context, AlwaysInlineAttr::Keyword_forceinline)); 3254 break; 3255 } 3256 case OMPD_taskloop: 3257 case OMPD_taskloop_simd: { 3258 QualType KmpInt32Ty = 3259 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3260 .withConst(); 3261 QualType KmpUInt64Ty = 3262 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3263 .withConst(); 3264 QualType KmpInt64Ty = 3265 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3266 .withConst(); 3267 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3268 QualType KmpInt32PtrTy = 3269 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3270 QualType Args[] = {VoidPtrTy}; 3271 FunctionProtoType::ExtProtoInfo EPI; 3272 EPI.Variadic = true; 3273 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3274 Sema::CapturedParamNameType Params[] = { 3275 std::make_pair(".global_tid.", KmpInt32Ty), 3276 std::make_pair(".part_id.", KmpInt32PtrTy), 3277 std::make_pair(".privates.", VoidPtrTy), 3278 std::make_pair( 3279 ".copy_fn.", 3280 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3281 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3282 std::make_pair(".lb.", KmpUInt64Ty), 3283 std::make_pair(".ub.", KmpUInt64Ty), 3284 std::make_pair(".st.", KmpInt64Ty), 3285 std::make_pair(".liter.", KmpInt32Ty), 3286 std::make_pair(".reductions.", VoidPtrTy), 3287 std::make_pair(StringRef(), QualType()) // __context with shared vars 3288 }; 3289 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3290 Params); 3291 // Mark this captured region as inlined, because we don't use outlined 3292 // function directly. 3293 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3294 AlwaysInlineAttr::CreateImplicit( 3295 Context, AlwaysInlineAttr::Keyword_forceinline)); 3296 break; 3297 } 3298 case OMPD_distribute_parallel_for_simd: 3299 case OMPD_distribute_parallel_for: { 3300 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3301 QualType KmpInt32PtrTy = 3302 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3303 Sema::CapturedParamNameType Params[] = { 3304 std::make_pair(".global_tid.", KmpInt32PtrTy), 3305 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3306 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3307 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3308 std::make_pair(StringRef(), QualType()) // __context with shared vars 3309 }; 3310 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3311 Params); 3312 break; 3313 } 3314 case OMPD_target_teams_distribute_parallel_for: 3315 case OMPD_target_teams_distribute_parallel_for_simd: { 3316 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3317 QualType KmpInt32PtrTy = 3318 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3319 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3320 3321 QualType Args[] = {VoidPtrTy}; 3322 FunctionProtoType::ExtProtoInfo EPI; 3323 EPI.Variadic = true; 3324 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3325 Sema::CapturedParamNameType Params[] = { 3326 std::make_pair(".global_tid.", KmpInt32Ty), 3327 std::make_pair(".part_id.", KmpInt32PtrTy), 3328 std::make_pair(".privates.", VoidPtrTy), 3329 std::make_pair( 3330 ".copy_fn.", 3331 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3332 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3333 std::make_pair(StringRef(), QualType()) // __context with shared vars 3334 }; 3335 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3336 Params, /*OpenMPCaptureLevel=*/0); 3337 // Mark this captured region as inlined, because we don't use outlined 3338 // function directly. 3339 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3340 AlwaysInlineAttr::CreateImplicit( 3341 Context, AlwaysInlineAttr::Keyword_forceinline)); 3342 Sema::CapturedParamNameType ParamsTarget[] = { 3343 std::make_pair(StringRef(), QualType()) // __context with shared vars 3344 }; 3345 // Start a captured region for 'target' with no implicit parameters. 3346 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3347 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3348 3349 Sema::CapturedParamNameType ParamsTeams[] = { 3350 std::make_pair(".global_tid.", KmpInt32PtrTy), 3351 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3352 std::make_pair(StringRef(), QualType()) // __context with shared vars 3353 }; 3354 // Start a captured region for 'target' with no implicit parameters. 3355 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3356 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3357 3358 Sema::CapturedParamNameType ParamsParallel[] = { 3359 std::make_pair(".global_tid.", KmpInt32PtrTy), 3360 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3361 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3362 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3363 std::make_pair(StringRef(), QualType()) // __context with shared vars 3364 }; 3365 // Start a captured region for 'teams' or 'parallel'. Both regions have 3366 // the same implicit parameters. 3367 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3368 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3369 break; 3370 } 3371 3372 case OMPD_teams_distribute_parallel_for: 3373 case OMPD_teams_distribute_parallel_for_simd: { 3374 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3375 QualType KmpInt32PtrTy = 3376 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3377 3378 Sema::CapturedParamNameType ParamsTeams[] = { 3379 std::make_pair(".global_tid.", KmpInt32PtrTy), 3380 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3381 std::make_pair(StringRef(), QualType()) // __context with shared vars 3382 }; 3383 // Start a captured region for 'target' with no implicit parameters. 3384 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3385 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3386 3387 Sema::CapturedParamNameType ParamsParallel[] = { 3388 std::make_pair(".global_tid.", KmpInt32PtrTy), 3389 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3390 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3391 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3392 std::make_pair(StringRef(), QualType()) // __context with shared vars 3393 }; 3394 // Start a captured region for 'teams' or 'parallel'. Both regions have 3395 // the same implicit parameters. 3396 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3397 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3398 break; 3399 } 3400 case OMPD_target_update: 3401 case OMPD_target_enter_data: 3402 case OMPD_target_exit_data: { 3403 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3404 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3405 QualType KmpInt32PtrTy = 3406 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3407 QualType Args[] = {VoidPtrTy}; 3408 FunctionProtoType::ExtProtoInfo EPI; 3409 EPI.Variadic = true; 3410 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3411 Sema::CapturedParamNameType Params[] = { 3412 std::make_pair(".global_tid.", KmpInt32Ty), 3413 std::make_pair(".part_id.", KmpInt32PtrTy), 3414 std::make_pair(".privates.", VoidPtrTy), 3415 std::make_pair( 3416 ".copy_fn.", 3417 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3418 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3419 std::make_pair(StringRef(), QualType()) // __context with shared vars 3420 }; 3421 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3422 Params); 3423 // Mark this captured region as inlined, because we don't use outlined 3424 // function directly. 3425 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3426 AlwaysInlineAttr::CreateImplicit( 3427 Context, AlwaysInlineAttr::Keyword_forceinline)); 3428 break; 3429 } 3430 case OMPD_threadprivate: 3431 case OMPD_allocate: 3432 case OMPD_taskyield: 3433 case OMPD_barrier: 3434 case OMPD_taskwait: 3435 case OMPD_cancellation_point: 3436 case OMPD_cancel: 3437 case OMPD_flush: 3438 case OMPD_declare_reduction: 3439 case OMPD_declare_mapper: 3440 case OMPD_declare_simd: 3441 case OMPD_declare_target: 3442 case OMPD_end_declare_target: 3443 case OMPD_requires: 3444 llvm_unreachable("OpenMP Directive is not allowed"); 3445 case OMPD_unknown: 3446 llvm_unreachable("Unknown OpenMP directive"); 3447 } 3448 } 3449 3450 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3451 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3452 getOpenMPCaptureRegions(CaptureRegions, DKind); 3453 return CaptureRegions.size(); 3454 } 3455 3456 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3457 Expr *CaptureExpr, bool WithInit, 3458 bool AsExpression) { 3459 assert(CaptureExpr); 3460 ASTContext &C = S.getASTContext(); 3461 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3462 QualType Ty = Init->getType(); 3463 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3464 if (S.getLangOpts().CPlusPlus) { 3465 Ty = C.getLValueReferenceType(Ty); 3466 } else { 3467 Ty = C.getPointerType(Ty); 3468 ExprResult Res = 3469 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3470 if (!Res.isUsable()) 3471 return nullptr; 3472 Init = Res.get(); 3473 } 3474 WithInit = true; 3475 } 3476 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3477 CaptureExpr->getBeginLoc()); 3478 if (!WithInit) 3479 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3480 S.CurContext->addHiddenDecl(CED); 3481 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3482 return CED; 3483 } 3484 3485 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3486 bool WithInit) { 3487 OMPCapturedExprDecl *CD; 3488 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3489 CD = cast<OMPCapturedExprDecl>(VD); 3490 else 3491 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3492 /*AsExpression=*/false); 3493 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3494 CaptureExpr->getExprLoc()); 3495 } 3496 3497 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3498 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3499 if (!Ref) { 3500 OMPCapturedExprDecl *CD = buildCaptureDecl( 3501 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3502 /*WithInit=*/true, /*AsExpression=*/true); 3503 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3504 CaptureExpr->getExprLoc()); 3505 } 3506 ExprResult Res = Ref; 3507 if (!S.getLangOpts().CPlusPlus && 3508 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3509 Ref->getType()->isPointerType()) { 3510 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3511 if (!Res.isUsable()) 3512 return ExprError(); 3513 } 3514 return S.DefaultLvalueConversion(Res.get()); 3515 } 3516 3517 namespace { 3518 // OpenMP directives parsed in this section are represented as a 3519 // CapturedStatement with an associated statement. If a syntax error 3520 // is detected during the parsing of the associated statement, the 3521 // compiler must abort processing and close the CapturedStatement. 3522 // 3523 // Combined directives such as 'target parallel' have more than one 3524 // nested CapturedStatements. This RAII ensures that we unwind out 3525 // of all the nested CapturedStatements when an error is found. 3526 class CaptureRegionUnwinderRAII { 3527 private: 3528 Sema &S; 3529 bool &ErrorFound; 3530 OpenMPDirectiveKind DKind = OMPD_unknown; 3531 3532 public: 3533 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3534 OpenMPDirectiveKind DKind) 3535 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3536 ~CaptureRegionUnwinderRAII() { 3537 if (ErrorFound) { 3538 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3539 while (--ThisCaptureLevel >= 0) 3540 S.ActOnCapturedRegionError(); 3541 } 3542 } 3543 }; 3544 } // namespace 3545 3546 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3547 // Capture variables captured by reference in lambdas for target-based 3548 // directives. 3549 if (!CurContext->isDependentContext() && 3550 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3551 isOpenMPTargetDataManagementDirective( 3552 DSAStack->getCurrentDirective()))) { 3553 QualType Type = V->getType(); 3554 if (const auto *RD = Type.getCanonicalType() 3555 .getNonReferenceType() 3556 ->getAsCXXRecordDecl()) { 3557 bool SavedForceCaptureByReferenceInTargetExecutable = 3558 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3559 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3560 /*V=*/true); 3561 if (RD->isLambda()) { 3562 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3563 FieldDecl *ThisCapture; 3564 RD->getCaptureFields(Captures, ThisCapture); 3565 for (const LambdaCapture &LC : RD->captures()) { 3566 if (LC.getCaptureKind() == LCK_ByRef) { 3567 VarDecl *VD = LC.getCapturedVar(); 3568 DeclContext *VDC = VD->getDeclContext(); 3569 if (!VDC->Encloses(CurContext)) 3570 continue; 3571 MarkVariableReferenced(LC.getLocation(), VD); 3572 } else if (LC.getCaptureKind() == LCK_This) { 3573 QualType ThisTy = getCurrentThisType(); 3574 if (!ThisTy.isNull() && 3575 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3576 CheckCXXThisCapture(LC.getLocation()); 3577 } 3578 } 3579 } 3580 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3581 SavedForceCaptureByReferenceInTargetExecutable); 3582 } 3583 } 3584 } 3585 3586 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3587 ArrayRef<OMPClause *> Clauses) { 3588 bool ErrorFound = false; 3589 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3590 *this, ErrorFound, DSAStack->getCurrentDirective()); 3591 if (!S.isUsable()) { 3592 ErrorFound = true; 3593 return StmtError(); 3594 } 3595 3596 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3597 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3598 OMPOrderedClause *OC = nullptr; 3599 OMPScheduleClause *SC = nullptr; 3600 SmallVector<const OMPLinearClause *, 4> LCs; 3601 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3602 // This is required for proper codegen. 3603 for (OMPClause *Clause : Clauses) { 3604 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3605 Clause->getClauseKind() == OMPC_in_reduction) { 3606 // Capture taskgroup task_reduction descriptors inside the tasking regions 3607 // with the corresponding in_reduction items. 3608 auto *IRC = cast<OMPInReductionClause>(Clause); 3609 for (Expr *E : IRC->taskgroup_descriptors()) 3610 if (E) 3611 MarkDeclarationsReferencedInExpr(E); 3612 } 3613 if (isOpenMPPrivate(Clause->getClauseKind()) || 3614 Clause->getClauseKind() == OMPC_copyprivate || 3615 (getLangOpts().OpenMPUseTLS && 3616 getASTContext().getTargetInfo().isTLSSupported() && 3617 Clause->getClauseKind() == OMPC_copyin)) { 3618 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3619 // Mark all variables in private list clauses as used in inner region. 3620 for (Stmt *VarRef : Clause->children()) { 3621 if (auto *E = cast_or_null<Expr>(VarRef)) { 3622 MarkDeclarationsReferencedInExpr(E); 3623 } 3624 } 3625 DSAStack->setForceVarCapturing(/*V=*/false); 3626 } else if (CaptureRegions.size() > 1 || 3627 CaptureRegions.back() != OMPD_unknown) { 3628 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3629 PICs.push_back(C); 3630 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3631 if (Expr *E = C->getPostUpdateExpr()) 3632 MarkDeclarationsReferencedInExpr(E); 3633 } 3634 } 3635 if (Clause->getClauseKind() == OMPC_schedule) 3636 SC = cast<OMPScheduleClause>(Clause); 3637 else if (Clause->getClauseKind() == OMPC_ordered) 3638 OC = cast<OMPOrderedClause>(Clause); 3639 else if (Clause->getClauseKind() == OMPC_linear) 3640 LCs.push_back(cast<OMPLinearClause>(Clause)); 3641 } 3642 // OpenMP, 2.7.1 Loop Construct, Restrictions 3643 // The nonmonotonic modifier cannot be specified if an ordered clause is 3644 // specified. 3645 if (SC && 3646 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3647 SC->getSecondScheduleModifier() == 3648 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3649 OC) { 3650 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3651 ? SC->getFirstScheduleModifierLoc() 3652 : SC->getSecondScheduleModifierLoc(), 3653 diag::err_omp_schedule_nonmonotonic_ordered) 3654 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3655 ErrorFound = true; 3656 } 3657 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3658 for (const OMPLinearClause *C : LCs) { 3659 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3660 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3661 } 3662 ErrorFound = true; 3663 } 3664 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3665 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3666 OC->getNumForLoops()) { 3667 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3668 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3669 ErrorFound = true; 3670 } 3671 if (ErrorFound) { 3672 return StmtError(); 3673 } 3674 StmtResult SR = S; 3675 unsigned CompletedRegions = 0; 3676 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3677 // Mark all variables in private list clauses as used in inner region. 3678 // Required for proper codegen of combined directives. 3679 // TODO: add processing for other clauses. 3680 if (ThisCaptureRegion != OMPD_unknown) { 3681 for (const clang::OMPClauseWithPreInit *C : PICs) { 3682 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3683 // Find the particular capture region for the clause if the 3684 // directive is a combined one with multiple capture regions. 3685 // If the directive is not a combined one, the capture region 3686 // associated with the clause is OMPD_unknown and is generated 3687 // only once. 3688 if (CaptureRegion == ThisCaptureRegion || 3689 CaptureRegion == OMPD_unknown) { 3690 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3691 for (Decl *D : DS->decls()) 3692 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3693 } 3694 } 3695 } 3696 } 3697 if (++CompletedRegions == CaptureRegions.size()) 3698 DSAStack->setBodyComplete(); 3699 SR = ActOnCapturedRegionEnd(SR.get()); 3700 } 3701 return SR; 3702 } 3703 3704 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3705 OpenMPDirectiveKind CancelRegion, 3706 SourceLocation StartLoc) { 3707 // CancelRegion is only needed for cancel and cancellation_point. 3708 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3709 return false; 3710 3711 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3712 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3713 return false; 3714 3715 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3716 << getOpenMPDirectiveName(CancelRegion); 3717 return true; 3718 } 3719 3720 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3721 OpenMPDirectiveKind CurrentRegion, 3722 const DeclarationNameInfo &CurrentName, 3723 OpenMPDirectiveKind CancelRegion, 3724 SourceLocation StartLoc) { 3725 if (Stack->getCurScope()) { 3726 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3727 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3728 bool NestingProhibited = false; 3729 bool CloseNesting = true; 3730 bool OrphanSeen = false; 3731 enum { 3732 NoRecommend, 3733 ShouldBeInParallelRegion, 3734 ShouldBeInOrderedRegion, 3735 ShouldBeInTargetRegion, 3736 ShouldBeInTeamsRegion 3737 } Recommend = NoRecommend; 3738 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3739 // OpenMP [2.16, Nesting of Regions] 3740 // OpenMP constructs may not be nested inside a simd region. 3741 // OpenMP [2.8.1,simd Construct, Restrictions] 3742 // An ordered construct with the simd clause is the only OpenMP 3743 // construct that can appear in the simd region. 3744 // Allowing a SIMD construct nested in another SIMD construct is an 3745 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3746 // message. 3747 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3748 ? diag::err_omp_prohibited_region_simd 3749 : diag::warn_omp_nesting_simd); 3750 return CurrentRegion != OMPD_simd; 3751 } 3752 if (ParentRegion == OMPD_atomic) { 3753 // OpenMP [2.16, Nesting of Regions] 3754 // OpenMP constructs may not be nested inside an atomic region. 3755 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3756 return true; 3757 } 3758 if (CurrentRegion == OMPD_section) { 3759 // OpenMP [2.7.2, sections Construct, Restrictions] 3760 // Orphaned section directives are prohibited. That is, the section 3761 // directives must appear within the sections construct and must not be 3762 // encountered elsewhere in the sections region. 3763 if (ParentRegion != OMPD_sections && 3764 ParentRegion != OMPD_parallel_sections) { 3765 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3766 << (ParentRegion != OMPD_unknown) 3767 << getOpenMPDirectiveName(ParentRegion); 3768 return true; 3769 } 3770 return false; 3771 } 3772 // Allow some constructs (except teams and cancellation constructs) to be 3773 // orphaned (they could be used in functions, called from OpenMP regions 3774 // with the required preconditions). 3775 if (ParentRegion == OMPD_unknown && 3776 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3777 CurrentRegion != OMPD_cancellation_point && 3778 CurrentRegion != OMPD_cancel) 3779 return false; 3780 if (CurrentRegion == OMPD_cancellation_point || 3781 CurrentRegion == OMPD_cancel) { 3782 // OpenMP [2.16, Nesting of Regions] 3783 // A cancellation point construct for which construct-type-clause is 3784 // taskgroup must be nested inside a task construct. A cancellation 3785 // point construct for which construct-type-clause is not taskgroup must 3786 // be closely nested inside an OpenMP construct that matches the type 3787 // specified in construct-type-clause. 3788 // A cancel construct for which construct-type-clause is taskgroup must be 3789 // nested inside a task construct. A cancel construct for which 3790 // construct-type-clause is not taskgroup must be closely nested inside an 3791 // OpenMP construct that matches the type specified in 3792 // construct-type-clause. 3793 NestingProhibited = 3794 !((CancelRegion == OMPD_parallel && 3795 (ParentRegion == OMPD_parallel || 3796 ParentRegion == OMPD_target_parallel)) || 3797 (CancelRegion == OMPD_for && 3798 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3799 ParentRegion == OMPD_target_parallel_for || 3800 ParentRegion == OMPD_distribute_parallel_for || 3801 ParentRegion == OMPD_teams_distribute_parallel_for || 3802 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3803 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3804 (CancelRegion == OMPD_sections && 3805 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3806 ParentRegion == OMPD_parallel_sections))); 3807 OrphanSeen = ParentRegion == OMPD_unknown; 3808 } else if (CurrentRegion == OMPD_master) { 3809 // OpenMP [2.16, Nesting of Regions] 3810 // A master region may not be closely nested inside a worksharing, 3811 // atomic, or explicit task region. 3812 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3813 isOpenMPTaskingDirective(ParentRegion); 3814 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3815 // OpenMP [2.16, Nesting of Regions] 3816 // A critical region may not be nested (closely or otherwise) inside a 3817 // critical region with the same name. Note that this restriction is not 3818 // sufficient to prevent deadlock. 3819 SourceLocation PreviousCriticalLoc; 3820 bool DeadLock = Stack->hasDirective( 3821 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3822 const DeclarationNameInfo &DNI, 3823 SourceLocation Loc) { 3824 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3825 PreviousCriticalLoc = Loc; 3826 return true; 3827 } 3828 return false; 3829 }, 3830 false /* skip top directive */); 3831 if (DeadLock) { 3832 SemaRef.Diag(StartLoc, 3833 diag::err_omp_prohibited_region_critical_same_name) 3834 << CurrentName.getName(); 3835 if (PreviousCriticalLoc.isValid()) 3836 SemaRef.Diag(PreviousCriticalLoc, 3837 diag::note_omp_previous_critical_region); 3838 return true; 3839 } 3840 } else if (CurrentRegion == OMPD_barrier) { 3841 // OpenMP [2.16, Nesting of Regions] 3842 // A barrier region may not be closely nested inside a worksharing, 3843 // explicit task, critical, ordered, atomic, or master region. 3844 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3845 isOpenMPTaskingDirective(ParentRegion) || 3846 ParentRegion == OMPD_master || 3847 ParentRegion == OMPD_critical || 3848 ParentRegion == OMPD_ordered; 3849 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3850 !isOpenMPParallelDirective(CurrentRegion) && 3851 !isOpenMPTeamsDirective(CurrentRegion)) { 3852 // OpenMP [2.16, Nesting of Regions] 3853 // A worksharing region may not be closely nested inside a worksharing, 3854 // explicit task, critical, ordered, atomic, or master region. 3855 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3856 isOpenMPTaskingDirective(ParentRegion) || 3857 ParentRegion == OMPD_master || 3858 ParentRegion == OMPD_critical || 3859 ParentRegion == OMPD_ordered; 3860 Recommend = ShouldBeInParallelRegion; 3861 } else if (CurrentRegion == OMPD_ordered) { 3862 // OpenMP [2.16, Nesting of Regions] 3863 // An ordered region may not be closely nested inside a critical, 3864 // atomic, or explicit task region. 3865 // An ordered region must be closely nested inside a loop region (or 3866 // parallel loop region) with an ordered clause. 3867 // OpenMP [2.8.1,simd Construct, Restrictions] 3868 // An ordered construct with the simd clause is the only OpenMP construct 3869 // that can appear in the simd region. 3870 NestingProhibited = ParentRegion == OMPD_critical || 3871 isOpenMPTaskingDirective(ParentRegion) || 3872 !(isOpenMPSimdDirective(ParentRegion) || 3873 Stack->isParentOrderedRegion()); 3874 Recommend = ShouldBeInOrderedRegion; 3875 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3876 // OpenMP [2.16, Nesting of Regions] 3877 // If specified, a teams construct must be contained within a target 3878 // construct. 3879 NestingProhibited = ParentRegion != OMPD_target; 3880 OrphanSeen = ParentRegion == OMPD_unknown; 3881 Recommend = ShouldBeInTargetRegion; 3882 } 3883 if (!NestingProhibited && 3884 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3885 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3886 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3887 // OpenMP [2.16, Nesting of Regions] 3888 // distribute, parallel, parallel sections, parallel workshare, and the 3889 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3890 // constructs that can be closely nested in the teams region. 3891 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3892 !isOpenMPDistributeDirective(CurrentRegion); 3893 Recommend = ShouldBeInParallelRegion; 3894 } 3895 if (!NestingProhibited && 3896 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3897 // OpenMP 4.5 [2.17 Nesting of Regions] 3898 // The region associated with the distribute construct must be strictly 3899 // nested inside a teams region 3900 NestingProhibited = 3901 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3902 Recommend = ShouldBeInTeamsRegion; 3903 } 3904 if (!NestingProhibited && 3905 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3906 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3907 // OpenMP 4.5 [2.17 Nesting of Regions] 3908 // If a target, target update, target data, target enter data, or 3909 // target exit data construct is encountered during execution of a 3910 // target region, the behavior is unspecified. 3911 NestingProhibited = Stack->hasDirective( 3912 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3913 SourceLocation) { 3914 if (isOpenMPTargetExecutionDirective(K)) { 3915 OffendingRegion = K; 3916 return true; 3917 } 3918 return false; 3919 }, 3920 false /* don't skip top directive */); 3921 CloseNesting = false; 3922 } 3923 if (NestingProhibited) { 3924 if (OrphanSeen) { 3925 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3926 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3927 } else { 3928 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3929 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3930 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3931 } 3932 return true; 3933 } 3934 } 3935 return false; 3936 } 3937 3938 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3939 ArrayRef<OMPClause *> Clauses, 3940 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3941 bool ErrorFound = false; 3942 unsigned NamedModifiersNumber = 0; 3943 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3944 OMPD_unknown + 1); 3945 SmallVector<SourceLocation, 4> NameModifierLoc; 3946 for (const OMPClause *C : Clauses) { 3947 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3948 // At most one if clause without a directive-name-modifier can appear on 3949 // the directive. 3950 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3951 if (FoundNameModifiers[CurNM]) { 3952 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3953 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3954 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3955 ErrorFound = true; 3956 } else if (CurNM != OMPD_unknown) { 3957 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3958 ++NamedModifiersNumber; 3959 } 3960 FoundNameModifiers[CurNM] = IC; 3961 if (CurNM == OMPD_unknown) 3962 continue; 3963 // Check if the specified name modifier is allowed for the current 3964 // directive. 3965 // At most one if clause with the particular directive-name-modifier can 3966 // appear on the directive. 3967 bool MatchFound = false; 3968 for (auto NM : AllowedNameModifiers) { 3969 if (CurNM == NM) { 3970 MatchFound = true; 3971 break; 3972 } 3973 } 3974 if (!MatchFound) { 3975 S.Diag(IC->getNameModifierLoc(), 3976 diag::err_omp_wrong_if_directive_name_modifier) 3977 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3978 ErrorFound = true; 3979 } 3980 } 3981 } 3982 // If any if clause on the directive includes a directive-name-modifier then 3983 // all if clauses on the directive must include a directive-name-modifier. 3984 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3985 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3986 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3987 diag::err_omp_no_more_if_clause); 3988 } else { 3989 std::string Values; 3990 std::string Sep(", "); 3991 unsigned AllowedCnt = 0; 3992 unsigned TotalAllowedNum = 3993 AllowedNameModifiers.size() - NamedModifiersNumber; 3994 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3995 ++Cnt) { 3996 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3997 if (!FoundNameModifiers[NM]) { 3998 Values += "'"; 3999 Values += getOpenMPDirectiveName(NM); 4000 Values += "'"; 4001 if (AllowedCnt + 2 == TotalAllowedNum) 4002 Values += " or "; 4003 else if (AllowedCnt + 1 != TotalAllowedNum) 4004 Values += Sep; 4005 ++AllowedCnt; 4006 } 4007 } 4008 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4009 diag::err_omp_unnamed_if_clause) 4010 << (TotalAllowedNum > 1) << Values; 4011 } 4012 for (SourceLocation Loc : NameModifierLoc) { 4013 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4014 } 4015 ErrorFound = true; 4016 } 4017 return ErrorFound; 4018 } 4019 4020 static std::pair<ValueDecl *, bool> 4021 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4022 SourceRange &ERange, bool AllowArraySection = false) { 4023 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4024 RefExpr->containsUnexpandedParameterPack()) 4025 return std::make_pair(nullptr, true); 4026 4027 // OpenMP [3.1, C/C++] 4028 // A list item is a variable name. 4029 // OpenMP [2.9.3.3, Restrictions, p.1] 4030 // A variable that is part of another variable (as an array or 4031 // structure element) cannot appear in a private clause. 4032 RefExpr = RefExpr->IgnoreParens(); 4033 enum { 4034 NoArrayExpr = -1, 4035 ArraySubscript = 0, 4036 OMPArraySection = 1 4037 } IsArrayExpr = NoArrayExpr; 4038 if (AllowArraySection) { 4039 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4040 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4041 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4042 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4043 RefExpr = Base; 4044 IsArrayExpr = ArraySubscript; 4045 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4046 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4047 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4048 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4049 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4050 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4051 RefExpr = Base; 4052 IsArrayExpr = OMPArraySection; 4053 } 4054 } 4055 ELoc = RefExpr->getExprLoc(); 4056 ERange = RefExpr->getSourceRange(); 4057 RefExpr = RefExpr->IgnoreParenImpCasts(); 4058 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4059 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4060 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4061 (S.getCurrentThisType().isNull() || !ME || 4062 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4063 !isa<FieldDecl>(ME->getMemberDecl()))) { 4064 if (IsArrayExpr != NoArrayExpr) { 4065 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4066 << ERange; 4067 } else { 4068 S.Diag(ELoc, 4069 AllowArraySection 4070 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4071 : diag::err_omp_expected_var_name_member_expr) 4072 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4073 } 4074 return std::make_pair(nullptr, false); 4075 } 4076 return std::make_pair( 4077 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4078 } 4079 4080 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4081 ArrayRef<OMPClause *> Clauses) { 4082 assert(!S.CurContext->isDependentContext() && 4083 "Expected non-dependent context."); 4084 auto AllocateRange = 4085 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4086 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4087 DeclToCopy; 4088 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4089 return isOpenMPPrivate(C->getClauseKind()); 4090 }); 4091 for (OMPClause *Cl : PrivateRange) { 4092 MutableArrayRef<Expr *>::iterator I, It, Et; 4093 if (Cl->getClauseKind() == OMPC_private) { 4094 auto *PC = cast<OMPPrivateClause>(Cl); 4095 I = PC->private_copies().begin(); 4096 It = PC->varlist_begin(); 4097 Et = PC->varlist_end(); 4098 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4099 auto *PC = cast<OMPFirstprivateClause>(Cl); 4100 I = PC->private_copies().begin(); 4101 It = PC->varlist_begin(); 4102 Et = PC->varlist_end(); 4103 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4104 auto *PC = cast<OMPLastprivateClause>(Cl); 4105 I = PC->private_copies().begin(); 4106 It = PC->varlist_begin(); 4107 Et = PC->varlist_end(); 4108 } else if (Cl->getClauseKind() == OMPC_linear) { 4109 auto *PC = cast<OMPLinearClause>(Cl); 4110 I = PC->privates().begin(); 4111 It = PC->varlist_begin(); 4112 Et = PC->varlist_end(); 4113 } else if (Cl->getClauseKind() == OMPC_reduction) { 4114 auto *PC = cast<OMPReductionClause>(Cl); 4115 I = PC->privates().begin(); 4116 It = PC->varlist_begin(); 4117 Et = PC->varlist_end(); 4118 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4119 auto *PC = cast<OMPTaskReductionClause>(Cl); 4120 I = PC->privates().begin(); 4121 It = PC->varlist_begin(); 4122 Et = PC->varlist_end(); 4123 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4124 auto *PC = cast<OMPInReductionClause>(Cl); 4125 I = PC->privates().begin(); 4126 It = PC->varlist_begin(); 4127 Et = PC->varlist_end(); 4128 } else { 4129 llvm_unreachable("Expected private clause."); 4130 } 4131 for (Expr *E : llvm::make_range(It, Et)) { 4132 if (!*I) { 4133 ++I; 4134 continue; 4135 } 4136 SourceLocation ELoc; 4137 SourceRange ERange; 4138 Expr *SimpleRefExpr = E; 4139 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4140 /*AllowArraySection=*/true); 4141 DeclToCopy.try_emplace(Res.first, 4142 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4143 ++I; 4144 } 4145 } 4146 for (OMPClause *C : AllocateRange) { 4147 auto *AC = cast<OMPAllocateClause>(C); 4148 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4149 getAllocatorKind(S, Stack, AC->getAllocator()); 4150 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4151 // For task, taskloop or target directives, allocation requests to memory 4152 // allocators with the trait access set to thread result in unspecified 4153 // behavior. 4154 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4155 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4156 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4157 S.Diag(AC->getAllocator()->getExprLoc(), 4158 diag::warn_omp_allocate_thread_on_task_target_directive) 4159 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4160 } 4161 for (Expr *E : AC->varlists()) { 4162 SourceLocation ELoc; 4163 SourceRange ERange; 4164 Expr *SimpleRefExpr = E; 4165 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4166 ValueDecl *VD = Res.first; 4167 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4168 if (!isOpenMPPrivate(Data.CKind)) { 4169 S.Diag(E->getExprLoc(), 4170 diag::err_omp_expected_private_copy_for_allocate); 4171 continue; 4172 } 4173 VarDecl *PrivateVD = DeclToCopy[VD]; 4174 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4175 AllocatorKind, AC->getAllocator())) 4176 continue; 4177 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4178 E->getSourceRange()); 4179 } 4180 } 4181 } 4182 4183 StmtResult Sema::ActOnOpenMPExecutableDirective( 4184 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4185 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4186 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4187 StmtResult Res = StmtError(); 4188 // First check CancelRegion which is then used in checkNestingOfRegions. 4189 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4190 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4191 StartLoc)) 4192 return StmtError(); 4193 4194 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4195 VarsWithInheritedDSAType VarsWithInheritedDSA; 4196 bool ErrorFound = false; 4197 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4198 if (AStmt && !CurContext->isDependentContext()) { 4199 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4200 4201 // Check default data sharing attributes for referenced variables. 4202 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4203 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4204 Stmt *S = AStmt; 4205 while (--ThisCaptureLevel >= 0) 4206 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4207 DSAChecker.Visit(S); 4208 if (!isOpenMPTargetDataManagementDirective(Kind) && 4209 !isOpenMPTaskingDirective(Kind)) { 4210 // Visit subcaptures to generate implicit clauses for captured vars. 4211 auto *CS = cast<CapturedStmt>(AStmt); 4212 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4213 getOpenMPCaptureRegions(CaptureRegions, Kind); 4214 // Ignore outer tasking regions for target directives. 4215 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4216 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4217 DSAChecker.visitSubCaptures(CS); 4218 } 4219 if (DSAChecker.isErrorFound()) 4220 return StmtError(); 4221 // Generate list of implicitly defined firstprivate variables. 4222 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4223 4224 SmallVector<Expr *, 4> ImplicitFirstprivates( 4225 DSAChecker.getImplicitFirstprivate().begin(), 4226 DSAChecker.getImplicitFirstprivate().end()); 4227 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4228 DSAChecker.getImplicitMap().end()); 4229 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4230 for (OMPClause *C : Clauses) { 4231 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4232 for (Expr *E : IRC->taskgroup_descriptors()) 4233 if (E) 4234 ImplicitFirstprivates.emplace_back(E); 4235 } 4236 } 4237 if (!ImplicitFirstprivates.empty()) { 4238 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4239 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4240 SourceLocation())) { 4241 ClausesWithImplicit.push_back(Implicit); 4242 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4243 ImplicitFirstprivates.size(); 4244 } else { 4245 ErrorFound = true; 4246 } 4247 } 4248 if (!ImplicitMaps.empty()) { 4249 CXXScopeSpec MapperIdScopeSpec; 4250 DeclarationNameInfo MapperId; 4251 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4252 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4253 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4254 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4255 ClausesWithImplicit.emplace_back(Implicit); 4256 ErrorFound |= 4257 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4258 } else { 4259 ErrorFound = true; 4260 } 4261 } 4262 } 4263 4264 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4265 switch (Kind) { 4266 case OMPD_parallel: 4267 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4268 EndLoc); 4269 AllowedNameModifiers.push_back(OMPD_parallel); 4270 break; 4271 case OMPD_simd: 4272 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4273 VarsWithInheritedDSA); 4274 break; 4275 case OMPD_for: 4276 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4277 VarsWithInheritedDSA); 4278 break; 4279 case OMPD_for_simd: 4280 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4281 EndLoc, VarsWithInheritedDSA); 4282 break; 4283 case OMPD_sections: 4284 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4285 EndLoc); 4286 break; 4287 case OMPD_section: 4288 assert(ClausesWithImplicit.empty() && 4289 "No clauses are allowed for 'omp section' directive"); 4290 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4291 break; 4292 case OMPD_single: 4293 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4294 EndLoc); 4295 break; 4296 case OMPD_master: 4297 assert(ClausesWithImplicit.empty() && 4298 "No clauses are allowed for 'omp master' directive"); 4299 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4300 break; 4301 case OMPD_critical: 4302 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4303 StartLoc, EndLoc); 4304 break; 4305 case OMPD_parallel_for: 4306 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4307 EndLoc, VarsWithInheritedDSA); 4308 AllowedNameModifiers.push_back(OMPD_parallel); 4309 break; 4310 case OMPD_parallel_for_simd: 4311 Res = ActOnOpenMPParallelForSimdDirective( 4312 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4313 AllowedNameModifiers.push_back(OMPD_parallel); 4314 break; 4315 case OMPD_parallel_sections: 4316 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4317 StartLoc, EndLoc); 4318 AllowedNameModifiers.push_back(OMPD_parallel); 4319 break; 4320 case OMPD_task: 4321 Res = 4322 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4323 AllowedNameModifiers.push_back(OMPD_task); 4324 break; 4325 case OMPD_taskyield: 4326 assert(ClausesWithImplicit.empty() && 4327 "No clauses are allowed for 'omp taskyield' directive"); 4328 assert(AStmt == nullptr && 4329 "No associated statement allowed for 'omp taskyield' directive"); 4330 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4331 break; 4332 case OMPD_barrier: 4333 assert(ClausesWithImplicit.empty() && 4334 "No clauses are allowed for 'omp barrier' directive"); 4335 assert(AStmt == nullptr && 4336 "No associated statement allowed for 'omp barrier' directive"); 4337 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4338 break; 4339 case OMPD_taskwait: 4340 assert(ClausesWithImplicit.empty() && 4341 "No clauses are allowed for 'omp taskwait' directive"); 4342 assert(AStmt == nullptr && 4343 "No associated statement allowed for 'omp taskwait' directive"); 4344 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4345 break; 4346 case OMPD_taskgroup: 4347 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4348 EndLoc); 4349 break; 4350 case OMPD_flush: 4351 assert(AStmt == nullptr && 4352 "No associated statement allowed for 'omp flush' directive"); 4353 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4354 break; 4355 case OMPD_ordered: 4356 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4357 EndLoc); 4358 break; 4359 case OMPD_atomic: 4360 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4361 EndLoc); 4362 break; 4363 case OMPD_teams: 4364 Res = 4365 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4366 break; 4367 case OMPD_target: 4368 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4369 EndLoc); 4370 AllowedNameModifiers.push_back(OMPD_target); 4371 break; 4372 case OMPD_target_parallel: 4373 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4374 StartLoc, EndLoc); 4375 AllowedNameModifiers.push_back(OMPD_target); 4376 AllowedNameModifiers.push_back(OMPD_parallel); 4377 break; 4378 case OMPD_target_parallel_for: 4379 Res = ActOnOpenMPTargetParallelForDirective( 4380 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4381 AllowedNameModifiers.push_back(OMPD_target); 4382 AllowedNameModifiers.push_back(OMPD_parallel); 4383 break; 4384 case OMPD_cancellation_point: 4385 assert(ClausesWithImplicit.empty() && 4386 "No clauses are allowed for 'omp cancellation point' directive"); 4387 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4388 "cancellation point' directive"); 4389 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4390 break; 4391 case OMPD_cancel: 4392 assert(AStmt == nullptr && 4393 "No associated statement allowed for 'omp cancel' directive"); 4394 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4395 CancelRegion); 4396 AllowedNameModifiers.push_back(OMPD_cancel); 4397 break; 4398 case OMPD_target_data: 4399 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4400 EndLoc); 4401 AllowedNameModifiers.push_back(OMPD_target_data); 4402 break; 4403 case OMPD_target_enter_data: 4404 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4405 EndLoc, AStmt); 4406 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4407 break; 4408 case OMPD_target_exit_data: 4409 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4410 EndLoc, AStmt); 4411 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4412 break; 4413 case OMPD_taskloop: 4414 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4415 EndLoc, VarsWithInheritedDSA); 4416 AllowedNameModifiers.push_back(OMPD_taskloop); 4417 break; 4418 case OMPD_taskloop_simd: 4419 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4420 EndLoc, VarsWithInheritedDSA); 4421 AllowedNameModifiers.push_back(OMPD_taskloop); 4422 break; 4423 case OMPD_distribute: 4424 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4425 EndLoc, VarsWithInheritedDSA); 4426 break; 4427 case OMPD_target_update: 4428 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4429 EndLoc, AStmt); 4430 AllowedNameModifiers.push_back(OMPD_target_update); 4431 break; 4432 case OMPD_distribute_parallel_for: 4433 Res = ActOnOpenMPDistributeParallelForDirective( 4434 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4435 AllowedNameModifiers.push_back(OMPD_parallel); 4436 break; 4437 case OMPD_distribute_parallel_for_simd: 4438 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4439 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4440 AllowedNameModifiers.push_back(OMPD_parallel); 4441 break; 4442 case OMPD_distribute_simd: 4443 Res = ActOnOpenMPDistributeSimdDirective( 4444 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4445 break; 4446 case OMPD_target_parallel_for_simd: 4447 Res = ActOnOpenMPTargetParallelForSimdDirective( 4448 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4449 AllowedNameModifiers.push_back(OMPD_target); 4450 AllowedNameModifiers.push_back(OMPD_parallel); 4451 break; 4452 case OMPD_target_simd: 4453 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4454 EndLoc, VarsWithInheritedDSA); 4455 AllowedNameModifiers.push_back(OMPD_target); 4456 break; 4457 case OMPD_teams_distribute: 4458 Res = ActOnOpenMPTeamsDistributeDirective( 4459 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4460 break; 4461 case OMPD_teams_distribute_simd: 4462 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4463 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4464 break; 4465 case OMPD_teams_distribute_parallel_for_simd: 4466 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4467 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4468 AllowedNameModifiers.push_back(OMPD_parallel); 4469 break; 4470 case OMPD_teams_distribute_parallel_for: 4471 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4472 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4473 AllowedNameModifiers.push_back(OMPD_parallel); 4474 break; 4475 case OMPD_target_teams: 4476 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4477 EndLoc); 4478 AllowedNameModifiers.push_back(OMPD_target); 4479 break; 4480 case OMPD_target_teams_distribute: 4481 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4482 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4483 AllowedNameModifiers.push_back(OMPD_target); 4484 break; 4485 case OMPD_target_teams_distribute_parallel_for: 4486 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4487 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4488 AllowedNameModifiers.push_back(OMPD_target); 4489 AllowedNameModifiers.push_back(OMPD_parallel); 4490 break; 4491 case OMPD_target_teams_distribute_parallel_for_simd: 4492 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4493 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4494 AllowedNameModifiers.push_back(OMPD_target); 4495 AllowedNameModifiers.push_back(OMPD_parallel); 4496 break; 4497 case OMPD_target_teams_distribute_simd: 4498 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4499 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4500 AllowedNameModifiers.push_back(OMPD_target); 4501 break; 4502 case OMPD_declare_target: 4503 case OMPD_end_declare_target: 4504 case OMPD_threadprivate: 4505 case OMPD_allocate: 4506 case OMPD_declare_reduction: 4507 case OMPD_declare_mapper: 4508 case OMPD_declare_simd: 4509 case OMPD_requires: 4510 llvm_unreachable("OpenMP Directive is not allowed"); 4511 case OMPD_unknown: 4512 llvm_unreachable("Unknown OpenMP directive"); 4513 } 4514 4515 ErrorFound = Res.isInvalid() || ErrorFound; 4516 4517 // Check variables in the clauses if default(none) was specified. 4518 if (DSAStack->getDefaultDSA() == DSA_none) { 4519 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4520 for (OMPClause *C : Clauses) { 4521 switch (C->getClauseKind()) { 4522 case OMPC_num_threads: 4523 case OMPC_dist_schedule: 4524 // Do not analyse if no parent teams directive. 4525 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4526 break; 4527 continue; 4528 case OMPC_if: 4529 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4530 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4531 break; 4532 continue; 4533 case OMPC_schedule: 4534 break; 4535 case OMPC_ordered: 4536 case OMPC_device: 4537 case OMPC_num_teams: 4538 case OMPC_thread_limit: 4539 case OMPC_priority: 4540 case OMPC_grainsize: 4541 case OMPC_num_tasks: 4542 case OMPC_hint: 4543 case OMPC_collapse: 4544 case OMPC_safelen: 4545 case OMPC_simdlen: 4546 case OMPC_final: 4547 case OMPC_default: 4548 case OMPC_proc_bind: 4549 case OMPC_private: 4550 case OMPC_firstprivate: 4551 case OMPC_lastprivate: 4552 case OMPC_shared: 4553 case OMPC_reduction: 4554 case OMPC_task_reduction: 4555 case OMPC_in_reduction: 4556 case OMPC_linear: 4557 case OMPC_aligned: 4558 case OMPC_copyin: 4559 case OMPC_copyprivate: 4560 case OMPC_nowait: 4561 case OMPC_untied: 4562 case OMPC_mergeable: 4563 case OMPC_allocate: 4564 case OMPC_read: 4565 case OMPC_write: 4566 case OMPC_update: 4567 case OMPC_capture: 4568 case OMPC_seq_cst: 4569 case OMPC_depend: 4570 case OMPC_threads: 4571 case OMPC_simd: 4572 case OMPC_map: 4573 case OMPC_nogroup: 4574 case OMPC_defaultmap: 4575 case OMPC_to: 4576 case OMPC_from: 4577 case OMPC_use_device_ptr: 4578 case OMPC_is_device_ptr: 4579 continue; 4580 case OMPC_allocator: 4581 case OMPC_flush: 4582 case OMPC_threadprivate: 4583 case OMPC_uniform: 4584 case OMPC_unknown: 4585 case OMPC_unified_address: 4586 case OMPC_unified_shared_memory: 4587 case OMPC_reverse_offload: 4588 case OMPC_dynamic_allocators: 4589 case OMPC_atomic_default_mem_order: 4590 case OMPC_device_type: 4591 llvm_unreachable("Unexpected clause"); 4592 } 4593 for (Stmt *CC : C->children()) { 4594 if (CC) 4595 DSAChecker.Visit(CC); 4596 } 4597 } 4598 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4599 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4600 } 4601 for (const auto &P : VarsWithInheritedDSA) { 4602 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4603 continue; 4604 ErrorFound = true; 4605 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4606 << P.first << P.second->getSourceRange(); 4607 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4608 } 4609 4610 if (!AllowedNameModifiers.empty()) 4611 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4612 ErrorFound; 4613 4614 if (ErrorFound) 4615 return StmtError(); 4616 4617 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4618 Res.getAs<OMPExecutableDirective>() 4619 ->getStructuredBlock() 4620 ->setIsOMPStructuredBlock(true); 4621 } 4622 4623 if (!CurContext->isDependentContext() && 4624 isOpenMPTargetExecutionDirective(Kind) && 4625 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4626 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4627 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4628 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4629 // Register target to DSA Stack. 4630 DSAStack->addTargetDirLocation(StartLoc); 4631 } 4632 4633 return Res; 4634 } 4635 4636 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4637 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4638 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4639 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4640 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4641 assert(Aligneds.size() == Alignments.size()); 4642 assert(Linears.size() == LinModifiers.size()); 4643 assert(Linears.size() == Steps.size()); 4644 if (!DG || DG.get().isNull()) 4645 return DeclGroupPtrTy(); 4646 4647 if (!DG.get().isSingleDecl()) { 4648 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4649 return DG; 4650 } 4651 Decl *ADecl = DG.get().getSingleDecl(); 4652 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4653 ADecl = FTD->getTemplatedDecl(); 4654 4655 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4656 if (!FD) { 4657 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4658 return DeclGroupPtrTy(); 4659 } 4660 4661 // OpenMP [2.8.2, declare simd construct, Description] 4662 // The parameter of the simdlen clause must be a constant positive integer 4663 // expression. 4664 ExprResult SL; 4665 if (Simdlen) 4666 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4667 // OpenMP [2.8.2, declare simd construct, Description] 4668 // The special this pointer can be used as if was one of the arguments to the 4669 // function in any of the linear, aligned, or uniform clauses. 4670 // The uniform clause declares one or more arguments to have an invariant 4671 // value for all concurrent invocations of the function in the execution of a 4672 // single SIMD loop. 4673 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4674 const Expr *UniformedLinearThis = nullptr; 4675 for (const Expr *E : Uniforms) { 4676 E = E->IgnoreParenImpCasts(); 4677 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4678 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4679 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4680 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4681 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4682 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4683 continue; 4684 } 4685 if (isa<CXXThisExpr>(E)) { 4686 UniformedLinearThis = E; 4687 continue; 4688 } 4689 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4690 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4691 } 4692 // OpenMP [2.8.2, declare simd construct, Description] 4693 // The aligned clause declares that the object to which each list item points 4694 // is aligned to the number of bytes expressed in the optional parameter of 4695 // the aligned clause. 4696 // The special this pointer can be used as if was one of the arguments to the 4697 // function in any of the linear, aligned, or uniform clauses. 4698 // The type of list items appearing in the aligned clause must be array, 4699 // pointer, reference to array, or reference to pointer. 4700 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4701 const Expr *AlignedThis = nullptr; 4702 for (const Expr *E : Aligneds) { 4703 E = E->IgnoreParenImpCasts(); 4704 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4705 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4706 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4707 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4708 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4709 ->getCanonicalDecl() == CanonPVD) { 4710 // OpenMP [2.8.1, simd construct, Restrictions] 4711 // A list-item cannot appear in more than one aligned clause. 4712 if (AlignedArgs.count(CanonPVD) > 0) { 4713 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4714 << 1 << E->getSourceRange(); 4715 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4716 diag::note_omp_explicit_dsa) 4717 << getOpenMPClauseName(OMPC_aligned); 4718 continue; 4719 } 4720 AlignedArgs[CanonPVD] = E; 4721 QualType QTy = PVD->getType() 4722 .getNonReferenceType() 4723 .getUnqualifiedType() 4724 .getCanonicalType(); 4725 const Type *Ty = QTy.getTypePtrOrNull(); 4726 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4727 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4728 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4729 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4730 } 4731 continue; 4732 } 4733 } 4734 if (isa<CXXThisExpr>(E)) { 4735 if (AlignedThis) { 4736 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4737 << 2 << E->getSourceRange(); 4738 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4739 << getOpenMPClauseName(OMPC_aligned); 4740 } 4741 AlignedThis = E; 4742 continue; 4743 } 4744 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4745 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4746 } 4747 // The optional parameter of the aligned clause, alignment, must be a constant 4748 // positive integer expression. If no optional parameter is specified, 4749 // implementation-defined default alignments for SIMD instructions on the 4750 // target platforms are assumed. 4751 SmallVector<const Expr *, 4> NewAligns; 4752 for (Expr *E : Alignments) { 4753 ExprResult Align; 4754 if (E) 4755 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4756 NewAligns.push_back(Align.get()); 4757 } 4758 // OpenMP [2.8.2, declare simd construct, Description] 4759 // The linear clause declares one or more list items to be private to a SIMD 4760 // lane and to have a linear relationship with respect to the iteration space 4761 // of a loop. 4762 // The special this pointer can be used as if was one of the arguments to the 4763 // function in any of the linear, aligned, or uniform clauses. 4764 // When a linear-step expression is specified in a linear clause it must be 4765 // either a constant integer expression or an integer-typed parameter that is 4766 // specified in a uniform clause on the directive. 4767 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4768 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4769 auto MI = LinModifiers.begin(); 4770 for (const Expr *E : Linears) { 4771 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4772 ++MI; 4773 E = E->IgnoreParenImpCasts(); 4774 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4775 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4776 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4777 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4778 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4779 ->getCanonicalDecl() == CanonPVD) { 4780 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4781 // A list-item cannot appear in more than one linear clause. 4782 if (LinearArgs.count(CanonPVD) > 0) { 4783 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4784 << getOpenMPClauseName(OMPC_linear) 4785 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4786 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4787 diag::note_omp_explicit_dsa) 4788 << getOpenMPClauseName(OMPC_linear); 4789 continue; 4790 } 4791 // Each argument can appear in at most one uniform or linear clause. 4792 if (UniformedArgs.count(CanonPVD) > 0) { 4793 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4794 << getOpenMPClauseName(OMPC_linear) 4795 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4796 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4797 diag::note_omp_explicit_dsa) 4798 << getOpenMPClauseName(OMPC_uniform); 4799 continue; 4800 } 4801 LinearArgs[CanonPVD] = E; 4802 if (E->isValueDependent() || E->isTypeDependent() || 4803 E->isInstantiationDependent() || 4804 E->containsUnexpandedParameterPack()) 4805 continue; 4806 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4807 PVD->getOriginalType()); 4808 continue; 4809 } 4810 } 4811 if (isa<CXXThisExpr>(E)) { 4812 if (UniformedLinearThis) { 4813 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4814 << getOpenMPClauseName(OMPC_linear) 4815 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4816 << E->getSourceRange(); 4817 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4818 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4819 : OMPC_linear); 4820 continue; 4821 } 4822 UniformedLinearThis = E; 4823 if (E->isValueDependent() || E->isTypeDependent() || 4824 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4825 continue; 4826 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4827 E->getType()); 4828 continue; 4829 } 4830 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4831 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4832 } 4833 Expr *Step = nullptr; 4834 Expr *NewStep = nullptr; 4835 SmallVector<Expr *, 4> NewSteps; 4836 for (Expr *E : Steps) { 4837 // Skip the same step expression, it was checked already. 4838 if (Step == E || !E) { 4839 NewSteps.push_back(E ? NewStep : nullptr); 4840 continue; 4841 } 4842 Step = E; 4843 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4844 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4845 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4846 if (UniformedArgs.count(CanonPVD) == 0) { 4847 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4848 << Step->getSourceRange(); 4849 } else if (E->isValueDependent() || E->isTypeDependent() || 4850 E->isInstantiationDependent() || 4851 E->containsUnexpandedParameterPack() || 4852 CanonPVD->getType()->hasIntegerRepresentation()) { 4853 NewSteps.push_back(Step); 4854 } else { 4855 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4856 << Step->getSourceRange(); 4857 } 4858 continue; 4859 } 4860 NewStep = Step; 4861 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4862 !Step->isInstantiationDependent() && 4863 !Step->containsUnexpandedParameterPack()) { 4864 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4865 .get(); 4866 if (NewStep) 4867 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4868 } 4869 NewSteps.push_back(NewStep); 4870 } 4871 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4872 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4873 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4874 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4875 const_cast<Expr **>(Linears.data()), Linears.size(), 4876 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4877 NewSteps.data(), NewSteps.size(), SR); 4878 ADecl->addAttr(NewAttr); 4879 return ConvertDeclToDeclGroup(ADecl); 4880 } 4881 4882 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4883 Stmt *AStmt, 4884 SourceLocation StartLoc, 4885 SourceLocation EndLoc) { 4886 if (!AStmt) 4887 return StmtError(); 4888 4889 auto *CS = cast<CapturedStmt>(AStmt); 4890 // 1.2.2 OpenMP Language Terminology 4891 // Structured block - An executable statement with a single entry at the 4892 // top and a single exit at the bottom. 4893 // The point of exit cannot be a branch out of the structured block. 4894 // longjmp() and throw() must not violate the entry/exit criteria. 4895 CS->getCapturedDecl()->setNothrow(); 4896 4897 setFunctionHasBranchProtectedScope(); 4898 4899 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4900 DSAStack->isCancelRegion()); 4901 } 4902 4903 namespace { 4904 /// Iteration space of a single for loop. 4905 struct LoopIterationSpace final { 4906 /// True if the condition operator is the strict compare operator (<, > or 4907 /// !=). 4908 bool IsStrictCompare = false; 4909 /// Condition of the loop. 4910 Expr *PreCond = nullptr; 4911 /// This expression calculates the number of iterations in the loop. 4912 /// It is always possible to calculate it before starting the loop. 4913 Expr *NumIterations = nullptr; 4914 /// The loop counter variable. 4915 Expr *CounterVar = nullptr; 4916 /// Private loop counter variable. 4917 Expr *PrivateCounterVar = nullptr; 4918 /// This is initializer for the initial value of #CounterVar. 4919 Expr *CounterInit = nullptr; 4920 /// This is step for the #CounterVar used to generate its update: 4921 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4922 Expr *CounterStep = nullptr; 4923 /// Should step be subtracted? 4924 bool Subtract = false; 4925 /// Source range of the loop init. 4926 SourceRange InitSrcRange; 4927 /// Source range of the loop condition. 4928 SourceRange CondSrcRange; 4929 /// Source range of the loop increment. 4930 SourceRange IncSrcRange; 4931 /// Minimum value that can have the loop control variable. Used to support 4932 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 4933 /// since only such variables can be used in non-loop invariant expressions. 4934 Expr *MinValue = nullptr; 4935 /// Maximum value that can have the loop control variable. Used to support 4936 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 4937 /// since only such variables can be used in non-loop invariant expressions. 4938 Expr *MaxValue = nullptr; 4939 /// true, if the lower bound depends on the outer loop control var. 4940 bool IsNonRectangularLB = false; 4941 /// true, if the upper bound depends on the outer loop control var. 4942 bool IsNonRectangularUB = false; 4943 /// Index of the loop this loop depends on and forms non-rectangular loop 4944 /// nest. 4945 unsigned LoopDependentIdx = 0; 4946 /// Final condition for the non-rectangular loop nest support. It is used to 4947 /// check that the number of iterations for this particular counter must be 4948 /// finished. 4949 Expr *FinalCondition = nullptr; 4950 }; 4951 4952 /// Helper class for checking canonical form of the OpenMP loops and 4953 /// extracting iteration space of each loop in the loop nest, that will be used 4954 /// for IR generation. 4955 class OpenMPIterationSpaceChecker { 4956 /// Reference to Sema. 4957 Sema &SemaRef; 4958 /// Data-sharing stack. 4959 DSAStackTy &Stack; 4960 /// A location for diagnostics (when there is no some better location). 4961 SourceLocation DefaultLoc; 4962 /// A location for diagnostics (when increment is not compatible). 4963 SourceLocation ConditionLoc; 4964 /// A source location for referring to loop init later. 4965 SourceRange InitSrcRange; 4966 /// A source location for referring to condition later. 4967 SourceRange ConditionSrcRange; 4968 /// A source location for referring to increment later. 4969 SourceRange IncrementSrcRange; 4970 /// Loop variable. 4971 ValueDecl *LCDecl = nullptr; 4972 /// Reference to loop variable. 4973 Expr *LCRef = nullptr; 4974 /// Lower bound (initializer for the var). 4975 Expr *LB = nullptr; 4976 /// Upper bound. 4977 Expr *UB = nullptr; 4978 /// Loop step (increment). 4979 Expr *Step = nullptr; 4980 /// This flag is true when condition is one of: 4981 /// Var < UB 4982 /// Var <= UB 4983 /// UB > Var 4984 /// UB >= Var 4985 /// This will have no value when the condition is != 4986 llvm::Optional<bool> TestIsLessOp; 4987 /// This flag is true when condition is strict ( < or > ). 4988 bool TestIsStrictOp = false; 4989 /// This flag is true when step is subtracted on each iteration. 4990 bool SubtractStep = false; 4991 /// The outer loop counter this loop depends on (if any). 4992 const ValueDecl *DepDecl = nullptr; 4993 /// Contains number of loop (starts from 1) on which loop counter init 4994 /// expression of this loop depends on. 4995 Optional<unsigned> InitDependOnLC; 4996 /// Contains number of loop (starts from 1) on which loop counter condition 4997 /// expression of this loop depends on. 4998 Optional<unsigned> CondDependOnLC; 4999 /// Checks if the provide statement depends on the loop counter. 5000 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5001 /// Original condition required for checking of the exit condition for 5002 /// non-rectangular loop. 5003 Expr *Condition = nullptr; 5004 5005 public: 5006 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5007 SourceLocation DefaultLoc) 5008 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5009 ConditionLoc(DefaultLoc) {} 5010 /// Check init-expr for canonical loop form and save loop counter 5011 /// variable - #Var and its initialization value - #LB. 5012 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5013 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5014 /// for less/greater and for strict/non-strict comparison. 5015 bool checkAndSetCond(Expr *S); 5016 /// Check incr-expr for canonical loop form and return true if it 5017 /// does not conform, otherwise save loop step (#Step). 5018 bool checkAndSetInc(Expr *S); 5019 /// Return the loop counter variable. 5020 ValueDecl *getLoopDecl() const { return LCDecl; } 5021 /// Return the reference expression to loop counter variable. 5022 Expr *getLoopDeclRefExpr() const { return LCRef; } 5023 /// Source range of the loop init. 5024 SourceRange getInitSrcRange() const { return InitSrcRange; } 5025 /// Source range of the loop condition. 5026 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5027 /// Source range of the loop increment. 5028 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5029 /// True if the step should be subtracted. 5030 bool shouldSubtractStep() const { return SubtractStep; } 5031 /// True, if the compare operator is strict (<, > or !=). 5032 bool isStrictTestOp() const { return TestIsStrictOp; } 5033 /// Build the expression to calculate the number of iterations. 5034 Expr *buildNumIterations( 5035 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5036 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5037 /// Build the precondition expression for the loops. 5038 Expr * 5039 buildPreCond(Scope *S, Expr *Cond, 5040 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5041 /// Build reference expression to the counter be used for codegen. 5042 DeclRefExpr * 5043 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5044 DSAStackTy &DSA) const; 5045 /// Build reference expression to the private counter be used for 5046 /// codegen. 5047 Expr *buildPrivateCounterVar() const; 5048 /// Build initialization of the counter be used for codegen. 5049 Expr *buildCounterInit() const; 5050 /// Build step of the counter be used for codegen. 5051 Expr *buildCounterStep() const; 5052 /// Build loop data with counter value for depend clauses in ordered 5053 /// directives. 5054 Expr * 5055 buildOrderedLoopData(Scope *S, Expr *Counter, 5056 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5057 SourceLocation Loc, Expr *Inc = nullptr, 5058 OverloadedOperatorKind OOK = OO_Amp); 5059 /// Builds the minimum value for the loop counter. 5060 std::pair<Expr *, Expr *> buildMinMaxValues( 5061 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5062 /// Builds final condition for the non-rectangular loops. 5063 Expr *buildFinalCondition(Scope *S) const; 5064 /// Return true if any expression is dependent. 5065 bool dependent() const; 5066 /// Returns true if the initializer forms non-rectangular loop. 5067 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5068 /// Returns true if the condition forms non-rectangular loop. 5069 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5070 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5071 unsigned getLoopDependentIdx() const { 5072 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5073 } 5074 5075 private: 5076 /// Check the right-hand side of an assignment in the increment 5077 /// expression. 5078 bool checkAndSetIncRHS(Expr *RHS); 5079 /// Helper to set loop counter variable and its initializer. 5080 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5081 bool EmitDiags); 5082 /// Helper to set upper bound. 5083 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5084 SourceRange SR, SourceLocation SL); 5085 /// Helper to set loop increment. 5086 bool setStep(Expr *NewStep, bool Subtract); 5087 }; 5088 5089 bool OpenMPIterationSpaceChecker::dependent() const { 5090 if (!LCDecl) { 5091 assert(!LB && !UB && !Step); 5092 return false; 5093 } 5094 return LCDecl->getType()->isDependentType() || 5095 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5096 (Step && Step->isValueDependent()); 5097 } 5098 5099 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5100 Expr *NewLCRefExpr, 5101 Expr *NewLB, bool EmitDiags) { 5102 // State consistency checking to ensure correct usage. 5103 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5104 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5105 if (!NewLCDecl || !NewLB) 5106 return true; 5107 LCDecl = getCanonicalDecl(NewLCDecl); 5108 LCRef = NewLCRefExpr; 5109 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5110 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5111 if ((Ctor->isCopyOrMoveConstructor() || 5112 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5113 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5114 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5115 LB = NewLB; 5116 if (EmitDiags) 5117 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5118 return false; 5119 } 5120 5121 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5122 llvm::Optional<bool> LessOp, 5123 bool StrictOp, SourceRange SR, 5124 SourceLocation SL) { 5125 // State consistency checking to ensure correct usage. 5126 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5127 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5128 if (!NewUB) 5129 return true; 5130 UB = NewUB; 5131 if (LessOp) 5132 TestIsLessOp = LessOp; 5133 TestIsStrictOp = StrictOp; 5134 ConditionSrcRange = SR; 5135 ConditionLoc = SL; 5136 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5137 return false; 5138 } 5139 5140 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5141 // State consistency checking to ensure correct usage. 5142 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5143 if (!NewStep) 5144 return true; 5145 if (!NewStep->isValueDependent()) { 5146 // Check that the step is integer expression. 5147 SourceLocation StepLoc = NewStep->getBeginLoc(); 5148 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5149 StepLoc, getExprAsWritten(NewStep)); 5150 if (Val.isInvalid()) 5151 return true; 5152 NewStep = Val.get(); 5153 5154 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5155 // If test-expr is of form var relational-op b and relational-op is < or 5156 // <= then incr-expr must cause var to increase on each iteration of the 5157 // loop. If test-expr is of form var relational-op b and relational-op is 5158 // > or >= then incr-expr must cause var to decrease on each iteration of 5159 // the loop. 5160 // If test-expr is of form b relational-op var and relational-op is < or 5161 // <= then incr-expr must cause var to decrease on each iteration of the 5162 // loop. If test-expr is of form b relational-op var and relational-op is 5163 // > or >= then incr-expr must cause var to increase on each iteration of 5164 // the loop. 5165 llvm::APSInt Result; 5166 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5167 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5168 bool IsConstNeg = 5169 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5170 bool IsConstPos = 5171 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5172 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5173 5174 // != with increment is treated as <; != with decrement is treated as > 5175 if (!TestIsLessOp.hasValue()) 5176 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5177 if (UB && (IsConstZero || 5178 (TestIsLessOp.getValue() ? 5179 (IsConstNeg || (IsUnsigned && Subtract)) : 5180 (IsConstPos || (IsUnsigned && !Subtract))))) { 5181 SemaRef.Diag(NewStep->getExprLoc(), 5182 diag::err_omp_loop_incr_not_compatible) 5183 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5184 SemaRef.Diag(ConditionLoc, 5185 diag::note_omp_loop_cond_requres_compatible_incr) 5186 << TestIsLessOp.getValue() << ConditionSrcRange; 5187 return true; 5188 } 5189 if (TestIsLessOp.getValue() == Subtract) { 5190 NewStep = 5191 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5192 .get(); 5193 Subtract = !Subtract; 5194 } 5195 } 5196 5197 Step = NewStep; 5198 SubtractStep = Subtract; 5199 return false; 5200 } 5201 5202 namespace { 5203 /// Checker for the non-rectangular loops. Checks if the initializer or 5204 /// condition expression references loop counter variable. 5205 class LoopCounterRefChecker final 5206 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5207 Sema &SemaRef; 5208 DSAStackTy &Stack; 5209 const ValueDecl *CurLCDecl = nullptr; 5210 const ValueDecl *DepDecl = nullptr; 5211 const ValueDecl *PrevDepDecl = nullptr; 5212 bool IsInitializer = true; 5213 unsigned BaseLoopId = 0; 5214 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5215 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5216 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5217 << (IsInitializer ? 0 : 1); 5218 return false; 5219 } 5220 const auto &&Data = Stack.isLoopControlVariable(VD); 5221 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5222 // The type of the loop iterator on which we depend may not have a random 5223 // access iterator type. 5224 if (Data.first && VD->getType()->isRecordType()) { 5225 SmallString<128> Name; 5226 llvm::raw_svector_ostream OS(Name); 5227 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5228 /*Qualified=*/true); 5229 SemaRef.Diag(E->getExprLoc(), 5230 diag::err_omp_wrong_dependency_iterator_type) 5231 << OS.str(); 5232 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5233 return false; 5234 } 5235 if (Data.first && 5236 (DepDecl || (PrevDepDecl && 5237 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5238 if (!DepDecl && PrevDepDecl) 5239 DepDecl = PrevDepDecl; 5240 SmallString<128> Name; 5241 llvm::raw_svector_ostream OS(Name); 5242 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5243 /*Qualified=*/true); 5244 SemaRef.Diag(E->getExprLoc(), 5245 diag::err_omp_invariant_or_linear_dependency) 5246 << OS.str(); 5247 return false; 5248 } 5249 if (Data.first) { 5250 DepDecl = VD; 5251 BaseLoopId = Data.first; 5252 } 5253 return Data.first; 5254 } 5255 5256 public: 5257 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5258 const ValueDecl *VD = E->getDecl(); 5259 if (isa<VarDecl>(VD)) 5260 return checkDecl(E, VD); 5261 return false; 5262 } 5263 bool VisitMemberExpr(const MemberExpr *E) { 5264 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5265 const ValueDecl *VD = E->getMemberDecl(); 5266 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5267 return checkDecl(E, VD); 5268 } 5269 return false; 5270 } 5271 bool VisitStmt(const Stmt *S) { 5272 bool Res = false; 5273 for (const Stmt *Child : S->children()) 5274 Res = (Child && Visit(Child)) || Res; 5275 return Res; 5276 } 5277 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5278 const ValueDecl *CurLCDecl, bool IsInitializer, 5279 const ValueDecl *PrevDepDecl = nullptr) 5280 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5281 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5282 unsigned getBaseLoopId() const { 5283 assert(CurLCDecl && "Expected loop dependency."); 5284 return BaseLoopId; 5285 } 5286 const ValueDecl *getDepDecl() const { 5287 assert(CurLCDecl && "Expected loop dependency."); 5288 return DepDecl; 5289 } 5290 }; 5291 } // namespace 5292 5293 Optional<unsigned> 5294 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5295 bool IsInitializer) { 5296 // Check for the non-rectangular loops. 5297 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5298 DepDecl); 5299 if (LoopStmtChecker.Visit(S)) { 5300 DepDecl = LoopStmtChecker.getDepDecl(); 5301 return LoopStmtChecker.getBaseLoopId(); 5302 } 5303 return llvm::None; 5304 } 5305 5306 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5307 // Check init-expr for canonical loop form and save loop counter 5308 // variable - #Var and its initialization value - #LB. 5309 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5310 // var = lb 5311 // integer-type var = lb 5312 // random-access-iterator-type var = lb 5313 // pointer-type var = lb 5314 // 5315 if (!S) { 5316 if (EmitDiags) { 5317 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5318 } 5319 return true; 5320 } 5321 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5322 if (!ExprTemp->cleanupsHaveSideEffects()) 5323 S = ExprTemp->getSubExpr(); 5324 5325 InitSrcRange = S->getSourceRange(); 5326 if (Expr *E = dyn_cast<Expr>(S)) 5327 S = E->IgnoreParens(); 5328 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5329 if (BO->getOpcode() == BO_Assign) { 5330 Expr *LHS = BO->getLHS()->IgnoreParens(); 5331 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5332 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5333 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5334 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5335 EmitDiags); 5336 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5337 } 5338 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5339 if (ME->isArrow() && 5340 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5341 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5342 EmitDiags); 5343 } 5344 } 5345 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5346 if (DS->isSingleDecl()) { 5347 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5348 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5349 // Accept non-canonical init form here but emit ext. warning. 5350 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5351 SemaRef.Diag(S->getBeginLoc(), 5352 diag::ext_omp_loop_not_canonical_init) 5353 << S->getSourceRange(); 5354 return setLCDeclAndLB( 5355 Var, 5356 buildDeclRefExpr(SemaRef, Var, 5357 Var->getType().getNonReferenceType(), 5358 DS->getBeginLoc()), 5359 Var->getInit(), EmitDiags); 5360 } 5361 } 5362 } 5363 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5364 if (CE->getOperator() == OO_Equal) { 5365 Expr *LHS = CE->getArg(0); 5366 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5367 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5368 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5369 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5370 EmitDiags); 5371 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5372 } 5373 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5374 if (ME->isArrow() && 5375 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5376 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5377 EmitDiags); 5378 } 5379 } 5380 } 5381 5382 if (dependent() || SemaRef.CurContext->isDependentContext()) 5383 return false; 5384 if (EmitDiags) { 5385 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5386 << S->getSourceRange(); 5387 } 5388 return true; 5389 } 5390 5391 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5392 /// variable (which may be the loop variable) if possible. 5393 static const ValueDecl *getInitLCDecl(const Expr *E) { 5394 if (!E) 5395 return nullptr; 5396 E = getExprAsWritten(E); 5397 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5398 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5399 if ((Ctor->isCopyOrMoveConstructor() || 5400 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5401 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5402 E = CE->getArg(0)->IgnoreParenImpCasts(); 5403 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5404 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5405 return getCanonicalDecl(VD); 5406 } 5407 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5408 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5409 return getCanonicalDecl(ME->getMemberDecl()); 5410 return nullptr; 5411 } 5412 5413 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5414 // Check test-expr for canonical form, save upper-bound UB, flags for 5415 // less/greater and for strict/non-strict comparison. 5416 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5417 // var relational-op b 5418 // b relational-op var 5419 // 5420 if (!S) { 5421 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 5422 return true; 5423 } 5424 Condition = S; 5425 S = getExprAsWritten(S); 5426 SourceLocation CondLoc = S->getBeginLoc(); 5427 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5428 if (BO->isRelationalOp()) { 5429 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5430 return setUB(BO->getRHS(), 5431 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5432 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5433 BO->getSourceRange(), BO->getOperatorLoc()); 5434 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5435 return setUB(BO->getLHS(), 5436 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5437 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5438 BO->getSourceRange(), BO->getOperatorLoc()); 5439 } else if (BO->getOpcode() == BO_NE) 5440 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 5441 BO->getRHS() : BO->getLHS(), 5442 /*LessOp=*/llvm::None, 5443 /*StrictOp=*/true, 5444 BO->getSourceRange(), BO->getOperatorLoc()); 5445 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5446 if (CE->getNumArgs() == 2) { 5447 auto Op = CE->getOperator(); 5448 switch (Op) { 5449 case OO_Greater: 5450 case OO_GreaterEqual: 5451 case OO_Less: 5452 case OO_LessEqual: 5453 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5454 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5455 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5456 CE->getOperatorLoc()); 5457 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5458 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5459 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5460 CE->getOperatorLoc()); 5461 break; 5462 case OO_ExclaimEqual: 5463 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 5464 CE->getArg(1) : CE->getArg(0), 5465 /*LessOp=*/llvm::None, 5466 /*StrictOp=*/true, 5467 CE->getSourceRange(), 5468 CE->getOperatorLoc()); 5469 break; 5470 default: 5471 break; 5472 } 5473 } 5474 } 5475 if (dependent() || SemaRef.CurContext->isDependentContext()) 5476 return false; 5477 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5478 << S->getSourceRange() << LCDecl; 5479 return true; 5480 } 5481 5482 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5483 // RHS of canonical loop form increment can be: 5484 // var + incr 5485 // incr + var 5486 // var - incr 5487 // 5488 RHS = RHS->IgnoreParenImpCasts(); 5489 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5490 if (BO->isAdditiveOp()) { 5491 bool IsAdd = BO->getOpcode() == BO_Add; 5492 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5493 return setStep(BO->getRHS(), !IsAdd); 5494 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5495 return setStep(BO->getLHS(), /*Subtract=*/false); 5496 } 5497 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5498 bool IsAdd = CE->getOperator() == OO_Plus; 5499 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5500 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5501 return setStep(CE->getArg(1), !IsAdd); 5502 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5503 return setStep(CE->getArg(0), /*Subtract=*/false); 5504 } 5505 } 5506 if (dependent() || SemaRef.CurContext->isDependentContext()) 5507 return false; 5508 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5509 << RHS->getSourceRange() << LCDecl; 5510 return true; 5511 } 5512 5513 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5514 // Check incr-expr for canonical loop form and return true if it 5515 // does not conform. 5516 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5517 // ++var 5518 // var++ 5519 // --var 5520 // var-- 5521 // var += incr 5522 // var -= incr 5523 // var = var + incr 5524 // var = incr + var 5525 // var = var - incr 5526 // 5527 if (!S) { 5528 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5529 return true; 5530 } 5531 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5532 if (!ExprTemp->cleanupsHaveSideEffects()) 5533 S = ExprTemp->getSubExpr(); 5534 5535 IncrementSrcRange = S->getSourceRange(); 5536 S = S->IgnoreParens(); 5537 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5538 if (UO->isIncrementDecrementOp() && 5539 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5540 return setStep(SemaRef 5541 .ActOnIntegerConstant(UO->getBeginLoc(), 5542 (UO->isDecrementOp() ? -1 : 1)) 5543 .get(), 5544 /*Subtract=*/false); 5545 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5546 switch (BO->getOpcode()) { 5547 case BO_AddAssign: 5548 case BO_SubAssign: 5549 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5550 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5551 break; 5552 case BO_Assign: 5553 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5554 return checkAndSetIncRHS(BO->getRHS()); 5555 break; 5556 default: 5557 break; 5558 } 5559 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5560 switch (CE->getOperator()) { 5561 case OO_PlusPlus: 5562 case OO_MinusMinus: 5563 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5564 return setStep(SemaRef 5565 .ActOnIntegerConstant( 5566 CE->getBeginLoc(), 5567 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5568 .get(), 5569 /*Subtract=*/false); 5570 break; 5571 case OO_PlusEqual: 5572 case OO_MinusEqual: 5573 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5574 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5575 break; 5576 case OO_Equal: 5577 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5578 return checkAndSetIncRHS(CE->getArg(1)); 5579 break; 5580 default: 5581 break; 5582 } 5583 } 5584 if (dependent() || SemaRef.CurContext->isDependentContext()) 5585 return false; 5586 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5587 << S->getSourceRange() << LCDecl; 5588 return true; 5589 } 5590 5591 static ExprResult 5592 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5593 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5594 if (SemaRef.CurContext->isDependentContext()) 5595 return ExprResult(Capture); 5596 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5597 return SemaRef.PerformImplicitConversion( 5598 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5599 /*AllowExplicit=*/true); 5600 auto I = Captures.find(Capture); 5601 if (I != Captures.end()) 5602 return buildCapture(SemaRef, Capture, I->second); 5603 DeclRefExpr *Ref = nullptr; 5604 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5605 Captures[Capture] = Ref; 5606 return Res; 5607 } 5608 5609 /// Build the expression to calculate the number of iterations. 5610 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5611 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5612 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5613 ExprResult Diff; 5614 QualType VarType = LCDecl->getType().getNonReferenceType(); 5615 if (VarType->isIntegerType() || VarType->isPointerType() || 5616 SemaRef.getLangOpts().CPlusPlus) { 5617 Expr *LBVal = LB; 5618 Expr *UBVal = UB; 5619 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5620 // max(LB(MinVal), LB(MaxVal)) 5621 if (InitDependOnLC) { 5622 const LoopIterationSpace &IS = 5623 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5624 InitDependOnLC.getValueOr( 5625 CondDependOnLC.getValueOr(0))]; 5626 if (!IS.MinValue || !IS.MaxValue) 5627 return nullptr; 5628 // OuterVar = Min 5629 ExprResult MinValue = 5630 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5631 if (!MinValue.isUsable()) 5632 return nullptr; 5633 5634 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5635 IS.CounterVar, MinValue.get()); 5636 if (!LBMinVal.isUsable()) 5637 return nullptr; 5638 // OuterVar = Min, LBVal 5639 LBMinVal = 5640 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5641 if (!LBMinVal.isUsable()) 5642 return nullptr; 5643 // (OuterVar = Min, LBVal) 5644 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5645 if (!LBMinVal.isUsable()) 5646 return nullptr; 5647 5648 // OuterVar = Max 5649 ExprResult MaxValue = 5650 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5651 if (!MaxValue.isUsable()) 5652 return nullptr; 5653 5654 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5655 IS.CounterVar, MaxValue.get()); 5656 if (!LBMaxVal.isUsable()) 5657 return nullptr; 5658 // OuterVar = Max, LBVal 5659 LBMaxVal = 5660 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5661 if (!LBMaxVal.isUsable()) 5662 return nullptr; 5663 // (OuterVar = Max, LBVal) 5664 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5665 if (!LBMaxVal.isUsable()) 5666 return nullptr; 5667 5668 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 5669 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 5670 if (!LBMin || !LBMax) 5671 return nullptr; 5672 // LB(MinVal) < LB(MaxVal) 5673 ExprResult MinLessMaxRes = 5674 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 5675 if (!MinLessMaxRes.isUsable()) 5676 return nullptr; 5677 Expr *MinLessMax = 5678 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 5679 if (!MinLessMax) 5680 return nullptr; 5681 if (TestIsLessOp.getValue()) { 5682 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 5683 // LB(MaxVal)) 5684 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5685 MinLessMax, LBMin, LBMax); 5686 if (!MinLB.isUsable()) 5687 return nullptr; 5688 LBVal = MinLB.get(); 5689 } else { 5690 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 5691 // LB(MaxVal)) 5692 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5693 MinLessMax, LBMax, LBMin); 5694 if (!MaxLB.isUsable()) 5695 return nullptr; 5696 LBVal = MaxLB.get(); 5697 } 5698 } 5699 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 5700 // min(UB(MinVal), UB(MaxVal)) 5701 if (CondDependOnLC) { 5702 const LoopIterationSpace &IS = 5703 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5704 InitDependOnLC.getValueOr( 5705 CondDependOnLC.getValueOr(0))]; 5706 if (!IS.MinValue || !IS.MaxValue) 5707 return nullptr; 5708 // OuterVar = Min 5709 ExprResult MinValue = 5710 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5711 if (!MinValue.isUsable()) 5712 return nullptr; 5713 5714 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5715 IS.CounterVar, MinValue.get()); 5716 if (!UBMinVal.isUsable()) 5717 return nullptr; 5718 // OuterVar = Min, UBVal 5719 UBMinVal = 5720 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 5721 if (!UBMinVal.isUsable()) 5722 return nullptr; 5723 // (OuterVar = Min, UBVal) 5724 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 5725 if (!UBMinVal.isUsable()) 5726 return nullptr; 5727 5728 // OuterVar = Max 5729 ExprResult MaxValue = 5730 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5731 if (!MaxValue.isUsable()) 5732 return nullptr; 5733 5734 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5735 IS.CounterVar, MaxValue.get()); 5736 if (!UBMaxVal.isUsable()) 5737 return nullptr; 5738 // OuterVar = Max, UBVal 5739 UBMaxVal = 5740 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 5741 if (!UBMaxVal.isUsable()) 5742 return nullptr; 5743 // (OuterVar = Max, UBVal) 5744 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 5745 if (!UBMaxVal.isUsable()) 5746 return nullptr; 5747 5748 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 5749 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 5750 if (!UBMin || !UBMax) 5751 return nullptr; 5752 // UB(MinVal) > UB(MaxVal) 5753 ExprResult MinGreaterMaxRes = 5754 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 5755 if (!MinGreaterMaxRes.isUsable()) 5756 return nullptr; 5757 Expr *MinGreaterMax = 5758 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 5759 if (!MinGreaterMax) 5760 return nullptr; 5761 if (TestIsLessOp.getValue()) { 5762 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 5763 // UB(MaxVal)) 5764 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 5765 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 5766 if (!MaxUB.isUsable()) 5767 return nullptr; 5768 UBVal = MaxUB.get(); 5769 } else { 5770 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 5771 // UB(MaxVal)) 5772 ExprResult MinUB = SemaRef.ActOnConditionalOp( 5773 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 5774 if (!MinUB.isUsable()) 5775 return nullptr; 5776 UBVal = MinUB.get(); 5777 } 5778 } 5779 // Upper - Lower 5780 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 5781 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 5782 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5783 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5784 if (!Upper || !Lower) 5785 return nullptr; 5786 5787 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5788 5789 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5790 // BuildBinOp already emitted error, this one is to point user to upper 5791 // and lower bound, and to tell what is passed to 'operator-'. 5792 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5793 << Upper->getSourceRange() << Lower->getSourceRange(); 5794 return nullptr; 5795 } 5796 } 5797 5798 if (!Diff.isUsable()) 5799 return nullptr; 5800 5801 // Upper - Lower [- 1] 5802 if (TestIsStrictOp) 5803 Diff = SemaRef.BuildBinOp( 5804 S, DefaultLoc, BO_Sub, Diff.get(), 5805 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5806 if (!Diff.isUsable()) 5807 return nullptr; 5808 5809 // Upper - Lower [- 1] + Step 5810 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5811 if (!NewStep.isUsable()) 5812 return nullptr; 5813 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5814 if (!Diff.isUsable()) 5815 return nullptr; 5816 5817 // Parentheses (for dumping/debugging purposes only). 5818 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5819 if (!Diff.isUsable()) 5820 return nullptr; 5821 5822 // (Upper - Lower [- 1] + Step) / Step 5823 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5824 if (!Diff.isUsable()) 5825 return nullptr; 5826 5827 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5828 QualType Type = Diff.get()->getType(); 5829 ASTContext &C = SemaRef.Context; 5830 bool UseVarType = VarType->hasIntegerRepresentation() && 5831 C.getTypeSize(Type) > C.getTypeSize(VarType); 5832 if (!Type->isIntegerType() || UseVarType) { 5833 unsigned NewSize = 5834 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5835 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5836 : Type->hasSignedIntegerRepresentation(); 5837 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5838 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5839 Diff = SemaRef.PerformImplicitConversion( 5840 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5841 if (!Diff.isUsable()) 5842 return nullptr; 5843 } 5844 } 5845 if (LimitedType) { 5846 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5847 if (NewSize != C.getTypeSize(Type)) { 5848 if (NewSize < C.getTypeSize(Type)) { 5849 assert(NewSize == 64 && "incorrect loop var size"); 5850 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5851 << InitSrcRange << ConditionSrcRange; 5852 } 5853 QualType NewType = C.getIntTypeForBitwidth( 5854 NewSize, Type->hasSignedIntegerRepresentation() || 5855 C.getTypeSize(Type) < NewSize); 5856 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5857 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5858 Sema::AA_Converting, true); 5859 if (!Diff.isUsable()) 5860 return nullptr; 5861 } 5862 } 5863 } 5864 5865 return Diff.get(); 5866 } 5867 5868 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 5869 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5870 // Do not build for iterators, they cannot be used in non-rectangular loop 5871 // nests. 5872 if (LCDecl->getType()->isRecordType()) 5873 return std::make_pair(nullptr, nullptr); 5874 // If we subtract, the min is in the condition, otherwise the min is in the 5875 // init value. 5876 Expr *MinExpr = nullptr; 5877 Expr *MaxExpr = nullptr; 5878 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5879 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5880 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 5881 : CondDependOnLC.hasValue(); 5882 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 5883 : InitDependOnLC.hasValue(); 5884 Expr *Lower = 5885 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5886 Expr *Upper = 5887 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5888 if (!Upper || !Lower) 5889 return std::make_pair(nullptr, nullptr); 5890 5891 if (TestIsLessOp.getValue()) 5892 MinExpr = Lower; 5893 else 5894 MaxExpr = Upper; 5895 5896 // Build minimum/maximum value based on number of iterations. 5897 ExprResult Diff; 5898 QualType VarType = LCDecl->getType().getNonReferenceType(); 5899 5900 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5901 if (!Diff.isUsable()) 5902 return std::make_pair(nullptr, nullptr); 5903 5904 // Upper - Lower [- 1] 5905 if (TestIsStrictOp) 5906 Diff = SemaRef.BuildBinOp( 5907 S, DefaultLoc, BO_Sub, Diff.get(), 5908 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5909 if (!Diff.isUsable()) 5910 return std::make_pair(nullptr, nullptr); 5911 5912 // Upper - Lower [- 1] + Step 5913 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5914 if (!NewStep.isUsable()) 5915 return std::make_pair(nullptr, nullptr); 5916 5917 // Parentheses (for dumping/debugging purposes only). 5918 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5919 if (!Diff.isUsable()) 5920 return std::make_pair(nullptr, nullptr); 5921 5922 // (Upper - Lower [- 1]) / Step 5923 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5924 if (!Diff.isUsable()) 5925 return std::make_pair(nullptr, nullptr); 5926 5927 // ((Upper - Lower [- 1]) / Step) * Step 5928 // Parentheses (for dumping/debugging purposes only). 5929 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5930 if (!Diff.isUsable()) 5931 return std::make_pair(nullptr, nullptr); 5932 5933 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 5934 if (!Diff.isUsable()) 5935 return std::make_pair(nullptr, nullptr); 5936 5937 // Convert to the original type or ptrdiff_t, if original type is pointer. 5938 if (!VarType->isAnyPointerType() && 5939 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 5940 Diff = SemaRef.PerformImplicitConversion( 5941 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 5942 } else if (VarType->isAnyPointerType() && 5943 !SemaRef.Context.hasSameType( 5944 Diff.get()->getType(), 5945 SemaRef.Context.getUnsignedPointerDiffType())) { 5946 Diff = SemaRef.PerformImplicitConversion( 5947 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 5948 Sema::AA_Converting, /*AllowExplicit=*/true); 5949 } 5950 if (!Diff.isUsable()) 5951 return std::make_pair(nullptr, nullptr); 5952 5953 // Parentheses (for dumping/debugging purposes only). 5954 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5955 if (!Diff.isUsable()) 5956 return std::make_pair(nullptr, nullptr); 5957 5958 if (TestIsLessOp.getValue()) { 5959 // MinExpr = Lower; 5960 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 5961 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 5962 if (!Diff.isUsable()) 5963 return std::make_pair(nullptr, nullptr); 5964 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 5965 if (!Diff.isUsable()) 5966 return std::make_pair(nullptr, nullptr); 5967 MaxExpr = Diff.get(); 5968 } else { 5969 // MaxExpr = Upper; 5970 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 5971 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 5972 if (!Diff.isUsable()) 5973 return std::make_pair(nullptr, nullptr); 5974 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 5975 if (!Diff.isUsable()) 5976 return std::make_pair(nullptr, nullptr); 5977 MinExpr = Diff.get(); 5978 } 5979 5980 return std::make_pair(MinExpr, MaxExpr); 5981 } 5982 5983 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 5984 if (InitDependOnLC || CondDependOnLC) 5985 return Condition; 5986 return nullptr; 5987 } 5988 5989 Expr *OpenMPIterationSpaceChecker::buildPreCond( 5990 Scope *S, Expr *Cond, 5991 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5992 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 5993 Sema::TentativeAnalysisScope Trap(SemaRef); 5994 5995 ExprResult NewLB = 5996 InitDependOnLC ? LB : tryBuildCapture(SemaRef, LB, Captures); 5997 ExprResult NewUB = 5998 CondDependOnLC ? UB : tryBuildCapture(SemaRef, UB, Captures); 5999 if (!NewLB.isUsable() || !NewUB.isUsable()) 6000 return nullptr; 6001 6002 ExprResult CondExpr = 6003 SemaRef.BuildBinOp(S, DefaultLoc, 6004 TestIsLessOp.getValue() ? 6005 (TestIsStrictOp ? BO_LT : BO_LE) : 6006 (TestIsStrictOp ? BO_GT : BO_GE), 6007 NewLB.get(), NewUB.get()); 6008 if (CondExpr.isUsable()) { 6009 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6010 SemaRef.Context.BoolTy)) 6011 CondExpr = SemaRef.PerformImplicitConversion( 6012 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6013 /*AllowExplicit=*/true); 6014 } 6015 6016 // Otherwise use original loop condition and evaluate it in runtime. 6017 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6018 } 6019 6020 /// Build reference expression to the counter be used for codegen. 6021 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6022 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6023 DSAStackTy &DSA) const { 6024 auto *VD = dyn_cast<VarDecl>(LCDecl); 6025 if (!VD) { 6026 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6027 DeclRefExpr *Ref = buildDeclRefExpr( 6028 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6029 const DSAStackTy::DSAVarData Data = 6030 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6031 // If the loop control decl is explicitly marked as private, do not mark it 6032 // as captured again. 6033 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6034 Captures.insert(std::make_pair(LCRef, Ref)); 6035 return Ref; 6036 } 6037 return cast<DeclRefExpr>(LCRef); 6038 } 6039 6040 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6041 if (LCDecl && !LCDecl->isInvalidDecl()) { 6042 QualType Type = LCDecl->getType().getNonReferenceType(); 6043 VarDecl *PrivateVar = buildVarDecl( 6044 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6045 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6046 isa<VarDecl>(LCDecl) 6047 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6048 : nullptr); 6049 if (PrivateVar->isInvalidDecl()) 6050 return nullptr; 6051 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6052 } 6053 return nullptr; 6054 } 6055 6056 /// Build initialization of the counter to be used for codegen. 6057 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6058 6059 /// Build step of the counter be used for codegen. 6060 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6061 6062 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6063 Scope *S, Expr *Counter, 6064 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6065 Expr *Inc, OverloadedOperatorKind OOK) { 6066 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6067 if (!Cnt) 6068 return nullptr; 6069 if (Inc) { 6070 assert((OOK == OO_Plus || OOK == OO_Minus) && 6071 "Expected only + or - operations for depend clauses."); 6072 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6073 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6074 if (!Cnt) 6075 return nullptr; 6076 } 6077 ExprResult Diff; 6078 QualType VarType = LCDecl->getType().getNonReferenceType(); 6079 if (VarType->isIntegerType() || VarType->isPointerType() || 6080 SemaRef.getLangOpts().CPlusPlus) { 6081 // Upper - Lower 6082 Expr *Upper = TestIsLessOp.getValue() 6083 ? Cnt 6084 : tryBuildCapture(SemaRef, UB, Captures).get(); 6085 Expr *Lower = TestIsLessOp.getValue() 6086 ? tryBuildCapture(SemaRef, LB, Captures).get() 6087 : Cnt; 6088 if (!Upper || !Lower) 6089 return nullptr; 6090 6091 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6092 6093 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6094 // BuildBinOp already emitted error, this one is to point user to upper 6095 // and lower bound, and to tell what is passed to 'operator-'. 6096 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6097 << Upper->getSourceRange() << Lower->getSourceRange(); 6098 return nullptr; 6099 } 6100 } 6101 6102 if (!Diff.isUsable()) 6103 return nullptr; 6104 6105 // Parentheses (for dumping/debugging purposes only). 6106 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6107 if (!Diff.isUsable()) 6108 return nullptr; 6109 6110 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6111 if (!NewStep.isUsable()) 6112 return nullptr; 6113 // (Upper - Lower) / Step 6114 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6115 if (!Diff.isUsable()) 6116 return nullptr; 6117 6118 return Diff.get(); 6119 } 6120 } // namespace 6121 6122 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6123 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6124 assert(Init && "Expected loop in canonical form."); 6125 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6126 if (AssociatedLoops > 0 && 6127 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6128 DSAStack->loopStart(); 6129 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6130 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6131 if (ValueDecl *D = ISC.getLoopDecl()) { 6132 auto *VD = dyn_cast<VarDecl>(D); 6133 DeclRefExpr *PrivateRef = nullptr; 6134 if (!VD) { 6135 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6136 VD = Private; 6137 } else { 6138 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6139 /*WithInit=*/false); 6140 VD = cast<VarDecl>(PrivateRef->getDecl()); 6141 } 6142 } 6143 DSAStack->addLoopControlVariable(D, VD); 6144 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6145 if (LD != D->getCanonicalDecl()) { 6146 DSAStack->resetPossibleLoopCounter(); 6147 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6148 MarkDeclarationsReferencedInExpr( 6149 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6150 Var->getType().getNonLValueExprType(Context), 6151 ForLoc, /*RefersToCapture=*/true)); 6152 } 6153 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6154 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6155 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6156 // associated for-loop of a simd construct with just one associated 6157 // for-loop may be listed in a linear clause with a constant-linear-step 6158 // that is the increment of the associated for-loop. The loop iteration 6159 // variable(s) in the associated for-loop(s) of a for or parallel for 6160 // construct may be listed in a private or lastprivate clause. 6161 DSAStackTy::DSAVarData DVar = 6162 DSAStack->getTopDSA(D, /*FromParent=*/false); 6163 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6164 // is declared in the loop and it is predetermined as a private. 6165 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6166 OpenMPClauseKind PredeterminedCKind = 6167 isOpenMPSimdDirective(DKind) 6168 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6169 : OMPC_private; 6170 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6171 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6172 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6173 DVar.CKind != OMPC_private))) || 6174 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6175 isOpenMPDistributeDirective(DKind)) && 6176 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6177 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6178 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6179 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6180 << getOpenMPClauseName(DVar.CKind) 6181 << getOpenMPDirectiveName(DKind) 6182 << getOpenMPClauseName(PredeterminedCKind); 6183 if (DVar.RefExpr == nullptr) 6184 DVar.CKind = PredeterminedCKind; 6185 reportOriginalDsa(*this, DSAStack, D, DVar, 6186 /*IsLoopIterVar=*/true); 6187 } else if (LoopDeclRefExpr) { 6188 // Make the loop iteration variable private (for worksharing 6189 // constructs), linear (for simd directives with the only one 6190 // associated loop) or lastprivate (for simd directives with several 6191 // collapsed or ordered loops). 6192 if (DVar.CKind == OMPC_unknown) 6193 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6194 PrivateRef); 6195 } 6196 } 6197 } 6198 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6199 } 6200 } 6201 6202 /// Called on a for stmt to check and extract its iteration space 6203 /// for further processing (such as collapsing). 6204 static bool checkOpenMPIterationSpace( 6205 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6206 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6207 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6208 Expr *OrderedLoopCountExpr, 6209 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6210 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6211 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6212 // OpenMP [2.6, Canonical Loop Form] 6213 // for (init-expr; test-expr; incr-expr) structured-block 6214 auto *For = dyn_cast_or_null<ForStmt>(S); 6215 if (!For) { 6216 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6217 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6218 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6219 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6220 if (TotalNestedLoopCount > 1) { 6221 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6222 SemaRef.Diag(DSA.getConstructLoc(), 6223 diag::note_omp_collapse_ordered_expr) 6224 << 2 << CollapseLoopCountExpr->getSourceRange() 6225 << OrderedLoopCountExpr->getSourceRange(); 6226 else if (CollapseLoopCountExpr) 6227 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6228 diag::note_omp_collapse_ordered_expr) 6229 << 0 << CollapseLoopCountExpr->getSourceRange(); 6230 else 6231 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6232 diag::note_omp_collapse_ordered_expr) 6233 << 1 << OrderedLoopCountExpr->getSourceRange(); 6234 } 6235 return true; 6236 } 6237 assert(For->getBody()); 6238 6239 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 6240 6241 // Check init. 6242 Stmt *Init = For->getInit(); 6243 if (ISC.checkAndSetInit(Init)) 6244 return true; 6245 6246 bool HasErrors = false; 6247 6248 // Check loop variable's type. 6249 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6250 // OpenMP [2.6, Canonical Loop Form] 6251 // Var is one of the following: 6252 // A variable of signed or unsigned integer type. 6253 // For C++, a variable of a random access iterator type. 6254 // For C, a variable of a pointer type. 6255 QualType VarType = LCDecl->getType().getNonReferenceType(); 6256 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6257 !VarType->isPointerType() && 6258 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6259 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6260 << SemaRef.getLangOpts().CPlusPlus; 6261 HasErrors = true; 6262 } 6263 6264 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6265 // a Construct 6266 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6267 // parallel for construct is (are) private. 6268 // The loop iteration variable in the associated for-loop of a simd 6269 // construct with just one associated for-loop is linear with a 6270 // constant-linear-step that is the increment of the associated for-loop. 6271 // Exclude loop var from the list of variables with implicitly defined data 6272 // sharing attributes. 6273 VarsWithImplicitDSA.erase(LCDecl); 6274 6275 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6276 6277 // Check test-expr. 6278 HasErrors |= ISC.checkAndSetCond(For->getCond()); 6279 6280 // Check incr-expr. 6281 HasErrors |= ISC.checkAndSetInc(For->getInc()); 6282 } 6283 6284 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6285 return HasErrors; 6286 6287 // Build the loop's iteration space representation. 6288 ResultIterSpaces[CurrentNestedLoopCount].PreCond = 6289 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 6290 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6291 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6292 (isOpenMPWorksharingDirective(DKind) || 6293 isOpenMPTaskLoopDirective(DKind) || 6294 isOpenMPDistributeDirective(DKind)), 6295 Captures); 6296 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6297 ISC.buildCounterVar(Captures, DSA); 6298 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6299 ISC.buildPrivateCounterVar(); 6300 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6301 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6302 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6303 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6304 ISC.getConditionSrcRange(); 6305 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6306 ISC.getIncrementSrcRange(); 6307 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6308 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6309 ISC.isStrictTestOp(); 6310 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6311 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6312 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6313 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6314 ISC.buildFinalCondition(DSA.getCurScope()); 6315 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6316 ISC.doesInitDependOnLC(); 6317 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6318 ISC.doesCondDependOnLC(); 6319 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6320 ISC.getLoopDependentIdx(); 6321 6322 HasErrors |= 6323 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6324 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6325 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6326 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6327 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6328 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6329 if (!HasErrors && DSA.isOrderedRegion()) { 6330 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6331 if (CurrentNestedLoopCount < 6332 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6333 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6334 CurrentNestedLoopCount, 6335 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6336 DSA.getOrderedRegionParam().second->setLoopCounter( 6337 CurrentNestedLoopCount, 6338 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6339 } 6340 } 6341 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6342 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6343 // Erroneous case - clause has some problems. 6344 continue; 6345 } 6346 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6347 Pair.second.size() <= CurrentNestedLoopCount) { 6348 // Erroneous case - clause has some problems. 6349 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6350 continue; 6351 } 6352 Expr *CntValue; 6353 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6354 CntValue = ISC.buildOrderedLoopData( 6355 DSA.getCurScope(), 6356 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6357 Pair.first->getDependencyLoc()); 6358 else 6359 CntValue = ISC.buildOrderedLoopData( 6360 DSA.getCurScope(), 6361 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6362 Pair.first->getDependencyLoc(), 6363 Pair.second[CurrentNestedLoopCount].first, 6364 Pair.second[CurrentNestedLoopCount].second); 6365 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6366 } 6367 } 6368 6369 return HasErrors; 6370 } 6371 6372 /// Build 'VarRef = Start. 6373 static ExprResult 6374 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6375 ExprResult Start, bool IsNonRectangularLB, 6376 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6377 // Build 'VarRef = Start. 6378 ExprResult NewStart = IsNonRectangularLB 6379 ? Start.get() 6380 : tryBuildCapture(SemaRef, Start.get(), Captures); 6381 if (!NewStart.isUsable()) 6382 return ExprError(); 6383 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6384 VarRef.get()->getType())) { 6385 NewStart = SemaRef.PerformImplicitConversion( 6386 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6387 /*AllowExplicit=*/true); 6388 if (!NewStart.isUsable()) 6389 return ExprError(); 6390 } 6391 6392 ExprResult Init = 6393 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6394 return Init; 6395 } 6396 6397 /// Build 'VarRef = Start + Iter * Step'. 6398 static ExprResult buildCounterUpdate( 6399 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6400 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6401 bool IsNonRectangularLB, 6402 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6403 // Add parentheses (for debugging purposes only). 6404 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6405 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6406 !Step.isUsable()) 6407 return ExprError(); 6408 6409 ExprResult NewStep = Step; 6410 if (Captures) 6411 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6412 if (NewStep.isInvalid()) 6413 return ExprError(); 6414 ExprResult Update = 6415 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6416 if (!Update.isUsable()) 6417 return ExprError(); 6418 6419 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6420 // 'VarRef = Start (+|-) Iter * Step'. 6421 if (!Start.isUsable()) 6422 return ExprError(); 6423 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6424 if (!NewStart.isUsable()) 6425 return ExprError(); 6426 if (Captures && !IsNonRectangularLB) 6427 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6428 if (NewStart.isInvalid()) 6429 return ExprError(); 6430 6431 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6432 ExprResult SavedUpdate = Update; 6433 ExprResult UpdateVal; 6434 if (VarRef.get()->getType()->isOverloadableType() || 6435 NewStart.get()->getType()->isOverloadableType() || 6436 Update.get()->getType()->isOverloadableType()) { 6437 Sema::TentativeAnalysisScope Trap(SemaRef); 6438 6439 Update = 6440 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6441 if (Update.isUsable()) { 6442 UpdateVal = 6443 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6444 VarRef.get(), SavedUpdate.get()); 6445 if (UpdateVal.isUsable()) { 6446 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6447 UpdateVal.get()); 6448 } 6449 } 6450 } 6451 6452 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6453 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6454 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6455 NewStart.get(), SavedUpdate.get()); 6456 if (!Update.isUsable()) 6457 return ExprError(); 6458 6459 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6460 VarRef.get()->getType())) { 6461 Update = SemaRef.PerformImplicitConversion( 6462 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6463 if (!Update.isUsable()) 6464 return ExprError(); 6465 } 6466 6467 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6468 } 6469 return Update; 6470 } 6471 6472 /// Convert integer expression \a E to make it have at least \a Bits 6473 /// bits. 6474 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6475 if (E == nullptr) 6476 return ExprError(); 6477 ASTContext &C = SemaRef.Context; 6478 QualType OldType = E->getType(); 6479 unsigned HasBits = C.getTypeSize(OldType); 6480 if (HasBits >= Bits) 6481 return ExprResult(E); 6482 // OK to convert to signed, because new type has more bits than old. 6483 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6484 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6485 true); 6486 } 6487 6488 /// Check if the given expression \a E is a constant integer that fits 6489 /// into \a Bits bits. 6490 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6491 if (E == nullptr) 6492 return false; 6493 llvm::APSInt Result; 6494 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6495 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6496 return false; 6497 } 6498 6499 /// Build preinits statement for the given declarations. 6500 static Stmt *buildPreInits(ASTContext &Context, 6501 MutableArrayRef<Decl *> PreInits) { 6502 if (!PreInits.empty()) { 6503 return new (Context) DeclStmt( 6504 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6505 SourceLocation(), SourceLocation()); 6506 } 6507 return nullptr; 6508 } 6509 6510 /// Build preinits statement for the given declarations. 6511 static Stmt * 6512 buildPreInits(ASTContext &Context, 6513 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6514 if (!Captures.empty()) { 6515 SmallVector<Decl *, 16> PreInits; 6516 for (const auto &Pair : Captures) 6517 PreInits.push_back(Pair.second->getDecl()); 6518 return buildPreInits(Context, PreInits); 6519 } 6520 return nullptr; 6521 } 6522 6523 /// Build postupdate expression for the given list of postupdates expressions. 6524 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6525 Expr *PostUpdate = nullptr; 6526 if (!PostUpdates.empty()) { 6527 for (Expr *E : PostUpdates) { 6528 Expr *ConvE = S.BuildCStyleCastExpr( 6529 E->getExprLoc(), 6530 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6531 E->getExprLoc(), E) 6532 .get(); 6533 PostUpdate = PostUpdate 6534 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6535 PostUpdate, ConvE) 6536 .get() 6537 : ConvE; 6538 } 6539 } 6540 return PostUpdate; 6541 } 6542 6543 /// Called on a for stmt to check itself and nested loops (if any). 6544 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6545 /// number of collapsed loops otherwise. 6546 static unsigned 6547 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6548 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6549 DSAStackTy &DSA, 6550 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6551 OMPLoopDirective::HelperExprs &Built) { 6552 unsigned NestedLoopCount = 1; 6553 if (CollapseLoopCountExpr) { 6554 // Found 'collapse' clause - calculate collapse number. 6555 Expr::EvalResult Result; 6556 if (!CollapseLoopCountExpr->isValueDependent() && 6557 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6558 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6559 } else { 6560 Built.clear(/*Size=*/1); 6561 return 1; 6562 } 6563 } 6564 unsigned OrderedLoopCount = 1; 6565 if (OrderedLoopCountExpr) { 6566 // Found 'ordered' clause - calculate collapse number. 6567 Expr::EvalResult EVResult; 6568 if (!OrderedLoopCountExpr->isValueDependent() && 6569 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6570 SemaRef.getASTContext())) { 6571 llvm::APSInt Result = EVResult.Val.getInt(); 6572 if (Result.getLimitedValue() < NestedLoopCount) { 6573 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6574 diag::err_omp_wrong_ordered_loop_count) 6575 << OrderedLoopCountExpr->getSourceRange(); 6576 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6577 diag::note_collapse_loop_count) 6578 << CollapseLoopCountExpr->getSourceRange(); 6579 } 6580 OrderedLoopCount = Result.getLimitedValue(); 6581 } else { 6582 Built.clear(/*Size=*/1); 6583 return 1; 6584 } 6585 } 6586 // This is helper routine for loop directives (e.g., 'for', 'simd', 6587 // 'for simd', etc.). 6588 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6589 SmallVector<LoopIterationSpace, 4> IterSpaces( 6590 std::max(OrderedLoopCount, NestedLoopCount)); 6591 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6592 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6593 if (checkOpenMPIterationSpace( 6594 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6595 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6596 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6597 return 0; 6598 // Move on to the next nested for loop, or to the loop body. 6599 // OpenMP [2.8.1, simd construct, Restrictions] 6600 // All loops associated with the construct must be perfectly nested; that 6601 // is, there must be no intervening code nor any OpenMP directive between 6602 // any two loops. 6603 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6604 } 6605 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6606 if (checkOpenMPIterationSpace( 6607 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6608 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6609 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6610 return 0; 6611 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6612 // Handle initialization of captured loop iterator variables. 6613 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6614 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6615 Captures[DRE] = DRE; 6616 } 6617 } 6618 // Move on to the next nested for loop, or to the loop body. 6619 // OpenMP [2.8.1, simd construct, Restrictions] 6620 // All loops associated with the construct must be perfectly nested; that 6621 // is, there must be no intervening code nor any OpenMP directive between 6622 // any two loops. 6623 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6624 } 6625 6626 Built.clear(/* size */ NestedLoopCount); 6627 6628 if (SemaRef.CurContext->isDependentContext()) 6629 return NestedLoopCount; 6630 6631 // An example of what is generated for the following code: 6632 // 6633 // #pragma omp simd collapse(2) ordered(2) 6634 // for (i = 0; i < NI; ++i) 6635 // for (k = 0; k < NK; ++k) 6636 // for (j = J0; j < NJ; j+=2) { 6637 // <loop body> 6638 // } 6639 // 6640 // We generate the code below. 6641 // Note: the loop body may be outlined in CodeGen. 6642 // Note: some counters may be C++ classes, operator- is used to find number of 6643 // iterations and operator+= to calculate counter value. 6644 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6645 // or i64 is currently supported). 6646 // 6647 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6648 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6649 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6650 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6651 // // similar updates for vars in clauses (e.g. 'linear') 6652 // <loop body (using local i and j)> 6653 // } 6654 // i = NI; // assign final values of counters 6655 // j = NJ; 6656 // 6657 6658 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6659 // the iteration counts of the collapsed for loops. 6660 // Precondition tests if there is at least one iteration (all conditions are 6661 // true). 6662 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6663 Expr *N0 = IterSpaces[0].NumIterations; 6664 ExprResult LastIteration32 = 6665 widenIterationCount(/*Bits=*/32, 6666 SemaRef 6667 .PerformImplicitConversion( 6668 N0->IgnoreImpCasts(), N0->getType(), 6669 Sema::AA_Converting, /*AllowExplicit=*/true) 6670 .get(), 6671 SemaRef); 6672 ExprResult LastIteration64 = widenIterationCount( 6673 /*Bits=*/64, 6674 SemaRef 6675 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6676 Sema::AA_Converting, 6677 /*AllowExplicit=*/true) 6678 .get(), 6679 SemaRef); 6680 6681 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6682 return NestedLoopCount; 6683 6684 ASTContext &C = SemaRef.Context; 6685 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6686 6687 Scope *CurScope = DSA.getCurScope(); 6688 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6689 if (PreCond.isUsable()) { 6690 PreCond = 6691 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6692 PreCond.get(), IterSpaces[Cnt].PreCond); 6693 } 6694 Expr *N = IterSpaces[Cnt].NumIterations; 6695 SourceLocation Loc = N->getExprLoc(); 6696 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6697 if (LastIteration32.isUsable()) 6698 LastIteration32 = SemaRef.BuildBinOp( 6699 CurScope, Loc, BO_Mul, LastIteration32.get(), 6700 SemaRef 6701 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6702 Sema::AA_Converting, 6703 /*AllowExplicit=*/true) 6704 .get()); 6705 if (LastIteration64.isUsable()) 6706 LastIteration64 = SemaRef.BuildBinOp( 6707 CurScope, Loc, BO_Mul, LastIteration64.get(), 6708 SemaRef 6709 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6710 Sema::AA_Converting, 6711 /*AllowExplicit=*/true) 6712 .get()); 6713 } 6714 6715 // Choose either the 32-bit or 64-bit version. 6716 ExprResult LastIteration = LastIteration64; 6717 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6718 (LastIteration32.isUsable() && 6719 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6720 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6721 fitsInto( 6722 /*Bits=*/32, 6723 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6724 LastIteration64.get(), SemaRef)))) 6725 LastIteration = LastIteration32; 6726 QualType VType = LastIteration.get()->getType(); 6727 QualType RealVType = VType; 6728 QualType StrideVType = VType; 6729 if (isOpenMPTaskLoopDirective(DKind)) { 6730 VType = 6731 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6732 StrideVType = 6733 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6734 } 6735 6736 if (!LastIteration.isUsable()) 6737 return 0; 6738 6739 // Save the number of iterations. 6740 ExprResult NumIterations = LastIteration; 6741 { 6742 LastIteration = SemaRef.BuildBinOp( 6743 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6744 LastIteration.get(), 6745 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6746 if (!LastIteration.isUsable()) 6747 return 0; 6748 } 6749 6750 // Calculate the last iteration number beforehand instead of doing this on 6751 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6752 llvm::APSInt Result; 6753 bool IsConstant = 6754 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6755 ExprResult CalcLastIteration; 6756 if (!IsConstant) { 6757 ExprResult SaveRef = 6758 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6759 LastIteration = SaveRef; 6760 6761 // Prepare SaveRef + 1. 6762 NumIterations = SemaRef.BuildBinOp( 6763 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6764 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6765 if (!NumIterations.isUsable()) 6766 return 0; 6767 } 6768 6769 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6770 6771 // Build variables passed into runtime, necessary for worksharing directives. 6772 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6773 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6774 isOpenMPDistributeDirective(DKind)) { 6775 // Lower bound variable, initialized with zero. 6776 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6777 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6778 SemaRef.AddInitializerToDecl(LBDecl, 6779 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6780 /*DirectInit*/ false); 6781 6782 // Upper bound variable, initialized with last iteration number. 6783 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6784 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6785 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6786 /*DirectInit*/ false); 6787 6788 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6789 // This will be used to implement clause 'lastprivate'. 6790 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6791 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6792 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6793 SemaRef.AddInitializerToDecl(ILDecl, 6794 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6795 /*DirectInit*/ false); 6796 6797 // Stride variable returned by runtime (we initialize it to 1 by default). 6798 VarDecl *STDecl = 6799 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6800 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6801 SemaRef.AddInitializerToDecl(STDecl, 6802 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6803 /*DirectInit*/ false); 6804 6805 // Build expression: UB = min(UB, LastIteration) 6806 // It is necessary for CodeGen of directives with static scheduling. 6807 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6808 UB.get(), LastIteration.get()); 6809 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6810 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6811 LastIteration.get(), UB.get()); 6812 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6813 CondOp.get()); 6814 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6815 6816 // If we have a combined directive that combines 'distribute', 'for' or 6817 // 'simd' we need to be able to access the bounds of the schedule of the 6818 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6819 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6820 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6821 // Lower bound variable, initialized with zero. 6822 VarDecl *CombLBDecl = 6823 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6824 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6825 SemaRef.AddInitializerToDecl( 6826 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6827 /*DirectInit*/ false); 6828 6829 // Upper bound variable, initialized with last iteration number. 6830 VarDecl *CombUBDecl = 6831 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6832 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6833 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6834 /*DirectInit*/ false); 6835 6836 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6837 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6838 ExprResult CombCondOp = 6839 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6840 LastIteration.get(), CombUB.get()); 6841 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6842 CombCondOp.get()); 6843 CombEUB = 6844 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6845 6846 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6847 // We expect to have at least 2 more parameters than the 'parallel' 6848 // directive does - the lower and upper bounds of the previous schedule. 6849 assert(CD->getNumParams() >= 4 && 6850 "Unexpected number of parameters in loop combined directive"); 6851 6852 // Set the proper type for the bounds given what we learned from the 6853 // enclosed loops. 6854 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6855 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6856 6857 // Previous lower and upper bounds are obtained from the region 6858 // parameters. 6859 PrevLB = 6860 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6861 PrevUB = 6862 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6863 } 6864 } 6865 6866 // Build the iteration variable and its initialization before loop. 6867 ExprResult IV; 6868 ExprResult Init, CombInit; 6869 { 6870 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6871 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6872 Expr *RHS = 6873 (isOpenMPWorksharingDirective(DKind) || 6874 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6875 ? LB.get() 6876 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6877 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6878 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6879 6880 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6881 Expr *CombRHS = 6882 (isOpenMPWorksharingDirective(DKind) || 6883 isOpenMPTaskLoopDirective(DKind) || 6884 isOpenMPDistributeDirective(DKind)) 6885 ? CombLB.get() 6886 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6887 CombInit = 6888 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6889 CombInit = 6890 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6891 } 6892 } 6893 6894 bool UseStrictCompare = 6895 RealVType->hasUnsignedIntegerRepresentation() && 6896 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6897 return LIS.IsStrictCompare; 6898 }); 6899 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6900 // unsigned IV)) for worksharing loops. 6901 SourceLocation CondLoc = AStmt->getBeginLoc(); 6902 Expr *BoundUB = UB.get(); 6903 if (UseStrictCompare) { 6904 BoundUB = 6905 SemaRef 6906 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6907 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6908 .get(); 6909 BoundUB = 6910 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6911 } 6912 ExprResult Cond = 6913 (isOpenMPWorksharingDirective(DKind) || 6914 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6915 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6916 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6917 BoundUB) 6918 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6919 NumIterations.get()); 6920 ExprResult CombDistCond; 6921 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6922 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6923 NumIterations.get()); 6924 } 6925 6926 ExprResult CombCond; 6927 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6928 Expr *BoundCombUB = CombUB.get(); 6929 if (UseStrictCompare) { 6930 BoundCombUB = 6931 SemaRef 6932 .BuildBinOp( 6933 CurScope, CondLoc, BO_Add, BoundCombUB, 6934 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6935 .get(); 6936 BoundCombUB = 6937 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6938 .get(); 6939 } 6940 CombCond = 6941 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6942 IV.get(), BoundCombUB); 6943 } 6944 // Loop increment (IV = IV + 1) 6945 SourceLocation IncLoc = AStmt->getBeginLoc(); 6946 ExprResult Inc = 6947 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6948 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6949 if (!Inc.isUsable()) 6950 return 0; 6951 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6952 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6953 if (!Inc.isUsable()) 6954 return 0; 6955 6956 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6957 // Used for directives with static scheduling. 6958 // In combined construct, add combined version that use CombLB and CombUB 6959 // base variables for the update 6960 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6961 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6962 isOpenMPDistributeDirective(DKind)) { 6963 // LB + ST 6964 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6965 if (!NextLB.isUsable()) 6966 return 0; 6967 // LB = LB + ST 6968 NextLB = 6969 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6970 NextLB = 6971 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6972 if (!NextLB.isUsable()) 6973 return 0; 6974 // UB + ST 6975 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6976 if (!NextUB.isUsable()) 6977 return 0; 6978 // UB = UB + ST 6979 NextUB = 6980 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6981 NextUB = 6982 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6983 if (!NextUB.isUsable()) 6984 return 0; 6985 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6986 CombNextLB = 6987 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6988 if (!NextLB.isUsable()) 6989 return 0; 6990 // LB = LB + ST 6991 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 6992 CombNextLB.get()); 6993 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 6994 /*DiscardedValue*/ false); 6995 if (!CombNextLB.isUsable()) 6996 return 0; 6997 // UB + ST 6998 CombNextUB = 6999 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7000 if (!CombNextUB.isUsable()) 7001 return 0; 7002 // UB = UB + ST 7003 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7004 CombNextUB.get()); 7005 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7006 /*DiscardedValue*/ false); 7007 if (!CombNextUB.isUsable()) 7008 return 0; 7009 } 7010 } 7011 7012 // Create increment expression for distribute loop when combined in a same 7013 // directive with for as IV = IV + ST; ensure upper bound expression based 7014 // on PrevUB instead of NumIterations - used to implement 'for' when found 7015 // in combination with 'distribute', like in 'distribute parallel for' 7016 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7017 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7018 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7019 DistCond = SemaRef.BuildBinOp( 7020 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7021 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7022 7023 DistInc = 7024 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7025 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7026 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7027 DistInc.get()); 7028 DistInc = 7029 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7030 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7031 7032 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7033 // construct 7034 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7035 ExprResult IsUBGreater = 7036 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7037 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7038 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7039 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7040 CondOp.get()); 7041 PrevEUB = 7042 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7043 7044 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7045 // parallel for is in combination with a distribute directive with 7046 // schedule(static, 1) 7047 Expr *BoundPrevUB = PrevUB.get(); 7048 if (UseStrictCompare) { 7049 BoundPrevUB = 7050 SemaRef 7051 .BuildBinOp( 7052 CurScope, CondLoc, BO_Add, BoundPrevUB, 7053 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7054 .get(); 7055 BoundPrevUB = 7056 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7057 .get(); 7058 } 7059 ParForInDistCond = 7060 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7061 IV.get(), BoundPrevUB); 7062 } 7063 7064 // Build updates and final values of the loop counters. 7065 bool HasErrors = false; 7066 Built.Counters.resize(NestedLoopCount); 7067 Built.Inits.resize(NestedLoopCount); 7068 Built.Updates.resize(NestedLoopCount); 7069 Built.Finals.resize(NestedLoopCount); 7070 Built.DependentCounters.resize(NestedLoopCount); 7071 Built.DependentInits.resize(NestedLoopCount); 7072 Built.FinalsConditions.resize(NestedLoopCount); 7073 { 7074 // We implement the following algorithm for obtaining the 7075 // original loop iteration variable values based on the 7076 // value of the collapsed loop iteration variable IV. 7077 // 7078 // Let n+1 be the number of collapsed loops in the nest. 7079 // Iteration variables (I0, I1, .... In) 7080 // Iteration counts (N0, N1, ... Nn) 7081 // 7082 // Acc = IV; 7083 // 7084 // To compute Ik for loop k, 0 <= k <= n, generate: 7085 // Prod = N(k+1) * N(k+2) * ... * Nn; 7086 // Ik = Acc / Prod; 7087 // Acc -= Ik * Prod; 7088 // 7089 ExprResult Acc = IV; 7090 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7091 LoopIterationSpace &IS = IterSpaces[Cnt]; 7092 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7093 ExprResult Iter; 7094 7095 // Compute prod 7096 ExprResult Prod = 7097 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7098 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7099 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7100 IterSpaces[K].NumIterations); 7101 7102 // Iter = Acc / Prod 7103 // If there is at least one more inner loop to avoid 7104 // multiplication by 1. 7105 if (Cnt + 1 < NestedLoopCount) 7106 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7107 Acc.get(), Prod.get()); 7108 else 7109 Iter = Acc; 7110 if (!Iter.isUsable()) { 7111 HasErrors = true; 7112 break; 7113 } 7114 7115 // Update Acc: 7116 // Acc -= Iter * Prod 7117 // Check if there is at least one more inner loop to avoid 7118 // multiplication by 1. 7119 if (Cnt + 1 < NestedLoopCount) 7120 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7121 Iter.get(), Prod.get()); 7122 else 7123 Prod = Iter; 7124 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7125 Acc.get(), Prod.get()); 7126 7127 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7128 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7129 DeclRefExpr *CounterVar = buildDeclRefExpr( 7130 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7131 /*RefersToCapture=*/true); 7132 ExprResult Init = 7133 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7134 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7135 if (!Init.isUsable()) { 7136 HasErrors = true; 7137 break; 7138 } 7139 ExprResult Update = buildCounterUpdate( 7140 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7141 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7142 if (!Update.isUsable()) { 7143 HasErrors = true; 7144 break; 7145 } 7146 7147 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7148 ExprResult Final = 7149 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7150 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7151 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7152 if (!Final.isUsable()) { 7153 HasErrors = true; 7154 break; 7155 } 7156 7157 if (!Update.isUsable() || !Final.isUsable()) { 7158 HasErrors = true; 7159 break; 7160 } 7161 // Save results 7162 Built.Counters[Cnt] = IS.CounterVar; 7163 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7164 Built.Inits[Cnt] = Init.get(); 7165 Built.Updates[Cnt] = Update.get(); 7166 Built.Finals[Cnt] = Final.get(); 7167 Built.DependentCounters[Cnt] = nullptr; 7168 Built.DependentInits[Cnt] = nullptr; 7169 Built.FinalsConditions[Cnt] = nullptr; 7170 if (IS.IsNonRectangularLB) { 7171 Built.DependentCounters[Cnt] = 7172 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7173 Built.DependentInits[Cnt] = 7174 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7175 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7176 } 7177 } 7178 } 7179 7180 if (HasErrors) 7181 return 0; 7182 7183 // Save results 7184 Built.IterationVarRef = IV.get(); 7185 Built.LastIteration = LastIteration.get(); 7186 Built.NumIterations = NumIterations.get(); 7187 Built.CalcLastIteration = SemaRef 7188 .ActOnFinishFullExpr(CalcLastIteration.get(), 7189 /*DiscardedValue=*/false) 7190 .get(); 7191 Built.PreCond = PreCond.get(); 7192 Built.PreInits = buildPreInits(C, Captures); 7193 Built.Cond = Cond.get(); 7194 Built.Init = Init.get(); 7195 Built.Inc = Inc.get(); 7196 Built.LB = LB.get(); 7197 Built.UB = UB.get(); 7198 Built.IL = IL.get(); 7199 Built.ST = ST.get(); 7200 Built.EUB = EUB.get(); 7201 Built.NLB = NextLB.get(); 7202 Built.NUB = NextUB.get(); 7203 Built.PrevLB = PrevLB.get(); 7204 Built.PrevUB = PrevUB.get(); 7205 Built.DistInc = DistInc.get(); 7206 Built.PrevEUB = PrevEUB.get(); 7207 Built.DistCombinedFields.LB = CombLB.get(); 7208 Built.DistCombinedFields.UB = CombUB.get(); 7209 Built.DistCombinedFields.EUB = CombEUB.get(); 7210 Built.DistCombinedFields.Init = CombInit.get(); 7211 Built.DistCombinedFields.Cond = CombCond.get(); 7212 Built.DistCombinedFields.NLB = CombNextLB.get(); 7213 Built.DistCombinedFields.NUB = CombNextUB.get(); 7214 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7215 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7216 7217 return NestedLoopCount; 7218 } 7219 7220 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7221 auto CollapseClauses = 7222 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7223 if (CollapseClauses.begin() != CollapseClauses.end()) 7224 return (*CollapseClauses.begin())->getNumForLoops(); 7225 return nullptr; 7226 } 7227 7228 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7229 auto OrderedClauses = 7230 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7231 if (OrderedClauses.begin() != OrderedClauses.end()) 7232 return (*OrderedClauses.begin())->getNumForLoops(); 7233 return nullptr; 7234 } 7235 7236 static bool checkSimdlenSafelenSpecified(Sema &S, 7237 const ArrayRef<OMPClause *> Clauses) { 7238 const OMPSafelenClause *Safelen = nullptr; 7239 const OMPSimdlenClause *Simdlen = nullptr; 7240 7241 for (const OMPClause *Clause : Clauses) { 7242 if (Clause->getClauseKind() == OMPC_safelen) 7243 Safelen = cast<OMPSafelenClause>(Clause); 7244 else if (Clause->getClauseKind() == OMPC_simdlen) 7245 Simdlen = cast<OMPSimdlenClause>(Clause); 7246 if (Safelen && Simdlen) 7247 break; 7248 } 7249 7250 if (Simdlen && Safelen) { 7251 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7252 const Expr *SafelenLength = Safelen->getSafelen(); 7253 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7254 SimdlenLength->isInstantiationDependent() || 7255 SimdlenLength->containsUnexpandedParameterPack()) 7256 return false; 7257 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7258 SafelenLength->isInstantiationDependent() || 7259 SafelenLength->containsUnexpandedParameterPack()) 7260 return false; 7261 Expr::EvalResult SimdlenResult, SafelenResult; 7262 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7263 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7264 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7265 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7266 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7267 // If both simdlen and safelen clauses are specified, the value of the 7268 // simdlen parameter must be less than or equal to the value of the safelen 7269 // parameter. 7270 if (SimdlenRes > SafelenRes) { 7271 S.Diag(SimdlenLength->getExprLoc(), 7272 diag::err_omp_wrong_simdlen_safelen_values) 7273 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7274 return true; 7275 } 7276 } 7277 return false; 7278 } 7279 7280 StmtResult 7281 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7282 SourceLocation StartLoc, SourceLocation EndLoc, 7283 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7284 if (!AStmt) 7285 return StmtError(); 7286 7287 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7288 OMPLoopDirective::HelperExprs B; 7289 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7290 // define the nested loops number. 7291 unsigned NestedLoopCount = checkOpenMPLoop( 7292 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7293 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7294 if (NestedLoopCount == 0) 7295 return StmtError(); 7296 7297 assert((CurContext->isDependentContext() || B.builtAll()) && 7298 "omp simd loop exprs were not built"); 7299 7300 if (!CurContext->isDependentContext()) { 7301 // Finalize the clauses that need pre-built expressions for CodeGen. 7302 for (OMPClause *C : Clauses) { 7303 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7304 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7305 B.NumIterations, *this, CurScope, 7306 DSAStack)) 7307 return StmtError(); 7308 } 7309 } 7310 7311 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7312 return StmtError(); 7313 7314 setFunctionHasBranchProtectedScope(); 7315 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7316 Clauses, AStmt, B); 7317 } 7318 7319 StmtResult 7320 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7321 SourceLocation StartLoc, SourceLocation EndLoc, 7322 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7323 if (!AStmt) 7324 return StmtError(); 7325 7326 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7327 OMPLoopDirective::HelperExprs B; 7328 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7329 // define the nested loops number. 7330 unsigned NestedLoopCount = checkOpenMPLoop( 7331 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7332 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7333 if (NestedLoopCount == 0) 7334 return StmtError(); 7335 7336 assert((CurContext->isDependentContext() || B.builtAll()) && 7337 "omp for loop exprs were not built"); 7338 7339 if (!CurContext->isDependentContext()) { 7340 // Finalize the clauses that need pre-built expressions for CodeGen. 7341 for (OMPClause *C : Clauses) { 7342 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7343 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7344 B.NumIterations, *this, CurScope, 7345 DSAStack)) 7346 return StmtError(); 7347 } 7348 } 7349 7350 setFunctionHasBranchProtectedScope(); 7351 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7352 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7353 } 7354 7355 StmtResult Sema::ActOnOpenMPForSimdDirective( 7356 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7357 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7358 if (!AStmt) 7359 return StmtError(); 7360 7361 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7362 OMPLoopDirective::HelperExprs B; 7363 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7364 // define the nested loops number. 7365 unsigned NestedLoopCount = 7366 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7367 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7368 VarsWithImplicitDSA, B); 7369 if (NestedLoopCount == 0) 7370 return StmtError(); 7371 7372 assert((CurContext->isDependentContext() || B.builtAll()) && 7373 "omp for simd loop exprs were not built"); 7374 7375 if (!CurContext->isDependentContext()) { 7376 // Finalize the clauses that need pre-built expressions for CodeGen. 7377 for (OMPClause *C : Clauses) { 7378 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7379 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7380 B.NumIterations, *this, CurScope, 7381 DSAStack)) 7382 return StmtError(); 7383 } 7384 } 7385 7386 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7387 return StmtError(); 7388 7389 setFunctionHasBranchProtectedScope(); 7390 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7391 Clauses, AStmt, B); 7392 } 7393 7394 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7395 Stmt *AStmt, 7396 SourceLocation StartLoc, 7397 SourceLocation EndLoc) { 7398 if (!AStmt) 7399 return StmtError(); 7400 7401 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7402 auto BaseStmt = AStmt; 7403 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7404 BaseStmt = CS->getCapturedStmt(); 7405 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7406 auto S = C->children(); 7407 if (S.begin() == S.end()) 7408 return StmtError(); 7409 // All associated statements must be '#pragma omp section' except for 7410 // the first one. 7411 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7412 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7413 if (SectionStmt) 7414 Diag(SectionStmt->getBeginLoc(), 7415 diag::err_omp_sections_substmt_not_section); 7416 return StmtError(); 7417 } 7418 cast<OMPSectionDirective>(SectionStmt) 7419 ->setHasCancel(DSAStack->isCancelRegion()); 7420 } 7421 } else { 7422 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7423 return StmtError(); 7424 } 7425 7426 setFunctionHasBranchProtectedScope(); 7427 7428 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7429 DSAStack->isCancelRegion()); 7430 } 7431 7432 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7433 SourceLocation StartLoc, 7434 SourceLocation EndLoc) { 7435 if (!AStmt) 7436 return StmtError(); 7437 7438 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7439 7440 setFunctionHasBranchProtectedScope(); 7441 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7442 7443 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7444 DSAStack->isCancelRegion()); 7445 } 7446 7447 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7448 Stmt *AStmt, 7449 SourceLocation StartLoc, 7450 SourceLocation EndLoc) { 7451 if (!AStmt) 7452 return StmtError(); 7453 7454 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7455 7456 setFunctionHasBranchProtectedScope(); 7457 7458 // OpenMP [2.7.3, single Construct, Restrictions] 7459 // The copyprivate clause must not be used with the nowait clause. 7460 const OMPClause *Nowait = nullptr; 7461 const OMPClause *Copyprivate = nullptr; 7462 for (const OMPClause *Clause : Clauses) { 7463 if (Clause->getClauseKind() == OMPC_nowait) 7464 Nowait = Clause; 7465 else if (Clause->getClauseKind() == OMPC_copyprivate) 7466 Copyprivate = Clause; 7467 if (Copyprivate && Nowait) { 7468 Diag(Copyprivate->getBeginLoc(), 7469 diag::err_omp_single_copyprivate_with_nowait); 7470 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7471 return StmtError(); 7472 } 7473 } 7474 7475 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7476 } 7477 7478 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7479 SourceLocation StartLoc, 7480 SourceLocation EndLoc) { 7481 if (!AStmt) 7482 return StmtError(); 7483 7484 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7485 7486 setFunctionHasBranchProtectedScope(); 7487 7488 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7489 } 7490 7491 StmtResult Sema::ActOnOpenMPCriticalDirective( 7492 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7493 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7494 if (!AStmt) 7495 return StmtError(); 7496 7497 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7498 7499 bool ErrorFound = false; 7500 llvm::APSInt Hint; 7501 SourceLocation HintLoc; 7502 bool DependentHint = false; 7503 for (const OMPClause *C : Clauses) { 7504 if (C->getClauseKind() == OMPC_hint) { 7505 if (!DirName.getName()) { 7506 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7507 ErrorFound = true; 7508 } 7509 Expr *E = cast<OMPHintClause>(C)->getHint(); 7510 if (E->isTypeDependent() || E->isValueDependent() || 7511 E->isInstantiationDependent()) { 7512 DependentHint = true; 7513 } else { 7514 Hint = E->EvaluateKnownConstInt(Context); 7515 HintLoc = C->getBeginLoc(); 7516 } 7517 } 7518 } 7519 if (ErrorFound) 7520 return StmtError(); 7521 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7522 if (Pair.first && DirName.getName() && !DependentHint) { 7523 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7524 Diag(StartLoc, diag::err_omp_critical_with_hint); 7525 if (HintLoc.isValid()) 7526 Diag(HintLoc, diag::note_omp_critical_hint_here) 7527 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7528 else 7529 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7530 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7531 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7532 << 1 7533 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7534 /*Radix=*/10, /*Signed=*/false); 7535 } else { 7536 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7537 } 7538 } 7539 } 7540 7541 setFunctionHasBranchProtectedScope(); 7542 7543 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7544 Clauses, AStmt); 7545 if (!Pair.first && DirName.getName() && !DependentHint) 7546 DSAStack->addCriticalWithHint(Dir, Hint); 7547 return Dir; 7548 } 7549 7550 StmtResult Sema::ActOnOpenMPParallelForDirective( 7551 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7552 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7553 if (!AStmt) 7554 return StmtError(); 7555 7556 auto *CS = cast<CapturedStmt>(AStmt); 7557 // 1.2.2 OpenMP Language Terminology 7558 // Structured block - An executable statement with a single entry at the 7559 // top and a single exit at the bottom. 7560 // The point of exit cannot be a branch out of the structured block. 7561 // longjmp() and throw() must not violate the entry/exit criteria. 7562 CS->getCapturedDecl()->setNothrow(); 7563 7564 OMPLoopDirective::HelperExprs B; 7565 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7566 // define the nested loops number. 7567 unsigned NestedLoopCount = 7568 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7569 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7570 VarsWithImplicitDSA, B); 7571 if (NestedLoopCount == 0) 7572 return StmtError(); 7573 7574 assert((CurContext->isDependentContext() || B.builtAll()) && 7575 "omp parallel for loop exprs were not built"); 7576 7577 if (!CurContext->isDependentContext()) { 7578 // Finalize the clauses that need pre-built expressions for CodeGen. 7579 for (OMPClause *C : Clauses) { 7580 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7581 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7582 B.NumIterations, *this, CurScope, 7583 DSAStack)) 7584 return StmtError(); 7585 } 7586 } 7587 7588 setFunctionHasBranchProtectedScope(); 7589 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7590 NestedLoopCount, Clauses, AStmt, B, 7591 DSAStack->isCancelRegion()); 7592 } 7593 7594 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7595 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7596 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7597 if (!AStmt) 7598 return StmtError(); 7599 7600 auto *CS = cast<CapturedStmt>(AStmt); 7601 // 1.2.2 OpenMP Language Terminology 7602 // Structured block - An executable statement with a single entry at the 7603 // top and a single exit at the bottom. 7604 // The point of exit cannot be a branch out of the structured block. 7605 // longjmp() and throw() must not violate the entry/exit criteria. 7606 CS->getCapturedDecl()->setNothrow(); 7607 7608 OMPLoopDirective::HelperExprs B; 7609 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7610 // define the nested loops number. 7611 unsigned NestedLoopCount = 7612 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7613 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7614 VarsWithImplicitDSA, B); 7615 if (NestedLoopCount == 0) 7616 return StmtError(); 7617 7618 if (!CurContext->isDependentContext()) { 7619 // Finalize the clauses that need pre-built expressions for CodeGen. 7620 for (OMPClause *C : Clauses) { 7621 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7622 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7623 B.NumIterations, *this, CurScope, 7624 DSAStack)) 7625 return StmtError(); 7626 } 7627 } 7628 7629 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7630 return StmtError(); 7631 7632 setFunctionHasBranchProtectedScope(); 7633 return OMPParallelForSimdDirective::Create( 7634 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7635 } 7636 7637 StmtResult 7638 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7639 Stmt *AStmt, SourceLocation StartLoc, 7640 SourceLocation EndLoc) { 7641 if (!AStmt) 7642 return StmtError(); 7643 7644 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7645 auto BaseStmt = AStmt; 7646 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7647 BaseStmt = CS->getCapturedStmt(); 7648 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7649 auto S = C->children(); 7650 if (S.begin() == S.end()) 7651 return StmtError(); 7652 // All associated statements must be '#pragma omp section' except for 7653 // the first one. 7654 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7655 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7656 if (SectionStmt) 7657 Diag(SectionStmt->getBeginLoc(), 7658 diag::err_omp_parallel_sections_substmt_not_section); 7659 return StmtError(); 7660 } 7661 cast<OMPSectionDirective>(SectionStmt) 7662 ->setHasCancel(DSAStack->isCancelRegion()); 7663 } 7664 } else { 7665 Diag(AStmt->getBeginLoc(), 7666 diag::err_omp_parallel_sections_not_compound_stmt); 7667 return StmtError(); 7668 } 7669 7670 setFunctionHasBranchProtectedScope(); 7671 7672 return OMPParallelSectionsDirective::Create( 7673 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7674 } 7675 7676 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7677 Stmt *AStmt, SourceLocation StartLoc, 7678 SourceLocation EndLoc) { 7679 if (!AStmt) 7680 return StmtError(); 7681 7682 auto *CS = cast<CapturedStmt>(AStmt); 7683 // 1.2.2 OpenMP Language Terminology 7684 // Structured block - An executable statement with a single entry at the 7685 // top and a single exit at the bottom. 7686 // The point of exit cannot be a branch out of the structured block. 7687 // longjmp() and throw() must not violate the entry/exit criteria. 7688 CS->getCapturedDecl()->setNothrow(); 7689 7690 setFunctionHasBranchProtectedScope(); 7691 7692 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7693 DSAStack->isCancelRegion()); 7694 } 7695 7696 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7697 SourceLocation EndLoc) { 7698 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7699 } 7700 7701 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7702 SourceLocation EndLoc) { 7703 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7704 } 7705 7706 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7707 SourceLocation EndLoc) { 7708 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7709 } 7710 7711 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7712 Stmt *AStmt, 7713 SourceLocation StartLoc, 7714 SourceLocation EndLoc) { 7715 if (!AStmt) 7716 return StmtError(); 7717 7718 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7719 7720 setFunctionHasBranchProtectedScope(); 7721 7722 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7723 AStmt, 7724 DSAStack->getTaskgroupReductionRef()); 7725 } 7726 7727 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7728 SourceLocation StartLoc, 7729 SourceLocation EndLoc) { 7730 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7731 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7732 } 7733 7734 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7735 Stmt *AStmt, 7736 SourceLocation StartLoc, 7737 SourceLocation EndLoc) { 7738 const OMPClause *DependFound = nullptr; 7739 const OMPClause *DependSourceClause = nullptr; 7740 const OMPClause *DependSinkClause = nullptr; 7741 bool ErrorFound = false; 7742 const OMPThreadsClause *TC = nullptr; 7743 const OMPSIMDClause *SC = nullptr; 7744 for (const OMPClause *C : Clauses) { 7745 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7746 DependFound = C; 7747 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7748 if (DependSourceClause) { 7749 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7750 << getOpenMPDirectiveName(OMPD_ordered) 7751 << getOpenMPClauseName(OMPC_depend) << 2; 7752 ErrorFound = true; 7753 } else { 7754 DependSourceClause = C; 7755 } 7756 if (DependSinkClause) { 7757 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7758 << 0; 7759 ErrorFound = true; 7760 } 7761 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7762 if (DependSourceClause) { 7763 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7764 << 1; 7765 ErrorFound = true; 7766 } 7767 DependSinkClause = C; 7768 } 7769 } else if (C->getClauseKind() == OMPC_threads) { 7770 TC = cast<OMPThreadsClause>(C); 7771 } else if (C->getClauseKind() == OMPC_simd) { 7772 SC = cast<OMPSIMDClause>(C); 7773 } 7774 } 7775 if (!ErrorFound && !SC && 7776 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7777 // OpenMP [2.8.1,simd Construct, Restrictions] 7778 // An ordered construct with the simd clause is the only OpenMP construct 7779 // that can appear in the simd region. 7780 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7781 ErrorFound = true; 7782 } else if (DependFound && (TC || SC)) { 7783 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7784 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7785 ErrorFound = true; 7786 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7787 Diag(DependFound->getBeginLoc(), 7788 diag::err_omp_ordered_directive_without_param); 7789 ErrorFound = true; 7790 } else if (TC || Clauses.empty()) { 7791 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 7792 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 7793 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 7794 << (TC != nullptr); 7795 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7796 ErrorFound = true; 7797 } 7798 } 7799 if ((!AStmt && !DependFound) || ErrorFound) 7800 return StmtError(); 7801 7802 if (AStmt) { 7803 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7804 7805 setFunctionHasBranchProtectedScope(); 7806 } 7807 7808 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7809 } 7810 7811 namespace { 7812 /// Helper class for checking expression in 'omp atomic [update]' 7813 /// construct. 7814 class OpenMPAtomicUpdateChecker { 7815 /// Error results for atomic update expressions. 7816 enum ExprAnalysisErrorCode { 7817 /// A statement is not an expression statement. 7818 NotAnExpression, 7819 /// Expression is not builtin binary or unary operation. 7820 NotABinaryOrUnaryExpression, 7821 /// Unary operation is not post-/pre- increment/decrement operation. 7822 NotAnUnaryIncDecExpression, 7823 /// An expression is not of scalar type. 7824 NotAScalarType, 7825 /// A binary operation is not an assignment operation. 7826 NotAnAssignmentOp, 7827 /// RHS part of the binary operation is not a binary expression. 7828 NotABinaryExpression, 7829 /// RHS part is not additive/multiplicative/shift/biwise binary 7830 /// expression. 7831 NotABinaryOperator, 7832 /// RHS binary operation does not have reference to the updated LHS 7833 /// part. 7834 NotAnUpdateExpression, 7835 /// No errors is found. 7836 NoError 7837 }; 7838 /// Reference to Sema. 7839 Sema &SemaRef; 7840 /// A location for note diagnostics (when error is found). 7841 SourceLocation NoteLoc; 7842 /// 'x' lvalue part of the source atomic expression. 7843 Expr *X; 7844 /// 'expr' rvalue part of the source atomic expression. 7845 Expr *E; 7846 /// Helper expression of the form 7847 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7848 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7849 Expr *UpdateExpr; 7850 /// Is 'x' a LHS in a RHS part of full update expression. It is 7851 /// important for non-associative operations. 7852 bool IsXLHSInRHSPart; 7853 BinaryOperatorKind Op; 7854 SourceLocation OpLoc; 7855 /// true if the source expression is a postfix unary operation, false 7856 /// if it is a prefix unary operation. 7857 bool IsPostfixUpdate; 7858 7859 public: 7860 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7861 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7862 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7863 /// Check specified statement that it is suitable for 'atomic update' 7864 /// constructs and extract 'x', 'expr' and Operation from the original 7865 /// expression. If DiagId and NoteId == 0, then only check is performed 7866 /// without error notification. 7867 /// \param DiagId Diagnostic which should be emitted if error is found. 7868 /// \param NoteId Diagnostic note for the main error message. 7869 /// \return true if statement is not an update expression, false otherwise. 7870 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7871 /// Return the 'x' lvalue part of the source atomic expression. 7872 Expr *getX() const { return X; } 7873 /// Return the 'expr' rvalue part of the source atomic expression. 7874 Expr *getExpr() const { return E; } 7875 /// Return the update expression used in calculation of the updated 7876 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7877 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7878 Expr *getUpdateExpr() const { return UpdateExpr; } 7879 /// Return true if 'x' is LHS in RHS part of full update expression, 7880 /// false otherwise. 7881 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7882 7883 /// true if the source expression is a postfix unary operation, false 7884 /// if it is a prefix unary operation. 7885 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7886 7887 private: 7888 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7889 unsigned NoteId = 0); 7890 }; 7891 } // namespace 7892 7893 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7894 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7895 ExprAnalysisErrorCode ErrorFound = NoError; 7896 SourceLocation ErrorLoc, NoteLoc; 7897 SourceRange ErrorRange, NoteRange; 7898 // Allowed constructs are: 7899 // x = x binop expr; 7900 // x = expr binop x; 7901 if (AtomicBinOp->getOpcode() == BO_Assign) { 7902 X = AtomicBinOp->getLHS(); 7903 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7904 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7905 if (AtomicInnerBinOp->isMultiplicativeOp() || 7906 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7907 AtomicInnerBinOp->isBitwiseOp()) { 7908 Op = AtomicInnerBinOp->getOpcode(); 7909 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7910 Expr *LHS = AtomicInnerBinOp->getLHS(); 7911 Expr *RHS = AtomicInnerBinOp->getRHS(); 7912 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7913 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7914 /*Canonical=*/true); 7915 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7916 /*Canonical=*/true); 7917 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7918 /*Canonical=*/true); 7919 if (XId == LHSId) { 7920 E = RHS; 7921 IsXLHSInRHSPart = true; 7922 } else if (XId == RHSId) { 7923 E = LHS; 7924 IsXLHSInRHSPart = false; 7925 } else { 7926 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7927 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7928 NoteLoc = X->getExprLoc(); 7929 NoteRange = X->getSourceRange(); 7930 ErrorFound = NotAnUpdateExpression; 7931 } 7932 } else { 7933 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7934 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7935 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7936 NoteRange = SourceRange(NoteLoc, NoteLoc); 7937 ErrorFound = NotABinaryOperator; 7938 } 7939 } else { 7940 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7941 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7942 ErrorFound = NotABinaryExpression; 7943 } 7944 } else { 7945 ErrorLoc = AtomicBinOp->getExprLoc(); 7946 ErrorRange = AtomicBinOp->getSourceRange(); 7947 NoteLoc = AtomicBinOp->getOperatorLoc(); 7948 NoteRange = SourceRange(NoteLoc, NoteLoc); 7949 ErrorFound = NotAnAssignmentOp; 7950 } 7951 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7952 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7953 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7954 return true; 7955 } 7956 if (SemaRef.CurContext->isDependentContext()) 7957 E = X = UpdateExpr = nullptr; 7958 return ErrorFound != NoError; 7959 } 7960 7961 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7962 unsigned NoteId) { 7963 ExprAnalysisErrorCode ErrorFound = NoError; 7964 SourceLocation ErrorLoc, NoteLoc; 7965 SourceRange ErrorRange, NoteRange; 7966 // Allowed constructs are: 7967 // x++; 7968 // x--; 7969 // ++x; 7970 // --x; 7971 // x binop= expr; 7972 // x = x binop expr; 7973 // x = expr binop x; 7974 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7975 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7976 if (AtomicBody->getType()->isScalarType() || 7977 AtomicBody->isInstantiationDependent()) { 7978 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7979 AtomicBody->IgnoreParenImpCasts())) { 7980 // Check for Compound Assignment Operation 7981 Op = BinaryOperator::getOpForCompoundAssignment( 7982 AtomicCompAssignOp->getOpcode()); 7983 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7984 E = AtomicCompAssignOp->getRHS(); 7985 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7986 IsXLHSInRHSPart = true; 7987 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7988 AtomicBody->IgnoreParenImpCasts())) { 7989 // Check for Binary Operation 7990 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 7991 return true; 7992 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 7993 AtomicBody->IgnoreParenImpCasts())) { 7994 // Check for Unary Operation 7995 if (AtomicUnaryOp->isIncrementDecrementOp()) { 7996 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 7997 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 7998 OpLoc = AtomicUnaryOp->getOperatorLoc(); 7999 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8000 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8001 IsXLHSInRHSPart = true; 8002 } else { 8003 ErrorFound = NotAnUnaryIncDecExpression; 8004 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8005 ErrorRange = AtomicUnaryOp->getSourceRange(); 8006 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8007 NoteRange = SourceRange(NoteLoc, NoteLoc); 8008 } 8009 } else if (!AtomicBody->isInstantiationDependent()) { 8010 ErrorFound = NotABinaryOrUnaryExpression; 8011 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8012 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8013 } 8014 } else { 8015 ErrorFound = NotAScalarType; 8016 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8017 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8018 } 8019 } else { 8020 ErrorFound = NotAnExpression; 8021 NoteLoc = ErrorLoc = S->getBeginLoc(); 8022 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8023 } 8024 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8025 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8026 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8027 return true; 8028 } 8029 if (SemaRef.CurContext->isDependentContext()) 8030 E = X = UpdateExpr = nullptr; 8031 if (ErrorFound == NoError && E && X) { 8032 // Build an update expression of form 'OpaqueValueExpr(x) binop 8033 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8034 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8035 auto *OVEX = new (SemaRef.getASTContext()) 8036 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8037 auto *OVEExpr = new (SemaRef.getASTContext()) 8038 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8039 ExprResult Update = 8040 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8041 IsXLHSInRHSPart ? OVEExpr : OVEX); 8042 if (Update.isInvalid()) 8043 return true; 8044 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8045 Sema::AA_Casting); 8046 if (Update.isInvalid()) 8047 return true; 8048 UpdateExpr = Update.get(); 8049 } 8050 return ErrorFound != NoError; 8051 } 8052 8053 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8054 Stmt *AStmt, 8055 SourceLocation StartLoc, 8056 SourceLocation EndLoc) { 8057 if (!AStmt) 8058 return StmtError(); 8059 8060 auto *CS = cast<CapturedStmt>(AStmt); 8061 // 1.2.2 OpenMP Language Terminology 8062 // Structured block - An executable statement with a single entry at the 8063 // top and a single exit at the bottom. 8064 // The point of exit cannot be a branch out of the structured block. 8065 // longjmp() and throw() must not violate the entry/exit criteria. 8066 OpenMPClauseKind AtomicKind = OMPC_unknown; 8067 SourceLocation AtomicKindLoc; 8068 for (const OMPClause *C : Clauses) { 8069 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8070 C->getClauseKind() == OMPC_update || 8071 C->getClauseKind() == OMPC_capture) { 8072 if (AtomicKind != OMPC_unknown) { 8073 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8074 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8075 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8076 << getOpenMPClauseName(AtomicKind); 8077 } else { 8078 AtomicKind = C->getClauseKind(); 8079 AtomicKindLoc = C->getBeginLoc(); 8080 } 8081 } 8082 } 8083 8084 Stmt *Body = CS->getCapturedStmt(); 8085 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8086 Body = EWC->getSubExpr(); 8087 8088 Expr *X = nullptr; 8089 Expr *V = nullptr; 8090 Expr *E = nullptr; 8091 Expr *UE = nullptr; 8092 bool IsXLHSInRHSPart = false; 8093 bool IsPostfixUpdate = false; 8094 // OpenMP [2.12.6, atomic Construct] 8095 // In the next expressions: 8096 // * x and v (as applicable) are both l-value expressions with scalar type. 8097 // * During the execution of an atomic region, multiple syntactic 8098 // occurrences of x must designate the same storage location. 8099 // * Neither of v and expr (as applicable) may access the storage location 8100 // designated by x. 8101 // * Neither of x and expr (as applicable) may access the storage location 8102 // designated by v. 8103 // * expr is an expression with scalar type. 8104 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8105 // * binop, binop=, ++, and -- are not overloaded operators. 8106 // * The expression x binop expr must be numerically equivalent to x binop 8107 // (expr). This requirement is satisfied if the operators in expr have 8108 // precedence greater than binop, or by using parentheses around expr or 8109 // subexpressions of expr. 8110 // * The expression expr binop x must be numerically equivalent to (expr) 8111 // binop x. This requirement is satisfied if the operators in expr have 8112 // precedence equal to or greater than binop, or by using parentheses around 8113 // expr or subexpressions of expr. 8114 // * For forms that allow multiple occurrences of x, the number of times 8115 // that x is evaluated is unspecified. 8116 if (AtomicKind == OMPC_read) { 8117 enum { 8118 NotAnExpression, 8119 NotAnAssignmentOp, 8120 NotAScalarType, 8121 NotAnLValue, 8122 NoError 8123 } ErrorFound = NoError; 8124 SourceLocation ErrorLoc, NoteLoc; 8125 SourceRange ErrorRange, NoteRange; 8126 // If clause is read: 8127 // v = x; 8128 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8129 const auto *AtomicBinOp = 8130 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8131 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8132 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8133 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8134 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8135 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8136 if (!X->isLValue() || !V->isLValue()) { 8137 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8138 ErrorFound = NotAnLValue; 8139 ErrorLoc = AtomicBinOp->getExprLoc(); 8140 ErrorRange = AtomicBinOp->getSourceRange(); 8141 NoteLoc = NotLValueExpr->getExprLoc(); 8142 NoteRange = NotLValueExpr->getSourceRange(); 8143 } 8144 } else if (!X->isInstantiationDependent() || 8145 !V->isInstantiationDependent()) { 8146 const Expr *NotScalarExpr = 8147 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8148 ? V 8149 : X; 8150 ErrorFound = NotAScalarType; 8151 ErrorLoc = AtomicBinOp->getExprLoc(); 8152 ErrorRange = AtomicBinOp->getSourceRange(); 8153 NoteLoc = NotScalarExpr->getExprLoc(); 8154 NoteRange = NotScalarExpr->getSourceRange(); 8155 } 8156 } else if (!AtomicBody->isInstantiationDependent()) { 8157 ErrorFound = NotAnAssignmentOp; 8158 ErrorLoc = AtomicBody->getExprLoc(); 8159 ErrorRange = AtomicBody->getSourceRange(); 8160 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8161 : AtomicBody->getExprLoc(); 8162 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8163 : AtomicBody->getSourceRange(); 8164 } 8165 } else { 8166 ErrorFound = NotAnExpression; 8167 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8168 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8169 } 8170 if (ErrorFound != NoError) { 8171 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8172 << ErrorRange; 8173 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8174 << NoteRange; 8175 return StmtError(); 8176 } 8177 if (CurContext->isDependentContext()) 8178 V = X = nullptr; 8179 } else if (AtomicKind == OMPC_write) { 8180 enum { 8181 NotAnExpression, 8182 NotAnAssignmentOp, 8183 NotAScalarType, 8184 NotAnLValue, 8185 NoError 8186 } ErrorFound = NoError; 8187 SourceLocation ErrorLoc, NoteLoc; 8188 SourceRange ErrorRange, NoteRange; 8189 // If clause is write: 8190 // x = expr; 8191 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8192 const auto *AtomicBinOp = 8193 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8194 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8195 X = AtomicBinOp->getLHS(); 8196 E = AtomicBinOp->getRHS(); 8197 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8198 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8199 if (!X->isLValue()) { 8200 ErrorFound = NotAnLValue; 8201 ErrorLoc = AtomicBinOp->getExprLoc(); 8202 ErrorRange = AtomicBinOp->getSourceRange(); 8203 NoteLoc = X->getExprLoc(); 8204 NoteRange = X->getSourceRange(); 8205 } 8206 } else if (!X->isInstantiationDependent() || 8207 !E->isInstantiationDependent()) { 8208 const Expr *NotScalarExpr = 8209 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8210 ? E 8211 : X; 8212 ErrorFound = NotAScalarType; 8213 ErrorLoc = AtomicBinOp->getExprLoc(); 8214 ErrorRange = AtomicBinOp->getSourceRange(); 8215 NoteLoc = NotScalarExpr->getExprLoc(); 8216 NoteRange = NotScalarExpr->getSourceRange(); 8217 } 8218 } else if (!AtomicBody->isInstantiationDependent()) { 8219 ErrorFound = NotAnAssignmentOp; 8220 ErrorLoc = AtomicBody->getExprLoc(); 8221 ErrorRange = AtomicBody->getSourceRange(); 8222 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8223 : AtomicBody->getExprLoc(); 8224 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8225 : AtomicBody->getSourceRange(); 8226 } 8227 } else { 8228 ErrorFound = NotAnExpression; 8229 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8230 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8231 } 8232 if (ErrorFound != NoError) { 8233 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8234 << ErrorRange; 8235 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8236 << NoteRange; 8237 return StmtError(); 8238 } 8239 if (CurContext->isDependentContext()) 8240 E = X = nullptr; 8241 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8242 // If clause is update: 8243 // x++; 8244 // x--; 8245 // ++x; 8246 // --x; 8247 // x binop= expr; 8248 // x = x binop expr; 8249 // x = expr binop x; 8250 OpenMPAtomicUpdateChecker Checker(*this); 8251 if (Checker.checkStatement( 8252 Body, (AtomicKind == OMPC_update) 8253 ? diag::err_omp_atomic_update_not_expression_statement 8254 : diag::err_omp_atomic_not_expression_statement, 8255 diag::note_omp_atomic_update)) 8256 return StmtError(); 8257 if (!CurContext->isDependentContext()) { 8258 E = Checker.getExpr(); 8259 X = Checker.getX(); 8260 UE = Checker.getUpdateExpr(); 8261 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8262 } 8263 } else if (AtomicKind == OMPC_capture) { 8264 enum { 8265 NotAnAssignmentOp, 8266 NotACompoundStatement, 8267 NotTwoSubstatements, 8268 NotASpecificExpression, 8269 NoError 8270 } ErrorFound = NoError; 8271 SourceLocation ErrorLoc, NoteLoc; 8272 SourceRange ErrorRange, NoteRange; 8273 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8274 // If clause is a capture: 8275 // v = x++; 8276 // v = x--; 8277 // v = ++x; 8278 // v = --x; 8279 // v = x binop= expr; 8280 // v = x = x binop expr; 8281 // v = x = expr binop x; 8282 const auto *AtomicBinOp = 8283 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8284 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8285 V = AtomicBinOp->getLHS(); 8286 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8287 OpenMPAtomicUpdateChecker Checker(*this); 8288 if (Checker.checkStatement( 8289 Body, diag::err_omp_atomic_capture_not_expression_statement, 8290 diag::note_omp_atomic_update)) 8291 return StmtError(); 8292 E = Checker.getExpr(); 8293 X = Checker.getX(); 8294 UE = Checker.getUpdateExpr(); 8295 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8296 IsPostfixUpdate = Checker.isPostfixUpdate(); 8297 } else if (!AtomicBody->isInstantiationDependent()) { 8298 ErrorLoc = AtomicBody->getExprLoc(); 8299 ErrorRange = AtomicBody->getSourceRange(); 8300 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8301 : AtomicBody->getExprLoc(); 8302 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8303 : AtomicBody->getSourceRange(); 8304 ErrorFound = NotAnAssignmentOp; 8305 } 8306 if (ErrorFound != NoError) { 8307 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8308 << ErrorRange; 8309 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8310 return StmtError(); 8311 } 8312 if (CurContext->isDependentContext()) 8313 UE = V = E = X = nullptr; 8314 } else { 8315 // If clause is a capture: 8316 // { v = x; x = expr; } 8317 // { v = x; x++; } 8318 // { v = x; x--; } 8319 // { v = x; ++x; } 8320 // { v = x; --x; } 8321 // { v = x; x binop= expr; } 8322 // { v = x; x = x binop expr; } 8323 // { v = x; x = expr binop x; } 8324 // { x++; v = x; } 8325 // { x--; v = x; } 8326 // { ++x; v = x; } 8327 // { --x; v = x; } 8328 // { x binop= expr; v = x; } 8329 // { x = x binop expr; v = x; } 8330 // { x = expr binop x; v = x; } 8331 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8332 // Check that this is { expr1; expr2; } 8333 if (CS->size() == 2) { 8334 Stmt *First = CS->body_front(); 8335 Stmt *Second = CS->body_back(); 8336 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8337 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8338 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8339 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8340 // Need to find what subexpression is 'v' and what is 'x'. 8341 OpenMPAtomicUpdateChecker Checker(*this); 8342 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8343 BinaryOperator *BinOp = nullptr; 8344 if (IsUpdateExprFound) { 8345 BinOp = dyn_cast<BinaryOperator>(First); 8346 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8347 } 8348 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8349 // { v = x; x++; } 8350 // { v = x; x--; } 8351 // { v = x; ++x; } 8352 // { v = x; --x; } 8353 // { v = x; x binop= expr; } 8354 // { v = x; x = x binop expr; } 8355 // { v = x; x = expr binop x; } 8356 // Check that the first expression has form v = x. 8357 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8358 llvm::FoldingSetNodeID XId, PossibleXId; 8359 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8360 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8361 IsUpdateExprFound = XId == PossibleXId; 8362 if (IsUpdateExprFound) { 8363 V = BinOp->getLHS(); 8364 X = Checker.getX(); 8365 E = Checker.getExpr(); 8366 UE = Checker.getUpdateExpr(); 8367 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8368 IsPostfixUpdate = true; 8369 } 8370 } 8371 if (!IsUpdateExprFound) { 8372 IsUpdateExprFound = !Checker.checkStatement(First); 8373 BinOp = nullptr; 8374 if (IsUpdateExprFound) { 8375 BinOp = dyn_cast<BinaryOperator>(Second); 8376 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8377 } 8378 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8379 // { x++; v = x; } 8380 // { x--; v = x; } 8381 // { ++x; v = x; } 8382 // { --x; v = x; } 8383 // { x binop= expr; v = x; } 8384 // { x = x binop expr; v = x; } 8385 // { x = expr binop x; v = x; } 8386 // Check that the second expression has form v = x. 8387 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8388 llvm::FoldingSetNodeID XId, PossibleXId; 8389 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8390 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8391 IsUpdateExprFound = XId == PossibleXId; 8392 if (IsUpdateExprFound) { 8393 V = BinOp->getLHS(); 8394 X = Checker.getX(); 8395 E = Checker.getExpr(); 8396 UE = Checker.getUpdateExpr(); 8397 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8398 IsPostfixUpdate = false; 8399 } 8400 } 8401 } 8402 if (!IsUpdateExprFound) { 8403 // { v = x; x = expr; } 8404 auto *FirstExpr = dyn_cast<Expr>(First); 8405 auto *SecondExpr = dyn_cast<Expr>(Second); 8406 if (!FirstExpr || !SecondExpr || 8407 !(FirstExpr->isInstantiationDependent() || 8408 SecondExpr->isInstantiationDependent())) { 8409 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8410 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8411 ErrorFound = NotAnAssignmentOp; 8412 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8413 : First->getBeginLoc(); 8414 NoteRange = ErrorRange = FirstBinOp 8415 ? FirstBinOp->getSourceRange() 8416 : SourceRange(ErrorLoc, ErrorLoc); 8417 } else { 8418 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8419 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8420 ErrorFound = NotAnAssignmentOp; 8421 NoteLoc = ErrorLoc = SecondBinOp 8422 ? SecondBinOp->getOperatorLoc() 8423 : Second->getBeginLoc(); 8424 NoteRange = ErrorRange = 8425 SecondBinOp ? SecondBinOp->getSourceRange() 8426 : SourceRange(ErrorLoc, ErrorLoc); 8427 } else { 8428 Expr *PossibleXRHSInFirst = 8429 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8430 Expr *PossibleXLHSInSecond = 8431 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8432 llvm::FoldingSetNodeID X1Id, X2Id; 8433 PossibleXRHSInFirst->Profile(X1Id, Context, 8434 /*Canonical=*/true); 8435 PossibleXLHSInSecond->Profile(X2Id, Context, 8436 /*Canonical=*/true); 8437 IsUpdateExprFound = X1Id == X2Id; 8438 if (IsUpdateExprFound) { 8439 V = FirstBinOp->getLHS(); 8440 X = SecondBinOp->getLHS(); 8441 E = SecondBinOp->getRHS(); 8442 UE = nullptr; 8443 IsXLHSInRHSPart = false; 8444 IsPostfixUpdate = true; 8445 } else { 8446 ErrorFound = NotASpecificExpression; 8447 ErrorLoc = FirstBinOp->getExprLoc(); 8448 ErrorRange = FirstBinOp->getSourceRange(); 8449 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8450 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8451 } 8452 } 8453 } 8454 } 8455 } 8456 } else { 8457 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8458 NoteRange = ErrorRange = 8459 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8460 ErrorFound = NotTwoSubstatements; 8461 } 8462 } else { 8463 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8464 NoteRange = ErrorRange = 8465 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8466 ErrorFound = NotACompoundStatement; 8467 } 8468 if (ErrorFound != NoError) { 8469 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8470 << ErrorRange; 8471 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8472 return StmtError(); 8473 } 8474 if (CurContext->isDependentContext()) 8475 UE = V = E = X = nullptr; 8476 } 8477 } 8478 8479 setFunctionHasBranchProtectedScope(); 8480 8481 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8482 X, V, E, UE, IsXLHSInRHSPart, 8483 IsPostfixUpdate); 8484 } 8485 8486 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8487 Stmt *AStmt, 8488 SourceLocation StartLoc, 8489 SourceLocation EndLoc) { 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 = getOpenMPCaptureLevels(OMPD_target); 8501 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8502 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8503 // 1.2.2 OpenMP Language Terminology 8504 // Structured block - An executable statement with a single entry at the 8505 // top and a single exit at the bottom. 8506 // The point of exit cannot be a branch out of the structured block. 8507 // longjmp() and throw() must not violate the entry/exit criteria. 8508 CS->getCapturedDecl()->setNothrow(); 8509 } 8510 8511 // OpenMP [2.16, Nesting of Regions] 8512 // If specified, a teams construct must be contained within a target 8513 // construct. That target construct must contain no statements or directives 8514 // outside of the teams construct. 8515 if (DSAStack->hasInnerTeamsRegion()) { 8516 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8517 bool OMPTeamsFound = true; 8518 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8519 auto I = CS->body_begin(); 8520 while (I != CS->body_end()) { 8521 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8522 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8523 OMPTeamsFound) { 8524 8525 OMPTeamsFound = false; 8526 break; 8527 } 8528 ++I; 8529 } 8530 assert(I != CS->body_end() && "Not found statement"); 8531 S = *I; 8532 } else { 8533 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8534 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8535 } 8536 if (!OMPTeamsFound) { 8537 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8538 Diag(DSAStack->getInnerTeamsRegionLoc(), 8539 diag::note_omp_nested_teams_construct_here); 8540 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8541 << isa<OMPExecutableDirective>(S); 8542 return StmtError(); 8543 } 8544 } 8545 8546 setFunctionHasBranchProtectedScope(); 8547 8548 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8549 } 8550 8551 StmtResult 8552 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8553 Stmt *AStmt, SourceLocation StartLoc, 8554 SourceLocation EndLoc) { 8555 if (!AStmt) 8556 return StmtError(); 8557 8558 auto *CS = cast<CapturedStmt>(AStmt); 8559 // 1.2.2 OpenMP Language Terminology 8560 // Structured block - An executable statement with a single entry at the 8561 // top and a single exit at the bottom. 8562 // The point of exit cannot be a branch out of the structured block. 8563 // longjmp() and throw() must not violate the entry/exit criteria. 8564 CS->getCapturedDecl()->setNothrow(); 8565 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8566 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8567 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8568 // 1.2.2 OpenMP Language Terminology 8569 // Structured block - An executable statement with a single entry at the 8570 // top and a single exit at the bottom. 8571 // The point of exit cannot be a branch out of the structured block. 8572 // longjmp() and throw() must not violate the entry/exit criteria. 8573 CS->getCapturedDecl()->setNothrow(); 8574 } 8575 8576 setFunctionHasBranchProtectedScope(); 8577 8578 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8579 AStmt); 8580 } 8581 8582 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8583 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8584 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8585 if (!AStmt) 8586 return StmtError(); 8587 8588 auto *CS = cast<CapturedStmt>(AStmt); 8589 // 1.2.2 OpenMP Language Terminology 8590 // Structured block - An executable statement with a single entry at the 8591 // top and a single exit at the bottom. 8592 // The point of exit cannot be a branch out of the structured block. 8593 // longjmp() and throw() must not violate the entry/exit criteria. 8594 CS->getCapturedDecl()->setNothrow(); 8595 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8596 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8597 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8598 // 1.2.2 OpenMP Language Terminology 8599 // Structured block - An executable statement with a single entry at the 8600 // top and a single exit at the bottom. 8601 // The point of exit cannot be a branch out of the structured block. 8602 // longjmp() and throw() must not violate the entry/exit criteria. 8603 CS->getCapturedDecl()->setNothrow(); 8604 } 8605 8606 OMPLoopDirective::HelperExprs B; 8607 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8608 // define the nested loops number. 8609 unsigned NestedLoopCount = 8610 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8611 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8612 VarsWithImplicitDSA, B); 8613 if (NestedLoopCount == 0) 8614 return StmtError(); 8615 8616 assert((CurContext->isDependentContext() || B.builtAll()) && 8617 "omp target parallel for loop exprs were not built"); 8618 8619 if (!CurContext->isDependentContext()) { 8620 // Finalize the clauses that need pre-built expressions for CodeGen. 8621 for (OMPClause *C : Clauses) { 8622 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8623 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8624 B.NumIterations, *this, CurScope, 8625 DSAStack)) 8626 return StmtError(); 8627 } 8628 } 8629 8630 setFunctionHasBranchProtectedScope(); 8631 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8632 NestedLoopCount, Clauses, AStmt, 8633 B, DSAStack->isCancelRegion()); 8634 } 8635 8636 /// Check for existence of a map clause in the list of clauses. 8637 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8638 const OpenMPClauseKind K) { 8639 return llvm::any_of( 8640 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8641 } 8642 8643 template <typename... Params> 8644 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8645 const Params... ClauseTypes) { 8646 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8647 } 8648 8649 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8650 Stmt *AStmt, 8651 SourceLocation StartLoc, 8652 SourceLocation EndLoc) { 8653 if (!AStmt) 8654 return StmtError(); 8655 8656 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8657 8658 // OpenMP [2.10.1, Restrictions, p. 97] 8659 // At least one map clause must appear on the directive. 8660 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8661 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8662 << "'map' or 'use_device_ptr'" 8663 << getOpenMPDirectiveName(OMPD_target_data); 8664 return StmtError(); 8665 } 8666 8667 setFunctionHasBranchProtectedScope(); 8668 8669 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8670 AStmt); 8671 } 8672 8673 StmtResult 8674 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8675 SourceLocation StartLoc, 8676 SourceLocation EndLoc, Stmt *AStmt) { 8677 if (!AStmt) 8678 return StmtError(); 8679 8680 auto *CS = cast<CapturedStmt>(AStmt); 8681 // 1.2.2 OpenMP Language Terminology 8682 // Structured block - An executable statement with a single entry at the 8683 // top and a single exit at the bottom. 8684 // The point of exit cannot be a branch out of the structured block. 8685 // longjmp() and throw() must not violate the entry/exit criteria. 8686 CS->getCapturedDecl()->setNothrow(); 8687 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8688 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8689 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8690 // 1.2.2 OpenMP Language Terminology 8691 // Structured block - An executable statement with a single entry at the 8692 // top and a single exit at the bottom. 8693 // The point of exit cannot be a branch out of the structured block. 8694 // longjmp() and throw() must not violate the entry/exit criteria. 8695 CS->getCapturedDecl()->setNothrow(); 8696 } 8697 8698 // OpenMP [2.10.2, Restrictions, p. 99] 8699 // At least one map clause must appear on the directive. 8700 if (!hasClauses(Clauses, OMPC_map)) { 8701 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8702 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8703 return StmtError(); 8704 } 8705 8706 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8707 AStmt); 8708 } 8709 8710 StmtResult 8711 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8712 SourceLocation StartLoc, 8713 SourceLocation EndLoc, Stmt *AStmt) { 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_target_exit_data); 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 // OpenMP [2.10.3, Restrictions, p. 102] 8736 // At least one map clause must appear on the directive. 8737 if (!hasClauses(Clauses, OMPC_map)) { 8738 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8739 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8740 return StmtError(); 8741 } 8742 8743 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8744 AStmt); 8745 } 8746 8747 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8748 SourceLocation StartLoc, 8749 SourceLocation EndLoc, 8750 Stmt *AStmt) { 8751 if (!AStmt) 8752 return StmtError(); 8753 8754 auto *CS = cast<CapturedStmt>(AStmt); 8755 // 1.2.2 OpenMP Language Terminology 8756 // Structured block - An executable statement with a single entry at the 8757 // top and a single exit at the bottom. 8758 // The point of exit cannot be a branch out of the structured block. 8759 // longjmp() and throw() must not violate the entry/exit criteria. 8760 CS->getCapturedDecl()->setNothrow(); 8761 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8762 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8763 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8764 // 1.2.2 OpenMP Language Terminology 8765 // Structured block - An executable statement with a single entry at the 8766 // top and a single exit at the bottom. 8767 // The point of exit cannot be a branch out of the structured block. 8768 // longjmp() and throw() must not violate the entry/exit criteria. 8769 CS->getCapturedDecl()->setNothrow(); 8770 } 8771 8772 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8773 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8774 return StmtError(); 8775 } 8776 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8777 AStmt); 8778 } 8779 8780 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8781 Stmt *AStmt, SourceLocation StartLoc, 8782 SourceLocation EndLoc) { 8783 if (!AStmt) 8784 return StmtError(); 8785 8786 auto *CS = cast<CapturedStmt>(AStmt); 8787 // 1.2.2 OpenMP Language Terminology 8788 // Structured block - An executable statement with a single entry at the 8789 // top and a single exit at the bottom. 8790 // The point of exit cannot be a branch out of the structured block. 8791 // longjmp() and throw() must not violate the entry/exit criteria. 8792 CS->getCapturedDecl()->setNothrow(); 8793 8794 setFunctionHasBranchProtectedScope(); 8795 8796 DSAStack->setParentTeamsRegionLoc(StartLoc); 8797 8798 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8799 } 8800 8801 StmtResult 8802 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8803 SourceLocation EndLoc, 8804 OpenMPDirectiveKind CancelRegion) { 8805 if (DSAStack->isParentNowaitRegion()) { 8806 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8807 return StmtError(); 8808 } 8809 if (DSAStack->isParentOrderedRegion()) { 8810 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8811 return StmtError(); 8812 } 8813 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8814 CancelRegion); 8815 } 8816 8817 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8818 SourceLocation StartLoc, 8819 SourceLocation EndLoc, 8820 OpenMPDirectiveKind CancelRegion) { 8821 if (DSAStack->isParentNowaitRegion()) { 8822 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8823 return StmtError(); 8824 } 8825 if (DSAStack->isParentOrderedRegion()) { 8826 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8827 return StmtError(); 8828 } 8829 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8830 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8831 CancelRegion); 8832 } 8833 8834 static bool checkGrainsizeNumTasksClauses(Sema &S, 8835 ArrayRef<OMPClause *> Clauses) { 8836 const OMPClause *PrevClause = nullptr; 8837 bool ErrorFound = false; 8838 for (const OMPClause *C : Clauses) { 8839 if (C->getClauseKind() == OMPC_grainsize || 8840 C->getClauseKind() == OMPC_num_tasks) { 8841 if (!PrevClause) 8842 PrevClause = C; 8843 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8844 S.Diag(C->getBeginLoc(), 8845 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8846 << getOpenMPClauseName(C->getClauseKind()) 8847 << getOpenMPClauseName(PrevClause->getClauseKind()); 8848 S.Diag(PrevClause->getBeginLoc(), 8849 diag::note_omp_previous_grainsize_num_tasks) 8850 << getOpenMPClauseName(PrevClause->getClauseKind()); 8851 ErrorFound = true; 8852 } 8853 } 8854 } 8855 return ErrorFound; 8856 } 8857 8858 static bool checkReductionClauseWithNogroup(Sema &S, 8859 ArrayRef<OMPClause *> Clauses) { 8860 const OMPClause *ReductionClause = nullptr; 8861 const OMPClause *NogroupClause = nullptr; 8862 for (const OMPClause *C : Clauses) { 8863 if (C->getClauseKind() == OMPC_reduction) { 8864 ReductionClause = C; 8865 if (NogroupClause) 8866 break; 8867 continue; 8868 } 8869 if (C->getClauseKind() == OMPC_nogroup) { 8870 NogroupClause = C; 8871 if (ReductionClause) 8872 break; 8873 continue; 8874 } 8875 } 8876 if (ReductionClause && NogroupClause) { 8877 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8878 << SourceRange(NogroupClause->getBeginLoc(), 8879 NogroupClause->getEndLoc()); 8880 return true; 8881 } 8882 return false; 8883 } 8884 8885 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8886 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8887 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8888 if (!AStmt) 8889 return StmtError(); 8890 8891 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8892 OMPLoopDirective::HelperExprs B; 8893 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8894 // define the nested loops number. 8895 unsigned NestedLoopCount = 8896 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8897 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8898 VarsWithImplicitDSA, B); 8899 if (NestedLoopCount == 0) 8900 return StmtError(); 8901 8902 assert((CurContext->isDependentContext() || B.builtAll()) && 8903 "omp for loop exprs were not built"); 8904 8905 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8906 // The grainsize clause and num_tasks clause are mutually exclusive and may 8907 // not appear on the same taskloop directive. 8908 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8909 return StmtError(); 8910 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8911 // If a reduction clause is present on the taskloop directive, the nogroup 8912 // clause must not be specified. 8913 if (checkReductionClauseWithNogroup(*this, Clauses)) 8914 return StmtError(); 8915 8916 setFunctionHasBranchProtectedScope(); 8917 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8918 NestedLoopCount, Clauses, AStmt, B); 8919 } 8920 8921 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8922 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8923 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8924 if (!AStmt) 8925 return StmtError(); 8926 8927 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8928 OMPLoopDirective::HelperExprs B; 8929 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8930 // define the nested loops number. 8931 unsigned NestedLoopCount = 8932 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8933 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8934 VarsWithImplicitDSA, B); 8935 if (NestedLoopCount == 0) 8936 return StmtError(); 8937 8938 assert((CurContext->isDependentContext() || B.builtAll()) && 8939 "omp for loop exprs were not built"); 8940 8941 if (!CurContext->isDependentContext()) { 8942 // Finalize the clauses that need pre-built expressions for CodeGen. 8943 for (OMPClause *C : Clauses) { 8944 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8945 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8946 B.NumIterations, *this, CurScope, 8947 DSAStack)) 8948 return StmtError(); 8949 } 8950 } 8951 8952 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8953 // The grainsize clause and num_tasks clause are mutually exclusive and may 8954 // not appear on the same taskloop directive. 8955 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8956 return StmtError(); 8957 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8958 // If a reduction clause is present on the taskloop directive, the nogroup 8959 // clause must not be specified. 8960 if (checkReductionClauseWithNogroup(*this, Clauses)) 8961 return StmtError(); 8962 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8963 return StmtError(); 8964 8965 setFunctionHasBranchProtectedScope(); 8966 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8967 NestedLoopCount, Clauses, AStmt, B); 8968 } 8969 8970 StmtResult Sema::ActOnOpenMPDistributeDirective( 8971 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8972 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8973 if (!AStmt) 8974 return StmtError(); 8975 8976 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8977 OMPLoopDirective::HelperExprs B; 8978 // In presence of clause 'collapse' with number of loops, it will 8979 // define the nested loops number. 8980 unsigned NestedLoopCount = 8981 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8982 nullptr /*ordered not a clause on distribute*/, AStmt, 8983 *this, *DSAStack, VarsWithImplicitDSA, B); 8984 if (NestedLoopCount == 0) 8985 return StmtError(); 8986 8987 assert((CurContext->isDependentContext() || B.builtAll()) && 8988 "omp for loop exprs were not built"); 8989 8990 setFunctionHasBranchProtectedScope(); 8991 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 8992 NestedLoopCount, Clauses, AStmt, B); 8993 } 8994 8995 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 8996 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8997 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8998 if (!AStmt) 8999 return StmtError(); 9000 9001 auto *CS = cast<CapturedStmt>(AStmt); 9002 // 1.2.2 OpenMP Language Terminology 9003 // Structured block - An executable statement with a single entry at the 9004 // top and a single exit at the bottom. 9005 // The point of exit cannot be a branch out of the structured block. 9006 // longjmp() and throw() must not violate the entry/exit criteria. 9007 CS->getCapturedDecl()->setNothrow(); 9008 for (int ThisCaptureLevel = 9009 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9010 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9011 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9012 // 1.2.2 OpenMP Language Terminology 9013 // Structured block - An executable statement with a single entry at the 9014 // top and a single exit at the bottom. 9015 // The point of exit cannot be a branch out of the structured block. 9016 // longjmp() and throw() must not violate the entry/exit criteria. 9017 CS->getCapturedDecl()->setNothrow(); 9018 } 9019 9020 OMPLoopDirective::HelperExprs B; 9021 // In presence of clause 'collapse' with number of loops, it will 9022 // define the nested loops number. 9023 unsigned NestedLoopCount = checkOpenMPLoop( 9024 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9025 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9026 VarsWithImplicitDSA, B); 9027 if (NestedLoopCount == 0) 9028 return StmtError(); 9029 9030 assert((CurContext->isDependentContext() || B.builtAll()) && 9031 "omp for loop exprs were not built"); 9032 9033 setFunctionHasBranchProtectedScope(); 9034 return OMPDistributeParallelForDirective::Create( 9035 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9036 DSAStack->isCancelRegion()); 9037 } 9038 9039 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9040 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9041 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9042 if (!AStmt) 9043 return StmtError(); 9044 9045 auto *CS = cast<CapturedStmt>(AStmt); 9046 // 1.2.2 OpenMP Language Terminology 9047 // Structured block - An executable statement with a single entry at the 9048 // top and a single exit at the bottom. 9049 // The point of exit cannot be a branch out of the structured block. 9050 // longjmp() and throw() must not violate the entry/exit criteria. 9051 CS->getCapturedDecl()->setNothrow(); 9052 for (int ThisCaptureLevel = 9053 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9054 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9055 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9056 // 1.2.2 OpenMP Language Terminology 9057 // Structured block - An executable statement with a single entry at the 9058 // top and a single exit at the bottom. 9059 // The point of exit cannot be a branch out of the structured block. 9060 // longjmp() and throw() must not violate the entry/exit criteria. 9061 CS->getCapturedDecl()->setNothrow(); 9062 } 9063 9064 OMPLoopDirective::HelperExprs B; 9065 // In presence of clause 'collapse' with number of loops, it will 9066 // define the nested loops number. 9067 unsigned NestedLoopCount = checkOpenMPLoop( 9068 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9069 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9070 VarsWithImplicitDSA, B); 9071 if (NestedLoopCount == 0) 9072 return StmtError(); 9073 9074 assert((CurContext->isDependentContext() || B.builtAll()) && 9075 "omp for loop exprs were not built"); 9076 9077 if (!CurContext->isDependentContext()) { 9078 // Finalize the clauses that need pre-built expressions for CodeGen. 9079 for (OMPClause *C : Clauses) { 9080 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9081 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9082 B.NumIterations, *this, CurScope, 9083 DSAStack)) 9084 return StmtError(); 9085 } 9086 } 9087 9088 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9089 return StmtError(); 9090 9091 setFunctionHasBranchProtectedScope(); 9092 return OMPDistributeParallelForSimdDirective::Create( 9093 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9094 } 9095 9096 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9097 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9098 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9099 if (!AStmt) 9100 return StmtError(); 9101 9102 auto *CS = cast<CapturedStmt>(AStmt); 9103 // 1.2.2 OpenMP Language Terminology 9104 // Structured block - An executable statement with a single entry at the 9105 // top and a single exit at the bottom. 9106 // The point of exit cannot be a branch out of the structured block. 9107 // longjmp() and throw() must not violate the entry/exit criteria. 9108 CS->getCapturedDecl()->setNothrow(); 9109 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9110 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9111 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9112 // 1.2.2 OpenMP Language Terminology 9113 // Structured block - An executable statement with a single entry at the 9114 // top and a single exit at the bottom. 9115 // The point of exit cannot be a branch out of the structured block. 9116 // longjmp() and throw() must not violate the entry/exit criteria. 9117 CS->getCapturedDecl()->setNothrow(); 9118 } 9119 9120 OMPLoopDirective::HelperExprs B; 9121 // In presence of clause 'collapse' with number of loops, it will 9122 // define the nested loops number. 9123 unsigned NestedLoopCount = 9124 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9125 nullptr /*ordered not a clause on distribute*/, CS, *this, 9126 *DSAStack, VarsWithImplicitDSA, B); 9127 if (NestedLoopCount == 0) 9128 return StmtError(); 9129 9130 assert((CurContext->isDependentContext() || B.builtAll()) && 9131 "omp for loop exprs were not built"); 9132 9133 if (!CurContext->isDependentContext()) { 9134 // Finalize the clauses that need pre-built expressions for CodeGen. 9135 for (OMPClause *C : Clauses) { 9136 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9137 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9138 B.NumIterations, *this, CurScope, 9139 DSAStack)) 9140 return StmtError(); 9141 } 9142 } 9143 9144 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9145 return StmtError(); 9146 9147 setFunctionHasBranchProtectedScope(); 9148 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9149 NestedLoopCount, Clauses, AStmt, B); 9150 } 9151 9152 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9153 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9154 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9155 if (!AStmt) 9156 return StmtError(); 9157 9158 auto *CS = cast<CapturedStmt>(AStmt); 9159 // 1.2.2 OpenMP Language Terminology 9160 // Structured block - An executable statement with a single entry at the 9161 // top and a single exit at the bottom. 9162 // The point of exit cannot be a branch out of the structured block. 9163 // longjmp() and throw() must not violate the entry/exit criteria. 9164 CS->getCapturedDecl()->setNothrow(); 9165 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9166 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9167 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9168 // 1.2.2 OpenMP Language Terminology 9169 // Structured block - An executable statement with a single entry at the 9170 // top and a single exit at the bottom. 9171 // The point of exit cannot be a branch out of the structured block. 9172 // longjmp() and throw() must not violate the entry/exit criteria. 9173 CS->getCapturedDecl()->setNothrow(); 9174 } 9175 9176 OMPLoopDirective::HelperExprs B; 9177 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9178 // define the nested loops number. 9179 unsigned NestedLoopCount = checkOpenMPLoop( 9180 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9181 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9182 VarsWithImplicitDSA, B); 9183 if (NestedLoopCount == 0) 9184 return StmtError(); 9185 9186 assert((CurContext->isDependentContext() || B.builtAll()) && 9187 "omp target parallel for simd loop exprs were not built"); 9188 9189 if (!CurContext->isDependentContext()) { 9190 // Finalize the clauses that need pre-built expressions for CodeGen. 9191 for (OMPClause *C : Clauses) { 9192 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9193 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9194 B.NumIterations, *this, CurScope, 9195 DSAStack)) 9196 return StmtError(); 9197 } 9198 } 9199 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9200 return StmtError(); 9201 9202 setFunctionHasBranchProtectedScope(); 9203 return OMPTargetParallelForSimdDirective::Create( 9204 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9205 } 9206 9207 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9208 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9209 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9210 if (!AStmt) 9211 return StmtError(); 9212 9213 auto *CS = cast<CapturedStmt>(AStmt); 9214 // 1.2.2 OpenMP Language Terminology 9215 // Structured block - An executable statement with a single entry at the 9216 // top and a single exit at the bottom. 9217 // The point of exit cannot be a branch out of the structured block. 9218 // longjmp() and throw() must not violate the entry/exit criteria. 9219 CS->getCapturedDecl()->setNothrow(); 9220 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9221 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9222 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9223 // 1.2.2 OpenMP Language Terminology 9224 // Structured block - An executable statement with a single entry at the 9225 // top and a single exit at the bottom. 9226 // The point of exit cannot be a branch out of the structured block. 9227 // longjmp() and throw() must not violate the entry/exit criteria. 9228 CS->getCapturedDecl()->setNothrow(); 9229 } 9230 9231 OMPLoopDirective::HelperExprs B; 9232 // In presence of clause 'collapse' with number of loops, it will define the 9233 // nested loops number. 9234 unsigned NestedLoopCount = 9235 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9236 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9237 VarsWithImplicitDSA, B); 9238 if (NestedLoopCount == 0) 9239 return StmtError(); 9240 9241 assert((CurContext->isDependentContext() || B.builtAll()) && 9242 "omp target simd loop exprs were not built"); 9243 9244 if (!CurContext->isDependentContext()) { 9245 // Finalize the clauses that need pre-built expressions for CodeGen. 9246 for (OMPClause *C : Clauses) { 9247 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9248 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9249 B.NumIterations, *this, CurScope, 9250 DSAStack)) 9251 return StmtError(); 9252 } 9253 } 9254 9255 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9256 return StmtError(); 9257 9258 setFunctionHasBranchProtectedScope(); 9259 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9260 NestedLoopCount, Clauses, AStmt, B); 9261 } 9262 9263 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9264 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9265 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9266 if (!AStmt) 9267 return StmtError(); 9268 9269 auto *CS = cast<CapturedStmt>(AStmt); 9270 // 1.2.2 OpenMP Language Terminology 9271 // Structured block - An executable statement with a single entry at the 9272 // top and a single exit at the bottom. 9273 // The point of exit cannot be a branch out of the structured block. 9274 // longjmp() and throw() must not violate the entry/exit criteria. 9275 CS->getCapturedDecl()->setNothrow(); 9276 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9277 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9278 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9279 // 1.2.2 OpenMP Language Terminology 9280 // Structured block - An executable statement with a single entry at the 9281 // top and a single exit at the bottom. 9282 // The point of exit cannot be a branch out of the structured block. 9283 // longjmp() and throw() must not violate the entry/exit criteria. 9284 CS->getCapturedDecl()->setNothrow(); 9285 } 9286 9287 OMPLoopDirective::HelperExprs B; 9288 // In presence of clause 'collapse' with number of loops, it will 9289 // define the nested loops number. 9290 unsigned NestedLoopCount = 9291 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9292 nullptr /*ordered not a clause on distribute*/, CS, *this, 9293 *DSAStack, VarsWithImplicitDSA, B); 9294 if (NestedLoopCount == 0) 9295 return StmtError(); 9296 9297 assert((CurContext->isDependentContext() || B.builtAll()) && 9298 "omp teams distribute loop exprs were not built"); 9299 9300 setFunctionHasBranchProtectedScope(); 9301 9302 DSAStack->setParentTeamsRegionLoc(StartLoc); 9303 9304 return OMPTeamsDistributeDirective::Create( 9305 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9306 } 9307 9308 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9309 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9310 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9311 if (!AStmt) 9312 return StmtError(); 9313 9314 auto *CS = cast<CapturedStmt>(AStmt); 9315 // 1.2.2 OpenMP Language Terminology 9316 // Structured block - An executable statement with a single entry at the 9317 // top and a single exit at the bottom. 9318 // The point of exit cannot be a branch out of the structured block. 9319 // longjmp() and throw() must not violate the entry/exit criteria. 9320 CS->getCapturedDecl()->setNothrow(); 9321 for (int ThisCaptureLevel = 9322 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9323 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9324 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9325 // 1.2.2 OpenMP Language Terminology 9326 // Structured block - An executable statement with a single entry at the 9327 // top and a single exit at the bottom. 9328 // The point of exit cannot be a branch out of the structured block. 9329 // longjmp() and throw() must not violate the entry/exit criteria. 9330 CS->getCapturedDecl()->setNothrow(); 9331 } 9332 9333 9334 OMPLoopDirective::HelperExprs B; 9335 // In presence of clause 'collapse' with number of loops, it will 9336 // define the nested loops number. 9337 unsigned NestedLoopCount = checkOpenMPLoop( 9338 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9339 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9340 VarsWithImplicitDSA, B); 9341 9342 if (NestedLoopCount == 0) 9343 return StmtError(); 9344 9345 assert((CurContext->isDependentContext() || B.builtAll()) && 9346 "omp teams distribute simd loop exprs were not built"); 9347 9348 if (!CurContext->isDependentContext()) { 9349 // Finalize the clauses that need pre-built expressions for CodeGen. 9350 for (OMPClause *C : Clauses) { 9351 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9352 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9353 B.NumIterations, *this, CurScope, 9354 DSAStack)) 9355 return StmtError(); 9356 } 9357 } 9358 9359 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9360 return StmtError(); 9361 9362 setFunctionHasBranchProtectedScope(); 9363 9364 DSAStack->setParentTeamsRegionLoc(StartLoc); 9365 9366 return OMPTeamsDistributeSimdDirective::Create( 9367 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9368 } 9369 9370 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9371 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9372 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9373 if (!AStmt) 9374 return StmtError(); 9375 9376 auto *CS = cast<CapturedStmt>(AStmt); 9377 // 1.2.2 OpenMP Language Terminology 9378 // Structured block - An executable statement with a single entry at the 9379 // top and a single exit at the bottom. 9380 // The point of exit cannot be a branch out of the structured block. 9381 // longjmp() and throw() must not violate the entry/exit criteria. 9382 CS->getCapturedDecl()->setNothrow(); 9383 9384 for (int ThisCaptureLevel = 9385 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9386 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9387 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9388 // 1.2.2 OpenMP Language Terminology 9389 // Structured block - An executable statement with a single entry at the 9390 // top and a single exit at the bottom. 9391 // The point of exit cannot be a branch out of the structured block. 9392 // longjmp() and throw() must not violate the entry/exit criteria. 9393 CS->getCapturedDecl()->setNothrow(); 9394 } 9395 9396 OMPLoopDirective::HelperExprs B; 9397 // In presence of clause 'collapse' with number of loops, it will 9398 // define the nested loops number. 9399 unsigned NestedLoopCount = checkOpenMPLoop( 9400 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9401 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9402 VarsWithImplicitDSA, B); 9403 9404 if (NestedLoopCount == 0) 9405 return StmtError(); 9406 9407 assert((CurContext->isDependentContext() || B.builtAll()) && 9408 "omp for loop exprs were not built"); 9409 9410 if (!CurContext->isDependentContext()) { 9411 // Finalize the clauses that need pre-built expressions for CodeGen. 9412 for (OMPClause *C : Clauses) { 9413 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9414 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9415 B.NumIterations, *this, CurScope, 9416 DSAStack)) 9417 return StmtError(); 9418 } 9419 } 9420 9421 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9422 return StmtError(); 9423 9424 setFunctionHasBranchProtectedScope(); 9425 9426 DSAStack->setParentTeamsRegionLoc(StartLoc); 9427 9428 return OMPTeamsDistributeParallelForSimdDirective::Create( 9429 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9430 } 9431 9432 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9433 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9434 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9435 if (!AStmt) 9436 return StmtError(); 9437 9438 auto *CS = cast<CapturedStmt>(AStmt); 9439 // 1.2.2 OpenMP Language Terminology 9440 // Structured block - An executable statement with a single entry at the 9441 // top and a single exit at the bottom. 9442 // The point of exit cannot be a branch out of the structured block. 9443 // longjmp() and throw() must not violate the entry/exit criteria. 9444 CS->getCapturedDecl()->setNothrow(); 9445 9446 for (int ThisCaptureLevel = 9447 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9448 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9449 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9450 // 1.2.2 OpenMP Language Terminology 9451 // Structured block - An executable statement with a single entry at the 9452 // top and a single exit at the bottom. 9453 // The point of exit cannot be a branch out of the structured block. 9454 // longjmp() and throw() must not violate the entry/exit criteria. 9455 CS->getCapturedDecl()->setNothrow(); 9456 } 9457 9458 OMPLoopDirective::HelperExprs B; 9459 // In presence of clause 'collapse' with number of loops, it will 9460 // define the nested loops number. 9461 unsigned NestedLoopCount = checkOpenMPLoop( 9462 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9463 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9464 VarsWithImplicitDSA, B); 9465 9466 if (NestedLoopCount == 0) 9467 return StmtError(); 9468 9469 assert((CurContext->isDependentContext() || B.builtAll()) && 9470 "omp for loop exprs were not built"); 9471 9472 setFunctionHasBranchProtectedScope(); 9473 9474 DSAStack->setParentTeamsRegionLoc(StartLoc); 9475 9476 return OMPTeamsDistributeParallelForDirective::Create( 9477 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9478 DSAStack->isCancelRegion()); 9479 } 9480 9481 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9482 Stmt *AStmt, 9483 SourceLocation StartLoc, 9484 SourceLocation EndLoc) { 9485 if (!AStmt) 9486 return StmtError(); 9487 9488 auto *CS = cast<CapturedStmt>(AStmt); 9489 // 1.2.2 OpenMP Language Terminology 9490 // Structured block - An executable statement with a single entry at the 9491 // top and a single exit at the bottom. 9492 // The point of exit cannot be a branch out of the structured block. 9493 // longjmp() and throw() must not violate the entry/exit criteria. 9494 CS->getCapturedDecl()->setNothrow(); 9495 9496 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9497 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9498 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9499 // 1.2.2 OpenMP Language Terminology 9500 // Structured block - An executable statement with a single entry at the 9501 // top and a single exit at the bottom. 9502 // The point of exit cannot be a branch out of the structured block. 9503 // longjmp() and throw() must not violate the entry/exit criteria. 9504 CS->getCapturedDecl()->setNothrow(); 9505 } 9506 setFunctionHasBranchProtectedScope(); 9507 9508 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9509 AStmt); 9510 } 9511 9512 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9513 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9514 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9515 if (!AStmt) 9516 return StmtError(); 9517 9518 auto *CS = cast<CapturedStmt>(AStmt); 9519 // 1.2.2 OpenMP Language Terminology 9520 // Structured block - An executable statement with a single entry at the 9521 // top and a single exit at the bottom. 9522 // The point of exit cannot be a branch out of the structured block. 9523 // longjmp() and throw() must not violate the entry/exit criteria. 9524 CS->getCapturedDecl()->setNothrow(); 9525 for (int ThisCaptureLevel = 9526 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9527 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9528 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9529 // 1.2.2 OpenMP Language Terminology 9530 // Structured block - An executable statement with a single entry at the 9531 // top and a single exit at the bottom. 9532 // The point of exit cannot be a branch out of the structured block. 9533 // longjmp() and throw() must not violate the entry/exit criteria. 9534 CS->getCapturedDecl()->setNothrow(); 9535 } 9536 9537 OMPLoopDirective::HelperExprs B; 9538 // In presence of clause 'collapse' with number of loops, it will 9539 // define the nested loops number. 9540 unsigned NestedLoopCount = checkOpenMPLoop( 9541 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9542 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9543 VarsWithImplicitDSA, B); 9544 if (NestedLoopCount == 0) 9545 return StmtError(); 9546 9547 assert((CurContext->isDependentContext() || B.builtAll()) && 9548 "omp target teams distribute loop exprs were not built"); 9549 9550 setFunctionHasBranchProtectedScope(); 9551 return OMPTargetTeamsDistributeDirective::Create( 9552 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9553 } 9554 9555 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 9556 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9557 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9558 if (!AStmt) 9559 return StmtError(); 9560 9561 auto *CS = cast<CapturedStmt>(AStmt); 9562 // 1.2.2 OpenMP Language Terminology 9563 // Structured block - An executable statement with a single entry at the 9564 // top and a single exit at the bottom. 9565 // The point of exit cannot be a branch out of the structured block. 9566 // longjmp() and throw() must not violate the entry/exit criteria. 9567 CS->getCapturedDecl()->setNothrow(); 9568 for (int ThisCaptureLevel = 9569 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 9570 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9571 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9572 // 1.2.2 OpenMP Language Terminology 9573 // Structured block - An executable statement with a single entry at the 9574 // top and a single exit at the bottom. 9575 // The point of exit cannot be a branch out of the structured block. 9576 // longjmp() and throw() must not violate the entry/exit criteria. 9577 CS->getCapturedDecl()->setNothrow(); 9578 } 9579 9580 OMPLoopDirective::HelperExprs B; 9581 // In presence of clause 'collapse' with number of loops, it will 9582 // define the nested loops number. 9583 unsigned NestedLoopCount = checkOpenMPLoop( 9584 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9585 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9586 VarsWithImplicitDSA, B); 9587 if (NestedLoopCount == 0) 9588 return StmtError(); 9589 9590 assert((CurContext->isDependentContext() || B.builtAll()) && 9591 "omp target teams distribute parallel for loop exprs were not built"); 9592 9593 if (!CurContext->isDependentContext()) { 9594 // Finalize the clauses that need pre-built expressions for CodeGen. 9595 for (OMPClause *C : Clauses) { 9596 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9597 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9598 B.NumIterations, *this, CurScope, 9599 DSAStack)) 9600 return StmtError(); 9601 } 9602 } 9603 9604 setFunctionHasBranchProtectedScope(); 9605 return OMPTargetTeamsDistributeParallelForDirective::Create( 9606 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9607 DSAStack->isCancelRegion()); 9608 } 9609 9610 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9611 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9612 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9613 if (!AStmt) 9614 return StmtError(); 9615 9616 auto *CS = cast<CapturedStmt>(AStmt); 9617 // 1.2.2 OpenMP Language Terminology 9618 // Structured block - An executable statement with a single entry at the 9619 // top and a single exit at the bottom. 9620 // The point of exit cannot be a branch out of the structured block. 9621 // longjmp() and throw() must not violate the entry/exit criteria. 9622 CS->getCapturedDecl()->setNothrow(); 9623 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9624 OMPD_target_teams_distribute_parallel_for_simd); 9625 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9626 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9627 // 1.2.2 OpenMP Language Terminology 9628 // Structured block - An executable statement with a single entry at the 9629 // top and a single exit at the bottom. 9630 // The point of exit cannot be a branch out of the structured block. 9631 // longjmp() and throw() must not violate the entry/exit criteria. 9632 CS->getCapturedDecl()->setNothrow(); 9633 } 9634 9635 OMPLoopDirective::HelperExprs B; 9636 // In presence of clause 'collapse' with number of loops, it will 9637 // define the nested loops number. 9638 unsigned NestedLoopCount = 9639 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9640 getCollapseNumberExpr(Clauses), 9641 nullptr /*ordered not a clause on distribute*/, CS, *this, 9642 *DSAStack, VarsWithImplicitDSA, B); 9643 if (NestedLoopCount == 0) 9644 return StmtError(); 9645 9646 assert((CurContext->isDependentContext() || B.builtAll()) && 9647 "omp target teams distribute parallel for simd loop exprs were not " 9648 "built"); 9649 9650 if (!CurContext->isDependentContext()) { 9651 // Finalize the clauses that need pre-built expressions for CodeGen. 9652 for (OMPClause *C : Clauses) { 9653 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9654 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9655 B.NumIterations, *this, CurScope, 9656 DSAStack)) 9657 return StmtError(); 9658 } 9659 } 9660 9661 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9662 return StmtError(); 9663 9664 setFunctionHasBranchProtectedScope(); 9665 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9666 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9667 } 9668 9669 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9670 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9671 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9672 if (!AStmt) 9673 return StmtError(); 9674 9675 auto *CS = cast<CapturedStmt>(AStmt); 9676 // 1.2.2 OpenMP Language Terminology 9677 // Structured block - An executable statement with a single entry at the 9678 // top and a single exit at the bottom. 9679 // The point of exit cannot be a branch out of the structured block. 9680 // longjmp() and throw() must not violate the entry/exit criteria. 9681 CS->getCapturedDecl()->setNothrow(); 9682 for (int ThisCaptureLevel = 9683 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9684 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9685 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9686 // 1.2.2 OpenMP Language Terminology 9687 // Structured block - An executable statement with a single entry at the 9688 // top and a single exit at the bottom. 9689 // The point of exit cannot be a branch out of the structured block. 9690 // longjmp() and throw() must not violate the entry/exit criteria. 9691 CS->getCapturedDecl()->setNothrow(); 9692 } 9693 9694 OMPLoopDirective::HelperExprs B; 9695 // In presence of clause 'collapse' with number of loops, it will 9696 // define the nested loops number. 9697 unsigned NestedLoopCount = checkOpenMPLoop( 9698 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9699 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9700 VarsWithImplicitDSA, B); 9701 if (NestedLoopCount == 0) 9702 return StmtError(); 9703 9704 assert((CurContext->isDependentContext() || B.builtAll()) && 9705 "omp target teams distribute simd loop exprs were not built"); 9706 9707 if (!CurContext->isDependentContext()) { 9708 // Finalize the clauses that need pre-built expressions for CodeGen. 9709 for (OMPClause *C : Clauses) { 9710 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9711 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9712 B.NumIterations, *this, CurScope, 9713 DSAStack)) 9714 return StmtError(); 9715 } 9716 } 9717 9718 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9719 return StmtError(); 9720 9721 setFunctionHasBranchProtectedScope(); 9722 return OMPTargetTeamsDistributeSimdDirective::Create( 9723 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9724 } 9725 9726 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9727 SourceLocation StartLoc, 9728 SourceLocation LParenLoc, 9729 SourceLocation EndLoc) { 9730 OMPClause *Res = nullptr; 9731 switch (Kind) { 9732 case OMPC_final: 9733 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9734 break; 9735 case OMPC_num_threads: 9736 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9737 break; 9738 case OMPC_safelen: 9739 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9740 break; 9741 case OMPC_simdlen: 9742 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9743 break; 9744 case OMPC_allocator: 9745 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9746 break; 9747 case OMPC_collapse: 9748 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9749 break; 9750 case OMPC_ordered: 9751 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9752 break; 9753 case OMPC_device: 9754 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9755 break; 9756 case OMPC_num_teams: 9757 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9758 break; 9759 case OMPC_thread_limit: 9760 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9761 break; 9762 case OMPC_priority: 9763 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9764 break; 9765 case OMPC_grainsize: 9766 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9767 break; 9768 case OMPC_num_tasks: 9769 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9770 break; 9771 case OMPC_hint: 9772 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9773 break; 9774 case OMPC_if: 9775 case OMPC_default: 9776 case OMPC_proc_bind: 9777 case OMPC_schedule: 9778 case OMPC_private: 9779 case OMPC_firstprivate: 9780 case OMPC_lastprivate: 9781 case OMPC_shared: 9782 case OMPC_reduction: 9783 case OMPC_task_reduction: 9784 case OMPC_in_reduction: 9785 case OMPC_linear: 9786 case OMPC_aligned: 9787 case OMPC_copyin: 9788 case OMPC_copyprivate: 9789 case OMPC_nowait: 9790 case OMPC_untied: 9791 case OMPC_mergeable: 9792 case OMPC_threadprivate: 9793 case OMPC_allocate: 9794 case OMPC_flush: 9795 case OMPC_read: 9796 case OMPC_write: 9797 case OMPC_update: 9798 case OMPC_capture: 9799 case OMPC_seq_cst: 9800 case OMPC_depend: 9801 case OMPC_threads: 9802 case OMPC_simd: 9803 case OMPC_map: 9804 case OMPC_nogroup: 9805 case OMPC_dist_schedule: 9806 case OMPC_defaultmap: 9807 case OMPC_unknown: 9808 case OMPC_uniform: 9809 case OMPC_to: 9810 case OMPC_from: 9811 case OMPC_use_device_ptr: 9812 case OMPC_is_device_ptr: 9813 case OMPC_unified_address: 9814 case OMPC_unified_shared_memory: 9815 case OMPC_reverse_offload: 9816 case OMPC_dynamic_allocators: 9817 case OMPC_atomic_default_mem_order: 9818 case OMPC_device_type: 9819 llvm_unreachable("Clause is not allowed."); 9820 } 9821 return Res; 9822 } 9823 9824 // An OpenMP directive such as 'target parallel' has two captured regions: 9825 // for the 'target' and 'parallel' respectively. This function returns 9826 // the region in which to capture expressions associated with a clause. 9827 // A return value of OMPD_unknown signifies that the expression should not 9828 // be captured. 9829 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9830 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9831 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9832 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9833 switch (CKind) { 9834 case OMPC_if: 9835 switch (DKind) { 9836 case OMPD_target_parallel: 9837 case OMPD_target_parallel_for: 9838 case OMPD_target_parallel_for_simd: 9839 // If this clause applies to the nested 'parallel' region, capture within 9840 // the 'target' region, otherwise do not capture. 9841 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9842 CaptureRegion = OMPD_target; 9843 break; 9844 case OMPD_target_teams_distribute_parallel_for: 9845 case OMPD_target_teams_distribute_parallel_for_simd: 9846 // If this clause applies to the nested 'parallel' region, capture within 9847 // the 'teams' region, otherwise do not capture. 9848 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9849 CaptureRegion = OMPD_teams; 9850 break; 9851 case OMPD_teams_distribute_parallel_for: 9852 case OMPD_teams_distribute_parallel_for_simd: 9853 CaptureRegion = OMPD_teams; 9854 break; 9855 case OMPD_target_update: 9856 case OMPD_target_enter_data: 9857 case OMPD_target_exit_data: 9858 CaptureRegion = OMPD_task; 9859 break; 9860 case OMPD_cancel: 9861 case OMPD_parallel: 9862 case OMPD_parallel_sections: 9863 case OMPD_parallel_for: 9864 case OMPD_parallel_for_simd: 9865 case OMPD_target: 9866 case OMPD_target_simd: 9867 case OMPD_target_teams: 9868 case OMPD_target_teams_distribute: 9869 case OMPD_target_teams_distribute_simd: 9870 case OMPD_distribute_parallel_for: 9871 case OMPD_distribute_parallel_for_simd: 9872 case OMPD_task: 9873 case OMPD_taskloop: 9874 case OMPD_taskloop_simd: 9875 case OMPD_target_data: 9876 // Do not capture if-clause expressions. 9877 break; 9878 case OMPD_threadprivate: 9879 case OMPD_allocate: 9880 case OMPD_taskyield: 9881 case OMPD_barrier: 9882 case OMPD_taskwait: 9883 case OMPD_cancellation_point: 9884 case OMPD_flush: 9885 case OMPD_declare_reduction: 9886 case OMPD_declare_mapper: 9887 case OMPD_declare_simd: 9888 case OMPD_declare_target: 9889 case OMPD_end_declare_target: 9890 case OMPD_teams: 9891 case OMPD_simd: 9892 case OMPD_for: 9893 case OMPD_for_simd: 9894 case OMPD_sections: 9895 case OMPD_section: 9896 case OMPD_single: 9897 case OMPD_master: 9898 case OMPD_critical: 9899 case OMPD_taskgroup: 9900 case OMPD_distribute: 9901 case OMPD_ordered: 9902 case OMPD_atomic: 9903 case OMPD_distribute_simd: 9904 case OMPD_teams_distribute: 9905 case OMPD_teams_distribute_simd: 9906 case OMPD_requires: 9907 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9908 case OMPD_unknown: 9909 llvm_unreachable("Unknown OpenMP directive"); 9910 } 9911 break; 9912 case OMPC_num_threads: 9913 switch (DKind) { 9914 case OMPD_target_parallel: 9915 case OMPD_target_parallel_for: 9916 case OMPD_target_parallel_for_simd: 9917 CaptureRegion = OMPD_target; 9918 break; 9919 case OMPD_teams_distribute_parallel_for: 9920 case OMPD_teams_distribute_parallel_for_simd: 9921 case OMPD_target_teams_distribute_parallel_for: 9922 case OMPD_target_teams_distribute_parallel_for_simd: 9923 CaptureRegion = OMPD_teams; 9924 break; 9925 case OMPD_parallel: 9926 case OMPD_parallel_sections: 9927 case OMPD_parallel_for: 9928 case OMPD_parallel_for_simd: 9929 case OMPD_distribute_parallel_for: 9930 case OMPD_distribute_parallel_for_simd: 9931 // Do not capture num_threads-clause expressions. 9932 break; 9933 case OMPD_target_data: 9934 case OMPD_target_enter_data: 9935 case OMPD_target_exit_data: 9936 case OMPD_target_update: 9937 case OMPD_target: 9938 case OMPD_target_simd: 9939 case OMPD_target_teams: 9940 case OMPD_target_teams_distribute: 9941 case OMPD_target_teams_distribute_simd: 9942 case OMPD_cancel: 9943 case OMPD_task: 9944 case OMPD_taskloop: 9945 case OMPD_taskloop_simd: 9946 case OMPD_threadprivate: 9947 case OMPD_allocate: 9948 case OMPD_taskyield: 9949 case OMPD_barrier: 9950 case OMPD_taskwait: 9951 case OMPD_cancellation_point: 9952 case OMPD_flush: 9953 case OMPD_declare_reduction: 9954 case OMPD_declare_mapper: 9955 case OMPD_declare_simd: 9956 case OMPD_declare_target: 9957 case OMPD_end_declare_target: 9958 case OMPD_teams: 9959 case OMPD_simd: 9960 case OMPD_for: 9961 case OMPD_for_simd: 9962 case OMPD_sections: 9963 case OMPD_section: 9964 case OMPD_single: 9965 case OMPD_master: 9966 case OMPD_critical: 9967 case OMPD_taskgroup: 9968 case OMPD_distribute: 9969 case OMPD_ordered: 9970 case OMPD_atomic: 9971 case OMPD_distribute_simd: 9972 case OMPD_teams_distribute: 9973 case OMPD_teams_distribute_simd: 9974 case OMPD_requires: 9975 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9976 case OMPD_unknown: 9977 llvm_unreachable("Unknown OpenMP directive"); 9978 } 9979 break; 9980 case OMPC_num_teams: 9981 switch (DKind) { 9982 case OMPD_target_teams: 9983 case OMPD_target_teams_distribute: 9984 case OMPD_target_teams_distribute_simd: 9985 case OMPD_target_teams_distribute_parallel_for: 9986 case OMPD_target_teams_distribute_parallel_for_simd: 9987 CaptureRegion = OMPD_target; 9988 break; 9989 case OMPD_teams_distribute_parallel_for: 9990 case OMPD_teams_distribute_parallel_for_simd: 9991 case OMPD_teams: 9992 case OMPD_teams_distribute: 9993 case OMPD_teams_distribute_simd: 9994 // Do not capture num_teams-clause expressions. 9995 break; 9996 case OMPD_distribute_parallel_for: 9997 case OMPD_distribute_parallel_for_simd: 9998 case OMPD_task: 9999 case OMPD_taskloop: 10000 case OMPD_taskloop_simd: 10001 case OMPD_target_data: 10002 case OMPD_target_enter_data: 10003 case OMPD_target_exit_data: 10004 case OMPD_target_update: 10005 case OMPD_cancel: 10006 case OMPD_parallel: 10007 case OMPD_parallel_sections: 10008 case OMPD_parallel_for: 10009 case OMPD_parallel_for_simd: 10010 case OMPD_target: 10011 case OMPD_target_simd: 10012 case OMPD_target_parallel: 10013 case OMPD_target_parallel_for: 10014 case OMPD_target_parallel_for_simd: 10015 case OMPD_threadprivate: 10016 case OMPD_allocate: 10017 case OMPD_taskyield: 10018 case OMPD_barrier: 10019 case OMPD_taskwait: 10020 case OMPD_cancellation_point: 10021 case OMPD_flush: 10022 case OMPD_declare_reduction: 10023 case OMPD_declare_mapper: 10024 case OMPD_declare_simd: 10025 case OMPD_declare_target: 10026 case OMPD_end_declare_target: 10027 case OMPD_simd: 10028 case OMPD_for: 10029 case OMPD_for_simd: 10030 case OMPD_sections: 10031 case OMPD_section: 10032 case OMPD_single: 10033 case OMPD_master: 10034 case OMPD_critical: 10035 case OMPD_taskgroup: 10036 case OMPD_distribute: 10037 case OMPD_ordered: 10038 case OMPD_atomic: 10039 case OMPD_distribute_simd: 10040 case OMPD_requires: 10041 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10042 case OMPD_unknown: 10043 llvm_unreachable("Unknown OpenMP directive"); 10044 } 10045 break; 10046 case OMPC_thread_limit: 10047 switch (DKind) { 10048 case OMPD_target_teams: 10049 case OMPD_target_teams_distribute: 10050 case OMPD_target_teams_distribute_simd: 10051 case OMPD_target_teams_distribute_parallel_for: 10052 case OMPD_target_teams_distribute_parallel_for_simd: 10053 CaptureRegion = OMPD_target; 10054 break; 10055 case OMPD_teams_distribute_parallel_for: 10056 case OMPD_teams_distribute_parallel_for_simd: 10057 case OMPD_teams: 10058 case OMPD_teams_distribute: 10059 case OMPD_teams_distribute_simd: 10060 // Do not capture thread_limit-clause expressions. 10061 break; 10062 case OMPD_distribute_parallel_for: 10063 case OMPD_distribute_parallel_for_simd: 10064 case OMPD_task: 10065 case OMPD_taskloop: 10066 case OMPD_taskloop_simd: 10067 case OMPD_target_data: 10068 case OMPD_target_enter_data: 10069 case OMPD_target_exit_data: 10070 case OMPD_target_update: 10071 case OMPD_cancel: 10072 case OMPD_parallel: 10073 case OMPD_parallel_sections: 10074 case OMPD_parallel_for: 10075 case OMPD_parallel_for_simd: 10076 case OMPD_target: 10077 case OMPD_target_simd: 10078 case OMPD_target_parallel: 10079 case OMPD_target_parallel_for: 10080 case OMPD_target_parallel_for_simd: 10081 case OMPD_threadprivate: 10082 case OMPD_allocate: 10083 case OMPD_taskyield: 10084 case OMPD_barrier: 10085 case OMPD_taskwait: 10086 case OMPD_cancellation_point: 10087 case OMPD_flush: 10088 case OMPD_declare_reduction: 10089 case OMPD_declare_mapper: 10090 case OMPD_declare_simd: 10091 case OMPD_declare_target: 10092 case OMPD_end_declare_target: 10093 case OMPD_simd: 10094 case OMPD_for: 10095 case OMPD_for_simd: 10096 case OMPD_sections: 10097 case OMPD_section: 10098 case OMPD_single: 10099 case OMPD_master: 10100 case OMPD_critical: 10101 case OMPD_taskgroup: 10102 case OMPD_distribute: 10103 case OMPD_ordered: 10104 case OMPD_atomic: 10105 case OMPD_distribute_simd: 10106 case OMPD_requires: 10107 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10108 case OMPD_unknown: 10109 llvm_unreachable("Unknown OpenMP directive"); 10110 } 10111 break; 10112 case OMPC_schedule: 10113 switch (DKind) { 10114 case OMPD_parallel_for: 10115 case OMPD_parallel_for_simd: 10116 case OMPD_distribute_parallel_for: 10117 case OMPD_distribute_parallel_for_simd: 10118 case OMPD_teams_distribute_parallel_for: 10119 case OMPD_teams_distribute_parallel_for_simd: 10120 case OMPD_target_parallel_for: 10121 case OMPD_target_parallel_for_simd: 10122 case OMPD_target_teams_distribute_parallel_for: 10123 case OMPD_target_teams_distribute_parallel_for_simd: 10124 CaptureRegion = OMPD_parallel; 10125 break; 10126 case OMPD_for: 10127 case OMPD_for_simd: 10128 // Do not capture schedule-clause expressions. 10129 break; 10130 case OMPD_task: 10131 case OMPD_taskloop: 10132 case OMPD_taskloop_simd: 10133 case OMPD_target_data: 10134 case OMPD_target_enter_data: 10135 case OMPD_target_exit_data: 10136 case OMPD_target_update: 10137 case OMPD_teams: 10138 case OMPD_teams_distribute: 10139 case OMPD_teams_distribute_simd: 10140 case OMPD_target_teams_distribute: 10141 case OMPD_target_teams_distribute_simd: 10142 case OMPD_target: 10143 case OMPD_target_simd: 10144 case OMPD_target_parallel: 10145 case OMPD_cancel: 10146 case OMPD_parallel: 10147 case OMPD_parallel_sections: 10148 case OMPD_threadprivate: 10149 case OMPD_allocate: 10150 case OMPD_taskyield: 10151 case OMPD_barrier: 10152 case OMPD_taskwait: 10153 case OMPD_cancellation_point: 10154 case OMPD_flush: 10155 case OMPD_declare_reduction: 10156 case OMPD_declare_mapper: 10157 case OMPD_declare_simd: 10158 case OMPD_declare_target: 10159 case OMPD_end_declare_target: 10160 case OMPD_simd: 10161 case OMPD_sections: 10162 case OMPD_section: 10163 case OMPD_single: 10164 case OMPD_master: 10165 case OMPD_critical: 10166 case OMPD_taskgroup: 10167 case OMPD_distribute: 10168 case OMPD_ordered: 10169 case OMPD_atomic: 10170 case OMPD_distribute_simd: 10171 case OMPD_target_teams: 10172 case OMPD_requires: 10173 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10174 case OMPD_unknown: 10175 llvm_unreachable("Unknown OpenMP directive"); 10176 } 10177 break; 10178 case OMPC_dist_schedule: 10179 switch (DKind) { 10180 case OMPD_teams_distribute_parallel_for: 10181 case OMPD_teams_distribute_parallel_for_simd: 10182 case OMPD_teams_distribute: 10183 case OMPD_teams_distribute_simd: 10184 case OMPD_target_teams_distribute_parallel_for: 10185 case OMPD_target_teams_distribute_parallel_for_simd: 10186 case OMPD_target_teams_distribute: 10187 case OMPD_target_teams_distribute_simd: 10188 CaptureRegion = OMPD_teams; 10189 break; 10190 case OMPD_distribute_parallel_for: 10191 case OMPD_distribute_parallel_for_simd: 10192 case OMPD_distribute: 10193 case OMPD_distribute_simd: 10194 // Do not capture thread_limit-clause expressions. 10195 break; 10196 case OMPD_parallel_for: 10197 case OMPD_parallel_for_simd: 10198 case OMPD_target_parallel_for_simd: 10199 case OMPD_target_parallel_for: 10200 case OMPD_task: 10201 case OMPD_taskloop: 10202 case OMPD_taskloop_simd: 10203 case OMPD_target_data: 10204 case OMPD_target_enter_data: 10205 case OMPD_target_exit_data: 10206 case OMPD_target_update: 10207 case OMPD_teams: 10208 case OMPD_target: 10209 case OMPD_target_simd: 10210 case OMPD_target_parallel: 10211 case OMPD_cancel: 10212 case OMPD_parallel: 10213 case OMPD_parallel_sections: 10214 case OMPD_threadprivate: 10215 case OMPD_allocate: 10216 case OMPD_taskyield: 10217 case OMPD_barrier: 10218 case OMPD_taskwait: 10219 case OMPD_cancellation_point: 10220 case OMPD_flush: 10221 case OMPD_declare_reduction: 10222 case OMPD_declare_mapper: 10223 case OMPD_declare_simd: 10224 case OMPD_declare_target: 10225 case OMPD_end_declare_target: 10226 case OMPD_simd: 10227 case OMPD_for: 10228 case OMPD_for_simd: 10229 case OMPD_sections: 10230 case OMPD_section: 10231 case OMPD_single: 10232 case OMPD_master: 10233 case OMPD_critical: 10234 case OMPD_taskgroup: 10235 case OMPD_ordered: 10236 case OMPD_atomic: 10237 case OMPD_target_teams: 10238 case OMPD_requires: 10239 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10240 case OMPD_unknown: 10241 llvm_unreachable("Unknown OpenMP directive"); 10242 } 10243 break; 10244 case OMPC_device: 10245 switch (DKind) { 10246 case OMPD_target_update: 10247 case OMPD_target_enter_data: 10248 case OMPD_target_exit_data: 10249 case OMPD_target: 10250 case OMPD_target_simd: 10251 case OMPD_target_teams: 10252 case OMPD_target_parallel: 10253 case OMPD_target_teams_distribute: 10254 case OMPD_target_teams_distribute_simd: 10255 case OMPD_target_parallel_for: 10256 case OMPD_target_parallel_for_simd: 10257 case OMPD_target_teams_distribute_parallel_for: 10258 case OMPD_target_teams_distribute_parallel_for_simd: 10259 CaptureRegion = OMPD_task; 10260 break; 10261 case OMPD_target_data: 10262 // Do not capture device-clause expressions. 10263 break; 10264 case OMPD_teams_distribute_parallel_for: 10265 case OMPD_teams_distribute_parallel_for_simd: 10266 case OMPD_teams: 10267 case OMPD_teams_distribute: 10268 case OMPD_teams_distribute_simd: 10269 case OMPD_distribute_parallel_for: 10270 case OMPD_distribute_parallel_for_simd: 10271 case OMPD_task: 10272 case OMPD_taskloop: 10273 case OMPD_taskloop_simd: 10274 case OMPD_cancel: 10275 case OMPD_parallel: 10276 case OMPD_parallel_sections: 10277 case OMPD_parallel_for: 10278 case OMPD_parallel_for_simd: 10279 case OMPD_threadprivate: 10280 case OMPD_allocate: 10281 case OMPD_taskyield: 10282 case OMPD_barrier: 10283 case OMPD_taskwait: 10284 case OMPD_cancellation_point: 10285 case OMPD_flush: 10286 case OMPD_declare_reduction: 10287 case OMPD_declare_mapper: 10288 case OMPD_declare_simd: 10289 case OMPD_declare_target: 10290 case OMPD_end_declare_target: 10291 case OMPD_simd: 10292 case OMPD_for: 10293 case OMPD_for_simd: 10294 case OMPD_sections: 10295 case OMPD_section: 10296 case OMPD_single: 10297 case OMPD_master: 10298 case OMPD_critical: 10299 case OMPD_taskgroup: 10300 case OMPD_distribute: 10301 case OMPD_ordered: 10302 case OMPD_atomic: 10303 case OMPD_distribute_simd: 10304 case OMPD_requires: 10305 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10306 case OMPD_unknown: 10307 llvm_unreachable("Unknown OpenMP directive"); 10308 } 10309 break; 10310 case OMPC_firstprivate: 10311 case OMPC_lastprivate: 10312 case OMPC_reduction: 10313 case OMPC_task_reduction: 10314 case OMPC_in_reduction: 10315 case OMPC_linear: 10316 case OMPC_default: 10317 case OMPC_proc_bind: 10318 case OMPC_final: 10319 case OMPC_safelen: 10320 case OMPC_simdlen: 10321 case OMPC_allocator: 10322 case OMPC_collapse: 10323 case OMPC_private: 10324 case OMPC_shared: 10325 case OMPC_aligned: 10326 case OMPC_copyin: 10327 case OMPC_copyprivate: 10328 case OMPC_ordered: 10329 case OMPC_nowait: 10330 case OMPC_untied: 10331 case OMPC_mergeable: 10332 case OMPC_threadprivate: 10333 case OMPC_allocate: 10334 case OMPC_flush: 10335 case OMPC_read: 10336 case OMPC_write: 10337 case OMPC_update: 10338 case OMPC_capture: 10339 case OMPC_seq_cst: 10340 case OMPC_depend: 10341 case OMPC_threads: 10342 case OMPC_simd: 10343 case OMPC_map: 10344 case OMPC_priority: 10345 case OMPC_grainsize: 10346 case OMPC_nogroup: 10347 case OMPC_num_tasks: 10348 case OMPC_hint: 10349 case OMPC_defaultmap: 10350 case OMPC_unknown: 10351 case OMPC_uniform: 10352 case OMPC_to: 10353 case OMPC_from: 10354 case OMPC_use_device_ptr: 10355 case OMPC_is_device_ptr: 10356 case OMPC_unified_address: 10357 case OMPC_unified_shared_memory: 10358 case OMPC_reverse_offload: 10359 case OMPC_dynamic_allocators: 10360 case OMPC_atomic_default_mem_order: 10361 case OMPC_device_type: 10362 llvm_unreachable("Unexpected OpenMP clause."); 10363 } 10364 return CaptureRegion; 10365 } 10366 10367 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10368 Expr *Condition, SourceLocation StartLoc, 10369 SourceLocation LParenLoc, 10370 SourceLocation NameModifierLoc, 10371 SourceLocation ColonLoc, 10372 SourceLocation EndLoc) { 10373 Expr *ValExpr = Condition; 10374 Stmt *HelperValStmt = nullptr; 10375 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10376 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10377 !Condition->isInstantiationDependent() && 10378 !Condition->containsUnexpandedParameterPack()) { 10379 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10380 if (Val.isInvalid()) 10381 return nullptr; 10382 10383 ValExpr = Val.get(); 10384 10385 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10386 CaptureRegion = 10387 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10388 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10389 ValExpr = MakeFullExpr(ValExpr).get(); 10390 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10391 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10392 HelperValStmt = buildPreInits(Context, Captures); 10393 } 10394 } 10395 10396 return new (Context) 10397 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10398 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10399 } 10400 10401 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10402 SourceLocation StartLoc, 10403 SourceLocation LParenLoc, 10404 SourceLocation EndLoc) { 10405 Expr *ValExpr = Condition; 10406 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10407 !Condition->isInstantiationDependent() && 10408 !Condition->containsUnexpandedParameterPack()) { 10409 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10410 if (Val.isInvalid()) 10411 return nullptr; 10412 10413 ValExpr = MakeFullExpr(Val.get()).get(); 10414 } 10415 10416 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10417 } 10418 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10419 Expr *Op) { 10420 if (!Op) 10421 return ExprError(); 10422 10423 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10424 public: 10425 IntConvertDiagnoser() 10426 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10427 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10428 QualType T) override { 10429 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10430 } 10431 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10432 QualType T) override { 10433 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10434 } 10435 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10436 QualType T, 10437 QualType ConvTy) override { 10438 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10439 } 10440 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 10441 QualType ConvTy) override { 10442 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10443 << ConvTy->isEnumeralType() << ConvTy; 10444 } 10445 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 10446 QualType T) override { 10447 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 10448 } 10449 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 10450 QualType ConvTy) override { 10451 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10452 << ConvTy->isEnumeralType() << ConvTy; 10453 } 10454 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 10455 QualType) override { 10456 llvm_unreachable("conversion functions are permitted"); 10457 } 10458 } ConvertDiagnoser; 10459 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 10460 } 10461 10462 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 10463 OpenMPClauseKind CKind, 10464 bool StrictlyPositive) { 10465 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 10466 !ValExpr->isInstantiationDependent()) { 10467 SourceLocation Loc = ValExpr->getExprLoc(); 10468 ExprResult Value = 10469 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 10470 if (Value.isInvalid()) 10471 return false; 10472 10473 ValExpr = Value.get(); 10474 // The expression must evaluate to a non-negative integer value. 10475 llvm::APSInt Result; 10476 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 10477 Result.isSigned() && 10478 !((!StrictlyPositive && Result.isNonNegative()) || 10479 (StrictlyPositive && Result.isStrictlyPositive()))) { 10480 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 10481 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10482 << ValExpr->getSourceRange(); 10483 return false; 10484 } 10485 } 10486 return true; 10487 } 10488 10489 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 10490 SourceLocation StartLoc, 10491 SourceLocation LParenLoc, 10492 SourceLocation EndLoc) { 10493 Expr *ValExpr = NumThreads; 10494 Stmt *HelperValStmt = nullptr; 10495 10496 // OpenMP [2.5, Restrictions] 10497 // The num_threads expression must evaluate to a positive integer value. 10498 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 10499 /*StrictlyPositive=*/true)) 10500 return nullptr; 10501 10502 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10503 OpenMPDirectiveKind CaptureRegion = 10504 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 10505 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10506 ValExpr = MakeFullExpr(ValExpr).get(); 10507 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10508 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10509 HelperValStmt = buildPreInits(Context, Captures); 10510 } 10511 10512 return new (Context) OMPNumThreadsClause( 10513 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 10514 } 10515 10516 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 10517 OpenMPClauseKind CKind, 10518 bool StrictlyPositive) { 10519 if (!E) 10520 return ExprError(); 10521 if (E->isValueDependent() || E->isTypeDependent() || 10522 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 10523 return E; 10524 llvm::APSInt Result; 10525 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 10526 if (ICE.isInvalid()) 10527 return ExprError(); 10528 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 10529 (!StrictlyPositive && !Result.isNonNegative())) { 10530 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 10531 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10532 << E->getSourceRange(); 10533 return ExprError(); 10534 } 10535 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 10536 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 10537 << E->getSourceRange(); 10538 return ExprError(); 10539 } 10540 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 10541 DSAStack->setAssociatedLoops(Result.getExtValue()); 10542 else if (CKind == OMPC_ordered) 10543 DSAStack->setAssociatedLoops(Result.getExtValue()); 10544 return ICE; 10545 } 10546 10547 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 10548 SourceLocation LParenLoc, 10549 SourceLocation EndLoc) { 10550 // OpenMP [2.8.1, simd construct, Description] 10551 // The parameter of the safelen clause must be a constant 10552 // positive integer expression. 10553 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 10554 if (Safelen.isInvalid()) 10555 return nullptr; 10556 return new (Context) 10557 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 10558 } 10559 10560 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 10561 SourceLocation LParenLoc, 10562 SourceLocation EndLoc) { 10563 // OpenMP [2.8.1, simd construct, Description] 10564 // The parameter of the simdlen clause must be a constant 10565 // positive integer expression. 10566 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 10567 if (Simdlen.isInvalid()) 10568 return nullptr; 10569 return new (Context) 10570 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 10571 } 10572 10573 /// Tries to find omp_allocator_handle_t type. 10574 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 10575 DSAStackTy *Stack) { 10576 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 10577 if (!OMPAllocatorHandleT.isNull()) 10578 return true; 10579 // Build the predefined allocator expressions. 10580 bool ErrorFound = false; 10581 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 10582 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 10583 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 10584 StringRef Allocator = 10585 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 10586 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 10587 auto *VD = dyn_cast_or_null<ValueDecl>( 10588 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 10589 if (!VD) { 10590 ErrorFound = true; 10591 break; 10592 } 10593 QualType AllocatorType = 10594 VD->getType().getNonLValueExprType(S.getASTContext()); 10595 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10596 if (!Res.isUsable()) { 10597 ErrorFound = true; 10598 break; 10599 } 10600 if (OMPAllocatorHandleT.isNull()) 10601 OMPAllocatorHandleT = AllocatorType; 10602 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10603 ErrorFound = true; 10604 break; 10605 } 10606 Stack->setAllocator(AllocatorKind, Res.get()); 10607 } 10608 if (ErrorFound) { 10609 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10610 return false; 10611 } 10612 OMPAllocatorHandleT.addConst(); 10613 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10614 return true; 10615 } 10616 10617 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10618 SourceLocation LParenLoc, 10619 SourceLocation EndLoc) { 10620 // OpenMP [2.11.3, allocate Directive, Description] 10621 // allocator is an expression of omp_allocator_handle_t type. 10622 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10623 return nullptr; 10624 10625 ExprResult Allocator = DefaultLvalueConversion(A); 10626 if (Allocator.isInvalid()) 10627 return nullptr; 10628 Allocator = PerformImplicitConversion(Allocator.get(), 10629 DSAStack->getOMPAllocatorHandleT(), 10630 Sema::AA_Initializing, 10631 /*AllowExplicit=*/true); 10632 if (Allocator.isInvalid()) 10633 return nullptr; 10634 return new (Context) 10635 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10636 } 10637 10638 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10639 SourceLocation StartLoc, 10640 SourceLocation LParenLoc, 10641 SourceLocation EndLoc) { 10642 // OpenMP [2.7.1, loop construct, Description] 10643 // OpenMP [2.8.1, simd construct, Description] 10644 // OpenMP [2.9.6, distribute construct, Description] 10645 // The parameter of the collapse clause must be a constant 10646 // positive integer expression. 10647 ExprResult NumForLoopsResult = 10648 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10649 if (NumForLoopsResult.isInvalid()) 10650 return nullptr; 10651 return new (Context) 10652 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10653 } 10654 10655 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10656 SourceLocation EndLoc, 10657 SourceLocation LParenLoc, 10658 Expr *NumForLoops) { 10659 // OpenMP [2.7.1, loop construct, Description] 10660 // OpenMP [2.8.1, simd construct, Description] 10661 // OpenMP [2.9.6, distribute construct, Description] 10662 // The parameter of the ordered clause must be a constant 10663 // positive integer expression if any. 10664 if (NumForLoops && LParenLoc.isValid()) { 10665 ExprResult NumForLoopsResult = 10666 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10667 if (NumForLoopsResult.isInvalid()) 10668 return nullptr; 10669 NumForLoops = NumForLoopsResult.get(); 10670 } else { 10671 NumForLoops = nullptr; 10672 } 10673 auto *Clause = OMPOrderedClause::Create( 10674 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10675 StartLoc, LParenLoc, EndLoc); 10676 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10677 return Clause; 10678 } 10679 10680 OMPClause *Sema::ActOnOpenMPSimpleClause( 10681 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10682 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10683 OMPClause *Res = nullptr; 10684 switch (Kind) { 10685 case OMPC_default: 10686 Res = 10687 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10688 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10689 break; 10690 case OMPC_proc_bind: 10691 Res = ActOnOpenMPProcBindClause( 10692 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10693 LParenLoc, EndLoc); 10694 break; 10695 case OMPC_atomic_default_mem_order: 10696 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10697 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10698 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10699 break; 10700 case OMPC_if: 10701 case OMPC_final: 10702 case OMPC_num_threads: 10703 case OMPC_safelen: 10704 case OMPC_simdlen: 10705 case OMPC_allocator: 10706 case OMPC_collapse: 10707 case OMPC_schedule: 10708 case OMPC_private: 10709 case OMPC_firstprivate: 10710 case OMPC_lastprivate: 10711 case OMPC_shared: 10712 case OMPC_reduction: 10713 case OMPC_task_reduction: 10714 case OMPC_in_reduction: 10715 case OMPC_linear: 10716 case OMPC_aligned: 10717 case OMPC_copyin: 10718 case OMPC_copyprivate: 10719 case OMPC_ordered: 10720 case OMPC_nowait: 10721 case OMPC_untied: 10722 case OMPC_mergeable: 10723 case OMPC_threadprivate: 10724 case OMPC_allocate: 10725 case OMPC_flush: 10726 case OMPC_read: 10727 case OMPC_write: 10728 case OMPC_update: 10729 case OMPC_capture: 10730 case OMPC_seq_cst: 10731 case OMPC_depend: 10732 case OMPC_device: 10733 case OMPC_threads: 10734 case OMPC_simd: 10735 case OMPC_map: 10736 case OMPC_num_teams: 10737 case OMPC_thread_limit: 10738 case OMPC_priority: 10739 case OMPC_grainsize: 10740 case OMPC_nogroup: 10741 case OMPC_num_tasks: 10742 case OMPC_hint: 10743 case OMPC_dist_schedule: 10744 case OMPC_defaultmap: 10745 case OMPC_unknown: 10746 case OMPC_uniform: 10747 case OMPC_to: 10748 case OMPC_from: 10749 case OMPC_use_device_ptr: 10750 case OMPC_is_device_ptr: 10751 case OMPC_unified_address: 10752 case OMPC_unified_shared_memory: 10753 case OMPC_reverse_offload: 10754 case OMPC_dynamic_allocators: 10755 case OMPC_device_type: 10756 llvm_unreachable("Clause is not allowed."); 10757 } 10758 return Res; 10759 } 10760 10761 static std::string 10762 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10763 ArrayRef<unsigned> Exclude = llvm::None) { 10764 SmallString<256> Buffer; 10765 llvm::raw_svector_ostream Out(Buffer); 10766 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10767 unsigned Skipped = Exclude.size(); 10768 auto S = Exclude.begin(), E = Exclude.end(); 10769 for (unsigned I = First; I < Last; ++I) { 10770 if (std::find(S, E, I) != E) { 10771 --Skipped; 10772 continue; 10773 } 10774 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10775 if (I == Bound - Skipped) 10776 Out << " or "; 10777 else if (I != Bound + 1 - Skipped) 10778 Out << ", "; 10779 } 10780 return Out.str(); 10781 } 10782 10783 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 10784 SourceLocation KindKwLoc, 10785 SourceLocation StartLoc, 10786 SourceLocation LParenLoc, 10787 SourceLocation EndLoc) { 10788 if (Kind == OMPC_DEFAULT_unknown) { 10789 static_assert(OMPC_DEFAULT_unknown > 0, 10790 "OMPC_DEFAULT_unknown not greater than 0"); 10791 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10792 << getListOfPossibleValues(OMPC_default, /*First=*/0, 10793 /*Last=*/OMPC_DEFAULT_unknown) 10794 << getOpenMPClauseName(OMPC_default); 10795 return nullptr; 10796 } 10797 switch (Kind) { 10798 case OMPC_DEFAULT_none: 10799 DSAStack->setDefaultDSANone(KindKwLoc); 10800 break; 10801 case OMPC_DEFAULT_shared: 10802 DSAStack->setDefaultDSAShared(KindKwLoc); 10803 break; 10804 case OMPC_DEFAULT_unknown: 10805 llvm_unreachable("Clause kind is not allowed."); 10806 break; 10807 } 10808 return new (Context) 10809 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10810 } 10811 10812 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10813 SourceLocation KindKwLoc, 10814 SourceLocation StartLoc, 10815 SourceLocation LParenLoc, 10816 SourceLocation EndLoc) { 10817 if (Kind == OMPC_PROC_BIND_unknown) { 10818 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10819 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10820 /*Last=*/OMPC_PROC_BIND_unknown) 10821 << getOpenMPClauseName(OMPC_proc_bind); 10822 return nullptr; 10823 } 10824 return new (Context) 10825 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10826 } 10827 10828 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10829 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10830 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10831 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10832 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10833 << getListOfPossibleValues( 10834 OMPC_atomic_default_mem_order, /*First=*/0, 10835 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10836 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10837 return nullptr; 10838 } 10839 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10840 LParenLoc, EndLoc); 10841 } 10842 10843 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10844 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10845 SourceLocation StartLoc, SourceLocation LParenLoc, 10846 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10847 SourceLocation EndLoc) { 10848 OMPClause *Res = nullptr; 10849 switch (Kind) { 10850 case OMPC_schedule: 10851 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10852 assert(Argument.size() == NumberOfElements && 10853 ArgumentLoc.size() == NumberOfElements); 10854 Res = ActOnOpenMPScheduleClause( 10855 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10856 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10857 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10858 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10859 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10860 break; 10861 case OMPC_if: 10862 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10863 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10864 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10865 DelimLoc, EndLoc); 10866 break; 10867 case OMPC_dist_schedule: 10868 Res = ActOnOpenMPDistScheduleClause( 10869 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10870 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10871 break; 10872 case OMPC_defaultmap: 10873 enum { Modifier, DefaultmapKind }; 10874 Res = ActOnOpenMPDefaultmapClause( 10875 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10876 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10877 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10878 EndLoc); 10879 break; 10880 case OMPC_final: 10881 case OMPC_num_threads: 10882 case OMPC_safelen: 10883 case OMPC_simdlen: 10884 case OMPC_allocator: 10885 case OMPC_collapse: 10886 case OMPC_default: 10887 case OMPC_proc_bind: 10888 case OMPC_private: 10889 case OMPC_firstprivate: 10890 case OMPC_lastprivate: 10891 case OMPC_shared: 10892 case OMPC_reduction: 10893 case OMPC_task_reduction: 10894 case OMPC_in_reduction: 10895 case OMPC_linear: 10896 case OMPC_aligned: 10897 case OMPC_copyin: 10898 case OMPC_copyprivate: 10899 case OMPC_ordered: 10900 case OMPC_nowait: 10901 case OMPC_untied: 10902 case OMPC_mergeable: 10903 case OMPC_threadprivate: 10904 case OMPC_allocate: 10905 case OMPC_flush: 10906 case OMPC_read: 10907 case OMPC_write: 10908 case OMPC_update: 10909 case OMPC_capture: 10910 case OMPC_seq_cst: 10911 case OMPC_depend: 10912 case OMPC_device: 10913 case OMPC_threads: 10914 case OMPC_simd: 10915 case OMPC_map: 10916 case OMPC_num_teams: 10917 case OMPC_thread_limit: 10918 case OMPC_priority: 10919 case OMPC_grainsize: 10920 case OMPC_nogroup: 10921 case OMPC_num_tasks: 10922 case OMPC_hint: 10923 case OMPC_unknown: 10924 case OMPC_uniform: 10925 case OMPC_to: 10926 case OMPC_from: 10927 case OMPC_use_device_ptr: 10928 case OMPC_is_device_ptr: 10929 case OMPC_unified_address: 10930 case OMPC_unified_shared_memory: 10931 case OMPC_reverse_offload: 10932 case OMPC_dynamic_allocators: 10933 case OMPC_atomic_default_mem_order: 10934 case OMPC_device_type: 10935 llvm_unreachable("Clause is not allowed."); 10936 } 10937 return Res; 10938 } 10939 10940 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10941 OpenMPScheduleClauseModifier M2, 10942 SourceLocation M1Loc, SourceLocation M2Loc) { 10943 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10944 SmallVector<unsigned, 2> Excluded; 10945 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10946 Excluded.push_back(M2); 10947 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10948 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10949 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10950 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10951 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10952 << getListOfPossibleValues(OMPC_schedule, 10953 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10954 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10955 Excluded) 10956 << getOpenMPClauseName(OMPC_schedule); 10957 return true; 10958 } 10959 return false; 10960 } 10961 10962 OMPClause *Sema::ActOnOpenMPScheduleClause( 10963 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10964 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10965 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10966 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10967 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10968 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10969 return nullptr; 10970 // OpenMP, 2.7.1, Loop Construct, Restrictions 10971 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10972 // but not both. 10973 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10974 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10975 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10976 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10977 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10978 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10979 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10980 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10981 return nullptr; 10982 } 10983 if (Kind == OMPC_SCHEDULE_unknown) { 10984 std::string Values; 10985 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10986 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10987 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10988 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10989 Exclude); 10990 } else { 10991 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10992 /*Last=*/OMPC_SCHEDULE_unknown); 10993 } 10994 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10995 << Values << getOpenMPClauseName(OMPC_schedule); 10996 return nullptr; 10997 } 10998 // OpenMP, 2.7.1, Loop Construct, Restrictions 10999 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11000 // schedule(guided). 11001 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11002 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11003 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11004 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11005 diag::err_omp_schedule_nonmonotonic_static); 11006 return nullptr; 11007 } 11008 Expr *ValExpr = ChunkSize; 11009 Stmt *HelperValStmt = nullptr; 11010 if (ChunkSize) { 11011 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11012 !ChunkSize->isInstantiationDependent() && 11013 !ChunkSize->containsUnexpandedParameterPack()) { 11014 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11015 ExprResult Val = 11016 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11017 if (Val.isInvalid()) 11018 return nullptr; 11019 11020 ValExpr = Val.get(); 11021 11022 // OpenMP [2.7.1, Restrictions] 11023 // chunk_size must be a loop invariant integer expression with a positive 11024 // value. 11025 llvm::APSInt Result; 11026 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11027 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11028 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11029 << "schedule" << 1 << ChunkSize->getSourceRange(); 11030 return nullptr; 11031 } 11032 } else if (getOpenMPCaptureRegionForClause( 11033 DSAStack->getCurrentDirective(), OMPC_schedule) != 11034 OMPD_unknown && 11035 !CurContext->isDependentContext()) { 11036 ValExpr = MakeFullExpr(ValExpr).get(); 11037 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11038 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11039 HelperValStmt = buildPreInits(Context, Captures); 11040 } 11041 } 11042 } 11043 11044 return new (Context) 11045 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11046 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11047 } 11048 11049 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11050 SourceLocation StartLoc, 11051 SourceLocation EndLoc) { 11052 OMPClause *Res = nullptr; 11053 switch (Kind) { 11054 case OMPC_ordered: 11055 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11056 break; 11057 case OMPC_nowait: 11058 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11059 break; 11060 case OMPC_untied: 11061 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11062 break; 11063 case OMPC_mergeable: 11064 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11065 break; 11066 case OMPC_read: 11067 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11068 break; 11069 case OMPC_write: 11070 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11071 break; 11072 case OMPC_update: 11073 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11074 break; 11075 case OMPC_capture: 11076 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11077 break; 11078 case OMPC_seq_cst: 11079 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11080 break; 11081 case OMPC_threads: 11082 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11083 break; 11084 case OMPC_simd: 11085 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11086 break; 11087 case OMPC_nogroup: 11088 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11089 break; 11090 case OMPC_unified_address: 11091 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11092 break; 11093 case OMPC_unified_shared_memory: 11094 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11095 break; 11096 case OMPC_reverse_offload: 11097 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11098 break; 11099 case OMPC_dynamic_allocators: 11100 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11101 break; 11102 case OMPC_if: 11103 case OMPC_final: 11104 case OMPC_num_threads: 11105 case OMPC_safelen: 11106 case OMPC_simdlen: 11107 case OMPC_allocator: 11108 case OMPC_collapse: 11109 case OMPC_schedule: 11110 case OMPC_private: 11111 case OMPC_firstprivate: 11112 case OMPC_lastprivate: 11113 case OMPC_shared: 11114 case OMPC_reduction: 11115 case OMPC_task_reduction: 11116 case OMPC_in_reduction: 11117 case OMPC_linear: 11118 case OMPC_aligned: 11119 case OMPC_copyin: 11120 case OMPC_copyprivate: 11121 case OMPC_default: 11122 case OMPC_proc_bind: 11123 case OMPC_threadprivate: 11124 case OMPC_allocate: 11125 case OMPC_flush: 11126 case OMPC_depend: 11127 case OMPC_device: 11128 case OMPC_map: 11129 case OMPC_num_teams: 11130 case OMPC_thread_limit: 11131 case OMPC_priority: 11132 case OMPC_grainsize: 11133 case OMPC_num_tasks: 11134 case OMPC_hint: 11135 case OMPC_dist_schedule: 11136 case OMPC_defaultmap: 11137 case OMPC_unknown: 11138 case OMPC_uniform: 11139 case OMPC_to: 11140 case OMPC_from: 11141 case OMPC_use_device_ptr: 11142 case OMPC_is_device_ptr: 11143 case OMPC_atomic_default_mem_order: 11144 case OMPC_device_type: 11145 llvm_unreachable("Clause is not allowed."); 11146 } 11147 return Res; 11148 } 11149 11150 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11151 SourceLocation EndLoc) { 11152 DSAStack->setNowaitRegion(); 11153 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11154 } 11155 11156 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11157 SourceLocation EndLoc) { 11158 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11159 } 11160 11161 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11162 SourceLocation EndLoc) { 11163 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11164 } 11165 11166 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11167 SourceLocation EndLoc) { 11168 return new (Context) OMPReadClause(StartLoc, EndLoc); 11169 } 11170 11171 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11172 SourceLocation EndLoc) { 11173 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11174 } 11175 11176 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11177 SourceLocation EndLoc) { 11178 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11179 } 11180 11181 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11182 SourceLocation EndLoc) { 11183 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11184 } 11185 11186 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11187 SourceLocation EndLoc) { 11188 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11189 } 11190 11191 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11192 SourceLocation EndLoc) { 11193 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11194 } 11195 11196 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11197 SourceLocation EndLoc) { 11198 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11199 } 11200 11201 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11202 SourceLocation EndLoc) { 11203 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11204 } 11205 11206 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11207 SourceLocation EndLoc) { 11208 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11209 } 11210 11211 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11212 SourceLocation EndLoc) { 11213 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11214 } 11215 11216 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11217 SourceLocation EndLoc) { 11218 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11219 } 11220 11221 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11222 SourceLocation EndLoc) { 11223 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11224 } 11225 11226 OMPClause *Sema::ActOnOpenMPVarListClause( 11227 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11228 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11229 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11230 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11231 OpenMPLinearClauseKind LinKind, 11232 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11233 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11234 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11235 SourceLocation StartLoc = Locs.StartLoc; 11236 SourceLocation LParenLoc = Locs.LParenLoc; 11237 SourceLocation EndLoc = Locs.EndLoc; 11238 OMPClause *Res = nullptr; 11239 switch (Kind) { 11240 case OMPC_private: 11241 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11242 break; 11243 case OMPC_firstprivate: 11244 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11245 break; 11246 case OMPC_lastprivate: 11247 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11248 break; 11249 case OMPC_shared: 11250 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11251 break; 11252 case OMPC_reduction: 11253 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11254 EndLoc, ReductionOrMapperIdScopeSpec, 11255 ReductionOrMapperId); 11256 break; 11257 case OMPC_task_reduction: 11258 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11259 EndLoc, ReductionOrMapperIdScopeSpec, 11260 ReductionOrMapperId); 11261 break; 11262 case OMPC_in_reduction: 11263 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11264 EndLoc, ReductionOrMapperIdScopeSpec, 11265 ReductionOrMapperId); 11266 break; 11267 case OMPC_linear: 11268 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11269 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11270 break; 11271 case OMPC_aligned: 11272 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11273 ColonLoc, EndLoc); 11274 break; 11275 case OMPC_copyin: 11276 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11277 break; 11278 case OMPC_copyprivate: 11279 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11280 break; 11281 case OMPC_flush: 11282 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11283 break; 11284 case OMPC_depend: 11285 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11286 StartLoc, LParenLoc, EndLoc); 11287 break; 11288 case OMPC_map: 11289 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11290 ReductionOrMapperIdScopeSpec, 11291 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11292 DepLinMapLoc, ColonLoc, VarList, Locs); 11293 break; 11294 case OMPC_to: 11295 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11296 ReductionOrMapperId, Locs); 11297 break; 11298 case OMPC_from: 11299 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11300 ReductionOrMapperId, Locs); 11301 break; 11302 case OMPC_use_device_ptr: 11303 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11304 break; 11305 case OMPC_is_device_ptr: 11306 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11307 break; 11308 case OMPC_allocate: 11309 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11310 ColonLoc, EndLoc); 11311 break; 11312 case OMPC_if: 11313 case OMPC_final: 11314 case OMPC_num_threads: 11315 case OMPC_safelen: 11316 case OMPC_simdlen: 11317 case OMPC_allocator: 11318 case OMPC_collapse: 11319 case OMPC_default: 11320 case OMPC_proc_bind: 11321 case OMPC_schedule: 11322 case OMPC_ordered: 11323 case OMPC_nowait: 11324 case OMPC_untied: 11325 case OMPC_mergeable: 11326 case OMPC_threadprivate: 11327 case OMPC_read: 11328 case OMPC_write: 11329 case OMPC_update: 11330 case OMPC_capture: 11331 case OMPC_seq_cst: 11332 case OMPC_device: 11333 case OMPC_threads: 11334 case OMPC_simd: 11335 case OMPC_num_teams: 11336 case OMPC_thread_limit: 11337 case OMPC_priority: 11338 case OMPC_grainsize: 11339 case OMPC_nogroup: 11340 case OMPC_num_tasks: 11341 case OMPC_hint: 11342 case OMPC_dist_schedule: 11343 case OMPC_defaultmap: 11344 case OMPC_unknown: 11345 case OMPC_uniform: 11346 case OMPC_unified_address: 11347 case OMPC_unified_shared_memory: 11348 case OMPC_reverse_offload: 11349 case OMPC_dynamic_allocators: 11350 case OMPC_atomic_default_mem_order: 11351 case OMPC_device_type: 11352 llvm_unreachable("Clause is not allowed."); 11353 } 11354 return Res; 11355 } 11356 11357 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11358 ExprObjectKind OK, SourceLocation Loc) { 11359 ExprResult Res = BuildDeclRefExpr( 11360 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11361 if (!Res.isUsable()) 11362 return ExprError(); 11363 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11364 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11365 if (!Res.isUsable()) 11366 return ExprError(); 11367 } 11368 if (VK != VK_LValue && Res.get()->isGLValue()) { 11369 Res = DefaultLvalueConversion(Res.get()); 11370 if (!Res.isUsable()) 11371 return ExprError(); 11372 } 11373 return Res; 11374 } 11375 11376 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11377 SourceLocation StartLoc, 11378 SourceLocation LParenLoc, 11379 SourceLocation EndLoc) { 11380 SmallVector<Expr *, 8> Vars; 11381 SmallVector<Expr *, 8> PrivateCopies; 11382 for (Expr *RefExpr : VarList) { 11383 assert(RefExpr && "NULL expr in OpenMP private clause."); 11384 SourceLocation ELoc; 11385 SourceRange ERange; 11386 Expr *SimpleRefExpr = RefExpr; 11387 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11388 if (Res.second) { 11389 // It will be analyzed later. 11390 Vars.push_back(RefExpr); 11391 PrivateCopies.push_back(nullptr); 11392 } 11393 ValueDecl *D = Res.first; 11394 if (!D) 11395 continue; 11396 11397 QualType Type = D->getType(); 11398 auto *VD = dyn_cast<VarDecl>(D); 11399 11400 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11401 // A variable that appears in a private clause must not have an incomplete 11402 // type or a reference type. 11403 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11404 continue; 11405 Type = Type.getNonReferenceType(); 11406 11407 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11408 // A variable that is privatized must not have a const-qualified type 11409 // unless it is of class type with a mutable member. This restriction does 11410 // not apply to the firstprivate clause. 11411 // 11412 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11413 // A variable that appears in a private clause must not have a 11414 // const-qualified type unless it is of class type with a mutable member. 11415 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11416 continue; 11417 11418 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11419 // in a Construct] 11420 // Variables with the predetermined data-sharing attributes may not be 11421 // listed in data-sharing attributes clauses, except for the cases 11422 // listed below. For these exceptions only, listing a predetermined 11423 // variable in a data-sharing attribute clause is allowed and overrides 11424 // the variable's predetermined data-sharing attributes. 11425 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11426 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 11427 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11428 << getOpenMPClauseName(OMPC_private); 11429 reportOriginalDsa(*this, DSAStack, D, DVar); 11430 continue; 11431 } 11432 11433 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11434 // Variably modified types are not supported for tasks. 11435 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11436 isOpenMPTaskingDirective(CurrDir)) { 11437 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11438 << getOpenMPClauseName(OMPC_private) << Type 11439 << getOpenMPDirectiveName(CurrDir); 11440 bool IsDecl = 11441 !VD || 11442 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11443 Diag(D->getLocation(), 11444 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11445 << D; 11446 continue; 11447 } 11448 11449 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11450 // A list item cannot appear in both a map clause and a data-sharing 11451 // attribute clause on the same construct 11452 // 11453 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11454 // A list item cannot appear in both a map clause and a data-sharing 11455 // attribute clause on the same construct unless the construct is a 11456 // combined construct. 11457 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 11458 CurrDir == OMPD_target) { 11459 OpenMPClauseKind ConflictKind; 11460 if (DSAStack->checkMappableExprComponentListsForDecl( 11461 VD, /*CurrentRegionOnly=*/true, 11462 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 11463 OpenMPClauseKind WhereFoundClauseKind) -> bool { 11464 ConflictKind = WhereFoundClauseKind; 11465 return true; 11466 })) { 11467 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11468 << getOpenMPClauseName(OMPC_private) 11469 << getOpenMPClauseName(ConflictKind) 11470 << getOpenMPDirectiveName(CurrDir); 11471 reportOriginalDsa(*this, DSAStack, D, DVar); 11472 continue; 11473 } 11474 } 11475 11476 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 11477 // A variable of class type (or array thereof) that appears in a private 11478 // clause requires an accessible, unambiguous default constructor for the 11479 // class type. 11480 // Generate helper private variable and initialize it with the default 11481 // value. The address of the original variable is replaced by the address of 11482 // the new private variable in CodeGen. This new variable is not added to 11483 // IdResolver, so the code in the OpenMP region uses original variable for 11484 // proper diagnostics. 11485 Type = Type.getUnqualifiedType(); 11486 VarDecl *VDPrivate = 11487 buildVarDecl(*this, ELoc, Type, D->getName(), 11488 D->hasAttrs() ? &D->getAttrs() : nullptr, 11489 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11490 ActOnUninitializedDecl(VDPrivate); 11491 if (VDPrivate->isInvalidDecl()) 11492 continue; 11493 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11494 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 11495 11496 DeclRefExpr *Ref = nullptr; 11497 if (!VD && !CurContext->isDependentContext()) 11498 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11499 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 11500 Vars.push_back((VD || CurContext->isDependentContext()) 11501 ? RefExpr->IgnoreParens() 11502 : Ref); 11503 PrivateCopies.push_back(VDPrivateRefExpr); 11504 } 11505 11506 if (Vars.empty()) 11507 return nullptr; 11508 11509 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11510 PrivateCopies); 11511 } 11512 11513 namespace { 11514 class DiagsUninitializedSeveretyRAII { 11515 private: 11516 DiagnosticsEngine &Diags; 11517 SourceLocation SavedLoc; 11518 bool IsIgnored = false; 11519 11520 public: 11521 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 11522 bool IsIgnored) 11523 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 11524 if (!IsIgnored) { 11525 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 11526 /*Map*/ diag::Severity::Ignored, Loc); 11527 } 11528 } 11529 ~DiagsUninitializedSeveretyRAII() { 11530 if (!IsIgnored) 11531 Diags.popMappings(SavedLoc); 11532 } 11533 }; 11534 } 11535 11536 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 11537 SourceLocation StartLoc, 11538 SourceLocation LParenLoc, 11539 SourceLocation EndLoc) { 11540 SmallVector<Expr *, 8> Vars; 11541 SmallVector<Expr *, 8> PrivateCopies; 11542 SmallVector<Expr *, 8> Inits; 11543 SmallVector<Decl *, 4> ExprCaptures; 11544 bool IsImplicitClause = 11545 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 11546 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 11547 11548 for (Expr *RefExpr : VarList) { 11549 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 11550 SourceLocation ELoc; 11551 SourceRange ERange; 11552 Expr *SimpleRefExpr = RefExpr; 11553 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11554 if (Res.second) { 11555 // It will be analyzed later. 11556 Vars.push_back(RefExpr); 11557 PrivateCopies.push_back(nullptr); 11558 Inits.push_back(nullptr); 11559 } 11560 ValueDecl *D = Res.first; 11561 if (!D) 11562 continue; 11563 11564 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 11565 QualType Type = D->getType(); 11566 auto *VD = dyn_cast<VarDecl>(D); 11567 11568 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11569 // A variable that appears in a private clause must not have an incomplete 11570 // type or a reference type. 11571 if (RequireCompleteType(ELoc, Type, 11572 diag::err_omp_firstprivate_incomplete_type)) 11573 continue; 11574 Type = Type.getNonReferenceType(); 11575 11576 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 11577 // A variable of class type (or array thereof) that appears in a private 11578 // clause requires an accessible, unambiguous copy constructor for the 11579 // class type. 11580 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11581 11582 // If an implicit firstprivate variable found it was checked already. 11583 DSAStackTy::DSAVarData TopDVar; 11584 if (!IsImplicitClause) { 11585 DSAStackTy::DSAVarData DVar = 11586 DSAStack->getTopDSA(D, /*FromParent=*/false); 11587 TopDVar = DVar; 11588 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11589 bool IsConstant = ElemType.isConstant(Context); 11590 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 11591 // A list item that specifies a given variable may not appear in more 11592 // than one clause on the same directive, except that a variable may be 11593 // specified in both firstprivate and lastprivate clauses. 11594 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11595 // A list item may appear in a firstprivate or lastprivate clause but not 11596 // both. 11597 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 11598 (isOpenMPDistributeDirective(CurrDir) || 11599 DVar.CKind != OMPC_lastprivate) && 11600 DVar.RefExpr) { 11601 Diag(ELoc, diag::err_omp_wrong_dsa) 11602 << getOpenMPClauseName(DVar.CKind) 11603 << getOpenMPClauseName(OMPC_firstprivate); 11604 reportOriginalDsa(*this, DSAStack, D, DVar); 11605 continue; 11606 } 11607 11608 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11609 // in a Construct] 11610 // Variables with the predetermined data-sharing attributes may not be 11611 // listed in data-sharing attributes clauses, except for the cases 11612 // listed below. For these exceptions only, listing a predetermined 11613 // variable in a data-sharing attribute clause is allowed and overrides 11614 // the variable's predetermined data-sharing attributes. 11615 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11616 // in a Construct, C/C++, p.2] 11617 // Variables with const-qualified type having no mutable member may be 11618 // listed in a firstprivate clause, even if they are static data members. 11619 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11620 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11621 Diag(ELoc, diag::err_omp_wrong_dsa) 11622 << getOpenMPClauseName(DVar.CKind) 11623 << getOpenMPClauseName(OMPC_firstprivate); 11624 reportOriginalDsa(*this, DSAStack, D, DVar); 11625 continue; 11626 } 11627 11628 // OpenMP [2.9.3.4, Restrictions, p.2] 11629 // A list item that is private within a parallel region must not appear 11630 // in a firstprivate clause on a worksharing construct if any of the 11631 // worksharing regions arising from the worksharing construct ever bind 11632 // to any of the parallel regions arising from the parallel construct. 11633 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11634 // A list item that is private within a teams region must not appear in a 11635 // firstprivate clause on a distribute construct if any of the distribute 11636 // regions arising from the distribute construct ever bind to any of the 11637 // teams regions arising from the teams construct. 11638 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11639 // A list item that appears in a reduction clause of a teams construct 11640 // must not appear in a firstprivate clause on a distribute construct if 11641 // any of the distribute regions arising from the distribute construct 11642 // ever bind to any of the teams regions arising from the teams construct. 11643 if ((isOpenMPWorksharingDirective(CurrDir) || 11644 isOpenMPDistributeDirective(CurrDir)) && 11645 !isOpenMPParallelDirective(CurrDir) && 11646 !isOpenMPTeamsDirective(CurrDir)) { 11647 DVar = DSAStack->getImplicitDSA(D, true); 11648 if (DVar.CKind != OMPC_shared && 11649 (isOpenMPParallelDirective(DVar.DKind) || 11650 isOpenMPTeamsDirective(DVar.DKind) || 11651 DVar.DKind == OMPD_unknown)) { 11652 Diag(ELoc, diag::err_omp_required_access) 11653 << getOpenMPClauseName(OMPC_firstprivate) 11654 << getOpenMPClauseName(OMPC_shared); 11655 reportOriginalDsa(*this, DSAStack, D, DVar); 11656 continue; 11657 } 11658 } 11659 // OpenMP [2.9.3.4, Restrictions, p.3] 11660 // A list item that appears in a reduction clause of a parallel construct 11661 // must not appear in a firstprivate clause on a worksharing or task 11662 // construct if any of the worksharing or task regions arising from the 11663 // worksharing or task construct ever bind to any of the parallel regions 11664 // arising from the parallel construct. 11665 // OpenMP [2.9.3.4, Restrictions, p.4] 11666 // A list item that appears in a reduction clause in worksharing 11667 // construct must not appear in a firstprivate clause in a task construct 11668 // encountered during execution of any of the worksharing regions arising 11669 // from the worksharing construct. 11670 if (isOpenMPTaskingDirective(CurrDir)) { 11671 DVar = DSAStack->hasInnermostDSA( 11672 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11673 [](OpenMPDirectiveKind K) { 11674 return isOpenMPParallelDirective(K) || 11675 isOpenMPWorksharingDirective(K) || 11676 isOpenMPTeamsDirective(K); 11677 }, 11678 /*FromParent=*/true); 11679 if (DVar.CKind == OMPC_reduction && 11680 (isOpenMPParallelDirective(DVar.DKind) || 11681 isOpenMPWorksharingDirective(DVar.DKind) || 11682 isOpenMPTeamsDirective(DVar.DKind))) { 11683 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11684 << getOpenMPDirectiveName(DVar.DKind); 11685 reportOriginalDsa(*this, DSAStack, D, DVar); 11686 continue; 11687 } 11688 } 11689 11690 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11691 // A list item cannot appear in both a map clause and a data-sharing 11692 // attribute clause on the same construct 11693 // 11694 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11695 // A list item cannot appear in both a map clause and a data-sharing 11696 // attribute clause on the same construct unless the construct is a 11697 // combined construct. 11698 if ((LangOpts.OpenMP <= 45 && 11699 isOpenMPTargetExecutionDirective(CurrDir)) || 11700 CurrDir == OMPD_target) { 11701 OpenMPClauseKind ConflictKind; 11702 if (DSAStack->checkMappableExprComponentListsForDecl( 11703 VD, /*CurrentRegionOnly=*/true, 11704 [&ConflictKind]( 11705 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11706 OpenMPClauseKind WhereFoundClauseKind) { 11707 ConflictKind = WhereFoundClauseKind; 11708 return true; 11709 })) { 11710 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11711 << getOpenMPClauseName(OMPC_firstprivate) 11712 << getOpenMPClauseName(ConflictKind) 11713 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11714 reportOriginalDsa(*this, DSAStack, D, DVar); 11715 continue; 11716 } 11717 } 11718 } 11719 11720 // Variably modified types are not supported for tasks. 11721 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11722 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11723 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11724 << getOpenMPClauseName(OMPC_firstprivate) << Type 11725 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11726 bool IsDecl = 11727 !VD || 11728 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11729 Diag(D->getLocation(), 11730 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11731 << D; 11732 continue; 11733 } 11734 11735 Type = Type.getUnqualifiedType(); 11736 VarDecl *VDPrivate = 11737 buildVarDecl(*this, ELoc, Type, D->getName(), 11738 D->hasAttrs() ? &D->getAttrs() : nullptr, 11739 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11740 // Generate helper private variable and initialize it with the value of the 11741 // original variable. The address of the original variable is replaced by 11742 // the address of the new private variable in the CodeGen. This new variable 11743 // is not added to IdResolver, so the code in the OpenMP region uses 11744 // original variable for proper diagnostics and variable capturing. 11745 Expr *VDInitRefExpr = nullptr; 11746 // For arrays generate initializer for single element and replace it by the 11747 // original array element in CodeGen. 11748 if (Type->isArrayType()) { 11749 VarDecl *VDInit = 11750 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11751 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11752 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11753 ElemType = ElemType.getUnqualifiedType(); 11754 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11755 ".firstprivate.temp"); 11756 InitializedEntity Entity = 11757 InitializedEntity::InitializeVariable(VDInitTemp); 11758 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11759 11760 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11761 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11762 if (Result.isInvalid()) 11763 VDPrivate->setInvalidDecl(); 11764 else 11765 VDPrivate->setInit(Result.getAs<Expr>()); 11766 // Remove temp variable declaration. 11767 Context.Deallocate(VDInitTemp); 11768 } else { 11769 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11770 ".firstprivate.temp"); 11771 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11772 RefExpr->getExprLoc()); 11773 AddInitializerToDecl(VDPrivate, 11774 DefaultLvalueConversion(VDInitRefExpr).get(), 11775 /*DirectInit=*/false); 11776 } 11777 if (VDPrivate->isInvalidDecl()) { 11778 if (IsImplicitClause) { 11779 Diag(RefExpr->getExprLoc(), 11780 diag::note_omp_task_predetermined_firstprivate_here); 11781 } 11782 continue; 11783 } 11784 CurContext->addDecl(VDPrivate); 11785 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11786 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 11787 RefExpr->getExprLoc()); 11788 DeclRefExpr *Ref = nullptr; 11789 if (!VD && !CurContext->isDependentContext()) { 11790 if (TopDVar.CKind == OMPC_lastprivate) { 11791 Ref = TopDVar.PrivateCopy; 11792 } else { 11793 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11794 if (!isOpenMPCapturedDecl(D)) 11795 ExprCaptures.push_back(Ref->getDecl()); 11796 } 11797 } 11798 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11799 Vars.push_back((VD || CurContext->isDependentContext()) 11800 ? RefExpr->IgnoreParens() 11801 : Ref); 11802 PrivateCopies.push_back(VDPrivateRefExpr); 11803 Inits.push_back(VDInitRefExpr); 11804 } 11805 11806 if (Vars.empty()) 11807 return nullptr; 11808 11809 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11810 Vars, PrivateCopies, Inits, 11811 buildPreInits(Context, ExprCaptures)); 11812 } 11813 11814 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11815 SourceLocation StartLoc, 11816 SourceLocation LParenLoc, 11817 SourceLocation EndLoc) { 11818 SmallVector<Expr *, 8> Vars; 11819 SmallVector<Expr *, 8> SrcExprs; 11820 SmallVector<Expr *, 8> DstExprs; 11821 SmallVector<Expr *, 8> AssignmentOps; 11822 SmallVector<Decl *, 4> ExprCaptures; 11823 SmallVector<Expr *, 4> ExprPostUpdates; 11824 for (Expr *RefExpr : VarList) { 11825 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11826 SourceLocation ELoc; 11827 SourceRange ERange; 11828 Expr *SimpleRefExpr = RefExpr; 11829 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11830 if (Res.second) { 11831 // It will be analyzed later. 11832 Vars.push_back(RefExpr); 11833 SrcExprs.push_back(nullptr); 11834 DstExprs.push_back(nullptr); 11835 AssignmentOps.push_back(nullptr); 11836 } 11837 ValueDecl *D = Res.first; 11838 if (!D) 11839 continue; 11840 11841 QualType Type = D->getType(); 11842 auto *VD = dyn_cast<VarDecl>(D); 11843 11844 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11845 // A variable that appears in a lastprivate clause must not have an 11846 // incomplete type or a reference type. 11847 if (RequireCompleteType(ELoc, Type, 11848 diag::err_omp_lastprivate_incomplete_type)) 11849 continue; 11850 Type = Type.getNonReferenceType(); 11851 11852 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11853 // A variable that is privatized must not have a const-qualified type 11854 // unless it is of class type with a mutable member. This restriction does 11855 // not apply to the firstprivate clause. 11856 // 11857 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11858 // A variable that appears in a lastprivate clause must not have a 11859 // const-qualified type unless it is of class type with a mutable member. 11860 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11861 continue; 11862 11863 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11864 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11865 // in a Construct] 11866 // Variables with the predetermined data-sharing attributes may not be 11867 // listed in data-sharing attributes clauses, except for the cases 11868 // listed below. 11869 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11870 // A list item may appear in a firstprivate or lastprivate clause but not 11871 // both. 11872 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11873 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11874 (isOpenMPDistributeDirective(CurrDir) || 11875 DVar.CKind != OMPC_firstprivate) && 11876 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11877 Diag(ELoc, diag::err_omp_wrong_dsa) 11878 << getOpenMPClauseName(DVar.CKind) 11879 << getOpenMPClauseName(OMPC_lastprivate); 11880 reportOriginalDsa(*this, DSAStack, D, DVar); 11881 continue; 11882 } 11883 11884 // OpenMP [2.14.3.5, Restrictions, p.2] 11885 // A list item that is private within a parallel region, or that appears in 11886 // the reduction clause of a parallel construct, must not appear in a 11887 // lastprivate clause on a worksharing construct if any of the corresponding 11888 // worksharing regions ever binds to any of the corresponding parallel 11889 // regions. 11890 DSAStackTy::DSAVarData TopDVar = DVar; 11891 if (isOpenMPWorksharingDirective(CurrDir) && 11892 !isOpenMPParallelDirective(CurrDir) && 11893 !isOpenMPTeamsDirective(CurrDir)) { 11894 DVar = DSAStack->getImplicitDSA(D, true); 11895 if (DVar.CKind != OMPC_shared) { 11896 Diag(ELoc, diag::err_omp_required_access) 11897 << getOpenMPClauseName(OMPC_lastprivate) 11898 << getOpenMPClauseName(OMPC_shared); 11899 reportOriginalDsa(*this, DSAStack, D, DVar); 11900 continue; 11901 } 11902 } 11903 11904 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11905 // A variable of class type (or array thereof) that appears in a 11906 // lastprivate clause requires an accessible, unambiguous default 11907 // constructor for the class type, unless the list item is also specified 11908 // in a firstprivate clause. 11909 // A variable of class type (or array thereof) that appears in a 11910 // lastprivate clause requires an accessible, unambiguous copy assignment 11911 // operator for the class type. 11912 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11913 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11914 Type.getUnqualifiedType(), ".lastprivate.src", 11915 D->hasAttrs() ? &D->getAttrs() : nullptr); 11916 DeclRefExpr *PseudoSrcExpr = 11917 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11918 VarDecl *DstVD = 11919 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11920 D->hasAttrs() ? &D->getAttrs() : nullptr); 11921 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11922 // For arrays generate assignment operation for single element and replace 11923 // it by the original array element in CodeGen. 11924 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11925 PseudoDstExpr, PseudoSrcExpr); 11926 if (AssignmentOp.isInvalid()) 11927 continue; 11928 AssignmentOp = 11929 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11930 if (AssignmentOp.isInvalid()) 11931 continue; 11932 11933 DeclRefExpr *Ref = nullptr; 11934 if (!VD && !CurContext->isDependentContext()) { 11935 if (TopDVar.CKind == OMPC_firstprivate) { 11936 Ref = TopDVar.PrivateCopy; 11937 } else { 11938 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11939 if (!isOpenMPCapturedDecl(D)) 11940 ExprCaptures.push_back(Ref->getDecl()); 11941 } 11942 if (TopDVar.CKind == OMPC_firstprivate || 11943 (!isOpenMPCapturedDecl(D) && 11944 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11945 ExprResult RefRes = DefaultLvalueConversion(Ref); 11946 if (!RefRes.isUsable()) 11947 continue; 11948 ExprResult PostUpdateRes = 11949 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11950 RefRes.get()); 11951 if (!PostUpdateRes.isUsable()) 11952 continue; 11953 ExprPostUpdates.push_back( 11954 IgnoredValueConversions(PostUpdateRes.get()).get()); 11955 } 11956 } 11957 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11958 Vars.push_back((VD || CurContext->isDependentContext()) 11959 ? RefExpr->IgnoreParens() 11960 : Ref); 11961 SrcExprs.push_back(PseudoSrcExpr); 11962 DstExprs.push_back(PseudoDstExpr); 11963 AssignmentOps.push_back(AssignmentOp.get()); 11964 } 11965 11966 if (Vars.empty()) 11967 return nullptr; 11968 11969 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11970 Vars, SrcExprs, DstExprs, AssignmentOps, 11971 buildPreInits(Context, ExprCaptures), 11972 buildPostUpdate(*this, ExprPostUpdates)); 11973 } 11974 11975 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11976 SourceLocation StartLoc, 11977 SourceLocation LParenLoc, 11978 SourceLocation EndLoc) { 11979 SmallVector<Expr *, 8> Vars; 11980 for (Expr *RefExpr : VarList) { 11981 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11982 SourceLocation ELoc; 11983 SourceRange ERange; 11984 Expr *SimpleRefExpr = RefExpr; 11985 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11986 if (Res.second) { 11987 // It will be analyzed later. 11988 Vars.push_back(RefExpr); 11989 } 11990 ValueDecl *D = Res.first; 11991 if (!D) 11992 continue; 11993 11994 auto *VD = dyn_cast<VarDecl>(D); 11995 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11996 // in a Construct] 11997 // Variables with the predetermined data-sharing attributes may not be 11998 // listed in data-sharing attributes clauses, except for the cases 11999 // listed below. For these exceptions only, listing a predetermined 12000 // variable in a data-sharing attribute clause is allowed and overrides 12001 // the variable's predetermined data-sharing attributes. 12002 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12003 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12004 DVar.RefExpr) { 12005 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12006 << getOpenMPClauseName(OMPC_shared); 12007 reportOriginalDsa(*this, DSAStack, D, DVar); 12008 continue; 12009 } 12010 12011 DeclRefExpr *Ref = nullptr; 12012 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12013 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12014 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12015 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12016 ? RefExpr->IgnoreParens() 12017 : Ref); 12018 } 12019 12020 if (Vars.empty()) 12021 return nullptr; 12022 12023 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12024 } 12025 12026 namespace { 12027 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12028 DSAStackTy *Stack; 12029 12030 public: 12031 bool VisitDeclRefExpr(DeclRefExpr *E) { 12032 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12033 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12034 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12035 return false; 12036 if (DVar.CKind != OMPC_unknown) 12037 return true; 12038 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12039 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12040 /*FromParent=*/true); 12041 return DVarPrivate.CKind != OMPC_unknown; 12042 } 12043 return false; 12044 } 12045 bool VisitStmt(Stmt *S) { 12046 for (Stmt *Child : S->children()) { 12047 if (Child && Visit(Child)) 12048 return true; 12049 } 12050 return false; 12051 } 12052 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12053 }; 12054 } // namespace 12055 12056 namespace { 12057 // Transform MemberExpression for specified FieldDecl of current class to 12058 // DeclRefExpr to specified OMPCapturedExprDecl. 12059 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12060 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12061 ValueDecl *Field = nullptr; 12062 DeclRefExpr *CapturedExpr = nullptr; 12063 12064 public: 12065 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12066 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12067 12068 ExprResult TransformMemberExpr(MemberExpr *E) { 12069 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12070 E->getMemberDecl() == Field) { 12071 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12072 return CapturedExpr; 12073 } 12074 return BaseTransform::TransformMemberExpr(E); 12075 } 12076 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12077 }; 12078 } // namespace 12079 12080 template <typename T, typename U> 12081 static T filterLookupForUDReductionAndMapper( 12082 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12083 for (U &Set : Lookups) { 12084 for (auto *D : Set) { 12085 if (T Res = Gen(cast<ValueDecl>(D))) 12086 return Res; 12087 } 12088 } 12089 return T(); 12090 } 12091 12092 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12093 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12094 12095 for (auto RD : D->redecls()) { 12096 // Don't bother with extra checks if we already know this one isn't visible. 12097 if (RD == D) 12098 continue; 12099 12100 auto ND = cast<NamedDecl>(RD); 12101 if (LookupResult::isVisible(SemaRef, ND)) 12102 return ND; 12103 } 12104 12105 return nullptr; 12106 } 12107 12108 static void 12109 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12110 SourceLocation Loc, QualType Ty, 12111 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12112 // Find all of the associated namespaces and classes based on the 12113 // arguments we have. 12114 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12115 Sema::AssociatedClassSet AssociatedClasses; 12116 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12117 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12118 AssociatedClasses); 12119 12120 // C++ [basic.lookup.argdep]p3: 12121 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12122 // and let Y be the lookup set produced by argument dependent 12123 // lookup (defined as follows). If X contains [...] then Y is 12124 // empty. Otherwise Y is the set of declarations found in the 12125 // namespaces associated with the argument types as described 12126 // below. The set of declarations found by the lookup of the name 12127 // is the union of X and Y. 12128 // 12129 // Here, we compute Y and add its members to the overloaded 12130 // candidate set. 12131 for (auto *NS : AssociatedNamespaces) { 12132 // When considering an associated namespace, the lookup is the 12133 // same as the lookup performed when the associated namespace is 12134 // used as a qualifier (3.4.3.2) except that: 12135 // 12136 // -- Any using-directives in the associated namespace are 12137 // ignored. 12138 // 12139 // -- Any namespace-scope friend functions declared in 12140 // associated classes are visible within their respective 12141 // namespaces even if they are not visible during an ordinary 12142 // lookup (11.4). 12143 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12144 for (auto *D : R) { 12145 auto *Underlying = D; 12146 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12147 Underlying = USD->getTargetDecl(); 12148 12149 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12150 !isa<OMPDeclareMapperDecl>(Underlying)) 12151 continue; 12152 12153 if (!SemaRef.isVisible(D)) { 12154 D = findAcceptableDecl(SemaRef, D); 12155 if (!D) 12156 continue; 12157 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12158 Underlying = USD->getTargetDecl(); 12159 } 12160 Lookups.emplace_back(); 12161 Lookups.back().addDecl(Underlying); 12162 } 12163 } 12164 } 12165 12166 static ExprResult 12167 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12168 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12169 const DeclarationNameInfo &ReductionId, QualType Ty, 12170 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12171 if (ReductionIdScopeSpec.isInvalid()) 12172 return ExprError(); 12173 SmallVector<UnresolvedSet<8>, 4> Lookups; 12174 if (S) { 12175 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12176 Lookup.suppressDiagnostics(); 12177 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12178 NamedDecl *D = Lookup.getRepresentativeDecl(); 12179 do { 12180 S = S->getParent(); 12181 } while (S && !S->isDeclScope(D)); 12182 if (S) 12183 S = S->getParent(); 12184 Lookups.emplace_back(); 12185 Lookups.back().append(Lookup.begin(), Lookup.end()); 12186 Lookup.clear(); 12187 } 12188 } else if (auto *ULE = 12189 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12190 Lookups.push_back(UnresolvedSet<8>()); 12191 Decl *PrevD = nullptr; 12192 for (NamedDecl *D : ULE->decls()) { 12193 if (D == PrevD) 12194 Lookups.push_back(UnresolvedSet<8>()); 12195 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12196 Lookups.back().addDecl(DRD); 12197 PrevD = D; 12198 } 12199 } 12200 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12201 Ty->isInstantiationDependentType() || 12202 Ty->containsUnexpandedParameterPack() || 12203 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12204 return !D->isInvalidDecl() && 12205 (D->getType()->isDependentType() || 12206 D->getType()->isInstantiationDependentType() || 12207 D->getType()->containsUnexpandedParameterPack()); 12208 })) { 12209 UnresolvedSet<8> ResSet; 12210 for (const UnresolvedSet<8> &Set : Lookups) { 12211 if (Set.empty()) 12212 continue; 12213 ResSet.append(Set.begin(), Set.end()); 12214 // The last item marks the end of all declarations at the specified scope. 12215 ResSet.addDecl(Set[Set.size() - 1]); 12216 } 12217 return UnresolvedLookupExpr::Create( 12218 SemaRef.Context, /*NamingClass=*/nullptr, 12219 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12220 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12221 } 12222 // Lookup inside the classes. 12223 // C++ [over.match.oper]p3: 12224 // For a unary operator @ with an operand of a type whose 12225 // cv-unqualified version is T1, and for a binary operator @ with 12226 // a left operand of a type whose cv-unqualified version is T1 and 12227 // a right operand of a type whose cv-unqualified version is T2, 12228 // three sets of candidate functions, designated member 12229 // candidates, non-member candidates and built-in candidates, are 12230 // constructed as follows: 12231 // -- If T1 is a complete class type or a class currently being 12232 // defined, the set of member candidates is the result of the 12233 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12234 // the set of member candidates is empty. 12235 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12236 Lookup.suppressDiagnostics(); 12237 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12238 // Complete the type if it can be completed. 12239 // If the type is neither complete nor being defined, bail out now. 12240 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12241 TyRec->getDecl()->getDefinition()) { 12242 Lookup.clear(); 12243 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12244 if (Lookup.empty()) { 12245 Lookups.emplace_back(); 12246 Lookups.back().append(Lookup.begin(), Lookup.end()); 12247 } 12248 } 12249 } 12250 // Perform ADL. 12251 if (SemaRef.getLangOpts().CPlusPlus) 12252 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12253 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12254 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12255 if (!D->isInvalidDecl() && 12256 SemaRef.Context.hasSameType(D->getType(), Ty)) 12257 return D; 12258 return nullptr; 12259 })) 12260 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12261 VK_LValue, Loc); 12262 if (SemaRef.getLangOpts().CPlusPlus) { 12263 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12264 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12265 if (!D->isInvalidDecl() && 12266 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12267 !Ty.isMoreQualifiedThan(D->getType())) 12268 return D; 12269 return nullptr; 12270 })) { 12271 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12272 /*DetectVirtual=*/false); 12273 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12274 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12275 VD->getType().getUnqualifiedType()))) { 12276 if (SemaRef.CheckBaseClassAccess( 12277 Loc, VD->getType(), Ty, Paths.front(), 12278 /*DiagID=*/0) != Sema::AR_inaccessible) { 12279 SemaRef.BuildBasePathArray(Paths, BasePath); 12280 return SemaRef.BuildDeclRefExpr( 12281 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12282 } 12283 } 12284 } 12285 } 12286 } 12287 if (ReductionIdScopeSpec.isSet()) { 12288 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12289 return ExprError(); 12290 } 12291 return ExprEmpty(); 12292 } 12293 12294 namespace { 12295 /// Data for the reduction-based clauses. 12296 struct ReductionData { 12297 /// List of original reduction items. 12298 SmallVector<Expr *, 8> Vars; 12299 /// List of private copies of the reduction items. 12300 SmallVector<Expr *, 8> Privates; 12301 /// LHS expressions for the reduction_op expressions. 12302 SmallVector<Expr *, 8> LHSs; 12303 /// RHS expressions for the reduction_op expressions. 12304 SmallVector<Expr *, 8> RHSs; 12305 /// Reduction operation expression. 12306 SmallVector<Expr *, 8> ReductionOps; 12307 /// Taskgroup descriptors for the corresponding reduction items in 12308 /// in_reduction clauses. 12309 SmallVector<Expr *, 8> TaskgroupDescriptors; 12310 /// List of captures for clause. 12311 SmallVector<Decl *, 4> ExprCaptures; 12312 /// List of postupdate expressions. 12313 SmallVector<Expr *, 4> ExprPostUpdates; 12314 ReductionData() = delete; 12315 /// Reserves required memory for the reduction data. 12316 ReductionData(unsigned Size) { 12317 Vars.reserve(Size); 12318 Privates.reserve(Size); 12319 LHSs.reserve(Size); 12320 RHSs.reserve(Size); 12321 ReductionOps.reserve(Size); 12322 TaskgroupDescriptors.reserve(Size); 12323 ExprCaptures.reserve(Size); 12324 ExprPostUpdates.reserve(Size); 12325 } 12326 /// Stores reduction item and reduction operation only (required for dependent 12327 /// reduction item). 12328 void push(Expr *Item, Expr *ReductionOp) { 12329 Vars.emplace_back(Item); 12330 Privates.emplace_back(nullptr); 12331 LHSs.emplace_back(nullptr); 12332 RHSs.emplace_back(nullptr); 12333 ReductionOps.emplace_back(ReductionOp); 12334 TaskgroupDescriptors.emplace_back(nullptr); 12335 } 12336 /// Stores reduction data. 12337 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12338 Expr *TaskgroupDescriptor) { 12339 Vars.emplace_back(Item); 12340 Privates.emplace_back(Private); 12341 LHSs.emplace_back(LHS); 12342 RHSs.emplace_back(RHS); 12343 ReductionOps.emplace_back(ReductionOp); 12344 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12345 } 12346 }; 12347 } // namespace 12348 12349 static bool checkOMPArraySectionConstantForReduction( 12350 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12351 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12352 const Expr *Length = OASE->getLength(); 12353 if (Length == nullptr) { 12354 // For array sections of the form [1:] or [:], we would need to analyze 12355 // the lower bound... 12356 if (OASE->getColonLoc().isValid()) 12357 return false; 12358 12359 // This is an array subscript which has implicit length 1! 12360 SingleElement = true; 12361 ArraySizes.push_back(llvm::APSInt::get(1)); 12362 } else { 12363 Expr::EvalResult Result; 12364 if (!Length->EvaluateAsInt(Result, Context)) 12365 return false; 12366 12367 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12368 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12369 ArraySizes.push_back(ConstantLengthValue); 12370 } 12371 12372 // Get the base of this array section and walk up from there. 12373 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12374 12375 // We require length = 1 for all array sections except the right-most to 12376 // guarantee that the memory region is contiguous and has no holes in it. 12377 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12378 Length = TempOASE->getLength(); 12379 if (Length == nullptr) { 12380 // For array sections of the form [1:] or [:], we would need to analyze 12381 // the lower bound... 12382 if (OASE->getColonLoc().isValid()) 12383 return false; 12384 12385 // This is an array subscript which has implicit length 1! 12386 ArraySizes.push_back(llvm::APSInt::get(1)); 12387 } else { 12388 Expr::EvalResult Result; 12389 if (!Length->EvaluateAsInt(Result, Context)) 12390 return false; 12391 12392 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12393 if (ConstantLengthValue.getSExtValue() != 1) 12394 return false; 12395 12396 ArraySizes.push_back(ConstantLengthValue); 12397 } 12398 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12399 } 12400 12401 // If we have a single element, we don't need to add the implicit lengths. 12402 if (!SingleElement) { 12403 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12404 // Has implicit length 1! 12405 ArraySizes.push_back(llvm::APSInt::get(1)); 12406 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12407 } 12408 } 12409 12410 // This array section can be privatized as a single value or as a constant 12411 // sized array. 12412 return true; 12413 } 12414 12415 static bool actOnOMPReductionKindClause( 12416 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12417 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12418 SourceLocation ColonLoc, SourceLocation EndLoc, 12419 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12420 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12421 DeclarationName DN = ReductionId.getName(); 12422 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12423 BinaryOperatorKind BOK = BO_Comma; 12424 12425 ASTContext &Context = S.Context; 12426 // OpenMP [2.14.3.6, reduction clause] 12427 // C 12428 // reduction-identifier is either an identifier or one of the following 12429 // operators: +, -, *, &, |, ^, && and || 12430 // C++ 12431 // reduction-identifier is either an id-expression or one of the following 12432 // operators: +, -, *, &, |, ^, && and || 12433 switch (OOK) { 12434 case OO_Plus: 12435 case OO_Minus: 12436 BOK = BO_Add; 12437 break; 12438 case OO_Star: 12439 BOK = BO_Mul; 12440 break; 12441 case OO_Amp: 12442 BOK = BO_And; 12443 break; 12444 case OO_Pipe: 12445 BOK = BO_Or; 12446 break; 12447 case OO_Caret: 12448 BOK = BO_Xor; 12449 break; 12450 case OO_AmpAmp: 12451 BOK = BO_LAnd; 12452 break; 12453 case OO_PipePipe: 12454 BOK = BO_LOr; 12455 break; 12456 case OO_New: 12457 case OO_Delete: 12458 case OO_Array_New: 12459 case OO_Array_Delete: 12460 case OO_Slash: 12461 case OO_Percent: 12462 case OO_Tilde: 12463 case OO_Exclaim: 12464 case OO_Equal: 12465 case OO_Less: 12466 case OO_Greater: 12467 case OO_LessEqual: 12468 case OO_GreaterEqual: 12469 case OO_PlusEqual: 12470 case OO_MinusEqual: 12471 case OO_StarEqual: 12472 case OO_SlashEqual: 12473 case OO_PercentEqual: 12474 case OO_CaretEqual: 12475 case OO_AmpEqual: 12476 case OO_PipeEqual: 12477 case OO_LessLess: 12478 case OO_GreaterGreater: 12479 case OO_LessLessEqual: 12480 case OO_GreaterGreaterEqual: 12481 case OO_EqualEqual: 12482 case OO_ExclaimEqual: 12483 case OO_Spaceship: 12484 case OO_PlusPlus: 12485 case OO_MinusMinus: 12486 case OO_Comma: 12487 case OO_ArrowStar: 12488 case OO_Arrow: 12489 case OO_Call: 12490 case OO_Subscript: 12491 case OO_Conditional: 12492 case OO_Coawait: 12493 case NUM_OVERLOADED_OPERATORS: 12494 llvm_unreachable("Unexpected reduction identifier"); 12495 case OO_None: 12496 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 12497 if (II->isStr("max")) 12498 BOK = BO_GT; 12499 else if (II->isStr("min")) 12500 BOK = BO_LT; 12501 } 12502 break; 12503 } 12504 SourceRange ReductionIdRange; 12505 if (ReductionIdScopeSpec.isValid()) 12506 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 12507 else 12508 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 12509 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 12510 12511 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 12512 bool FirstIter = true; 12513 for (Expr *RefExpr : VarList) { 12514 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 12515 // OpenMP [2.1, C/C++] 12516 // A list item is a variable or array section, subject to the restrictions 12517 // specified in Section 2.4 on page 42 and in each of the sections 12518 // describing clauses and directives for which a list appears. 12519 // OpenMP [2.14.3.3, Restrictions, p.1] 12520 // A variable that is part of another variable (as an array or 12521 // structure element) cannot appear in a private clause. 12522 if (!FirstIter && IR != ER) 12523 ++IR; 12524 FirstIter = false; 12525 SourceLocation ELoc; 12526 SourceRange ERange; 12527 Expr *SimpleRefExpr = RefExpr; 12528 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 12529 /*AllowArraySection=*/true); 12530 if (Res.second) { 12531 // Try to find 'declare reduction' corresponding construct before using 12532 // builtin/overloaded operators. 12533 QualType Type = Context.DependentTy; 12534 CXXCastPath BasePath; 12535 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12536 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12537 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12538 Expr *ReductionOp = nullptr; 12539 if (S.CurContext->isDependentContext() && 12540 (DeclareReductionRef.isUnset() || 12541 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 12542 ReductionOp = DeclareReductionRef.get(); 12543 // It will be analyzed later. 12544 RD.push(RefExpr, ReductionOp); 12545 } 12546 ValueDecl *D = Res.first; 12547 if (!D) 12548 continue; 12549 12550 Expr *TaskgroupDescriptor = nullptr; 12551 QualType Type; 12552 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 12553 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 12554 if (ASE) { 12555 Type = ASE->getType().getNonReferenceType(); 12556 } else if (OASE) { 12557 QualType BaseType = 12558 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 12559 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 12560 Type = ATy->getElementType(); 12561 else 12562 Type = BaseType->getPointeeType(); 12563 Type = Type.getNonReferenceType(); 12564 } else { 12565 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 12566 } 12567 auto *VD = dyn_cast<VarDecl>(D); 12568 12569 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12570 // A variable that appears in a private clause must not have an incomplete 12571 // type or a reference type. 12572 if (S.RequireCompleteType(ELoc, D->getType(), 12573 diag::err_omp_reduction_incomplete_type)) 12574 continue; 12575 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12576 // A list item that appears in a reduction clause must not be 12577 // const-qualified. 12578 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 12579 /*AcceptIfMutable*/ false, ASE || OASE)) 12580 continue; 12581 12582 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 12583 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 12584 // If a list-item is a reference type then it must bind to the same object 12585 // for all threads of the team. 12586 if (!ASE && !OASE) { 12587 if (VD) { 12588 VarDecl *VDDef = VD->getDefinition(); 12589 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 12590 DSARefChecker Check(Stack); 12591 if (Check.Visit(VDDef->getInit())) { 12592 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 12593 << getOpenMPClauseName(ClauseKind) << ERange; 12594 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 12595 continue; 12596 } 12597 } 12598 } 12599 12600 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12601 // in a Construct] 12602 // Variables with the predetermined data-sharing attributes may not be 12603 // listed in data-sharing attributes clauses, except for the cases 12604 // listed below. For these exceptions only, listing a predetermined 12605 // variable in a data-sharing attribute clause is allowed and overrides 12606 // the variable's predetermined data-sharing attributes. 12607 // OpenMP [2.14.3.6, Restrictions, p.3] 12608 // Any number of reduction clauses can be specified on the directive, 12609 // but a list item can appear only once in the reduction clauses for that 12610 // directive. 12611 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 12612 if (DVar.CKind == OMPC_reduction) { 12613 S.Diag(ELoc, diag::err_omp_once_referenced) 12614 << getOpenMPClauseName(ClauseKind); 12615 if (DVar.RefExpr) 12616 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12617 continue; 12618 } 12619 if (DVar.CKind != OMPC_unknown) { 12620 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12621 << getOpenMPClauseName(DVar.CKind) 12622 << getOpenMPClauseName(OMPC_reduction); 12623 reportOriginalDsa(S, Stack, D, DVar); 12624 continue; 12625 } 12626 12627 // OpenMP [2.14.3.6, Restrictions, p.1] 12628 // A list item that appears in a reduction clause of a worksharing 12629 // construct must be shared in the parallel regions to which any of the 12630 // worksharing regions arising from the worksharing construct bind. 12631 if (isOpenMPWorksharingDirective(CurrDir) && 12632 !isOpenMPParallelDirective(CurrDir) && 12633 !isOpenMPTeamsDirective(CurrDir)) { 12634 DVar = Stack->getImplicitDSA(D, true); 12635 if (DVar.CKind != OMPC_shared) { 12636 S.Diag(ELoc, diag::err_omp_required_access) 12637 << getOpenMPClauseName(OMPC_reduction) 12638 << getOpenMPClauseName(OMPC_shared); 12639 reportOriginalDsa(S, Stack, D, DVar); 12640 continue; 12641 } 12642 } 12643 } 12644 12645 // Try to find 'declare reduction' corresponding construct before using 12646 // builtin/overloaded operators. 12647 CXXCastPath BasePath; 12648 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12649 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12650 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12651 if (DeclareReductionRef.isInvalid()) 12652 continue; 12653 if (S.CurContext->isDependentContext() && 12654 (DeclareReductionRef.isUnset() || 12655 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12656 RD.push(RefExpr, DeclareReductionRef.get()); 12657 continue; 12658 } 12659 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12660 // Not allowed reduction identifier is found. 12661 S.Diag(ReductionId.getBeginLoc(), 12662 diag::err_omp_unknown_reduction_identifier) 12663 << Type << ReductionIdRange; 12664 continue; 12665 } 12666 12667 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12668 // The type of a list item that appears in a reduction clause must be valid 12669 // for the reduction-identifier. For a max or min reduction in C, the type 12670 // of the list item must be an allowed arithmetic data type: char, int, 12671 // float, double, or _Bool, possibly modified with long, short, signed, or 12672 // unsigned. For a max or min reduction in C++, the type of the list item 12673 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12674 // double, or bool, possibly modified with long, short, signed, or unsigned. 12675 if (DeclareReductionRef.isUnset()) { 12676 if ((BOK == BO_GT || BOK == BO_LT) && 12677 !(Type->isScalarType() || 12678 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12679 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12680 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12681 if (!ASE && !OASE) { 12682 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12683 VarDecl::DeclarationOnly; 12684 S.Diag(D->getLocation(), 12685 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12686 << D; 12687 } 12688 continue; 12689 } 12690 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12691 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12692 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12693 << getOpenMPClauseName(ClauseKind); 12694 if (!ASE && !OASE) { 12695 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12696 VarDecl::DeclarationOnly; 12697 S.Diag(D->getLocation(), 12698 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12699 << D; 12700 } 12701 continue; 12702 } 12703 } 12704 12705 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12706 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12707 D->hasAttrs() ? &D->getAttrs() : nullptr); 12708 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12709 D->hasAttrs() ? &D->getAttrs() : nullptr); 12710 QualType PrivateTy = Type; 12711 12712 // Try if we can determine constant lengths for all array sections and avoid 12713 // the VLA. 12714 bool ConstantLengthOASE = false; 12715 if (OASE) { 12716 bool SingleElement; 12717 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12718 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12719 Context, OASE, SingleElement, ArraySizes); 12720 12721 // If we don't have a single element, we must emit a constant array type. 12722 if (ConstantLengthOASE && !SingleElement) { 12723 for (llvm::APSInt &Size : ArraySizes) 12724 PrivateTy = Context.getConstantArrayType( 12725 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12726 } 12727 } 12728 12729 if ((OASE && !ConstantLengthOASE) || 12730 (!OASE && !ASE && 12731 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12732 if (!Context.getTargetInfo().isVLASupported()) { 12733 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 12734 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12735 S.Diag(ELoc, diag::note_vla_unsupported); 12736 } else { 12737 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12738 S.targetDiag(ELoc, diag::note_vla_unsupported); 12739 } 12740 continue; 12741 } 12742 // For arrays/array sections only: 12743 // Create pseudo array type for private copy. The size for this array will 12744 // be generated during codegen. 12745 // For array subscripts or single variables Private Ty is the same as Type 12746 // (type of the variable or single array element). 12747 PrivateTy = Context.getVariableArrayType( 12748 Type, 12749 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12750 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12751 } else if (!ASE && !OASE && 12752 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12753 PrivateTy = D->getType().getNonReferenceType(); 12754 } 12755 // Private copy. 12756 VarDecl *PrivateVD = 12757 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12758 D->hasAttrs() ? &D->getAttrs() : nullptr, 12759 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12760 // Add initializer for private variable. 12761 Expr *Init = nullptr; 12762 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12763 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12764 if (DeclareReductionRef.isUsable()) { 12765 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12766 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12767 if (DRD->getInitializer()) { 12768 Init = DRDRef; 12769 RHSVD->setInit(DRDRef); 12770 RHSVD->setInitStyle(VarDecl::CallInit); 12771 } 12772 } else { 12773 switch (BOK) { 12774 case BO_Add: 12775 case BO_Xor: 12776 case BO_Or: 12777 case BO_LOr: 12778 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12779 if (Type->isScalarType() || Type->isAnyComplexType()) 12780 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 12781 break; 12782 case BO_Mul: 12783 case BO_LAnd: 12784 if (Type->isScalarType() || Type->isAnyComplexType()) { 12785 // '*' and '&&' reduction ops - initializer is '1'. 12786 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 12787 } 12788 break; 12789 case BO_And: { 12790 // '&' reduction op - initializer is '~0'. 12791 QualType OrigType = Type; 12792 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 12793 Type = ComplexTy->getElementType(); 12794 if (Type->isRealFloatingType()) { 12795 llvm::APFloat InitValue = 12796 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 12797 /*isIEEE=*/true); 12798 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12799 Type, ELoc); 12800 } else if (Type->isScalarType()) { 12801 uint64_t Size = Context.getTypeSize(Type); 12802 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 12803 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 12804 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12805 } 12806 if (Init && OrigType->isAnyComplexType()) { 12807 // Init = 0xFFFF + 0xFFFFi; 12808 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 12809 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 12810 } 12811 Type = OrigType; 12812 break; 12813 } 12814 case BO_LT: 12815 case BO_GT: { 12816 // 'min' reduction op - initializer is 'Largest representable number in 12817 // the reduction list item type'. 12818 // 'max' reduction op - initializer is 'Least representable number in 12819 // the reduction list item type'. 12820 if (Type->isIntegerType() || Type->isPointerType()) { 12821 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12822 uint64_t Size = Context.getTypeSize(Type); 12823 QualType IntTy = 12824 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12825 llvm::APInt InitValue = 12826 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12827 : llvm::APInt::getMinValue(Size) 12828 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12829 : llvm::APInt::getMaxValue(Size); 12830 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12831 if (Type->isPointerType()) { 12832 // Cast to pointer type. 12833 ExprResult CastExpr = S.BuildCStyleCastExpr( 12834 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12835 if (CastExpr.isInvalid()) 12836 continue; 12837 Init = CastExpr.get(); 12838 } 12839 } else if (Type->isRealFloatingType()) { 12840 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12841 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12842 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12843 Type, ELoc); 12844 } 12845 break; 12846 } 12847 case BO_PtrMemD: 12848 case BO_PtrMemI: 12849 case BO_MulAssign: 12850 case BO_Div: 12851 case BO_Rem: 12852 case BO_Sub: 12853 case BO_Shl: 12854 case BO_Shr: 12855 case BO_LE: 12856 case BO_GE: 12857 case BO_EQ: 12858 case BO_NE: 12859 case BO_Cmp: 12860 case BO_AndAssign: 12861 case BO_XorAssign: 12862 case BO_OrAssign: 12863 case BO_Assign: 12864 case BO_AddAssign: 12865 case BO_SubAssign: 12866 case BO_DivAssign: 12867 case BO_RemAssign: 12868 case BO_ShlAssign: 12869 case BO_ShrAssign: 12870 case BO_Comma: 12871 llvm_unreachable("Unexpected reduction operation"); 12872 } 12873 } 12874 if (Init && DeclareReductionRef.isUnset()) 12875 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12876 else if (!Init) 12877 S.ActOnUninitializedDecl(RHSVD); 12878 if (RHSVD->isInvalidDecl()) 12879 continue; 12880 if (!RHSVD->hasInit() && 12881 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12882 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12883 << Type << ReductionIdRange; 12884 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12885 VarDecl::DeclarationOnly; 12886 S.Diag(D->getLocation(), 12887 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12888 << D; 12889 continue; 12890 } 12891 // Store initializer for single element in private copy. Will be used during 12892 // codegen. 12893 PrivateVD->setInit(RHSVD->getInit()); 12894 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12895 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12896 ExprResult ReductionOp; 12897 if (DeclareReductionRef.isUsable()) { 12898 QualType RedTy = DeclareReductionRef.get()->getType(); 12899 QualType PtrRedTy = Context.getPointerType(RedTy); 12900 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12901 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12902 if (!BasePath.empty()) { 12903 LHS = S.DefaultLvalueConversion(LHS.get()); 12904 RHS = S.DefaultLvalueConversion(RHS.get()); 12905 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12906 CK_UncheckedDerivedToBase, LHS.get(), 12907 &BasePath, LHS.get()->getValueKind()); 12908 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12909 CK_UncheckedDerivedToBase, RHS.get(), 12910 &BasePath, RHS.get()->getValueKind()); 12911 } 12912 FunctionProtoType::ExtProtoInfo EPI; 12913 QualType Params[] = {PtrRedTy, PtrRedTy}; 12914 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12915 auto *OVE = new (Context) OpaqueValueExpr( 12916 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12917 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12918 Expr *Args[] = {LHS.get(), RHS.get()}; 12919 ReductionOp = 12920 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12921 } else { 12922 ReductionOp = S.BuildBinOp( 12923 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12924 if (ReductionOp.isUsable()) { 12925 if (BOK != BO_LT && BOK != BO_GT) { 12926 ReductionOp = 12927 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12928 BO_Assign, LHSDRE, ReductionOp.get()); 12929 } else { 12930 auto *ConditionalOp = new (Context) 12931 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12932 Type, VK_LValue, OK_Ordinary); 12933 ReductionOp = 12934 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12935 BO_Assign, LHSDRE, ConditionalOp); 12936 } 12937 if (ReductionOp.isUsable()) 12938 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12939 /*DiscardedValue*/ false); 12940 } 12941 if (!ReductionOp.isUsable()) 12942 continue; 12943 } 12944 12945 // OpenMP [2.15.4.6, Restrictions, p.2] 12946 // A list item that appears in an in_reduction clause of a task construct 12947 // must appear in a task_reduction clause of a construct associated with a 12948 // taskgroup region that includes the participating task in its taskgroup 12949 // set. The construct associated with the innermost region that meets this 12950 // condition must specify the same reduction-identifier as the in_reduction 12951 // clause. 12952 if (ClauseKind == OMPC_in_reduction) { 12953 SourceRange ParentSR; 12954 BinaryOperatorKind ParentBOK; 12955 const Expr *ParentReductionOp; 12956 Expr *ParentBOKTD, *ParentReductionOpTD; 12957 DSAStackTy::DSAVarData ParentBOKDSA = 12958 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12959 ParentBOKTD); 12960 DSAStackTy::DSAVarData ParentReductionOpDSA = 12961 Stack->getTopMostTaskgroupReductionData( 12962 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12963 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12964 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12965 if (!IsParentBOK && !IsParentReductionOp) { 12966 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12967 continue; 12968 } 12969 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12970 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12971 IsParentReductionOp) { 12972 bool EmitError = true; 12973 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12974 llvm::FoldingSetNodeID RedId, ParentRedId; 12975 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12976 DeclareReductionRef.get()->Profile(RedId, Context, 12977 /*Canonical=*/true); 12978 EmitError = RedId != ParentRedId; 12979 } 12980 if (EmitError) { 12981 S.Diag(ReductionId.getBeginLoc(), 12982 diag::err_omp_reduction_identifier_mismatch) 12983 << ReductionIdRange << RefExpr->getSourceRange(); 12984 S.Diag(ParentSR.getBegin(), 12985 diag::note_omp_previous_reduction_identifier) 12986 << ParentSR 12987 << (IsParentBOK ? ParentBOKDSA.RefExpr 12988 : ParentReductionOpDSA.RefExpr) 12989 ->getSourceRange(); 12990 continue; 12991 } 12992 } 12993 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 12994 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 12995 } 12996 12997 DeclRefExpr *Ref = nullptr; 12998 Expr *VarsExpr = RefExpr->IgnoreParens(); 12999 if (!VD && !S.CurContext->isDependentContext()) { 13000 if (ASE || OASE) { 13001 TransformExprToCaptures RebuildToCapture(S, D); 13002 VarsExpr = 13003 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13004 Ref = RebuildToCapture.getCapturedExpr(); 13005 } else { 13006 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13007 } 13008 if (!S.isOpenMPCapturedDecl(D)) { 13009 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13010 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13011 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13012 if (!RefRes.isUsable()) 13013 continue; 13014 ExprResult PostUpdateRes = 13015 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13016 RefRes.get()); 13017 if (!PostUpdateRes.isUsable()) 13018 continue; 13019 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13020 Stack->getCurrentDirective() == OMPD_taskgroup) { 13021 S.Diag(RefExpr->getExprLoc(), 13022 diag::err_omp_reduction_non_addressable_expression) 13023 << RefExpr->getSourceRange(); 13024 continue; 13025 } 13026 RD.ExprPostUpdates.emplace_back( 13027 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13028 } 13029 } 13030 } 13031 // All reduction items are still marked as reduction (to do not increase 13032 // code base size). 13033 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13034 if (CurrDir == OMPD_taskgroup) { 13035 if (DeclareReductionRef.isUsable()) 13036 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13037 DeclareReductionRef.get()); 13038 else 13039 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13040 } 13041 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13042 TaskgroupDescriptor); 13043 } 13044 return RD.Vars.empty(); 13045 } 13046 13047 OMPClause *Sema::ActOnOpenMPReductionClause( 13048 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13049 SourceLocation ColonLoc, SourceLocation EndLoc, 13050 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13051 ArrayRef<Expr *> UnresolvedReductions) { 13052 ReductionData RD(VarList.size()); 13053 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13054 StartLoc, LParenLoc, ColonLoc, EndLoc, 13055 ReductionIdScopeSpec, ReductionId, 13056 UnresolvedReductions, RD)) 13057 return nullptr; 13058 13059 return OMPReductionClause::Create( 13060 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13061 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13062 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13063 buildPreInits(Context, RD.ExprCaptures), 13064 buildPostUpdate(*this, RD.ExprPostUpdates)); 13065 } 13066 13067 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13068 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13069 SourceLocation ColonLoc, SourceLocation EndLoc, 13070 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13071 ArrayRef<Expr *> UnresolvedReductions) { 13072 ReductionData RD(VarList.size()); 13073 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13074 StartLoc, LParenLoc, ColonLoc, EndLoc, 13075 ReductionIdScopeSpec, ReductionId, 13076 UnresolvedReductions, RD)) 13077 return nullptr; 13078 13079 return OMPTaskReductionClause::Create( 13080 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13081 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13082 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13083 buildPreInits(Context, RD.ExprCaptures), 13084 buildPostUpdate(*this, RD.ExprPostUpdates)); 13085 } 13086 13087 OMPClause *Sema::ActOnOpenMPInReductionClause( 13088 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13089 SourceLocation ColonLoc, SourceLocation EndLoc, 13090 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13091 ArrayRef<Expr *> UnresolvedReductions) { 13092 ReductionData RD(VarList.size()); 13093 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13094 StartLoc, LParenLoc, ColonLoc, EndLoc, 13095 ReductionIdScopeSpec, ReductionId, 13096 UnresolvedReductions, RD)) 13097 return nullptr; 13098 13099 return OMPInReductionClause::Create( 13100 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13101 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13102 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13103 buildPreInits(Context, RD.ExprCaptures), 13104 buildPostUpdate(*this, RD.ExprPostUpdates)); 13105 } 13106 13107 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13108 SourceLocation LinLoc) { 13109 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13110 LinKind == OMPC_LINEAR_unknown) { 13111 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13112 return true; 13113 } 13114 return false; 13115 } 13116 13117 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13118 OpenMPLinearClauseKind LinKind, 13119 QualType Type) { 13120 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13121 // A variable must not have an incomplete type or a reference type. 13122 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13123 return true; 13124 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13125 !Type->isReferenceType()) { 13126 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13127 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13128 return true; 13129 } 13130 Type = Type.getNonReferenceType(); 13131 13132 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13133 // A variable that is privatized must not have a const-qualified type 13134 // unless it is of class type with a mutable member. This restriction does 13135 // not apply to the firstprivate clause. 13136 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13137 return true; 13138 13139 // A list item must be of integral or pointer type. 13140 Type = Type.getUnqualifiedType().getCanonicalType(); 13141 const auto *Ty = Type.getTypePtrOrNull(); 13142 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13143 !Ty->isPointerType())) { 13144 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13145 if (D) { 13146 bool IsDecl = 13147 !VD || 13148 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13149 Diag(D->getLocation(), 13150 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13151 << D; 13152 } 13153 return true; 13154 } 13155 return false; 13156 } 13157 13158 OMPClause *Sema::ActOnOpenMPLinearClause( 13159 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13160 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13161 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13162 SmallVector<Expr *, 8> Vars; 13163 SmallVector<Expr *, 8> Privates; 13164 SmallVector<Expr *, 8> Inits; 13165 SmallVector<Decl *, 4> ExprCaptures; 13166 SmallVector<Expr *, 4> ExprPostUpdates; 13167 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13168 LinKind = OMPC_LINEAR_val; 13169 for (Expr *RefExpr : VarList) { 13170 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13171 SourceLocation ELoc; 13172 SourceRange ERange; 13173 Expr *SimpleRefExpr = RefExpr; 13174 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13175 if (Res.second) { 13176 // It will be analyzed later. 13177 Vars.push_back(RefExpr); 13178 Privates.push_back(nullptr); 13179 Inits.push_back(nullptr); 13180 } 13181 ValueDecl *D = Res.first; 13182 if (!D) 13183 continue; 13184 13185 QualType Type = D->getType(); 13186 auto *VD = dyn_cast<VarDecl>(D); 13187 13188 // OpenMP [2.14.3.7, linear clause] 13189 // A list-item cannot appear in more than one linear clause. 13190 // A list-item that appears in a linear clause cannot appear in any 13191 // other data-sharing attribute clause. 13192 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13193 if (DVar.RefExpr) { 13194 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13195 << getOpenMPClauseName(OMPC_linear); 13196 reportOriginalDsa(*this, DSAStack, D, DVar); 13197 continue; 13198 } 13199 13200 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13201 continue; 13202 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13203 13204 // Build private copy of original var. 13205 VarDecl *Private = 13206 buildVarDecl(*this, ELoc, Type, D->getName(), 13207 D->hasAttrs() ? &D->getAttrs() : nullptr, 13208 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13209 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13210 // Build var to save initial value. 13211 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13212 Expr *InitExpr; 13213 DeclRefExpr *Ref = nullptr; 13214 if (!VD && !CurContext->isDependentContext()) { 13215 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13216 if (!isOpenMPCapturedDecl(D)) { 13217 ExprCaptures.push_back(Ref->getDecl()); 13218 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13219 ExprResult RefRes = DefaultLvalueConversion(Ref); 13220 if (!RefRes.isUsable()) 13221 continue; 13222 ExprResult PostUpdateRes = 13223 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13224 SimpleRefExpr, RefRes.get()); 13225 if (!PostUpdateRes.isUsable()) 13226 continue; 13227 ExprPostUpdates.push_back( 13228 IgnoredValueConversions(PostUpdateRes.get()).get()); 13229 } 13230 } 13231 } 13232 if (LinKind == OMPC_LINEAR_uval) 13233 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13234 else 13235 InitExpr = VD ? SimpleRefExpr : Ref; 13236 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13237 /*DirectInit=*/false); 13238 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13239 13240 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13241 Vars.push_back((VD || CurContext->isDependentContext()) 13242 ? RefExpr->IgnoreParens() 13243 : Ref); 13244 Privates.push_back(PrivateRef); 13245 Inits.push_back(InitRef); 13246 } 13247 13248 if (Vars.empty()) 13249 return nullptr; 13250 13251 Expr *StepExpr = Step; 13252 Expr *CalcStepExpr = nullptr; 13253 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13254 !Step->isInstantiationDependent() && 13255 !Step->containsUnexpandedParameterPack()) { 13256 SourceLocation StepLoc = Step->getBeginLoc(); 13257 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13258 if (Val.isInvalid()) 13259 return nullptr; 13260 StepExpr = Val.get(); 13261 13262 // Build var to save the step value. 13263 VarDecl *SaveVar = 13264 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13265 ExprResult SaveRef = 13266 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13267 ExprResult CalcStep = 13268 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13269 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13270 13271 // Warn about zero linear step (it would be probably better specified as 13272 // making corresponding variables 'const'). 13273 llvm::APSInt Result; 13274 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13275 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13276 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13277 << (Vars.size() > 1); 13278 if (!IsConstant && CalcStep.isUsable()) { 13279 // Calculate the step beforehand instead of doing this on each iteration. 13280 // (This is not used if the number of iterations may be kfold-ed). 13281 CalcStepExpr = CalcStep.get(); 13282 } 13283 } 13284 13285 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13286 ColonLoc, EndLoc, Vars, Privates, Inits, 13287 StepExpr, CalcStepExpr, 13288 buildPreInits(Context, ExprCaptures), 13289 buildPostUpdate(*this, ExprPostUpdates)); 13290 } 13291 13292 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13293 Expr *NumIterations, Sema &SemaRef, 13294 Scope *S, DSAStackTy *Stack) { 13295 // Walk the vars and build update/final expressions for the CodeGen. 13296 SmallVector<Expr *, 8> Updates; 13297 SmallVector<Expr *, 8> Finals; 13298 SmallVector<Expr *, 8> UsedExprs; 13299 Expr *Step = Clause.getStep(); 13300 Expr *CalcStep = Clause.getCalcStep(); 13301 // OpenMP [2.14.3.7, linear clause] 13302 // If linear-step is not specified it is assumed to be 1. 13303 if (!Step) 13304 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13305 else if (CalcStep) 13306 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13307 bool HasErrors = false; 13308 auto CurInit = Clause.inits().begin(); 13309 auto CurPrivate = Clause.privates().begin(); 13310 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13311 for (Expr *RefExpr : Clause.varlists()) { 13312 SourceLocation ELoc; 13313 SourceRange ERange; 13314 Expr *SimpleRefExpr = RefExpr; 13315 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13316 ValueDecl *D = Res.first; 13317 if (Res.second || !D) { 13318 Updates.push_back(nullptr); 13319 Finals.push_back(nullptr); 13320 HasErrors = true; 13321 continue; 13322 } 13323 auto &&Info = Stack->isLoopControlVariable(D); 13324 // OpenMP [2.15.11, distribute simd Construct] 13325 // A list item may not appear in a linear clause, unless it is the loop 13326 // iteration variable. 13327 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13328 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13329 SemaRef.Diag(ELoc, 13330 diag::err_omp_linear_distribute_var_non_loop_iteration); 13331 Updates.push_back(nullptr); 13332 Finals.push_back(nullptr); 13333 HasErrors = true; 13334 continue; 13335 } 13336 Expr *InitExpr = *CurInit; 13337 13338 // Build privatized reference to the current linear var. 13339 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13340 Expr *CapturedRef; 13341 if (LinKind == OMPC_LINEAR_uval) 13342 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13343 else 13344 CapturedRef = 13345 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13346 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13347 /*RefersToCapture=*/true); 13348 13349 // Build update: Var = InitExpr + IV * Step 13350 ExprResult Update; 13351 if (!Info.first) 13352 Update = buildCounterUpdate( 13353 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13354 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13355 else 13356 Update = *CurPrivate; 13357 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13358 /*DiscardedValue*/ false); 13359 13360 // Build final: Var = InitExpr + NumIterations * Step 13361 ExprResult Final; 13362 if (!Info.first) 13363 Final = 13364 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13365 InitExpr, NumIterations, Step, /*Subtract=*/false, 13366 /*IsNonRectangularLB=*/false); 13367 else 13368 Final = *CurPrivate; 13369 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13370 /*DiscardedValue*/ false); 13371 13372 if (!Update.isUsable() || !Final.isUsable()) { 13373 Updates.push_back(nullptr); 13374 Finals.push_back(nullptr); 13375 UsedExprs.push_back(nullptr); 13376 HasErrors = true; 13377 } else { 13378 Updates.push_back(Update.get()); 13379 Finals.push_back(Final.get()); 13380 if (!Info.first) 13381 UsedExprs.push_back(SimpleRefExpr); 13382 } 13383 ++CurInit; 13384 ++CurPrivate; 13385 } 13386 if (Expr *S = Clause.getStep()) 13387 UsedExprs.push_back(S); 13388 // Fill the remaining part with the nullptr. 13389 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13390 Clause.setUpdates(Updates); 13391 Clause.setFinals(Finals); 13392 Clause.setUsedExprs(UsedExprs); 13393 return HasErrors; 13394 } 13395 13396 OMPClause *Sema::ActOnOpenMPAlignedClause( 13397 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13398 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13399 SmallVector<Expr *, 8> Vars; 13400 for (Expr *RefExpr : VarList) { 13401 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13402 SourceLocation ELoc; 13403 SourceRange ERange; 13404 Expr *SimpleRefExpr = RefExpr; 13405 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13406 if (Res.second) { 13407 // It will be analyzed later. 13408 Vars.push_back(RefExpr); 13409 } 13410 ValueDecl *D = Res.first; 13411 if (!D) 13412 continue; 13413 13414 QualType QType = D->getType(); 13415 auto *VD = dyn_cast<VarDecl>(D); 13416 13417 // OpenMP [2.8.1, simd construct, Restrictions] 13418 // The type of list items appearing in the aligned clause must be 13419 // array, pointer, reference to array, or reference to pointer. 13420 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13421 const Type *Ty = QType.getTypePtrOrNull(); 13422 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 13423 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 13424 << QType << getLangOpts().CPlusPlus << ERange; 13425 bool IsDecl = 13426 !VD || 13427 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13428 Diag(D->getLocation(), 13429 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13430 << D; 13431 continue; 13432 } 13433 13434 // OpenMP [2.8.1, simd construct, Restrictions] 13435 // A list-item cannot appear in more than one aligned clause. 13436 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 13437 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 13438 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 13439 << getOpenMPClauseName(OMPC_aligned); 13440 continue; 13441 } 13442 13443 DeclRefExpr *Ref = nullptr; 13444 if (!VD && isOpenMPCapturedDecl(D)) 13445 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13446 Vars.push_back(DefaultFunctionArrayConversion( 13447 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 13448 .get()); 13449 } 13450 13451 // OpenMP [2.8.1, simd construct, Description] 13452 // The parameter of the aligned clause, alignment, must be a constant 13453 // positive integer expression. 13454 // If no optional parameter is specified, implementation-defined default 13455 // alignments for SIMD instructions on the target platforms are assumed. 13456 if (Alignment != nullptr) { 13457 ExprResult AlignResult = 13458 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 13459 if (AlignResult.isInvalid()) 13460 return nullptr; 13461 Alignment = AlignResult.get(); 13462 } 13463 if (Vars.empty()) 13464 return nullptr; 13465 13466 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 13467 EndLoc, Vars, Alignment); 13468 } 13469 13470 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 13471 SourceLocation StartLoc, 13472 SourceLocation LParenLoc, 13473 SourceLocation EndLoc) { 13474 SmallVector<Expr *, 8> Vars; 13475 SmallVector<Expr *, 8> SrcExprs; 13476 SmallVector<Expr *, 8> DstExprs; 13477 SmallVector<Expr *, 8> AssignmentOps; 13478 for (Expr *RefExpr : VarList) { 13479 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 13480 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13481 // It will be analyzed later. 13482 Vars.push_back(RefExpr); 13483 SrcExprs.push_back(nullptr); 13484 DstExprs.push_back(nullptr); 13485 AssignmentOps.push_back(nullptr); 13486 continue; 13487 } 13488 13489 SourceLocation ELoc = RefExpr->getExprLoc(); 13490 // OpenMP [2.1, C/C++] 13491 // A list item is a variable name. 13492 // OpenMP [2.14.4.1, Restrictions, p.1] 13493 // A list item that appears in a copyin clause must be threadprivate. 13494 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 13495 if (!DE || !isa<VarDecl>(DE->getDecl())) { 13496 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 13497 << 0 << RefExpr->getSourceRange(); 13498 continue; 13499 } 13500 13501 Decl *D = DE->getDecl(); 13502 auto *VD = cast<VarDecl>(D); 13503 13504 QualType Type = VD->getType(); 13505 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 13506 // It will be analyzed later. 13507 Vars.push_back(DE); 13508 SrcExprs.push_back(nullptr); 13509 DstExprs.push_back(nullptr); 13510 AssignmentOps.push_back(nullptr); 13511 continue; 13512 } 13513 13514 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 13515 // A list item that appears in a copyin clause must be threadprivate. 13516 if (!DSAStack->isThreadPrivate(VD)) { 13517 Diag(ELoc, diag::err_omp_required_access) 13518 << getOpenMPClauseName(OMPC_copyin) 13519 << getOpenMPDirectiveName(OMPD_threadprivate); 13520 continue; 13521 } 13522 13523 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13524 // A variable of class type (or array thereof) that appears in a 13525 // copyin clause requires an accessible, unambiguous copy assignment 13526 // operator for the class type. 13527 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13528 VarDecl *SrcVD = 13529 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 13530 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13531 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 13532 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 13533 VarDecl *DstVD = 13534 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 13535 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13536 DeclRefExpr *PseudoDstExpr = 13537 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 13538 // For arrays generate assignment operation for single element and replace 13539 // it by the original array element in CodeGen. 13540 ExprResult AssignmentOp = 13541 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 13542 PseudoSrcExpr); 13543 if (AssignmentOp.isInvalid()) 13544 continue; 13545 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 13546 /*DiscardedValue*/ false); 13547 if (AssignmentOp.isInvalid()) 13548 continue; 13549 13550 DSAStack->addDSA(VD, DE, OMPC_copyin); 13551 Vars.push_back(DE); 13552 SrcExprs.push_back(PseudoSrcExpr); 13553 DstExprs.push_back(PseudoDstExpr); 13554 AssignmentOps.push_back(AssignmentOp.get()); 13555 } 13556 13557 if (Vars.empty()) 13558 return nullptr; 13559 13560 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13561 SrcExprs, DstExprs, AssignmentOps); 13562 } 13563 13564 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 13565 SourceLocation StartLoc, 13566 SourceLocation LParenLoc, 13567 SourceLocation EndLoc) { 13568 SmallVector<Expr *, 8> Vars; 13569 SmallVector<Expr *, 8> SrcExprs; 13570 SmallVector<Expr *, 8> DstExprs; 13571 SmallVector<Expr *, 8> AssignmentOps; 13572 for (Expr *RefExpr : VarList) { 13573 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13574 SourceLocation ELoc; 13575 SourceRange ERange; 13576 Expr *SimpleRefExpr = RefExpr; 13577 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13578 if (Res.second) { 13579 // It will be analyzed later. 13580 Vars.push_back(RefExpr); 13581 SrcExprs.push_back(nullptr); 13582 DstExprs.push_back(nullptr); 13583 AssignmentOps.push_back(nullptr); 13584 } 13585 ValueDecl *D = Res.first; 13586 if (!D) 13587 continue; 13588 13589 QualType Type = D->getType(); 13590 auto *VD = dyn_cast<VarDecl>(D); 13591 13592 // OpenMP [2.14.4.2, Restrictions, p.2] 13593 // A list item that appears in a copyprivate clause may not appear in a 13594 // private or firstprivate clause on the single construct. 13595 if (!VD || !DSAStack->isThreadPrivate(VD)) { 13596 DSAStackTy::DSAVarData DVar = 13597 DSAStack->getTopDSA(D, /*FromParent=*/false); 13598 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 13599 DVar.RefExpr) { 13600 Diag(ELoc, diag::err_omp_wrong_dsa) 13601 << getOpenMPClauseName(DVar.CKind) 13602 << getOpenMPClauseName(OMPC_copyprivate); 13603 reportOriginalDsa(*this, DSAStack, D, DVar); 13604 continue; 13605 } 13606 13607 // OpenMP [2.11.4.2, Restrictions, p.1] 13608 // All list items that appear in a copyprivate clause must be either 13609 // threadprivate or private in the enclosing context. 13610 if (DVar.CKind == OMPC_unknown) { 13611 DVar = DSAStack->getImplicitDSA(D, false); 13612 if (DVar.CKind == OMPC_shared) { 13613 Diag(ELoc, diag::err_omp_required_access) 13614 << getOpenMPClauseName(OMPC_copyprivate) 13615 << "threadprivate or private in the enclosing context"; 13616 reportOriginalDsa(*this, DSAStack, D, DVar); 13617 continue; 13618 } 13619 } 13620 } 13621 13622 // Variably modified types are not supported. 13623 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 13624 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13625 << getOpenMPClauseName(OMPC_copyprivate) << Type 13626 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13627 bool IsDecl = 13628 !VD || 13629 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13630 Diag(D->getLocation(), 13631 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13632 << D; 13633 continue; 13634 } 13635 13636 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13637 // A variable of class type (or array thereof) that appears in a 13638 // copyin clause requires an accessible, unambiguous copy assignment 13639 // operator for the class type. 13640 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13641 .getUnqualifiedType(); 13642 VarDecl *SrcVD = 13643 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13644 D->hasAttrs() ? &D->getAttrs() : nullptr); 13645 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13646 VarDecl *DstVD = 13647 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13648 D->hasAttrs() ? &D->getAttrs() : nullptr); 13649 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13650 ExprResult AssignmentOp = BuildBinOp( 13651 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13652 if (AssignmentOp.isInvalid()) 13653 continue; 13654 AssignmentOp = 13655 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13656 if (AssignmentOp.isInvalid()) 13657 continue; 13658 13659 // No need to mark vars as copyprivate, they are already threadprivate or 13660 // implicitly private. 13661 assert(VD || isOpenMPCapturedDecl(D)); 13662 Vars.push_back( 13663 VD ? RefExpr->IgnoreParens() 13664 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13665 SrcExprs.push_back(PseudoSrcExpr); 13666 DstExprs.push_back(PseudoDstExpr); 13667 AssignmentOps.push_back(AssignmentOp.get()); 13668 } 13669 13670 if (Vars.empty()) 13671 return nullptr; 13672 13673 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13674 Vars, SrcExprs, DstExprs, AssignmentOps); 13675 } 13676 13677 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13678 SourceLocation StartLoc, 13679 SourceLocation LParenLoc, 13680 SourceLocation EndLoc) { 13681 if (VarList.empty()) 13682 return nullptr; 13683 13684 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13685 } 13686 13687 OMPClause * 13688 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13689 SourceLocation DepLoc, SourceLocation ColonLoc, 13690 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13691 SourceLocation LParenLoc, SourceLocation EndLoc) { 13692 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13693 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13694 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13695 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13696 return nullptr; 13697 } 13698 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13699 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13700 DepKind == OMPC_DEPEND_sink)) { 13701 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13702 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13703 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13704 /*Last=*/OMPC_DEPEND_unknown, Except) 13705 << getOpenMPClauseName(OMPC_depend); 13706 return nullptr; 13707 } 13708 SmallVector<Expr *, 8> Vars; 13709 DSAStackTy::OperatorOffsetTy OpsOffs; 13710 llvm::APSInt DepCounter(/*BitWidth=*/32); 13711 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13712 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13713 if (const Expr *OrderedCountExpr = 13714 DSAStack->getParentOrderedRegionParam().first) { 13715 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13716 TotalDepCount.setIsUnsigned(/*Val=*/true); 13717 } 13718 } 13719 for (Expr *RefExpr : VarList) { 13720 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13721 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13722 // It will be analyzed later. 13723 Vars.push_back(RefExpr); 13724 continue; 13725 } 13726 13727 SourceLocation ELoc = RefExpr->getExprLoc(); 13728 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13729 if (DepKind == OMPC_DEPEND_sink) { 13730 if (DSAStack->getParentOrderedRegionParam().first && 13731 DepCounter >= TotalDepCount) { 13732 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13733 continue; 13734 } 13735 ++DepCounter; 13736 // OpenMP [2.13.9, Summary] 13737 // depend(dependence-type : vec), where dependence-type is: 13738 // 'sink' and where vec is the iteration vector, which has the form: 13739 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13740 // where n is the value specified by the ordered clause in the loop 13741 // directive, xi denotes the loop iteration variable of the i-th nested 13742 // loop associated with the loop directive, and di is a constant 13743 // non-negative integer. 13744 if (CurContext->isDependentContext()) { 13745 // It will be analyzed later. 13746 Vars.push_back(RefExpr); 13747 continue; 13748 } 13749 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13750 OverloadedOperatorKind OOK = OO_None; 13751 SourceLocation OOLoc; 13752 Expr *LHS = SimpleExpr; 13753 Expr *RHS = nullptr; 13754 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13755 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13756 OOLoc = BO->getOperatorLoc(); 13757 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13758 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13759 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13760 OOK = OCE->getOperator(); 13761 OOLoc = OCE->getOperatorLoc(); 13762 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13763 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13764 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13765 OOK = MCE->getMethodDecl() 13766 ->getNameInfo() 13767 .getName() 13768 .getCXXOverloadedOperator(); 13769 OOLoc = MCE->getCallee()->getExprLoc(); 13770 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13771 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13772 } 13773 SourceLocation ELoc; 13774 SourceRange ERange; 13775 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13776 if (Res.second) { 13777 // It will be analyzed later. 13778 Vars.push_back(RefExpr); 13779 } 13780 ValueDecl *D = Res.first; 13781 if (!D) 13782 continue; 13783 13784 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 13785 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 13786 continue; 13787 } 13788 if (RHS) { 13789 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 13790 RHS, OMPC_depend, /*StrictlyPositive=*/false); 13791 if (RHSRes.isInvalid()) 13792 continue; 13793 } 13794 if (!CurContext->isDependentContext() && 13795 DSAStack->getParentOrderedRegionParam().first && 13796 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 13797 const ValueDecl *VD = 13798 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 13799 if (VD) 13800 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 13801 << 1 << VD; 13802 else 13803 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 13804 continue; 13805 } 13806 OpsOffs.emplace_back(RHS, OOK); 13807 } else { 13808 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 13809 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 13810 (ASE && 13811 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 13812 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 13813 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13814 << RefExpr->getSourceRange(); 13815 continue; 13816 } 13817 13818 ExprResult Res; 13819 { 13820 Sema::TentativeAnalysisScope Trap(*this); 13821 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 13822 RefExpr->IgnoreParenImpCasts()); 13823 } 13824 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 13825 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13826 << RefExpr->getSourceRange(); 13827 continue; 13828 } 13829 } 13830 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13831 } 13832 13833 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13834 TotalDepCount > VarList.size() && 13835 DSAStack->getParentOrderedRegionParam().first && 13836 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13837 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13838 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13839 } 13840 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13841 Vars.empty()) 13842 return nullptr; 13843 13844 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13845 DepKind, DepLoc, ColonLoc, Vars, 13846 TotalDepCount.getZExtValue()); 13847 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13848 DSAStack->isParentOrderedRegion()) 13849 DSAStack->addDoacrossDependClause(C, OpsOffs); 13850 return C; 13851 } 13852 13853 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13854 SourceLocation LParenLoc, 13855 SourceLocation EndLoc) { 13856 Expr *ValExpr = Device; 13857 Stmt *HelperValStmt = nullptr; 13858 13859 // OpenMP [2.9.1, Restrictions] 13860 // The device expression must evaluate to a non-negative integer value. 13861 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13862 /*StrictlyPositive=*/false)) 13863 return nullptr; 13864 13865 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13866 OpenMPDirectiveKind CaptureRegion = 13867 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13868 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13869 ValExpr = MakeFullExpr(ValExpr).get(); 13870 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13871 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13872 HelperValStmt = buildPreInits(Context, Captures); 13873 } 13874 13875 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13876 StartLoc, LParenLoc, EndLoc); 13877 } 13878 13879 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13880 DSAStackTy *Stack, QualType QTy, 13881 bool FullCheck = true) { 13882 NamedDecl *ND; 13883 if (QTy->isIncompleteType(&ND)) { 13884 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13885 return false; 13886 } 13887 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13888 !QTy.isTrivialType(SemaRef.Context)) 13889 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13890 return true; 13891 } 13892 13893 /// Return true if it can be proven that the provided array expression 13894 /// (array section or array subscript) does NOT specify the whole size of the 13895 /// array whose base type is \a BaseQTy. 13896 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13897 const Expr *E, 13898 QualType BaseQTy) { 13899 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13900 13901 // If this is an array subscript, it refers to the whole size if the size of 13902 // the dimension is constant and equals 1. Also, an array section assumes the 13903 // format of an array subscript if no colon is used. 13904 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13905 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13906 return ATy->getSize().getSExtValue() != 1; 13907 // Size can't be evaluated statically. 13908 return false; 13909 } 13910 13911 assert(OASE && "Expecting array section if not an array subscript."); 13912 const Expr *LowerBound = OASE->getLowerBound(); 13913 const Expr *Length = OASE->getLength(); 13914 13915 // If there is a lower bound that does not evaluates to zero, we are not 13916 // covering the whole dimension. 13917 if (LowerBound) { 13918 Expr::EvalResult Result; 13919 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13920 return false; // Can't get the integer value as a constant. 13921 13922 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13923 if (ConstLowerBound.getSExtValue()) 13924 return true; 13925 } 13926 13927 // If we don't have a length we covering the whole dimension. 13928 if (!Length) 13929 return false; 13930 13931 // If the base is a pointer, we don't have a way to get the size of the 13932 // pointee. 13933 if (BaseQTy->isPointerType()) 13934 return false; 13935 13936 // We can only check if the length is the same as the size of the dimension 13937 // if we have a constant array. 13938 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13939 if (!CATy) 13940 return false; 13941 13942 Expr::EvalResult Result; 13943 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13944 return false; // Can't get the integer value as a constant. 13945 13946 llvm::APSInt ConstLength = Result.Val.getInt(); 13947 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13948 } 13949 13950 // Return true if it can be proven that the provided array expression (array 13951 // section or array subscript) does NOT specify a single element of the array 13952 // whose base type is \a BaseQTy. 13953 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13954 const Expr *E, 13955 QualType BaseQTy) { 13956 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13957 13958 // An array subscript always refer to a single element. Also, an array section 13959 // assumes the format of an array subscript if no colon is used. 13960 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13961 return false; 13962 13963 assert(OASE && "Expecting array section if not an array subscript."); 13964 const Expr *Length = OASE->getLength(); 13965 13966 // If we don't have a length we have to check if the array has unitary size 13967 // for this dimension. Also, we should always expect a length if the base type 13968 // is pointer. 13969 if (!Length) { 13970 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13971 return ATy->getSize().getSExtValue() != 1; 13972 // We cannot assume anything. 13973 return false; 13974 } 13975 13976 // Check if the length evaluates to 1. 13977 Expr::EvalResult Result; 13978 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13979 return false; // Can't get the integer value as a constant. 13980 13981 llvm::APSInt ConstLength = Result.Val.getInt(); 13982 return ConstLength.getSExtValue() != 1; 13983 } 13984 13985 // Return the expression of the base of the mappable expression or null if it 13986 // cannot be determined and do all the necessary checks to see if the expression 13987 // is valid as a standalone mappable expression. In the process, record all the 13988 // components of the expression. 13989 static const Expr *checkMapClauseExpressionBase( 13990 Sema &SemaRef, Expr *E, 13991 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 13992 OpenMPClauseKind CKind, bool NoDiagnose) { 13993 SourceLocation ELoc = E->getExprLoc(); 13994 SourceRange ERange = E->getSourceRange(); 13995 13996 // The base of elements of list in a map clause have to be either: 13997 // - a reference to variable or field. 13998 // - a member expression. 13999 // - an array expression. 14000 // 14001 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14002 // reference to 'r'. 14003 // 14004 // If we have: 14005 // 14006 // struct SS { 14007 // Bla S; 14008 // foo() { 14009 // #pragma omp target map (S.Arr[:12]); 14010 // } 14011 // } 14012 // 14013 // We want to retrieve the member expression 'this->S'; 14014 14015 const Expr *RelevantExpr = nullptr; 14016 14017 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14018 // If a list item is an array section, it must specify contiguous storage. 14019 // 14020 // For this restriction it is sufficient that we make sure only references 14021 // to variables or fields and array expressions, and that no array sections 14022 // exist except in the rightmost expression (unless they cover the whole 14023 // dimension of the array). E.g. these would be invalid: 14024 // 14025 // r.ArrS[3:5].Arr[6:7] 14026 // 14027 // r.ArrS[3:5].x 14028 // 14029 // but these would be valid: 14030 // r.ArrS[3].Arr[6:7] 14031 // 14032 // r.ArrS[3].x 14033 14034 bool AllowUnitySizeArraySection = true; 14035 bool AllowWholeSizeArraySection = true; 14036 14037 while (!RelevantExpr) { 14038 E = E->IgnoreParenImpCasts(); 14039 14040 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14041 if (!isa<VarDecl>(CurE->getDecl())) 14042 return nullptr; 14043 14044 RelevantExpr = CurE; 14045 14046 // If we got a reference to a declaration, we should not expect any array 14047 // section before that. 14048 AllowUnitySizeArraySection = false; 14049 AllowWholeSizeArraySection = false; 14050 14051 // Record the component. 14052 CurComponents.emplace_back(CurE, CurE->getDecl()); 14053 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14054 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14055 14056 if (isa<CXXThisExpr>(BaseE)) 14057 // We found a base expression: this->Val. 14058 RelevantExpr = CurE; 14059 else 14060 E = BaseE; 14061 14062 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14063 if (!NoDiagnose) { 14064 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14065 << CurE->getSourceRange(); 14066 return nullptr; 14067 } 14068 if (RelevantExpr) 14069 return nullptr; 14070 continue; 14071 } 14072 14073 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14074 14075 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14076 // A bit-field cannot appear in a map clause. 14077 // 14078 if (FD->isBitField()) { 14079 if (!NoDiagnose) { 14080 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14081 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14082 return nullptr; 14083 } 14084 if (RelevantExpr) 14085 return nullptr; 14086 continue; 14087 } 14088 14089 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14090 // If the type of a list item is a reference to a type T then the type 14091 // will be considered to be T for all purposes of this clause. 14092 QualType CurType = BaseE->getType().getNonReferenceType(); 14093 14094 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14095 // A list item cannot be a variable that is a member of a structure with 14096 // a union type. 14097 // 14098 if (CurType->isUnionType()) { 14099 if (!NoDiagnose) { 14100 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14101 << CurE->getSourceRange(); 14102 return nullptr; 14103 } 14104 continue; 14105 } 14106 14107 // If we got a member expression, we should not expect any array section 14108 // before that: 14109 // 14110 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14111 // If a list item is an element of a structure, only the rightmost symbol 14112 // of the variable reference can be an array section. 14113 // 14114 AllowUnitySizeArraySection = false; 14115 AllowWholeSizeArraySection = false; 14116 14117 // Record the component. 14118 CurComponents.emplace_back(CurE, FD); 14119 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14120 E = CurE->getBase()->IgnoreParenImpCasts(); 14121 14122 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14123 if (!NoDiagnose) { 14124 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14125 << 0 << CurE->getSourceRange(); 14126 return nullptr; 14127 } 14128 continue; 14129 } 14130 14131 // If we got an array subscript that express the whole dimension we 14132 // can have any array expressions before. If it only expressing part of 14133 // the dimension, we can only have unitary-size array expressions. 14134 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14135 E->getType())) 14136 AllowWholeSizeArraySection = false; 14137 14138 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14139 Expr::EvalResult Result; 14140 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14141 if (!Result.Val.getInt().isNullValue()) { 14142 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14143 diag::err_omp_invalid_map_this_expr); 14144 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14145 diag::note_omp_invalid_subscript_on_this_ptr_map); 14146 } 14147 } 14148 RelevantExpr = TE; 14149 } 14150 14151 // Record the component - we don't have any declaration associated. 14152 CurComponents.emplace_back(CurE, nullptr); 14153 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14154 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14155 E = CurE->getBase()->IgnoreParenImpCasts(); 14156 14157 QualType CurType = 14158 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14159 14160 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14161 // If the type of a list item is a reference to a type T then the type 14162 // will be considered to be T for all purposes of this clause. 14163 if (CurType->isReferenceType()) 14164 CurType = CurType->getPointeeType(); 14165 14166 bool IsPointer = CurType->isAnyPointerType(); 14167 14168 if (!IsPointer && !CurType->isArrayType()) { 14169 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14170 << 0 << CurE->getSourceRange(); 14171 return nullptr; 14172 } 14173 14174 bool NotWhole = 14175 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14176 bool NotUnity = 14177 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14178 14179 if (AllowWholeSizeArraySection) { 14180 // Any array section is currently allowed. Allowing a whole size array 14181 // section implies allowing a unity array section as well. 14182 // 14183 // If this array section refers to the whole dimension we can still 14184 // accept other array sections before this one, except if the base is a 14185 // pointer. Otherwise, only unitary sections are accepted. 14186 if (NotWhole || IsPointer) 14187 AllowWholeSizeArraySection = false; 14188 } else if (AllowUnitySizeArraySection && NotUnity) { 14189 // A unity or whole array section is not allowed and that is not 14190 // compatible with the properties of the current array section. 14191 SemaRef.Diag( 14192 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14193 << CurE->getSourceRange(); 14194 return nullptr; 14195 } 14196 14197 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14198 Expr::EvalResult ResultR; 14199 Expr::EvalResult ResultL; 14200 if (CurE->getLength()->EvaluateAsInt(ResultR, 14201 SemaRef.getASTContext())) { 14202 if (!ResultR.Val.getInt().isOneValue()) { 14203 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14204 diag::err_omp_invalid_map_this_expr); 14205 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14206 diag::note_omp_invalid_length_on_this_ptr_mapping); 14207 } 14208 } 14209 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14210 ResultL, SemaRef.getASTContext())) { 14211 if (!ResultL.Val.getInt().isNullValue()) { 14212 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14213 diag::err_omp_invalid_map_this_expr); 14214 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14215 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14216 } 14217 } 14218 RelevantExpr = TE; 14219 } 14220 14221 // Record the component - we don't have any declaration associated. 14222 CurComponents.emplace_back(CurE, nullptr); 14223 } else { 14224 if (!NoDiagnose) { 14225 // If nothing else worked, this is not a valid map clause expression. 14226 SemaRef.Diag( 14227 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14228 << ERange; 14229 } 14230 return nullptr; 14231 } 14232 } 14233 14234 return RelevantExpr; 14235 } 14236 14237 // Return true if expression E associated with value VD has conflicts with other 14238 // map information. 14239 static bool checkMapConflicts( 14240 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14241 bool CurrentRegionOnly, 14242 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14243 OpenMPClauseKind CKind) { 14244 assert(VD && E); 14245 SourceLocation ELoc = E->getExprLoc(); 14246 SourceRange ERange = E->getSourceRange(); 14247 14248 // In order to easily check the conflicts we need to match each component of 14249 // the expression under test with the components of the expressions that are 14250 // already in the stack. 14251 14252 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14253 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14254 "Map clause expression with unexpected base!"); 14255 14256 // Variables to help detecting enclosing problems in data environment nests. 14257 bool IsEnclosedByDataEnvironmentExpr = false; 14258 const Expr *EnclosingExpr = nullptr; 14259 14260 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14261 VD, CurrentRegionOnly, 14262 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14263 ERange, CKind, &EnclosingExpr, 14264 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14265 StackComponents, 14266 OpenMPClauseKind) { 14267 assert(!StackComponents.empty() && 14268 "Map clause expression with no components!"); 14269 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14270 "Map clause expression with unexpected base!"); 14271 (void)VD; 14272 14273 // The whole expression in the stack. 14274 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14275 14276 // Expressions must start from the same base. Here we detect at which 14277 // point both expressions diverge from each other and see if we can 14278 // detect if the memory referred to both expressions is contiguous and 14279 // do not overlap. 14280 auto CI = CurComponents.rbegin(); 14281 auto CE = CurComponents.rend(); 14282 auto SI = StackComponents.rbegin(); 14283 auto SE = StackComponents.rend(); 14284 for (; CI != CE && SI != SE; ++CI, ++SI) { 14285 14286 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14287 // At most one list item can be an array item derived from a given 14288 // variable in map clauses of the same construct. 14289 if (CurrentRegionOnly && 14290 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14291 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14292 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14293 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14294 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14295 diag::err_omp_multiple_array_items_in_map_clause) 14296 << CI->getAssociatedExpression()->getSourceRange(); 14297 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14298 diag::note_used_here) 14299 << SI->getAssociatedExpression()->getSourceRange(); 14300 return true; 14301 } 14302 14303 // Do both expressions have the same kind? 14304 if (CI->getAssociatedExpression()->getStmtClass() != 14305 SI->getAssociatedExpression()->getStmtClass()) 14306 break; 14307 14308 // Are we dealing with different variables/fields? 14309 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14310 break; 14311 } 14312 // Check if the extra components of the expressions in the enclosing 14313 // data environment are redundant for the current base declaration. 14314 // If they are, the maps completely overlap, which is legal. 14315 for (; SI != SE; ++SI) { 14316 QualType Type; 14317 if (const auto *ASE = 14318 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14319 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14320 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14321 SI->getAssociatedExpression())) { 14322 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14323 Type = 14324 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14325 } 14326 if (Type.isNull() || Type->isAnyPointerType() || 14327 checkArrayExpressionDoesNotReferToWholeSize( 14328 SemaRef, SI->getAssociatedExpression(), Type)) 14329 break; 14330 } 14331 14332 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14333 // List items of map clauses in the same construct must not share 14334 // original storage. 14335 // 14336 // If the expressions are exactly the same or one is a subset of the 14337 // other, it means they are sharing storage. 14338 if (CI == CE && SI == SE) { 14339 if (CurrentRegionOnly) { 14340 if (CKind == OMPC_map) { 14341 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14342 } else { 14343 assert(CKind == OMPC_to || CKind == OMPC_from); 14344 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14345 << ERange; 14346 } 14347 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14348 << RE->getSourceRange(); 14349 return true; 14350 } 14351 // If we find the same expression in the enclosing data environment, 14352 // that is legal. 14353 IsEnclosedByDataEnvironmentExpr = true; 14354 return false; 14355 } 14356 14357 QualType DerivedType = 14358 std::prev(CI)->getAssociatedDeclaration()->getType(); 14359 SourceLocation DerivedLoc = 14360 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14361 14362 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14363 // If the type of a list item is a reference to a type T then the type 14364 // will be considered to be T for all purposes of this clause. 14365 DerivedType = DerivedType.getNonReferenceType(); 14366 14367 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14368 // A variable for which the type is pointer and an array section 14369 // derived from that variable must not appear as list items of map 14370 // clauses of the same construct. 14371 // 14372 // Also, cover one of the cases in: 14373 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14374 // If any part of the original storage of a list item has corresponding 14375 // storage in the device data environment, all of the original storage 14376 // must have corresponding storage in the device data environment. 14377 // 14378 if (DerivedType->isAnyPointerType()) { 14379 if (CI == CE || SI == SE) { 14380 SemaRef.Diag( 14381 DerivedLoc, 14382 diag::err_omp_pointer_mapped_along_with_derived_section) 14383 << DerivedLoc; 14384 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14385 << RE->getSourceRange(); 14386 return true; 14387 } 14388 if (CI->getAssociatedExpression()->getStmtClass() != 14389 SI->getAssociatedExpression()->getStmtClass() || 14390 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14391 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14392 assert(CI != CE && SI != SE); 14393 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14394 << DerivedLoc; 14395 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14396 << RE->getSourceRange(); 14397 return true; 14398 } 14399 } 14400 14401 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14402 // List items of map clauses in the same construct must not share 14403 // original storage. 14404 // 14405 // An expression is a subset of the other. 14406 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14407 if (CKind == OMPC_map) { 14408 if (CI != CE || SI != SE) { 14409 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14410 // a pointer. 14411 auto Begin = 14412 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14413 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14414 auto It = Begin; 14415 while (It != End && !It->getAssociatedDeclaration()) 14416 std::advance(It, 1); 14417 assert(It != End && 14418 "Expected at least one component with the declaration."); 14419 if (It != Begin && It->getAssociatedDeclaration() 14420 ->getType() 14421 .getCanonicalType() 14422 ->isAnyPointerType()) { 14423 IsEnclosedByDataEnvironmentExpr = false; 14424 EnclosingExpr = nullptr; 14425 return false; 14426 } 14427 } 14428 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14429 } else { 14430 assert(CKind == OMPC_to || CKind == OMPC_from); 14431 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14432 << ERange; 14433 } 14434 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14435 << RE->getSourceRange(); 14436 return true; 14437 } 14438 14439 // The current expression uses the same base as other expression in the 14440 // data environment but does not contain it completely. 14441 if (!CurrentRegionOnly && SI != SE) 14442 EnclosingExpr = RE; 14443 14444 // The current expression is a subset of the expression in the data 14445 // environment. 14446 IsEnclosedByDataEnvironmentExpr |= 14447 (!CurrentRegionOnly && CI != CE && SI == SE); 14448 14449 return false; 14450 }); 14451 14452 if (CurrentRegionOnly) 14453 return FoundError; 14454 14455 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14456 // If any part of the original storage of a list item has corresponding 14457 // storage in the device data environment, all of the original storage must 14458 // have corresponding storage in the device data environment. 14459 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 14460 // If a list item is an element of a structure, and a different element of 14461 // the structure has a corresponding list item in the device data environment 14462 // prior to a task encountering the construct associated with the map clause, 14463 // then the list item must also have a corresponding list item in the device 14464 // data environment prior to the task encountering the construct. 14465 // 14466 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 14467 SemaRef.Diag(ELoc, 14468 diag::err_omp_original_storage_is_shared_and_does_not_contain) 14469 << ERange; 14470 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 14471 << EnclosingExpr->getSourceRange(); 14472 return true; 14473 } 14474 14475 return FoundError; 14476 } 14477 14478 // Look up the user-defined mapper given the mapper name and mapped type, and 14479 // build a reference to it. 14480 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 14481 CXXScopeSpec &MapperIdScopeSpec, 14482 const DeclarationNameInfo &MapperId, 14483 QualType Type, 14484 Expr *UnresolvedMapper) { 14485 if (MapperIdScopeSpec.isInvalid()) 14486 return ExprError(); 14487 // Find all user-defined mappers with the given MapperId. 14488 SmallVector<UnresolvedSet<8>, 4> Lookups; 14489 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 14490 Lookup.suppressDiagnostics(); 14491 if (S) { 14492 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 14493 NamedDecl *D = Lookup.getRepresentativeDecl(); 14494 while (S && !S->isDeclScope(D)) 14495 S = S->getParent(); 14496 if (S) 14497 S = S->getParent(); 14498 Lookups.emplace_back(); 14499 Lookups.back().append(Lookup.begin(), Lookup.end()); 14500 Lookup.clear(); 14501 } 14502 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 14503 // Extract the user-defined mappers with the given MapperId. 14504 Lookups.push_back(UnresolvedSet<8>()); 14505 for (NamedDecl *D : ULE->decls()) { 14506 auto *DMD = cast<OMPDeclareMapperDecl>(D); 14507 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 14508 Lookups.back().addDecl(DMD); 14509 } 14510 } 14511 // Defer the lookup for dependent types. The results will be passed through 14512 // UnresolvedMapper on instantiation. 14513 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 14514 Type->isInstantiationDependentType() || 14515 Type->containsUnexpandedParameterPack() || 14516 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14517 return !D->isInvalidDecl() && 14518 (D->getType()->isDependentType() || 14519 D->getType()->isInstantiationDependentType() || 14520 D->getType()->containsUnexpandedParameterPack()); 14521 })) { 14522 UnresolvedSet<8> URS; 14523 for (const UnresolvedSet<8> &Set : Lookups) { 14524 if (Set.empty()) 14525 continue; 14526 URS.append(Set.begin(), Set.end()); 14527 } 14528 return UnresolvedLookupExpr::Create( 14529 SemaRef.Context, /*NamingClass=*/nullptr, 14530 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 14531 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 14532 } 14533 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14534 // The type must be of struct, union or class type in C and C++ 14535 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 14536 return ExprEmpty(); 14537 SourceLocation Loc = MapperId.getLoc(); 14538 // Perform argument dependent lookup. 14539 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 14540 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 14541 // Return the first user-defined mapper with the desired type. 14542 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14543 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 14544 if (!D->isInvalidDecl() && 14545 SemaRef.Context.hasSameType(D->getType(), Type)) 14546 return D; 14547 return nullptr; 14548 })) 14549 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14550 // Find the first user-defined mapper with a type derived from the desired 14551 // type. 14552 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14553 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 14554 if (!D->isInvalidDecl() && 14555 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 14556 !Type.isMoreQualifiedThan(D->getType())) 14557 return D; 14558 return nullptr; 14559 })) { 14560 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14561 /*DetectVirtual=*/false); 14562 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 14563 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14564 VD->getType().getUnqualifiedType()))) { 14565 if (SemaRef.CheckBaseClassAccess( 14566 Loc, VD->getType(), Type, Paths.front(), 14567 /*DiagID=*/0) != Sema::AR_inaccessible) { 14568 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14569 } 14570 } 14571 } 14572 } 14573 // Report error if a mapper is specified, but cannot be found. 14574 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 14575 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 14576 << Type << MapperId.getName(); 14577 return ExprError(); 14578 } 14579 return ExprEmpty(); 14580 } 14581 14582 namespace { 14583 // Utility struct that gathers all the related lists associated with a mappable 14584 // expression. 14585 struct MappableVarListInfo { 14586 // The list of expressions. 14587 ArrayRef<Expr *> VarList; 14588 // The list of processed expressions. 14589 SmallVector<Expr *, 16> ProcessedVarList; 14590 // The mappble components for each expression. 14591 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 14592 // The base declaration of the variable. 14593 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 14594 // The reference to the user-defined mapper associated with every expression. 14595 SmallVector<Expr *, 16> UDMapperList; 14596 14597 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 14598 // We have a list of components and base declarations for each entry in the 14599 // variable list. 14600 VarComponents.reserve(VarList.size()); 14601 VarBaseDeclarations.reserve(VarList.size()); 14602 } 14603 }; 14604 } 14605 14606 // Check the validity of the provided variable list for the provided clause kind 14607 // \a CKind. In the check process the valid expressions, mappable expression 14608 // components, variables, and user-defined mappers are extracted and used to 14609 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 14610 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 14611 // and \a MapperId are expected to be valid if the clause kind is 'map'. 14612 static void checkMappableExpressionList( 14613 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 14614 MappableVarListInfo &MVLI, SourceLocation StartLoc, 14615 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 14616 ArrayRef<Expr *> UnresolvedMappers, 14617 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 14618 bool IsMapTypeImplicit = false) { 14619 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 14620 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 14621 "Unexpected clause kind with mappable expressions!"); 14622 14623 // If the identifier of user-defined mapper is not specified, it is "default". 14624 // We do not change the actual name in this clause to distinguish whether a 14625 // mapper is specified explicitly, i.e., it is not explicitly specified when 14626 // MapperId.getName() is empty. 14627 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 14628 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14629 MapperId.setName(DeclNames.getIdentifier( 14630 &SemaRef.getASTContext().Idents.get("default"))); 14631 } 14632 14633 // Iterators to find the current unresolved mapper expression. 14634 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14635 bool UpdateUMIt = false; 14636 Expr *UnresolvedMapper = nullptr; 14637 14638 // Keep track of the mappable components and base declarations in this clause. 14639 // Each entry in the list is going to have a list of components associated. We 14640 // record each set of the components so that we can build the clause later on. 14641 // In the end we should have the same amount of declarations and component 14642 // lists. 14643 14644 for (Expr *RE : MVLI.VarList) { 14645 assert(RE && "Null expr in omp to/from/map clause"); 14646 SourceLocation ELoc = RE->getExprLoc(); 14647 14648 // Find the current unresolved mapper expression. 14649 if (UpdateUMIt && UMIt != UMEnd) { 14650 UMIt++; 14651 assert( 14652 UMIt != UMEnd && 14653 "Expect the size of UnresolvedMappers to match with that of VarList"); 14654 } 14655 UpdateUMIt = true; 14656 if (UMIt != UMEnd) 14657 UnresolvedMapper = *UMIt; 14658 14659 const Expr *VE = RE->IgnoreParenLValueCasts(); 14660 14661 if (VE->isValueDependent() || VE->isTypeDependent() || 14662 VE->isInstantiationDependent() || 14663 VE->containsUnexpandedParameterPack()) { 14664 // Try to find the associated user-defined mapper. 14665 ExprResult ER = buildUserDefinedMapperRef( 14666 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14667 VE->getType().getCanonicalType(), UnresolvedMapper); 14668 if (ER.isInvalid()) 14669 continue; 14670 MVLI.UDMapperList.push_back(ER.get()); 14671 // We can only analyze this information once the missing information is 14672 // resolved. 14673 MVLI.ProcessedVarList.push_back(RE); 14674 continue; 14675 } 14676 14677 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14678 14679 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14680 SemaRef.Diag(ELoc, 14681 diag::err_omp_expected_named_var_member_or_array_expression) 14682 << RE->getSourceRange(); 14683 continue; 14684 } 14685 14686 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14687 ValueDecl *CurDeclaration = nullptr; 14688 14689 // Obtain the array or member expression bases if required. Also, fill the 14690 // components array with all the components identified in the process. 14691 const Expr *BE = checkMapClauseExpressionBase( 14692 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14693 if (!BE) 14694 continue; 14695 14696 assert(!CurComponents.empty() && 14697 "Invalid mappable expression information."); 14698 14699 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14700 // Add store "this" pointer to class in DSAStackTy for future checking 14701 DSAS->addMappedClassesQualTypes(TE->getType()); 14702 // Try to find the associated user-defined mapper. 14703 ExprResult ER = buildUserDefinedMapperRef( 14704 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14705 VE->getType().getCanonicalType(), UnresolvedMapper); 14706 if (ER.isInvalid()) 14707 continue; 14708 MVLI.UDMapperList.push_back(ER.get()); 14709 // Skip restriction checking for variable or field declarations 14710 MVLI.ProcessedVarList.push_back(RE); 14711 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14712 MVLI.VarComponents.back().append(CurComponents.begin(), 14713 CurComponents.end()); 14714 MVLI.VarBaseDeclarations.push_back(nullptr); 14715 continue; 14716 } 14717 14718 // For the following checks, we rely on the base declaration which is 14719 // expected to be associated with the last component. The declaration is 14720 // expected to be a variable or a field (if 'this' is being mapped). 14721 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14722 assert(CurDeclaration && "Null decl on map clause."); 14723 assert( 14724 CurDeclaration->isCanonicalDecl() && 14725 "Expecting components to have associated only canonical declarations."); 14726 14727 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14728 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14729 14730 assert((VD || FD) && "Only variables or fields are expected here!"); 14731 (void)FD; 14732 14733 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14734 // threadprivate variables cannot appear in a map clause. 14735 // OpenMP 4.5 [2.10.5, target update Construct] 14736 // threadprivate variables cannot appear in a from clause. 14737 if (VD && DSAS->isThreadPrivate(VD)) { 14738 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14739 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14740 << getOpenMPClauseName(CKind); 14741 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14742 continue; 14743 } 14744 14745 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14746 // A list item cannot appear in both a map clause and a data-sharing 14747 // attribute clause on the same construct. 14748 14749 // Check conflicts with other map clause expressions. We check the conflicts 14750 // with the current construct separately from the enclosing data 14751 // environment, because the restrictions are different. We only have to 14752 // check conflicts across regions for the map clauses. 14753 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14754 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14755 break; 14756 if (CKind == OMPC_map && 14757 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14758 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14759 break; 14760 14761 // OpenMP 4.5 [2.10.5, target update Construct] 14762 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14763 // If the type of a list item is a reference to a type T then the type will 14764 // be considered to be T for all purposes of this clause. 14765 auto I = llvm::find_if( 14766 CurComponents, 14767 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14768 return MC.getAssociatedDeclaration(); 14769 }); 14770 assert(I != CurComponents.end() && "Null decl on map clause."); 14771 QualType Type = 14772 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14773 14774 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14775 // A list item in a to or from clause must have a mappable type. 14776 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14777 // A list item must have a mappable type. 14778 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14779 DSAS, Type)) 14780 continue; 14781 14782 if (CKind == OMPC_map) { 14783 // target enter data 14784 // OpenMP [2.10.2, Restrictions, p. 99] 14785 // A map-type must be specified in all map clauses and must be either 14786 // to or alloc. 14787 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 14788 if (DKind == OMPD_target_enter_data && 14789 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 14790 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14791 << (IsMapTypeImplicit ? 1 : 0) 14792 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14793 << getOpenMPDirectiveName(DKind); 14794 continue; 14795 } 14796 14797 // target exit_data 14798 // OpenMP [2.10.3, Restrictions, p. 102] 14799 // A map-type must be specified in all map clauses and must be either 14800 // from, release, or delete. 14801 if (DKind == OMPD_target_exit_data && 14802 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 14803 MapType == OMPC_MAP_delete)) { 14804 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14805 << (IsMapTypeImplicit ? 1 : 0) 14806 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14807 << getOpenMPDirectiveName(DKind); 14808 continue; 14809 } 14810 14811 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14812 // A list item cannot appear in both a map clause and a data-sharing 14813 // attribute clause on the same construct 14814 // 14815 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 14816 // A list item cannot appear in both a map clause and a data-sharing 14817 // attribute clause on the same construct unless the construct is a 14818 // combined construct. 14819 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 14820 isOpenMPTargetExecutionDirective(DKind)) || 14821 DKind == OMPD_target)) { 14822 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14823 if (isOpenMPPrivate(DVar.CKind)) { 14824 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14825 << getOpenMPClauseName(DVar.CKind) 14826 << getOpenMPClauseName(OMPC_map) 14827 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 14828 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 14829 continue; 14830 } 14831 } 14832 } 14833 14834 // Try to find the associated user-defined mapper. 14835 ExprResult ER = buildUserDefinedMapperRef( 14836 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14837 Type.getCanonicalType(), UnresolvedMapper); 14838 if (ER.isInvalid()) 14839 continue; 14840 MVLI.UDMapperList.push_back(ER.get()); 14841 14842 // Save the current expression. 14843 MVLI.ProcessedVarList.push_back(RE); 14844 14845 // Store the components in the stack so that they can be used to check 14846 // against other clauses later on. 14847 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14848 /*WhereFoundClauseKind=*/OMPC_map); 14849 14850 // Save the components and declaration to create the clause. For purposes of 14851 // the clause creation, any component list that has has base 'this' uses 14852 // null as base declaration. 14853 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14854 MVLI.VarComponents.back().append(CurComponents.begin(), 14855 CurComponents.end()); 14856 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14857 : CurDeclaration); 14858 } 14859 } 14860 14861 OMPClause *Sema::ActOnOpenMPMapClause( 14862 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14863 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14864 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14865 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14866 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14867 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14868 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14869 OMPC_MAP_MODIFIER_unknown, 14870 OMPC_MAP_MODIFIER_unknown}; 14871 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14872 14873 // Process map-type-modifiers, flag errors for duplicate modifiers. 14874 unsigned Count = 0; 14875 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14876 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14877 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14878 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14879 continue; 14880 } 14881 assert(Count < OMPMapClause::NumberOfModifiers && 14882 "Modifiers exceed the allowed number of map type modifiers"); 14883 Modifiers[Count] = MapTypeModifiers[I]; 14884 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14885 ++Count; 14886 } 14887 14888 MappableVarListInfo MVLI(VarList); 14889 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14890 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14891 MapType, IsMapTypeImplicit); 14892 14893 // We need to produce a map clause even if we don't have variables so that 14894 // other diagnostics related with non-existing map clauses are accurate. 14895 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14896 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14897 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14898 MapperIdScopeSpec.getWithLocInContext(Context), 14899 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14900 } 14901 14902 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14903 TypeResult ParsedType) { 14904 assert(ParsedType.isUsable()); 14905 14906 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14907 if (ReductionType.isNull()) 14908 return QualType(); 14909 14910 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14911 // A type name in a declare reduction directive cannot be a function type, an 14912 // array type, a reference type, or a type qualified with const, volatile or 14913 // restrict. 14914 if (ReductionType.hasQualifiers()) { 14915 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14916 return QualType(); 14917 } 14918 14919 if (ReductionType->isFunctionType()) { 14920 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14921 return QualType(); 14922 } 14923 if (ReductionType->isReferenceType()) { 14924 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14925 return QualType(); 14926 } 14927 if (ReductionType->isArrayType()) { 14928 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14929 return QualType(); 14930 } 14931 return ReductionType; 14932 } 14933 14934 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14935 Scope *S, DeclContext *DC, DeclarationName Name, 14936 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14937 AccessSpecifier AS, Decl *PrevDeclInScope) { 14938 SmallVector<Decl *, 8> Decls; 14939 Decls.reserve(ReductionTypes.size()); 14940 14941 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14942 forRedeclarationInCurContext()); 14943 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14944 // A reduction-identifier may not be re-declared in the current scope for the 14945 // same type or for a type that is compatible according to the base language 14946 // rules. 14947 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14948 OMPDeclareReductionDecl *PrevDRD = nullptr; 14949 bool InCompoundScope = true; 14950 if (S != nullptr) { 14951 // Find previous declaration with the same name not referenced in other 14952 // declarations. 14953 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14954 InCompoundScope = 14955 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14956 LookupName(Lookup, S); 14957 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14958 /*AllowInlineNamespace=*/false); 14959 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14960 LookupResult::Filter Filter = Lookup.makeFilter(); 14961 while (Filter.hasNext()) { 14962 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14963 if (InCompoundScope) { 14964 auto I = UsedAsPrevious.find(PrevDecl); 14965 if (I == UsedAsPrevious.end()) 14966 UsedAsPrevious[PrevDecl] = false; 14967 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14968 UsedAsPrevious[D] = true; 14969 } 14970 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14971 PrevDecl->getLocation(); 14972 } 14973 Filter.done(); 14974 if (InCompoundScope) { 14975 for (const auto &PrevData : UsedAsPrevious) { 14976 if (!PrevData.second) { 14977 PrevDRD = PrevData.first; 14978 break; 14979 } 14980 } 14981 } 14982 } else if (PrevDeclInScope != nullptr) { 14983 auto *PrevDRDInScope = PrevDRD = 14984 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14985 do { 14986 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14987 PrevDRDInScope->getLocation(); 14988 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14989 } while (PrevDRDInScope != nullptr); 14990 } 14991 for (const auto &TyData : ReductionTypes) { 14992 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 14993 bool Invalid = false; 14994 if (I != PreviousRedeclTypes.end()) { 14995 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 14996 << TyData.first; 14997 Diag(I->second, diag::note_previous_definition); 14998 Invalid = true; 14999 } 15000 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15001 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15002 Name, TyData.first, PrevDRD); 15003 DC->addDecl(DRD); 15004 DRD->setAccess(AS); 15005 Decls.push_back(DRD); 15006 if (Invalid) 15007 DRD->setInvalidDecl(); 15008 else 15009 PrevDRD = DRD; 15010 } 15011 15012 return DeclGroupPtrTy::make( 15013 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15014 } 15015 15016 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15017 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15018 15019 // Enter new function scope. 15020 PushFunctionScope(); 15021 setFunctionHasBranchProtectedScope(); 15022 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15023 15024 if (S != nullptr) 15025 PushDeclContext(S, DRD); 15026 else 15027 CurContext = DRD; 15028 15029 PushExpressionEvaluationContext( 15030 ExpressionEvaluationContext::PotentiallyEvaluated); 15031 15032 QualType ReductionType = DRD->getType(); 15033 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15034 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15035 // uses semantics of argument handles by value, but it should be passed by 15036 // reference. C lang does not support references, so pass all parameters as 15037 // pointers. 15038 // Create 'T omp_in;' variable. 15039 VarDecl *OmpInParm = 15040 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15041 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15042 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15043 // uses semantics of argument handles by value, but it should be passed by 15044 // reference. C lang does not support references, so pass all parameters as 15045 // pointers. 15046 // Create 'T omp_out;' variable. 15047 VarDecl *OmpOutParm = 15048 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15049 if (S != nullptr) { 15050 PushOnScopeChains(OmpInParm, S); 15051 PushOnScopeChains(OmpOutParm, S); 15052 } else { 15053 DRD->addDecl(OmpInParm); 15054 DRD->addDecl(OmpOutParm); 15055 } 15056 Expr *InE = 15057 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15058 Expr *OutE = 15059 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15060 DRD->setCombinerData(InE, OutE); 15061 } 15062 15063 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15064 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15065 DiscardCleanupsInEvaluationContext(); 15066 PopExpressionEvaluationContext(); 15067 15068 PopDeclContext(); 15069 PopFunctionScopeInfo(); 15070 15071 if (Combiner != nullptr) 15072 DRD->setCombiner(Combiner); 15073 else 15074 DRD->setInvalidDecl(); 15075 } 15076 15077 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15078 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15079 15080 // Enter new function scope. 15081 PushFunctionScope(); 15082 setFunctionHasBranchProtectedScope(); 15083 15084 if (S != nullptr) 15085 PushDeclContext(S, DRD); 15086 else 15087 CurContext = DRD; 15088 15089 PushExpressionEvaluationContext( 15090 ExpressionEvaluationContext::PotentiallyEvaluated); 15091 15092 QualType ReductionType = DRD->getType(); 15093 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15094 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15095 // uses semantics of argument handles by value, but it should be passed by 15096 // reference. C lang does not support references, so pass all parameters as 15097 // pointers. 15098 // Create 'T omp_priv;' variable. 15099 VarDecl *OmpPrivParm = 15100 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15101 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15102 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15103 // uses semantics of argument handles by value, but it should be passed by 15104 // reference. C lang does not support references, so pass all parameters as 15105 // pointers. 15106 // Create 'T omp_orig;' variable. 15107 VarDecl *OmpOrigParm = 15108 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15109 if (S != nullptr) { 15110 PushOnScopeChains(OmpPrivParm, S); 15111 PushOnScopeChains(OmpOrigParm, S); 15112 } else { 15113 DRD->addDecl(OmpPrivParm); 15114 DRD->addDecl(OmpOrigParm); 15115 } 15116 Expr *OrigE = 15117 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15118 Expr *PrivE = 15119 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15120 DRD->setInitializerData(OrigE, PrivE); 15121 return OmpPrivParm; 15122 } 15123 15124 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15125 VarDecl *OmpPrivParm) { 15126 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15127 DiscardCleanupsInEvaluationContext(); 15128 PopExpressionEvaluationContext(); 15129 15130 PopDeclContext(); 15131 PopFunctionScopeInfo(); 15132 15133 if (Initializer != nullptr) { 15134 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15135 } else if (OmpPrivParm->hasInit()) { 15136 DRD->setInitializer(OmpPrivParm->getInit(), 15137 OmpPrivParm->isDirectInit() 15138 ? OMPDeclareReductionDecl::DirectInit 15139 : OMPDeclareReductionDecl::CopyInit); 15140 } else { 15141 DRD->setInvalidDecl(); 15142 } 15143 } 15144 15145 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15146 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15147 for (Decl *D : DeclReductions.get()) { 15148 if (IsValid) { 15149 if (S) 15150 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15151 /*AddToContext=*/false); 15152 } else { 15153 D->setInvalidDecl(); 15154 } 15155 } 15156 return DeclReductions; 15157 } 15158 15159 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15160 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15161 QualType T = TInfo->getType(); 15162 if (D.isInvalidType()) 15163 return true; 15164 15165 if (getLangOpts().CPlusPlus) { 15166 // Check that there are no default arguments (C++ only). 15167 CheckExtraCXXDefaultArguments(D); 15168 } 15169 15170 return CreateParsedType(T, TInfo); 15171 } 15172 15173 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15174 TypeResult ParsedType) { 15175 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15176 15177 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15178 assert(!MapperType.isNull() && "Expect valid mapper type"); 15179 15180 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15181 // The type must be of struct, union or class type in C and C++ 15182 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15183 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15184 return QualType(); 15185 } 15186 return MapperType; 15187 } 15188 15189 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15190 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15191 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15192 Decl *PrevDeclInScope) { 15193 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15194 forRedeclarationInCurContext()); 15195 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15196 // A mapper-identifier may not be redeclared in the current scope for the 15197 // same type or for a type that is compatible according to the base language 15198 // rules. 15199 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15200 OMPDeclareMapperDecl *PrevDMD = nullptr; 15201 bool InCompoundScope = true; 15202 if (S != nullptr) { 15203 // Find previous declaration with the same name not referenced in other 15204 // declarations. 15205 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15206 InCompoundScope = 15207 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15208 LookupName(Lookup, S); 15209 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15210 /*AllowInlineNamespace=*/false); 15211 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15212 LookupResult::Filter Filter = Lookup.makeFilter(); 15213 while (Filter.hasNext()) { 15214 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15215 if (InCompoundScope) { 15216 auto I = UsedAsPrevious.find(PrevDecl); 15217 if (I == UsedAsPrevious.end()) 15218 UsedAsPrevious[PrevDecl] = false; 15219 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15220 UsedAsPrevious[D] = true; 15221 } 15222 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15223 PrevDecl->getLocation(); 15224 } 15225 Filter.done(); 15226 if (InCompoundScope) { 15227 for (const auto &PrevData : UsedAsPrevious) { 15228 if (!PrevData.second) { 15229 PrevDMD = PrevData.first; 15230 break; 15231 } 15232 } 15233 } 15234 } else if (PrevDeclInScope) { 15235 auto *PrevDMDInScope = PrevDMD = 15236 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15237 do { 15238 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15239 PrevDMDInScope->getLocation(); 15240 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15241 } while (PrevDMDInScope != nullptr); 15242 } 15243 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15244 bool Invalid = false; 15245 if (I != PreviousRedeclTypes.end()) { 15246 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15247 << MapperType << Name; 15248 Diag(I->second, diag::note_previous_definition); 15249 Invalid = true; 15250 } 15251 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15252 MapperType, VN, PrevDMD); 15253 DC->addDecl(DMD); 15254 DMD->setAccess(AS); 15255 if (Invalid) 15256 DMD->setInvalidDecl(); 15257 15258 // Enter new function scope. 15259 PushFunctionScope(); 15260 setFunctionHasBranchProtectedScope(); 15261 15262 CurContext = DMD; 15263 15264 return DMD; 15265 } 15266 15267 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15268 Scope *S, 15269 QualType MapperType, 15270 SourceLocation StartLoc, 15271 DeclarationName VN) { 15272 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15273 if (S) 15274 PushOnScopeChains(VD, S); 15275 else 15276 DMD->addDecl(VD); 15277 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15278 DMD->setMapperVarRef(MapperVarRefExpr); 15279 } 15280 15281 Sema::DeclGroupPtrTy 15282 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15283 ArrayRef<OMPClause *> ClauseList) { 15284 PopDeclContext(); 15285 PopFunctionScopeInfo(); 15286 15287 if (D) { 15288 if (S) 15289 PushOnScopeChains(D, S, /*AddToContext=*/false); 15290 D->CreateClauses(Context, ClauseList); 15291 } 15292 15293 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15294 } 15295 15296 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15297 SourceLocation StartLoc, 15298 SourceLocation LParenLoc, 15299 SourceLocation EndLoc) { 15300 Expr *ValExpr = NumTeams; 15301 Stmt *HelperValStmt = nullptr; 15302 15303 // OpenMP [teams Constrcut, Restrictions] 15304 // The num_teams expression must evaluate to a positive integer value. 15305 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15306 /*StrictlyPositive=*/true)) 15307 return nullptr; 15308 15309 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15310 OpenMPDirectiveKind CaptureRegion = 15311 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15312 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15313 ValExpr = MakeFullExpr(ValExpr).get(); 15314 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15315 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15316 HelperValStmt = buildPreInits(Context, Captures); 15317 } 15318 15319 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15320 StartLoc, LParenLoc, EndLoc); 15321 } 15322 15323 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15324 SourceLocation StartLoc, 15325 SourceLocation LParenLoc, 15326 SourceLocation EndLoc) { 15327 Expr *ValExpr = ThreadLimit; 15328 Stmt *HelperValStmt = nullptr; 15329 15330 // OpenMP [teams Constrcut, Restrictions] 15331 // The thread_limit expression must evaluate to a positive integer value. 15332 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15333 /*StrictlyPositive=*/true)) 15334 return nullptr; 15335 15336 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15337 OpenMPDirectiveKind CaptureRegion = 15338 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15339 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15340 ValExpr = MakeFullExpr(ValExpr).get(); 15341 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15342 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15343 HelperValStmt = buildPreInits(Context, Captures); 15344 } 15345 15346 return new (Context) OMPThreadLimitClause( 15347 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15348 } 15349 15350 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15351 SourceLocation StartLoc, 15352 SourceLocation LParenLoc, 15353 SourceLocation EndLoc) { 15354 Expr *ValExpr = Priority; 15355 15356 // OpenMP [2.9.1, task Constrcut] 15357 // The priority-value is a non-negative numerical scalar expression. 15358 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 15359 /*StrictlyPositive=*/false)) 15360 return nullptr; 15361 15362 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15363 } 15364 15365 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15366 SourceLocation StartLoc, 15367 SourceLocation LParenLoc, 15368 SourceLocation EndLoc) { 15369 Expr *ValExpr = Grainsize; 15370 15371 // OpenMP [2.9.2, taskloop Constrcut] 15372 // The parameter of the grainsize clause must be a positive integer 15373 // expression. 15374 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 15375 /*StrictlyPositive=*/true)) 15376 return nullptr; 15377 15378 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15379 } 15380 15381 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15382 SourceLocation StartLoc, 15383 SourceLocation LParenLoc, 15384 SourceLocation EndLoc) { 15385 Expr *ValExpr = NumTasks; 15386 15387 // OpenMP [2.9.2, taskloop Constrcut] 15388 // The parameter of the num_tasks clause must be a positive integer 15389 // expression. 15390 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 15391 /*StrictlyPositive=*/true)) 15392 return nullptr; 15393 15394 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15395 } 15396 15397 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15398 SourceLocation LParenLoc, 15399 SourceLocation EndLoc) { 15400 // OpenMP [2.13.2, critical construct, Description] 15401 // ... where hint-expression is an integer constant expression that evaluates 15402 // to a valid lock hint. 15403 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15404 if (HintExpr.isInvalid()) 15405 return nullptr; 15406 return new (Context) 15407 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 15408 } 15409 15410 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 15411 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 15412 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 15413 SourceLocation EndLoc) { 15414 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 15415 std::string Values; 15416 Values += "'"; 15417 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 15418 Values += "'"; 15419 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 15420 << Values << getOpenMPClauseName(OMPC_dist_schedule); 15421 return nullptr; 15422 } 15423 Expr *ValExpr = ChunkSize; 15424 Stmt *HelperValStmt = nullptr; 15425 if (ChunkSize) { 15426 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 15427 !ChunkSize->isInstantiationDependent() && 15428 !ChunkSize->containsUnexpandedParameterPack()) { 15429 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 15430 ExprResult Val = 15431 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 15432 if (Val.isInvalid()) 15433 return nullptr; 15434 15435 ValExpr = Val.get(); 15436 15437 // OpenMP [2.7.1, Restrictions] 15438 // chunk_size must be a loop invariant integer expression with a positive 15439 // value. 15440 llvm::APSInt Result; 15441 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 15442 if (Result.isSigned() && !Result.isStrictlyPositive()) { 15443 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 15444 << "dist_schedule" << ChunkSize->getSourceRange(); 15445 return nullptr; 15446 } 15447 } else if (getOpenMPCaptureRegionForClause( 15448 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 15449 OMPD_unknown && 15450 !CurContext->isDependentContext()) { 15451 ValExpr = MakeFullExpr(ValExpr).get(); 15452 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15453 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15454 HelperValStmt = buildPreInits(Context, Captures); 15455 } 15456 } 15457 } 15458 15459 return new (Context) 15460 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 15461 Kind, ValExpr, HelperValStmt); 15462 } 15463 15464 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 15465 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 15466 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 15467 SourceLocation KindLoc, SourceLocation EndLoc) { 15468 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 15469 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 15470 std::string Value; 15471 SourceLocation Loc; 15472 Value += "'"; 15473 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 15474 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15475 OMPC_DEFAULTMAP_MODIFIER_tofrom); 15476 Loc = MLoc; 15477 } else { 15478 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15479 OMPC_DEFAULTMAP_scalar); 15480 Loc = KindLoc; 15481 } 15482 Value += "'"; 15483 Diag(Loc, diag::err_omp_unexpected_clause_value) 15484 << Value << getOpenMPClauseName(OMPC_defaultmap); 15485 return nullptr; 15486 } 15487 DSAStack->setDefaultDMAToFromScalar(StartLoc); 15488 15489 return new (Context) 15490 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 15491 } 15492 15493 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 15494 DeclContext *CurLexicalContext = getCurLexicalContext(); 15495 if (!CurLexicalContext->isFileContext() && 15496 !CurLexicalContext->isExternCContext() && 15497 !CurLexicalContext->isExternCXXContext() && 15498 !isa<CXXRecordDecl>(CurLexicalContext) && 15499 !isa<ClassTemplateDecl>(CurLexicalContext) && 15500 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 15501 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 15502 Diag(Loc, diag::err_omp_region_not_file_context); 15503 return false; 15504 } 15505 ++DeclareTargetNestingLevel; 15506 return true; 15507 } 15508 15509 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 15510 assert(DeclareTargetNestingLevel > 0 && 15511 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 15512 --DeclareTargetNestingLevel; 15513 } 15514 15515 NamedDecl * 15516 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 15517 const DeclarationNameInfo &Id, 15518 NamedDeclSetType &SameDirectiveDecls) { 15519 LookupResult Lookup(*this, Id, LookupOrdinaryName); 15520 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 15521 15522 if (Lookup.isAmbiguous()) 15523 return nullptr; 15524 Lookup.suppressDiagnostics(); 15525 15526 if (!Lookup.isSingleResult()) { 15527 VarOrFuncDeclFilterCCC CCC(*this); 15528 if (TypoCorrection Corrected = 15529 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 15530 CTK_ErrorRecovery)) { 15531 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 15532 << Id.getName()); 15533 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 15534 return nullptr; 15535 } 15536 15537 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 15538 return nullptr; 15539 } 15540 15541 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 15542 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 15543 !isa<FunctionTemplateDecl>(ND)) { 15544 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 15545 return nullptr; 15546 } 15547 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 15548 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 15549 return ND; 15550 } 15551 15552 void Sema::ActOnOpenMPDeclareTargetName( 15553 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 15554 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 15555 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 15556 isa<FunctionTemplateDecl>(ND)) && 15557 "Expected variable, function or function template."); 15558 15559 // Diagnose marking after use as it may lead to incorrect diagnosis and 15560 // codegen. 15561 if (LangOpts.OpenMP >= 50 && 15562 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 15563 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 15564 15565 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15566 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 15567 if (DevTy.hasValue() && *DevTy != DT) { 15568 Diag(Loc, diag::err_omp_device_type_mismatch) 15569 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 15570 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 15571 return; 15572 } 15573 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15574 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 15575 if (!Res) { 15576 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 15577 SourceRange(Loc, Loc)); 15578 ND->addAttr(A); 15579 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15580 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 15581 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 15582 } else if (*Res != MT) { 15583 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 15584 } 15585 } 15586 15587 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 15588 Sema &SemaRef, Decl *D) { 15589 if (!D || !isa<VarDecl>(D)) 15590 return; 15591 auto *VD = cast<VarDecl>(D); 15592 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15593 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15594 if (SemaRef.LangOpts.OpenMP >= 50 && 15595 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 15596 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 15597 VD->hasGlobalStorage()) { 15598 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15599 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15600 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 15601 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 15602 // If a lambda declaration and definition appears between a 15603 // declare target directive and the matching end declare target 15604 // directive, all variables that are captured by the lambda 15605 // expression must also appear in a to clause. 15606 SemaRef.Diag(VD->getLocation(), 15607 diag::err_omp_lambda_capture_in_declare_target_not_to); 15608 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 15609 << VD << 0 << SR; 15610 return; 15611 } 15612 } 15613 if (MapTy.hasValue()) 15614 return; 15615 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 15616 SemaRef.Diag(SL, diag::note_used_here) << SR; 15617 } 15618 15619 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 15620 Sema &SemaRef, DSAStackTy *Stack, 15621 ValueDecl *VD) { 15622 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 15623 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 15624 /*FullCheck=*/false); 15625 } 15626 15627 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 15628 SourceLocation IdLoc) { 15629 if (!D || D->isInvalidDecl()) 15630 return; 15631 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 15632 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 15633 if (auto *VD = dyn_cast<VarDecl>(D)) { 15634 // Only global variables can be marked as declare target. 15635 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 15636 !VD->isStaticDataMember()) 15637 return; 15638 // 2.10.6: threadprivate variable cannot appear in a declare target 15639 // directive. 15640 if (DSAStack->isThreadPrivate(VD)) { 15641 Diag(SL, diag::err_omp_threadprivate_in_target); 15642 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 15643 return; 15644 } 15645 } 15646 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 15647 D = FTD->getTemplatedDecl(); 15648 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 15649 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15650 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 15651 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 15652 Diag(IdLoc, diag::err_omp_function_in_link_clause); 15653 Diag(FD->getLocation(), diag::note_defined_here) << FD; 15654 return; 15655 } 15656 // Mark the function as must be emitted for the device. 15657 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15658 OMPDeclareTargetDeclAttr::getDeviceType(FD); 15659 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 15660 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 15661 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 15662 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 15663 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 15664 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 15665 } 15666 if (auto *VD = dyn_cast<ValueDecl>(D)) { 15667 // Problem if any with var declared with incomplete type will be reported 15668 // as normal, so no need to check it here. 15669 if ((E || !VD->getType()->isIncompleteType()) && 15670 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 15671 return; 15672 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 15673 // Checking declaration inside declare target region. 15674 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 15675 isa<FunctionTemplateDecl>(D)) { 15676 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 15677 Context, OMPDeclareTargetDeclAttr::MT_To, 15678 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 15679 D->addAttr(A); 15680 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15681 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 15682 } 15683 return; 15684 } 15685 } 15686 if (!E) 15687 return; 15688 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 15689 } 15690 15691 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15692 CXXScopeSpec &MapperIdScopeSpec, 15693 DeclarationNameInfo &MapperId, 15694 const OMPVarListLocTy &Locs, 15695 ArrayRef<Expr *> UnresolvedMappers) { 15696 MappableVarListInfo MVLI(VarList); 15697 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15698 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15699 if (MVLI.ProcessedVarList.empty()) 15700 return nullptr; 15701 15702 return OMPToClause::Create( 15703 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15704 MVLI.VarComponents, MVLI.UDMapperList, 15705 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15706 } 15707 15708 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15709 CXXScopeSpec &MapperIdScopeSpec, 15710 DeclarationNameInfo &MapperId, 15711 const OMPVarListLocTy &Locs, 15712 ArrayRef<Expr *> UnresolvedMappers) { 15713 MappableVarListInfo MVLI(VarList); 15714 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15715 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15716 if (MVLI.ProcessedVarList.empty()) 15717 return nullptr; 15718 15719 return OMPFromClause::Create( 15720 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15721 MVLI.VarComponents, MVLI.UDMapperList, 15722 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15723 } 15724 15725 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 15726 const OMPVarListLocTy &Locs) { 15727 MappableVarListInfo MVLI(VarList); 15728 SmallVector<Expr *, 8> PrivateCopies; 15729 SmallVector<Expr *, 8> Inits; 15730 15731 for (Expr *RefExpr : VarList) { 15732 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 15733 SourceLocation ELoc; 15734 SourceRange ERange; 15735 Expr *SimpleRefExpr = RefExpr; 15736 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15737 if (Res.second) { 15738 // It will be analyzed later. 15739 MVLI.ProcessedVarList.push_back(RefExpr); 15740 PrivateCopies.push_back(nullptr); 15741 Inits.push_back(nullptr); 15742 } 15743 ValueDecl *D = Res.first; 15744 if (!D) 15745 continue; 15746 15747 QualType Type = D->getType(); 15748 Type = Type.getNonReferenceType().getUnqualifiedType(); 15749 15750 auto *VD = dyn_cast<VarDecl>(D); 15751 15752 // Item should be a pointer or reference to pointer. 15753 if (!Type->isPointerType()) { 15754 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 15755 << 0 << RefExpr->getSourceRange(); 15756 continue; 15757 } 15758 15759 // Build the private variable and the expression that refers to it. 15760 auto VDPrivate = 15761 buildVarDecl(*this, ELoc, Type, D->getName(), 15762 D->hasAttrs() ? &D->getAttrs() : nullptr, 15763 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15764 if (VDPrivate->isInvalidDecl()) 15765 continue; 15766 15767 CurContext->addDecl(VDPrivate); 15768 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15769 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15770 15771 // Add temporary variable to initialize the private copy of the pointer. 15772 VarDecl *VDInit = 15773 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15774 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15775 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15776 AddInitializerToDecl(VDPrivate, 15777 DefaultLvalueConversion(VDInitRefExpr).get(), 15778 /*DirectInit=*/false); 15779 15780 // If required, build a capture to implement the privatization initialized 15781 // with the current list item value. 15782 DeclRefExpr *Ref = nullptr; 15783 if (!VD) 15784 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15785 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 15786 PrivateCopies.push_back(VDPrivateRefExpr); 15787 Inits.push_back(VDInitRefExpr); 15788 15789 // We need to add a data sharing attribute for this variable to make sure it 15790 // is correctly captured. A variable that shows up in a use_device_ptr has 15791 // similar properties of a first private variable. 15792 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15793 15794 // Create a mappable component for the list item. List items in this clause 15795 // only need a component. 15796 MVLI.VarBaseDeclarations.push_back(D); 15797 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15798 MVLI.VarComponents.back().push_back( 15799 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 15800 } 15801 15802 if (MVLI.ProcessedVarList.empty()) 15803 return nullptr; 15804 15805 return OMPUseDevicePtrClause::Create( 15806 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 15807 MVLI.VarBaseDeclarations, MVLI.VarComponents); 15808 } 15809 15810 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 15811 const OMPVarListLocTy &Locs) { 15812 MappableVarListInfo MVLI(VarList); 15813 for (Expr *RefExpr : VarList) { 15814 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 15815 SourceLocation ELoc; 15816 SourceRange ERange; 15817 Expr *SimpleRefExpr = RefExpr; 15818 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15819 if (Res.second) { 15820 // It will be analyzed later. 15821 MVLI.ProcessedVarList.push_back(RefExpr); 15822 } 15823 ValueDecl *D = Res.first; 15824 if (!D) 15825 continue; 15826 15827 QualType Type = D->getType(); 15828 // item should be a pointer or array or reference to pointer or array 15829 if (!Type.getNonReferenceType()->isPointerType() && 15830 !Type.getNonReferenceType()->isArrayType()) { 15831 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 15832 << 0 << RefExpr->getSourceRange(); 15833 continue; 15834 } 15835 15836 // Check if the declaration in the clause does not show up in any data 15837 // sharing attribute. 15838 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15839 if (isOpenMPPrivate(DVar.CKind)) { 15840 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15841 << getOpenMPClauseName(DVar.CKind) 15842 << getOpenMPClauseName(OMPC_is_device_ptr) 15843 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15844 reportOriginalDsa(*this, DSAStack, D, DVar); 15845 continue; 15846 } 15847 15848 const Expr *ConflictExpr; 15849 if (DSAStack->checkMappableExprComponentListsForDecl( 15850 D, /*CurrentRegionOnly=*/true, 15851 [&ConflictExpr]( 15852 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 15853 OpenMPClauseKind) -> bool { 15854 ConflictExpr = R.front().getAssociatedExpression(); 15855 return true; 15856 })) { 15857 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 15858 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 15859 << ConflictExpr->getSourceRange(); 15860 continue; 15861 } 15862 15863 // Store the components in the stack so that they can be used to check 15864 // against other clauses later on. 15865 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 15866 DSAStack->addMappableExpressionComponents( 15867 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 15868 15869 // Record the expression we've just processed. 15870 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 15871 15872 // Create a mappable component for the list item. List items in this clause 15873 // only need a component. We use a null declaration to signal fields in 15874 // 'this'. 15875 assert((isa<DeclRefExpr>(SimpleRefExpr) || 15876 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 15877 "Unexpected device pointer expression!"); 15878 MVLI.VarBaseDeclarations.push_back( 15879 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 15880 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15881 MVLI.VarComponents.back().push_back(MC); 15882 } 15883 15884 if (MVLI.ProcessedVarList.empty()) 15885 return nullptr; 15886 15887 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 15888 MVLI.VarBaseDeclarations, 15889 MVLI.VarComponents); 15890 } 15891 15892 OMPClause *Sema::ActOnOpenMPAllocateClause( 15893 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15894 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15895 if (Allocator) { 15896 // OpenMP [2.11.4 allocate Clause, Description] 15897 // allocator is an expression of omp_allocator_handle_t type. 15898 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15899 return nullptr; 15900 15901 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15902 if (AllocatorRes.isInvalid()) 15903 return nullptr; 15904 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15905 DSAStack->getOMPAllocatorHandleT(), 15906 Sema::AA_Initializing, 15907 /*AllowExplicit=*/true); 15908 if (AllocatorRes.isInvalid()) 15909 return nullptr; 15910 Allocator = AllocatorRes.get(); 15911 } else { 15912 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15913 // allocate clauses that appear on a target construct or on constructs in a 15914 // target region must specify an allocator expression unless a requires 15915 // directive with the dynamic_allocators clause is present in the same 15916 // compilation unit. 15917 if (LangOpts.OpenMPIsDevice && 15918 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15919 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15920 } 15921 // Analyze and build list of variables. 15922 SmallVector<Expr *, 8> Vars; 15923 for (Expr *RefExpr : VarList) { 15924 assert(RefExpr && "NULL expr in OpenMP private clause."); 15925 SourceLocation ELoc; 15926 SourceRange ERange; 15927 Expr *SimpleRefExpr = RefExpr; 15928 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15929 if (Res.second) { 15930 // It will be analyzed later. 15931 Vars.push_back(RefExpr); 15932 } 15933 ValueDecl *D = Res.first; 15934 if (!D) 15935 continue; 15936 15937 auto *VD = dyn_cast<VarDecl>(D); 15938 DeclRefExpr *Ref = nullptr; 15939 if (!VD && !CurContext->isDependentContext()) 15940 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15941 Vars.push_back((VD || CurContext->isDependentContext()) 15942 ? RefExpr->IgnoreParens() 15943 : Ref); 15944 } 15945 15946 if (Vars.empty()) 15947 return nullptr; 15948 15949 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15950 ColonLoc, EndLoc, Vars); 15951 } 15952