1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 bool HasMutipleLoops = false; 143 const Decl *PossiblyLoopCounter = nullptr; 144 bool NowaitRegion = false; 145 bool CancelRegion = false; 146 bool LoopStart = false; 147 bool BodyComplete = false; 148 SourceLocation InnerTeamsRegionLoc; 149 /// Reference to the taskgroup task_reduction reference expression. 150 Expr *TaskgroupReductionRef = nullptr; 151 llvm::DenseSet<QualType> MappedClassesQualTypes; 152 /// List of globals marked as declare target link in this target region 153 /// (isOpenMPTargetExecutionDirective(Directive) == true). 154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 156 Scope *CurScope, SourceLocation Loc) 157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 158 ConstructLoc(Loc) {} 159 SharingMapTy() = default; 160 }; 161 162 using StackTy = SmallVector<SharingMapTy, 4>; 163 164 /// Stack of used declaration and their data-sharing attributes. 165 DeclSAMapTy Threadprivates; 166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 168 /// true, if check for DSA must be from parent directive, false, if 169 /// from current directive. 170 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 171 Sema &SemaRef; 172 bool ForceCapturing = false; 173 /// true if all the variables in the target executable directives must be 174 /// captured by reference. 175 bool ForceCaptureByReferenceInTargetExecutable = false; 176 CriticalsWithHintsTy Criticals; 177 unsigned IgnoredStackElements = 0; 178 179 /// Iterators over the stack iterate in order from innermost to outermost 180 /// directive. 181 using const_iterator = StackTy::const_reverse_iterator; 182 const_iterator begin() const { 183 return Stack.empty() ? const_iterator() 184 : Stack.back().first.rbegin() + IgnoredStackElements; 185 } 186 const_iterator end() const { 187 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 188 } 189 using iterator = StackTy::reverse_iterator; 190 iterator begin() { 191 return Stack.empty() ? iterator() 192 : Stack.back().first.rbegin() + IgnoredStackElements; 193 } 194 iterator end() { 195 return Stack.empty() ? iterator() : Stack.back().first.rend(); 196 } 197 198 // Convenience operations to get at the elements of the stack. 199 200 bool isStackEmpty() const { 201 return Stack.empty() || 202 Stack.back().second != CurrentNonCapturingFunctionScope || 203 Stack.back().first.size() <= IgnoredStackElements; 204 } 205 size_t getStackSize() const { 206 return isStackEmpty() ? 0 207 : Stack.back().first.size() - IgnoredStackElements; 208 } 209 210 SharingMapTy *getTopOfStackOrNull() { 211 size_t Size = getStackSize(); 212 if (Size == 0) 213 return nullptr; 214 return &Stack.back().first[Size - 1]; 215 } 216 const SharingMapTy *getTopOfStackOrNull() const { 217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 218 } 219 SharingMapTy &getTopOfStack() { 220 assert(!isStackEmpty() && "no current directive"); 221 return *getTopOfStackOrNull(); 222 } 223 const SharingMapTy &getTopOfStack() const { 224 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 225 } 226 227 SharingMapTy *getSecondOnStackOrNull() { 228 size_t Size = getStackSize(); 229 if (Size <= 1) 230 return nullptr; 231 return &Stack.back().first[Size - 2]; 232 } 233 const SharingMapTy *getSecondOnStackOrNull() const { 234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 235 } 236 237 /// Get the stack element at a certain level (previously returned by 238 /// \c getNestingLevel). 239 /// 240 /// Note that nesting levels count from outermost to innermost, and this is 241 /// the reverse of our iteration order where new inner levels are pushed at 242 /// the front of the stack. 243 SharingMapTy &getStackElemAtLevel(unsigned Level) { 244 assert(Level < getStackSize() && "no such stack element"); 245 return Stack.back().first[Level]; 246 } 247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 249 } 250 251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 252 253 /// Checks if the variable is a local for OpenMP region. 254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 255 256 /// Vector of previously declared requires directives 257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 258 /// omp_allocator_handle_t type. 259 QualType OMPAllocatorHandleT; 260 /// Expression for the predefined allocators. 261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 262 nullptr}; 263 /// Vector of previously encountered target directives 264 SmallVector<SourceLocation, 2> TargetLocations; 265 266 public: 267 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 268 269 /// Sets omp_allocator_handle_t type. 270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 271 /// Gets omp_allocator_handle_t type. 272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 273 /// Sets the given default allocator. 274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 275 Expr *Allocator) { 276 OMPPredefinedAllocators[AllocatorKind] = Allocator; 277 } 278 /// Returns the specified default allocator. 279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 280 return OMPPredefinedAllocators[AllocatorKind]; 281 } 282 283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 284 OpenMPClauseKind getClauseParsingMode() const { 285 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 286 return ClauseKindMode; 287 } 288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 289 290 bool isBodyComplete() const { 291 const SharingMapTy *Top = getTopOfStackOrNull(); 292 return Top && Top->BodyComplete; 293 } 294 void setBodyComplete() { 295 getTopOfStack().BodyComplete = true; 296 } 297 298 bool isForceVarCapturing() const { return ForceCapturing; } 299 void setForceVarCapturing(bool V) { ForceCapturing = V; } 300 301 void setForceCaptureByReferenceInTargetExecutable(bool V) { 302 ForceCaptureByReferenceInTargetExecutable = V; 303 } 304 bool isForceCaptureByReferenceInTargetExecutable() const { 305 return ForceCaptureByReferenceInTargetExecutable; 306 } 307 308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 309 Scope *CurScope, SourceLocation Loc) { 310 assert(!IgnoredStackElements && 311 "cannot change stack while ignoring elements"); 312 if (Stack.empty() || 313 Stack.back().second != CurrentNonCapturingFunctionScope) 314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 316 Stack.back().first.back().DefaultAttrLoc = Loc; 317 } 318 319 void pop() { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 assert(!Stack.back().first.empty() && 323 "Data-sharing attributes stack is empty!"); 324 Stack.back().first.pop_back(); 325 } 326 327 /// RAII object to temporarily leave the scope of a directive when we want to 328 /// logically operate in its parent. 329 class ParentDirectiveScope { 330 DSAStackTy &Self; 331 bool Active; 332 public: 333 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 334 : Self(Self), Active(false) { 335 if (Activate) 336 enable(); 337 } 338 ~ParentDirectiveScope() { disable(); } 339 void disable() { 340 if (Active) { 341 --Self.IgnoredStackElements; 342 Active = false; 343 } 344 } 345 void enable() { 346 if (!Active) { 347 ++Self.IgnoredStackElements; 348 Active = true; 349 } 350 } 351 }; 352 353 /// Marks that we're started loop parsing. 354 void loopInit() { 355 assert(isOpenMPLoopDirective(getCurrentDirective()) && 356 "Expected loop-based directive."); 357 getTopOfStack().LoopStart = true; 358 } 359 /// Start capturing of the variables in the loop context. 360 void loopStart() { 361 assert(isOpenMPLoopDirective(getCurrentDirective()) && 362 "Expected loop-based directive."); 363 getTopOfStack().LoopStart = false; 364 } 365 /// true, if variables are captured, false otherwise. 366 bool isLoopStarted() const { 367 assert(isOpenMPLoopDirective(getCurrentDirective()) && 368 "Expected loop-based directive."); 369 return !getTopOfStack().LoopStart; 370 } 371 /// Marks (or clears) declaration as possibly loop counter. 372 void resetPossibleLoopCounter(const Decl *D = nullptr) { 373 getTopOfStack().PossiblyLoopCounter = 374 D ? D->getCanonicalDecl() : D; 375 } 376 /// Gets the possible loop counter decl. 377 const Decl *getPossiblyLoopCunter() const { 378 return getTopOfStack().PossiblyLoopCounter; 379 } 380 /// Start new OpenMP region stack in new non-capturing function. 381 void pushFunction() { 382 assert(!IgnoredStackElements && 383 "cannot change stack while ignoring elements"); 384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 385 assert(!isa<CapturingScopeInfo>(CurFnScope)); 386 CurrentNonCapturingFunctionScope = CurFnScope; 387 } 388 /// Pop region stack for non-capturing function. 389 void popFunction(const FunctionScopeInfo *OldFSI) { 390 assert(!IgnoredStackElements && 391 "cannot change stack while ignoring elements"); 392 if (!Stack.empty() && Stack.back().second == OldFSI) { 393 assert(Stack.back().first.empty()); 394 Stack.pop_back(); 395 } 396 CurrentNonCapturingFunctionScope = nullptr; 397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 398 if (!isa<CapturingScopeInfo>(FSI)) { 399 CurrentNonCapturingFunctionScope = FSI; 400 break; 401 } 402 } 403 } 404 405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 407 } 408 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 409 getCriticalWithHint(const DeclarationNameInfo &Name) const { 410 auto I = Criticals.find(Name.getAsString()); 411 if (I != Criticals.end()) 412 return I->second; 413 return std::make_pair(nullptr, llvm::APSInt()); 414 } 415 /// If 'aligned' declaration for given variable \a D was not seen yet, 416 /// add it and return NULL; otherwise return previous occurrence's expression 417 /// for diagnostics. 418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 419 420 /// Register specified variable as loop control variable. 421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 422 /// Check if the specified variable is a loop control variable for 423 /// current region. 424 /// \return The index of the loop control variable in the list of associated 425 /// for-loops (from outer to inner). 426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 427 /// Check if the specified variable is a loop control variable for 428 /// parent region. 429 /// \return The index of the loop control variable in the list of associated 430 /// for-loops (from outer to inner). 431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 432 /// Get the loop control variable for the I-th loop (or nullptr) in 433 /// parent directive. 434 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 435 436 /// Adds explicit data sharing attribute to the specified declaration. 437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 438 DeclRefExpr *PrivateCopy = nullptr); 439 440 /// Adds additional information for the reduction items with the reduction id 441 /// represented as an operator. 442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 443 BinaryOperatorKind BOK); 444 /// Adds additional information for the reduction items with the reduction id 445 /// represented as reduction identifier. 446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 447 const Expr *ReductionRef); 448 /// Returns the location and reduction operation from the innermost parent 449 /// region for the given \p D. 450 const DSAVarData 451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 452 BinaryOperatorKind &BOK, 453 Expr *&TaskgroupDescriptor) const; 454 /// Returns the location and reduction operation from the innermost parent 455 /// region for the given \p D. 456 const DSAVarData 457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 458 const Expr *&ReductionRef, 459 Expr *&TaskgroupDescriptor) const; 460 /// Return reduction reference expression for the current taskgroup. 461 Expr *getTaskgroupReductionRef() const { 462 assert(getTopOfStack().Directive == OMPD_taskgroup && 463 "taskgroup reference expression requested for non taskgroup " 464 "directive."); 465 return getTopOfStack().TaskgroupReductionRef; 466 } 467 /// Checks if the given \p VD declaration is actually a taskgroup reduction 468 /// descriptor variable at the \p Level of OpenMP regions. 469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 470 return getStackElemAtLevel(Level).TaskgroupReductionRef && 471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 472 ->getDecl() == VD; 473 } 474 475 /// Returns data sharing attributes from top of the stack for the 476 /// specified declaration. 477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 478 /// Returns data-sharing attributes for the specified declaration. 479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 480 /// Checks if the specified variables has data-sharing attributes which 481 /// match specified \a CPred predicate in any directive which matches \a DPred 482 /// predicate. 483 const DSAVarData 484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 486 bool FromParent) const; 487 /// Checks if the specified variables has data-sharing attributes which 488 /// match specified \a CPred predicate in any innermost directive which 489 /// matches \a DPred predicate. 490 const DSAVarData 491 hasInnermostDSA(ValueDecl *D, 492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 494 bool FromParent) const; 495 /// Checks if the specified variables has explicit data-sharing 496 /// attributes which match specified \a CPred predicate at the specified 497 /// OpenMP region. 498 bool hasExplicitDSA(const ValueDecl *D, 499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 500 unsigned Level, bool NotLastprivate = false) const; 501 502 /// Returns true if the directive at level \Level matches in the 503 /// specified \a DPred predicate. 504 bool hasExplicitDirective( 505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 506 unsigned Level) const; 507 508 /// Finds a directive which matches specified \a DPred predicate. 509 bool hasDirective( 510 const llvm::function_ref<bool( 511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 512 DPred, 513 bool FromParent) const; 514 515 /// Returns currently analyzed directive. 516 OpenMPDirectiveKind getCurrentDirective() const { 517 const SharingMapTy *Top = getTopOfStackOrNull(); 518 return Top ? Top->Directive : OMPD_unknown; 519 } 520 /// Returns directive kind at specified level. 521 OpenMPDirectiveKind getDirective(unsigned Level) const { 522 assert(!isStackEmpty() && "No directive at specified level."); 523 return getStackElemAtLevel(Level).Directive; 524 } 525 /// Returns the capture region at the specified level. 526 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 527 unsigned OpenMPCaptureLevel) const { 528 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 529 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 530 return CaptureRegions[OpenMPCaptureLevel]; 531 } 532 /// Returns parent directive. 533 OpenMPDirectiveKind getParentDirective() const { 534 const SharingMapTy *Parent = getSecondOnStackOrNull(); 535 return Parent ? Parent->Directive : OMPD_unknown; 536 } 537 538 /// Add requires decl to internal vector 539 void addRequiresDecl(OMPRequiresDecl *RD) { 540 RequiresDecls.push_back(RD); 541 } 542 543 /// Checks if the defined 'requires' directive has specified type of clause. 544 template <typename ClauseType> 545 bool hasRequiresDeclWithClause() { 546 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 547 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 548 return isa<ClauseType>(C); 549 }); 550 }); 551 } 552 553 /// Checks for a duplicate clause amongst previously declared requires 554 /// directives 555 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 556 bool IsDuplicate = false; 557 for (OMPClause *CNew : ClauseList) { 558 for (const OMPRequiresDecl *D : RequiresDecls) { 559 for (const OMPClause *CPrev : D->clauselists()) { 560 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 561 SemaRef.Diag(CNew->getBeginLoc(), 562 diag::err_omp_requires_clause_redeclaration) 563 << getOpenMPClauseName(CNew->getClauseKind()); 564 SemaRef.Diag(CPrev->getBeginLoc(), 565 diag::note_omp_requires_previous_clause) 566 << getOpenMPClauseName(CPrev->getClauseKind()); 567 IsDuplicate = true; 568 } 569 } 570 } 571 } 572 return IsDuplicate; 573 } 574 575 /// Add location of previously encountered target to internal vector 576 void addTargetDirLocation(SourceLocation LocStart) { 577 TargetLocations.push_back(LocStart); 578 } 579 580 // Return previously encountered target region locations. 581 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 582 return TargetLocations; 583 } 584 585 /// Set default data sharing attribute to none. 586 void setDefaultDSANone(SourceLocation Loc) { 587 getTopOfStack().DefaultAttr = DSA_none; 588 getTopOfStack().DefaultAttrLoc = Loc; 589 } 590 /// Set default data sharing attribute to shared. 591 void setDefaultDSAShared(SourceLocation Loc) { 592 getTopOfStack().DefaultAttr = DSA_shared; 593 getTopOfStack().DefaultAttrLoc = Loc; 594 } 595 /// Set default data mapping attribute to 'tofrom:scalar'. 596 void setDefaultDMAToFromScalar(SourceLocation Loc) { 597 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 598 getTopOfStack().DefaultMapAttrLoc = Loc; 599 } 600 601 DefaultDataSharingAttributes getDefaultDSA() const { 602 return isStackEmpty() ? DSA_unspecified 603 : getTopOfStack().DefaultAttr; 604 } 605 SourceLocation getDefaultDSALocation() const { 606 return isStackEmpty() ? SourceLocation() 607 : getTopOfStack().DefaultAttrLoc; 608 } 609 DefaultMapAttributes getDefaultDMA() const { 610 return isStackEmpty() ? DMA_unspecified 611 : getTopOfStack().DefaultMapAttr; 612 } 613 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 614 return getStackElemAtLevel(Level).DefaultMapAttr; 615 } 616 SourceLocation getDefaultDMALocation() const { 617 return isStackEmpty() ? SourceLocation() 618 : getTopOfStack().DefaultMapAttrLoc; 619 } 620 621 /// Checks if the specified variable is a threadprivate. 622 bool isThreadPrivate(VarDecl *D) { 623 const DSAVarData DVar = getTopDSA(D, false); 624 return isOpenMPThreadPrivate(DVar.CKind); 625 } 626 627 /// Marks current region as ordered (it has an 'ordered' clause). 628 void setOrderedRegion(bool IsOrdered, const Expr *Param, 629 OMPOrderedClause *Clause) { 630 if (IsOrdered) 631 getTopOfStack().OrderedRegion.emplace(Param, Clause); 632 else 633 getTopOfStack().OrderedRegion.reset(); 634 } 635 /// Returns true, if region is ordered (has associated 'ordered' clause), 636 /// false - otherwise. 637 bool isOrderedRegion() const { 638 if (const SharingMapTy *Top = getTopOfStackOrNull()) 639 return Top->OrderedRegion.hasValue(); 640 return false; 641 } 642 /// Returns optional parameter for the ordered region. 643 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 644 if (const SharingMapTy *Top = getTopOfStackOrNull()) 645 if (Top->OrderedRegion.hasValue()) 646 return Top->OrderedRegion.getValue(); 647 return std::make_pair(nullptr, nullptr); 648 } 649 /// Returns true, if parent region is ordered (has associated 650 /// 'ordered' clause), false - otherwise. 651 bool isParentOrderedRegion() const { 652 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 653 return Parent->OrderedRegion.hasValue(); 654 return false; 655 } 656 /// Returns optional parameter for the ordered region. 657 std::pair<const Expr *, OMPOrderedClause *> 658 getParentOrderedRegionParam() const { 659 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 660 if (Parent->OrderedRegion.hasValue()) 661 return Parent->OrderedRegion.getValue(); 662 return std::make_pair(nullptr, nullptr); 663 } 664 /// Marks current region as nowait (it has a 'nowait' clause). 665 void setNowaitRegion(bool IsNowait = true) { 666 getTopOfStack().NowaitRegion = IsNowait; 667 } 668 /// Returns true, if parent region is nowait (has associated 669 /// 'nowait' clause), false - otherwise. 670 bool isParentNowaitRegion() const { 671 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 672 return Parent->NowaitRegion; 673 return false; 674 } 675 /// Marks parent region as cancel region. 676 void setParentCancelRegion(bool Cancel = true) { 677 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 678 Parent->CancelRegion |= Cancel; 679 } 680 /// Return true if current region has inner cancel construct. 681 bool isCancelRegion() const { 682 const SharingMapTy *Top = getTopOfStackOrNull(); 683 return Top ? Top->CancelRegion : false; 684 } 685 686 /// Set collapse value for the region. 687 void setAssociatedLoops(unsigned Val) { 688 getTopOfStack().AssociatedLoops = Val; 689 if (Val > 1) 690 getTopOfStack().HasMutipleLoops = true; 691 } 692 /// Return collapse value for region. 693 unsigned getAssociatedLoops() const { 694 const SharingMapTy *Top = getTopOfStackOrNull(); 695 return Top ? Top->AssociatedLoops : 0; 696 } 697 /// Returns true if the construct is associated with multiple loops. 698 bool hasMutipleLoops() const { 699 const SharingMapTy *Top = getTopOfStackOrNull(); 700 return Top ? Top->HasMutipleLoops : false; 701 } 702 703 /// Marks current target region as one with closely nested teams 704 /// region. 705 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 706 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 707 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 708 } 709 /// Returns true, if current region has closely nested teams region. 710 bool hasInnerTeamsRegion() const { 711 return getInnerTeamsRegionLoc().isValid(); 712 } 713 /// Returns location of the nested teams region (if any). 714 SourceLocation getInnerTeamsRegionLoc() const { 715 const SharingMapTy *Top = getTopOfStackOrNull(); 716 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 717 } 718 719 Scope *getCurScope() const { 720 const SharingMapTy *Top = getTopOfStackOrNull(); 721 return Top ? Top->CurScope : nullptr; 722 } 723 SourceLocation getConstructLoc() const { 724 const SharingMapTy *Top = getTopOfStackOrNull(); 725 return Top ? Top->ConstructLoc : SourceLocation(); 726 } 727 728 /// Do the check specified in \a Check to all component lists and return true 729 /// if any issue is found. 730 bool checkMappableExprComponentListsForDecl( 731 const ValueDecl *VD, bool CurrentRegionOnly, 732 const llvm::function_ref< 733 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 734 OpenMPClauseKind)> 735 Check) const { 736 if (isStackEmpty()) 737 return false; 738 auto SI = begin(); 739 auto SE = end(); 740 741 if (SI == SE) 742 return false; 743 744 if (CurrentRegionOnly) 745 SE = std::next(SI); 746 else 747 std::advance(SI, 1); 748 749 for (; SI != SE; ++SI) { 750 auto MI = SI->MappedExprComponents.find(VD); 751 if (MI != SI->MappedExprComponents.end()) 752 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 753 MI->second.Components) 754 if (Check(L, MI->second.Kind)) 755 return true; 756 } 757 return false; 758 } 759 760 /// Do the check specified in \a Check to all component lists at a given level 761 /// and return true if any issue is found. 762 bool checkMappableExprComponentListsForDeclAtLevel( 763 const ValueDecl *VD, unsigned Level, 764 const llvm::function_ref< 765 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 766 OpenMPClauseKind)> 767 Check) const { 768 if (getStackSize() <= Level) 769 return false; 770 771 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 772 auto MI = StackElem.MappedExprComponents.find(VD); 773 if (MI != StackElem.MappedExprComponents.end()) 774 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 775 MI->second.Components) 776 if (Check(L, MI->second.Kind)) 777 return true; 778 return false; 779 } 780 781 /// Create a new mappable expression component list associated with a given 782 /// declaration and initialize it with the provided list of components. 783 void addMappableExpressionComponents( 784 const ValueDecl *VD, 785 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 786 OpenMPClauseKind WhereFoundClauseKind) { 787 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 788 // Create new entry and append the new components there. 789 MEC.Components.resize(MEC.Components.size() + 1); 790 MEC.Components.back().append(Components.begin(), Components.end()); 791 MEC.Kind = WhereFoundClauseKind; 792 } 793 794 unsigned getNestingLevel() const { 795 assert(!isStackEmpty()); 796 return getStackSize() - 1; 797 } 798 void addDoacrossDependClause(OMPDependClause *C, 799 const OperatorOffsetTy &OpsOffs) { 800 SharingMapTy *Parent = getSecondOnStackOrNull(); 801 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 802 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 803 } 804 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 805 getDoacrossDependClauses() const { 806 const SharingMapTy &StackElem = getTopOfStack(); 807 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 808 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 809 return llvm::make_range(Ref.begin(), Ref.end()); 810 } 811 return llvm::make_range(StackElem.DoacrossDepends.end(), 812 StackElem.DoacrossDepends.end()); 813 } 814 815 // Store types of classes which have been explicitly mapped 816 void addMappedClassesQualTypes(QualType QT) { 817 SharingMapTy &StackElem = getTopOfStack(); 818 StackElem.MappedClassesQualTypes.insert(QT); 819 } 820 821 // Return set of mapped classes types 822 bool isClassPreviouslyMapped(QualType QT) const { 823 const SharingMapTy &StackElem = getTopOfStack(); 824 return StackElem.MappedClassesQualTypes.count(QT) != 0; 825 } 826 827 /// Adds global declare target to the parent target region. 828 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 829 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 830 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 831 "Expected declare target link global."); 832 for (auto &Elem : *this) { 833 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 834 Elem.DeclareTargetLinkVarDecls.push_back(E); 835 return; 836 } 837 } 838 } 839 840 /// Returns the list of globals with declare target link if current directive 841 /// is target. 842 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 843 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 844 "Expected target executable directive."); 845 return getTopOfStack().DeclareTargetLinkVarDecls; 846 } 847 }; 848 849 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 850 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 851 } 852 853 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 854 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 855 DKind == OMPD_unknown; 856 } 857 858 } // namespace 859 860 static const Expr *getExprAsWritten(const Expr *E) { 861 if (const auto *FE = dyn_cast<FullExpr>(E)) 862 E = FE->getSubExpr(); 863 864 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 865 E = MTE->GetTemporaryExpr(); 866 867 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 868 E = Binder->getSubExpr(); 869 870 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 871 E = ICE->getSubExprAsWritten(); 872 return E->IgnoreParens(); 873 } 874 875 static Expr *getExprAsWritten(Expr *E) { 876 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 877 } 878 879 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 880 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 881 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 882 D = ME->getMemberDecl(); 883 const auto *VD = dyn_cast<VarDecl>(D); 884 const auto *FD = dyn_cast<FieldDecl>(D); 885 if (VD != nullptr) { 886 VD = VD->getCanonicalDecl(); 887 D = VD; 888 } else { 889 assert(FD); 890 FD = FD->getCanonicalDecl(); 891 D = FD; 892 } 893 return D; 894 } 895 896 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 897 return const_cast<ValueDecl *>( 898 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 899 } 900 901 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 902 ValueDecl *D) const { 903 D = getCanonicalDecl(D); 904 auto *VD = dyn_cast<VarDecl>(D); 905 const auto *FD = dyn_cast<FieldDecl>(D); 906 DSAVarData DVar; 907 if (Iter == end()) { 908 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 909 // in a region but not in construct] 910 // File-scope or namespace-scope variables referenced in called routines 911 // in the region are shared unless they appear in a threadprivate 912 // directive. 913 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 914 DVar.CKind = OMPC_shared; 915 916 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 917 // in a region but not in construct] 918 // Variables with static storage duration that are declared in called 919 // routines in the region are shared. 920 if (VD && VD->hasGlobalStorage()) 921 DVar.CKind = OMPC_shared; 922 923 // Non-static data members are shared by default. 924 if (FD) 925 DVar.CKind = OMPC_shared; 926 927 return DVar; 928 } 929 930 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 931 // in a Construct, C/C++, predetermined, p.1] 932 // Variables with automatic storage duration that are declared in a scope 933 // inside the construct are private. 934 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 935 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 936 DVar.CKind = OMPC_private; 937 return DVar; 938 } 939 940 DVar.DKind = Iter->Directive; 941 // Explicitly specified attributes and local variables with predetermined 942 // attributes. 943 if (Iter->SharingMap.count(D)) { 944 const DSAInfo &Data = Iter->SharingMap.lookup(D); 945 DVar.RefExpr = Data.RefExpr.getPointer(); 946 DVar.PrivateCopy = Data.PrivateCopy; 947 DVar.CKind = Data.Attributes; 948 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 949 return DVar; 950 } 951 952 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 953 // in a Construct, C/C++, implicitly determined, p.1] 954 // In a parallel or task construct, the data-sharing attributes of these 955 // variables are determined by the default clause, if present. 956 switch (Iter->DefaultAttr) { 957 case DSA_shared: 958 DVar.CKind = OMPC_shared; 959 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 960 return DVar; 961 case DSA_none: 962 return DVar; 963 case DSA_unspecified: 964 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 965 // in a Construct, implicitly determined, p.2] 966 // In a parallel construct, if no default clause is present, these 967 // variables are shared. 968 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 969 if ((isOpenMPParallelDirective(DVar.DKind) && 970 !isOpenMPTaskLoopDirective(DVar.DKind)) || 971 isOpenMPTeamsDirective(DVar.DKind)) { 972 DVar.CKind = OMPC_shared; 973 return DVar; 974 } 975 976 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 977 // in a Construct, implicitly determined, p.4] 978 // In a task construct, if no default clause is present, a variable that in 979 // the enclosing context is determined to be shared by all implicit tasks 980 // bound to the current team is shared. 981 if (isOpenMPTaskingDirective(DVar.DKind)) { 982 DSAVarData DVarTemp; 983 const_iterator I = Iter, E = end(); 984 do { 985 ++I; 986 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 987 // Referenced in a Construct, implicitly determined, p.6] 988 // In a task construct, if no default clause is present, a variable 989 // whose data-sharing attribute is not determined by the rules above is 990 // firstprivate. 991 DVarTemp = getDSA(I, D); 992 if (DVarTemp.CKind != OMPC_shared) { 993 DVar.RefExpr = nullptr; 994 DVar.CKind = OMPC_firstprivate; 995 return DVar; 996 } 997 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 998 DVar.CKind = 999 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1000 return DVar; 1001 } 1002 } 1003 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1004 // in a Construct, implicitly determined, p.3] 1005 // For constructs other than task, if no default clause is present, these 1006 // variables inherit their data-sharing attributes from the enclosing 1007 // context. 1008 return getDSA(++Iter, D); 1009 } 1010 1011 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1012 const Expr *NewDE) { 1013 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1014 D = getCanonicalDecl(D); 1015 SharingMapTy &StackElem = getTopOfStack(); 1016 auto It = StackElem.AlignedMap.find(D); 1017 if (It == StackElem.AlignedMap.end()) { 1018 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1019 StackElem.AlignedMap[D] = NewDE; 1020 return nullptr; 1021 } 1022 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1023 return It->second; 1024 } 1025 1026 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1027 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1028 D = getCanonicalDecl(D); 1029 SharingMapTy &StackElem = getTopOfStack(); 1030 StackElem.LCVMap.try_emplace( 1031 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1032 } 1033 1034 const DSAStackTy::LCDeclInfo 1035 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1036 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1037 D = getCanonicalDecl(D); 1038 const SharingMapTy &StackElem = getTopOfStack(); 1039 auto It = StackElem.LCVMap.find(D); 1040 if (It != StackElem.LCVMap.end()) 1041 return It->second; 1042 return {0, nullptr}; 1043 } 1044 1045 const DSAStackTy::LCDeclInfo 1046 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1047 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1048 assert(Parent && "Data-sharing attributes stack is empty"); 1049 D = getCanonicalDecl(D); 1050 auto It = Parent->LCVMap.find(D); 1051 if (It != Parent->LCVMap.end()) 1052 return It->second; 1053 return {0, nullptr}; 1054 } 1055 1056 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1057 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1058 assert(Parent && "Data-sharing attributes stack is empty"); 1059 if (Parent->LCVMap.size() < I) 1060 return nullptr; 1061 for (const auto &Pair : Parent->LCVMap) 1062 if (Pair.second.first == I) 1063 return Pair.first; 1064 return nullptr; 1065 } 1066 1067 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1068 DeclRefExpr *PrivateCopy) { 1069 D = getCanonicalDecl(D); 1070 if (A == OMPC_threadprivate) { 1071 DSAInfo &Data = Threadprivates[D]; 1072 Data.Attributes = A; 1073 Data.RefExpr.setPointer(E); 1074 Data.PrivateCopy = nullptr; 1075 } else { 1076 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1077 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1078 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1079 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1080 (isLoopControlVariable(D).first && A == OMPC_private)); 1081 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1082 Data.RefExpr.setInt(/*IntVal=*/true); 1083 return; 1084 } 1085 const bool IsLastprivate = 1086 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1087 Data.Attributes = A; 1088 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1089 Data.PrivateCopy = PrivateCopy; 1090 if (PrivateCopy) { 1091 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1092 Data.Attributes = A; 1093 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1094 Data.PrivateCopy = nullptr; 1095 } 1096 } 1097 } 1098 1099 /// Build a variable declaration for OpenMP loop iteration variable. 1100 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1101 StringRef Name, const AttrVec *Attrs = nullptr, 1102 DeclRefExpr *OrigRef = nullptr) { 1103 DeclContext *DC = SemaRef.CurContext; 1104 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1105 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1106 auto *Decl = 1107 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1108 if (Attrs) { 1109 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1110 I != E; ++I) 1111 Decl->addAttr(*I); 1112 } 1113 Decl->setImplicit(); 1114 if (OrigRef) { 1115 Decl->addAttr( 1116 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1117 } 1118 return Decl; 1119 } 1120 1121 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1122 SourceLocation Loc, 1123 bool RefersToCapture = false) { 1124 D->setReferenced(); 1125 D->markUsed(S.Context); 1126 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1127 SourceLocation(), D, RefersToCapture, Loc, Ty, 1128 VK_LValue); 1129 } 1130 1131 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1132 BinaryOperatorKind BOK) { 1133 D = getCanonicalDecl(D); 1134 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1135 assert( 1136 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1137 "Additional reduction info may be specified only for reduction items."); 1138 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1139 assert(ReductionData.ReductionRange.isInvalid() && 1140 getTopOfStack().Directive == OMPD_taskgroup && 1141 "Additional reduction info may be specified only once for reduction " 1142 "items."); 1143 ReductionData.set(BOK, SR); 1144 Expr *&TaskgroupReductionRef = 1145 getTopOfStack().TaskgroupReductionRef; 1146 if (!TaskgroupReductionRef) { 1147 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1148 SemaRef.Context.VoidPtrTy, ".task_red."); 1149 TaskgroupReductionRef = 1150 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1151 } 1152 } 1153 1154 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1155 const Expr *ReductionRef) { 1156 D = getCanonicalDecl(D); 1157 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1158 assert( 1159 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1160 "Additional reduction info may be specified only for reduction items."); 1161 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1162 assert(ReductionData.ReductionRange.isInvalid() && 1163 getTopOfStack().Directive == OMPD_taskgroup && 1164 "Additional reduction info may be specified only once for reduction " 1165 "items."); 1166 ReductionData.set(ReductionRef, SR); 1167 Expr *&TaskgroupReductionRef = 1168 getTopOfStack().TaskgroupReductionRef; 1169 if (!TaskgroupReductionRef) { 1170 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1171 SemaRef.Context.VoidPtrTy, ".task_red."); 1172 TaskgroupReductionRef = 1173 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1174 } 1175 } 1176 1177 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1178 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1179 Expr *&TaskgroupDescriptor) const { 1180 D = getCanonicalDecl(D); 1181 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1182 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1183 const DSAInfo &Data = I->SharingMap.lookup(D); 1184 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1185 continue; 1186 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1187 if (!ReductionData.ReductionOp || 1188 ReductionData.ReductionOp.is<const Expr *>()) 1189 return DSAVarData(); 1190 SR = ReductionData.ReductionRange; 1191 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1192 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1193 "expression for the descriptor is not " 1194 "set."); 1195 TaskgroupDescriptor = I->TaskgroupReductionRef; 1196 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1197 Data.PrivateCopy, I->DefaultAttrLoc); 1198 } 1199 return DSAVarData(); 1200 } 1201 1202 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1203 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1204 Expr *&TaskgroupDescriptor) const { 1205 D = getCanonicalDecl(D); 1206 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1207 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1208 const DSAInfo &Data = I->SharingMap.lookup(D); 1209 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1210 continue; 1211 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1212 if (!ReductionData.ReductionOp || 1213 !ReductionData.ReductionOp.is<const Expr *>()) 1214 return DSAVarData(); 1215 SR = ReductionData.ReductionRange; 1216 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1217 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1218 "expression for the descriptor is not " 1219 "set."); 1220 TaskgroupDescriptor = I->TaskgroupReductionRef; 1221 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1222 Data.PrivateCopy, I->DefaultAttrLoc); 1223 } 1224 return DSAVarData(); 1225 } 1226 1227 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1228 D = D->getCanonicalDecl(); 1229 for (const_iterator E = end(); I != E; ++I) { 1230 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1231 isOpenMPTargetExecutionDirective(I->Directive)) { 1232 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1233 Scope *CurScope = getCurScope(); 1234 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1235 CurScope = CurScope->getParent(); 1236 return CurScope != TopScope; 1237 } 1238 } 1239 return false; 1240 } 1241 1242 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1243 bool AcceptIfMutable = true, 1244 bool *IsClassType = nullptr) { 1245 ASTContext &Context = SemaRef.getASTContext(); 1246 Type = Type.getNonReferenceType().getCanonicalType(); 1247 bool IsConstant = Type.isConstant(Context); 1248 Type = Context.getBaseElementType(Type); 1249 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1250 ? Type->getAsCXXRecordDecl() 1251 : nullptr; 1252 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1253 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1254 RD = CTD->getTemplatedDecl(); 1255 if (IsClassType) 1256 *IsClassType = RD; 1257 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1258 RD->hasDefinition() && RD->hasMutableFields()); 1259 } 1260 1261 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1262 QualType Type, OpenMPClauseKind CKind, 1263 SourceLocation ELoc, 1264 bool AcceptIfMutable = true, 1265 bool ListItemNotVar = false) { 1266 ASTContext &Context = SemaRef.getASTContext(); 1267 bool IsClassType; 1268 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1269 unsigned Diag = ListItemNotVar 1270 ? diag::err_omp_const_list_item 1271 : IsClassType ? diag::err_omp_const_not_mutable_variable 1272 : diag::err_omp_const_variable; 1273 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1274 if (!ListItemNotVar && D) { 1275 const VarDecl *VD = dyn_cast<VarDecl>(D); 1276 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1277 VarDecl::DeclarationOnly; 1278 SemaRef.Diag(D->getLocation(), 1279 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1280 << D; 1281 } 1282 return true; 1283 } 1284 return false; 1285 } 1286 1287 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1288 bool FromParent) { 1289 D = getCanonicalDecl(D); 1290 DSAVarData DVar; 1291 1292 auto *VD = dyn_cast<VarDecl>(D); 1293 auto TI = Threadprivates.find(D); 1294 if (TI != Threadprivates.end()) { 1295 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1296 DVar.CKind = OMPC_threadprivate; 1297 return DVar; 1298 } 1299 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1300 DVar.RefExpr = buildDeclRefExpr( 1301 SemaRef, VD, D->getType().getNonReferenceType(), 1302 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1303 DVar.CKind = OMPC_threadprivate; 1304 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1305 return DVar; 1306 } 1307 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1308 // in a Construct, C/C++, predetermined, p.1] 1309 // Variables appearing in threadprivate directives are threadprivate. 1310 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1311 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1312 SemaRef.getLangOpts().OpenMPUseTLS && 1313 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1314 (VD && VD->getStorageClass() == SC_Register && 1315 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1316 DVar.RefExpr = buildDeclRefExpr( 1317 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1318 DVar.CKind = OMPC_threadprivate; 1319 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1320 return DVar; 1321 } 1322 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1323 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1324 !isLoopControlVariable(D).first) { 1325 const_iterator IterTarget = 1326 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1327 return isOpenMPTargetExecutionDirective(Data.Directive); 1328 }); 1329 if (IterTarget != end()) { 1330 const_iterator ParentIterTarget = IterTarget + 1; 1331 for (const_iterator Iter = begin(); 1332 Iter != ParentIterTarget; ++Iter) { 1333 if (isOpenMPLocal(VD, Iter)) { 1334 DVar.RefExpr = 1335 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1336 D->getLocation()); 1337 DVar.CKind = OMPC_threadprivate; 1338 return DVar; 1339 } 1340 } 1341 if (!isClauseParsingMode() || IterTarget != begin()) { 1342 auto DSAIter = IterTarget->SharingMap.find(D); 1343 if (DSAIter != IterTarget->SharingMap.end() && 1344 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1345 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1346 DVar.CKind = OMPC_threadprivate; 1347 return DVar; 1348 } 1349 const_iterator End = end(); 1350 if (!SemaRef.isOpenMPCapturedByRef( 1351 D, std::distance(ParentIterTarget, End), 1352 /*OpenMPCaptureLevel=*/0)) { 1353 DVar.RefExpr = 1354 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1355 IterTarget->ConstructLoc); 1356 DVar.CKind = OMPC_threadprivate; 1357 return DVar; 1358 } 1359 } 1360 } 1361 } 1362 1363 if (isStackEmpty()) 1364 // Not in OpenMP execution region and top scope was already checked. 1365 return DVar; 1366 1367 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1368 // in a Construct, C/C++, predetermined, p.4] 1369 // Static data members are shared. 1370 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1371 // in a Construct, C/C++, predetermined, p.7] 1372 // Variables with static storage duration that are declared in a scope 1373 // inside the construct are shared. 1374 if (VD && VD->isStaticDataMember()) { 1375 // Check for explicitly specified attributes. 1376 const_iterator I = begin(); 1377 const_iterator EndI = end(); 1378 if (FromParent && I != EndI) 1379 ++I; 1380 auto It = I->SharingMap.find(D); 1381 if (It != I->SharingMap.end()) { 1382 const DSAInfo &Data = It->getSecond(); 1383 DVar.RefExpr = Data.RefExpr.getPointer(); 1384 DVar.PrivateCopy = Data.PrivateCopy; 1385 DVar.CKind = Data.Attributes; 1386 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1387 DVar.DKind = I->Directive; 1388 return DVar; 1389 } 1390 1391 DVar.CKind = OMPC_shared; 1392 return DVar; 1393 } 1394 1395 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1396 // The predetermined shared attribute for const-qualified types having no 1397 // mutable members was removed after OpenMP 3.1. 1398 if (SemaRef.LangOpts.OpenMP <= 31) { 1399 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1400 // in a Construct, C/C++, predetermined, p.6] 1401 // Variables with const qualified type having no mutable member are 1402 // shared. 1403 if (isConstNotMutableType(SemaRef, D->getType())) { 1404 // Variables with const-qualified type having no mutable member may be 1405 // listed in a firstprivate clause, even if they are static data members. 1406 DSAVarData DVarTemp = hasInnermostDSA( 1407 D, 1408 [](OpenMPClauseKind C) { 1409 return C == OMPC_firstprivate || C == OMPC_shared; 1410 }, 1411 MatchesAlways, FromParent); 1412 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1413 return DVarTemp; 1414 1415 DVar.CKind = OMPC_shared; 1416 return DVar; 1417 } 1418 } 1419 1420 // Explicitly specified attributes and local variables with predetermined 1421 // attributes. 1422 const_iterator I = begin(); 1423 const_iterator EndI = end(); 1424 if (FromParent && I != EndI) 1425 ++I; 1426 auto It = I->SharingMap.find(D); 1427 if (It != I->SharingMap.end()) { 1428 const DSAInfo &Data = It->getSecond(); 1429 DVar.RefExpr = Data.RefExpr.getPointer(); 1430 DVar.PrivateCopy = Data.PrivateCopy; 1431 DVar.CKind = Data.Attributes; 1432 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1433 DVar.DKind = I->Directive; 1434 } 1435 1436 return DVar; 1437 } 1438 1439 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1440 bool FromParent) const { 1441 if (isStackEmpty()) { 1442 const_iterator I; 1443 return getDSA(I, D); 1444 } 1445 D = getCanonicalDecl(D); 1446 const_iterator StartI = begin(); 1447 const_iterator EndI = end(); 1448 if (FromParent && StartI != EndI) 1449 ++StartI; 1450 return getDSA(StartI, D); 1451 } 1452 1453 const DSAStackTy::DSAVarData 1454 DSAStackTy::hasDSA(ValueDecl *D, 1455 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1456 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1457 bool FromParent) const { 1458 if (isStackEmpty()) 1459 return {}; 1460 D = getCanonicalDecl(D); 1461 const_iterator I = begin(); 1462 const_iterator EndI = end(); 1463 if (FromParent && I != EndI) 1464 ++I; 1465 for (; I != EndI; ++I) { 1466 if (!DPred(I->Directive) && 1467 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1468 continue; 1469 const_iterator NewI = I; 1470 DSAVarData DVar = getDSA(NewI, D); 1471 if (I == NewI && CPred(DVar.CKind)) 1472 return DVar; 1473 } 1474 return {}; 1475 } 1476 1477 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1478 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1479 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1480 bool FromParent) const { 1481 if (isStackEmpty()) 1482 return {}; 1483 D = getCanonicalDecl(D); 1484 const_iterator StartI = begin(); 1485 const_iterator EndI = end(); 1486 if (FromParent && StartI != EndI) 1487 ++StartI; 1488 if (StartI == EndI || !DPred(StartI->Directive)) 1489 return {}; 1490 const_iterator NewI = StartI; 1491 DSAVarData DVar = getDSA(NewI, D); 1492 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1493 } 1494 1495 bool DSAStackTy::hasExplicitDSA( 1496 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1497 unsigned Level, bool NotLastprivate) const { 1498 if (getStackSize() <= Level) 1499 return false; 1500 D = getCanonicalDecl(D); 1501 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1502 auto I = StackElem.SharingMap.find(D); 1503 if (I != StackElem.SharingMap.end() && 1504 I->getSecond().RefExpr.getPointer() && 1505 CPred(I->getSecond().Attributes) && 1506 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1507 return true; 1508 // Check predetermined rules for the loop control variables. 1509 auto LI = StackElem.LCVMap.find(D); 1510 if (LI != StackElem.LCVMap.end()) 1511 return CPred(OMPC_private); 1512 return false; 1513 } 1514 1515 bool DSAStackTy::hasExplicitDirective( 1516 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1517 unsigned Level) const { 1518 if (getStackSize() <= Level) 1519 return false; 1520 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1521 return DPred(StackElem.Directive); 1522 } 1523 1524 bool DSAStackTy::hasDirective( 1525 const llvm::function_ref<bool(OpenMPDirectiveKind, 1526 const DeclarationNameInfo &, SourceLocation)> 1527 DPred, 1528 bool FromParent) const { 1529 // We look only in the enclosing region. 1530 size_t Skip = FromParent ? 2 : 1; 1531 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1532 I != E; ++I) { 1533 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1534 return true; 1535 } 1536 return false; 1537 } 1538 1539 void Sema::InitDataSharingAttributesStack() { 1540 VarDataSharingAttributesStack = new DSAStackTy(*this); 1541 } 1542 1543 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1544 1545 void Sema::pushOpenMPFunctionRegion() { 1546 DSAStack->pushFunction(); 1547 } 1548 1549 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1550 DSAStack->popFunction(OldFSI); 1551 } 1552 1553 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1554 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1555 "Expected OpenMP device compilation."); 1556 return !S.isInOpenMPTargetExecutionDirective() && 1557 !S.isInOpenMPDeclareTargetContext(); 1558 } 1559 1560 namespace { 1561 /// Status of the function emission on the host/device. 1562 enum class FunctionEmissionStatus { 1563 Emitted, 1564 Discarded, 1565 Unknown, 1566 }; 1567 } // anonymous namespace 1568 1569 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1570 unsigned DiagID) { 1571 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1572 "Expected OpenMP device compilation."); 1573 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1574 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1575 switch (FES) { 1576 case FunctionEmissionStatus::Emitted: 1577 Kind = DeviceDiagBuilder::K_Immediate; 1578 break; 1579 case FunctionEmissionStatus::Unknown: 1580 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1581 : DeviceDiagBuilder::K_Immediate; 1582 break; 1583 case FunctionEmissionStatus::TemplateDiscarded: 1584 case FunctionEmissionStatus::OMPDiscarded: 1585 Kind = DeviceDiagBuilder::K_Nop; 1586 break; 1587 case FunctionEmissionStatus::CUDADiscarded: 1588 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1589 break; 1590 } 1591 1592 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1593 } 1594 1595 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1596 unsigned DiagID) { 1597 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1598 "Expected OpenMP host compilation."); 1599 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1600 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1601 switch (FES) { 1602 case FunctionEmissionStatus::Emitted: 1603 Kind = DeviceDiagBuilder::K_Immediate; 1604 break; 1605 case FunctionEmissionStatus::Unknown: 1606 Kind = DeviceDiagBuilder::K_Deferred; 1607 break; 1608 case FunctionEmissionStatus::TemplateDiscarded: 1609 case FunctionEmissionStatus::OMPDiscarded: 1610 case FunctionEmissionStatus::CUDADiscarded: 1611 Kind = DeviceDiagBuilder::K_Nop; 1612 break; 1613 } 1614 1615 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1616 } 1617 1618 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1619 bool CheckForDelayedContext) { 1620 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1621 "Expected OpenMP device compilation."); 1622 assert(Callee && "Callee may not be null."); 1623 Callee = Callee->getMostRecentDecl(); 1624 FunctionDecl *Caller = getCurFunctionDecl(); 1625 1626 // host only function are not available on the device. 1627 if (Caller) { 1628 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1629 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1630 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1631 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1632 "CUDADiscarded unexpected in OpenMP device function check"); 1633 if ((CallerS == FunctionEmissionStatus::Emitted || 1634 (!isOpenMPDeviceDelayedContext(*this) && 1635 CallerS == FunctionEmissionStatus::Unknown)) && 1636 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1637 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1638 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1639 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1640 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1641 diag::note_omp_marked_device_type_here) 1642 << HostDevTy; 1643 return; 1644 } 1645 } 1646 // If the caller is known-emitted, mark the callee as known-emitted. 1647 // Otherwise, mark the call in our call graph so we can traverse it later. 1648 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1649 (!Caller && !CheckForDelayedContext) || 1650 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1651 markKnownEmitted(*this, Caller, Callee, Loc, 1652 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1653 return CheckForDelayedContext && 1654 S.getEmissionStatus(FD) == 1655 FunctionEmissionStatus::Emitted; 1656 }); 1657 else if (Caller) 1658 DeviceCallGraph[Caller].insert({Callee, Loc}); 1659 } 1660 1661 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1662 bool CheckCaller) { 1663 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1664 "Expected OpenMP host compilation."); 1665 assert(Callee && "Callee may not be null."); 1666 Callee = Callee->getMostRecentDecl(); 1667 FunctionDecl *Caller = getCurFunctionDecl(); 1668 1669 // device only function are not available on the host. 1670 if (Caller) { 1671 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1672 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1673 assert( 1674 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1675 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1676 "CUDADiscarded unexpected in OpenMP host function check"); 1677 if (CallerS == FunctionEmissionStatus::Emitted && 1678 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1679 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1680 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1681 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1682 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1683 diag::note_omp_marked_device_type_here) 1684 << NoHostDevTy; 1685 return; 1686 } 1687 } 1688 // If the caller is known-emitted, mark the callee as known-emitted. 1689 // Otherwise, mark the call in our call graph so we can traverse it later. 1690 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1691 if ((!CheckCaller && !Caller) || 1692 (Caller && 1693 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1694 markKnownEmitted( 1695 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1696 return CheckCaller && 1697 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1698 }); 1699 else if (Caller) 1700 DeviceCallGraph[Caller].insert({Callee, Loc}); 1701 } 1702 } 1703 1704 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1705 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1706 "OpenMP device compilation mode is expected."); 1707 QualType Ty = E->getType(); 1708 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1709 ((Ty->isFloat128Type() || 1710 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1711 !Context.getTargetInfo().hasFloat128Type()) || 1712 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1713 !Context.getTargetInfo().hasInt128Type())) 1714 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1715 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1716 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1717 } 1718 1719 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1720 unsigned OpenMPCaptureLevel) const { 1721 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1722 1723 ASTContext &Ctx = getASTContext(); 1724 bool IsByRef = true; 1725 1726 // Find the directive that is associated with the provided scope. 1727 D = cast<ValueDecl>(D->getCanonicalDecl()); 1728 QualType Ty = D->getType(); 1729 1730 bool IsVariableUsedInMapClause = false; 1731 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1732 // This table summarizes how a given variable should be passed to the device 1733 // given its type and the clauses where it appears. This table is based on 1734 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1735 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1736 // 1737 // ========================================================================= 1738 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1739 // | |(tofrom:scalar)| | pvt | | | | 1740 // ========================================================================= 1741 // | scl | | | | - | | bycopy| 1742 // | scl | | - | x | - | - | bycopy| 1743 // | scl | | x | - | - | - | null | 1744 // | scl | x | | | - | | byref | 1745 // | scl | x | - | x | - | - | bycopy| 1746 // | scl | x | x | - | - | - | null | 1747 // | scl | | - | - | - | x | byref | 1748 // | scl | x | - | - | - | x | byref | 1749 // 1750 // | agg | n.a. | | | - | | byref | 1751 // | agg | n.a. | - | x | - | - | byref | 1752 // | agg | n.a. | x | - | - | - | null | 1753 // | agg | n.a. | - | - | - | x | byref | 1754 // | agg | n.a. | - | - | - | x[] | byref | 1755 // 1756 // | ptr | n.a. | | | - | | bycopy| 1757 // | ptr | n.a. | - | x | - | - | bycopy| 1758 // | ptr | n.a. | x | - | - | - | null | 1759 // | ptr | n.a. | - | - | - | x | byref | 1760 // | ptr | n.a. | - | - | - | x[] | bycopy| 1761 // | ptr | n.a. | - | - | x | | bycopy| 1762 // | ptr | n.a. | - | - | x | x | bycopy| 1763 // | ptr | n.a. | - | - | x | x[] | bycopy| 1764 // ========================================================================= 1765 // Legend: 1766 // scl - scalar 1767 // ptr - pointer 1768 // agg - aggregate 1769 // x - applies 1770 // - - invalid in this combination 1771 // [] - mapped with an array section 1772 // byref - should be mapped by reference 1773 // byval - should be mapped by value 1774 // null - initialize a local variable to null on the device 1775 // 1776 // Observations: 1777 // - All scalar declarations that show up in a map clause have to be passed 1778 // by reference, because they may have been mapped in the enclosing data 1779 // environment. 1780 // - If the scalar value does not fit the size of uintptr, it has to be 1781 // passed by reference, regardless the result in the table above. 1782 // - For pointers mapped by value that have either an implicit map or an 1783 // array section, the runtime library may pass the NULL value to the 1784 // device instead of the value passed to it by the compiler. 1785 1786 if (Ty->isReferenceType()) 1787 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1788 1789 // Locate map clauses and see if the variable being captured is referred to 1790 // in any of those clauses. Here we only care about variables, not fields, 1791 // because fields are part of aggregates. 1792 bool IsVariableAssociatedWithSection = false; 1793 1794 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1795 D, Level, 1796 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1797 OMPClauseMappableExprCommon::MappableExprComponentListRef 1798 MapExprComponents, 1799 OpenMPClauseKind WhereFoundClauseKind) { 1800 // Only the map clause information influences how a variable is 1801 // captured. E.g. is_device_ptr does not require changing the default 1802 // behavior. 1803 if (WhereFoundClauseKind != OMPC_map) 1804 return false; 1805 1806 auto EI = MapExprComponents.rbegin(); 1807 auto EE = MapExprComponents.rend(); 1808 1809 assert(EI != EE && "Invalid map expression!"); 1810 1811 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1812 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1813 1814 ++EI; 1815 if (EI == EE) 1816 return false; 1817 1818 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1819 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1820 isa<MemberExpr>(EI->getAssociatedExpression())) { 1821 IsVariableAssociatedWithSection = true; 1822 // There is nothing more we need to know about this variable. 1823 return true; 1824 } 1825 1826 // Keep looking for more map info. 1827 return false; 1828 }); 1829 1830 if (IsVariableUsedInMapClause) { 1831 // If variable is identified in a map clause it is always captured by 1832 // reference except if it is a pointer that is dereferenced somehow. 1833 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1834 } else { 1835 // By default, all the data that has a scalar type is mapped by copy 1836 // (except for reduction variables). 1837 IsByRef = 1838 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1839 !Ty->isAnyPointerType()) || 1840 !Ty->isScalarType() || 1841 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1842 DSAStack->hasExplicitDSA( 1843 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1844 } 1845 } 1846 1847 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1848 IsByRef = 1849 ((IsVariableUsedInMapClause && 1850 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1851 OMPD_target) || 1852 !DSAStack->hasExplicitDSA( 1853 D, 1854 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1855 Level, /*NotLastprivate=*/true)) && 1856 // If the variable is artificial and must be captured by value - try to 1857 // capture by value. 1858 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1859 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1860 } 1861 1862 // When passing data by copy, we need to make sure it fits the uintptr size 1863 // and alignment, because the runtime library only deals with uintptr types. 1864 // If it does not fit the uintptr size, we need to pass the data by reference 1865 // instead. 1866 if (!IsByRef && 1867 (Ctx.getTypeSizeInChars(Ty) > 1868 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1869 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1870 IsByRef = true; 1871 } 1872 1873 return IsByRef; 1874 } 1875 1876 unsigned Sema::getOpenMPNestingLevel() const { 1877 assert(getLangOpts().OpenMP); 1878 return DSAStack->getNestingLevel(); 1879 } 1880 1881 bool Sema::isInOpenMPTargetExecutionDirective() const { 1882 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1883 !DSAStack->isClauseParsingMode()) || 1884 DSAStack->hasDirective( 1885 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1886 SourceLocation) -> bool { 1887 return isOpenMPTargetExecutionDirective(K); 1888 }, 1889 false); 1890 } 1891 1892 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1893 unsigned StopAt) { 1894 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1895 D = getCanonicalDecl(D); 1896 1897 auto *VD = dyn_cast<VarDecl>(D); 1898 // Do not capture constexpr variables. 1899 if (VD && VD->isConstexpr()) 1900 return nullptr; 1901 1902 // If we want to determine whether the variable should be captured from the 1903 // perspective of the current capturing scope, and we've already left all the 1904 // capturing scopes of the top directive on the stack, check from the 1905 // perspective of its parent directive (if any) instead. 1906 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1907 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1908 1909 // If we are attempting to capture a global variable in a directive with 1910 // 'target' we return true so that this global is also mapped to the device. 1911 // 1912 if (VD && !VD->hasLocalStorage() && 1913 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1914 if (isInOpenMPDeclareTargetContext()) { 1915 // Try to mark variable as declare target if it is used in capturing 1916 // regions. 1917 if (LangOpts.OpenMP <= 45 && 1918 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1919 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1920 return nullptr; 1921 } else if (isInOpenMPTargetExecutionDirective()) { 1922 // If the declaration is enclosed in a 'declare target' directive, 1923 // then it should not be captured. 1924 // 1925 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1926 return nullptr; 1927 return VD; 1928 } 1929 } 1930 1931 if (CheckScopeInfo) { 1932 bool OpenMPFound = false; 1933 for (unsigned I = StopAt + 1; I > 0; --I) { 1934 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1935 if(!isa<CapturingScopeInfo>(FSI)) 1936 return nullptr; 1937 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1938 if (RSI->CapRegionKind == CR_OpenMP) { 1939 OpenMPFound = true; 1940 break; 1941 } 1942 } 1943 if (!OpenMPFound) 1944 return nullptr; 1945 } 1946 1947 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1948 (!DSAStack->isClauseParsingMode() || 1949 DSAStack->getParentDirective() != OMPD_unknown)) { 1950 auto &&Info = DSAStack->isLoopControlVariable(D); 1951 if (Info.first || 1952 (VD && VD->hasLocalStorage() && 1953 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1954 (VD && DSAStack->isForceVarCapturing())) 1955 return VD ? VD : Info.second; 1956 DSAStackTy::DSAVarData DVarPrivate = 1957 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1958 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1959 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1960 // Threadprivate variables must not be captured. 1961 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1962 return nullptr; 1963 // The variable is not private or it is the variable in the directive with 1964 // default(none) clause and not used in any clause. 1965 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1966 [](OpenMPDirectiveKind) { return true; }, 1967 DSAStack->isClauseParsingMode()); 1968 if (DVarPrivate.CKind != OMPC_unknown || 1969 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1970 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1971 } 1972 return nullptr; 1973 } 1974 1975 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1976 unsigned Level) const { 1977 SmallVector<OpenMPDirectiveKind, 4> Regions; 1978 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1979 FunctionScopesIndex -= Regions.size(); 1980 } 1981 1982 void Sema::startOpenMPLoop() { 1983 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1984 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1985 DSAStack->loopInit(); 1986 } 1987 1988 void Sema::startOpenMPCXXRangeFor() { 1989 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1990 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1991 DSAStack->resetPossibleLoopCounter(); 1992 DSAStack->loopStart(); 1993 } 1994 } 1995 1996 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1997 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1998 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1999 if (DSAStack->getAssociatedLoops() > 0 && 2000 !DSAStack->isLoopStarted()) { 2001 DSAStack->resetPossibleLoopCounter(D); 2002 DSAStack->loopStart(); 2003 return true; 2004 } 2005 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2006 DSAStack->isLoopControlVariable(D).first) && 2007 !DSAStack->hasExplicitDSA( 2008 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2009 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2010 return true; 2011 } 2012 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2013 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2014 DSAStack->isForceVarCapturing() && 2015 !DSAStack->hasExplicitDSA( 2016 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2017 return true; 2018 } 2019 return DSAStack->hasExplicitDSA( 2020 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2021 (DSAStack->isClauseParsingMode() && 2022 DSAStack->getClauseParsingMode() == OMPC_private) || 2023 // Consider taskgroup reduction descriptor variable a private to avoid 2024 // possible capture in the region. 2025 (DSAStack->hasExplicitDirective( 2026 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2027 Level) && 2028 DSAStack->isTaskgroupReductionRef(D, Level)); 2029 } 2030 2031 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2032 unsigned Level) { 2033 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2034 D = getCanonicalDecl(D); 2035 OpenMPClauseKind OMPC = OMPC_unknown; 2036 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2037 const unsigned NewLevel = I - 1; 2038 if (DSAStack->hasExplicitDSA(D, 2039 [&OMPC](const OpenMPClauseKind K) { 2040 if (isOpenMPPrivate(K)) { 2041 OMPC = K; 2042 return true; 2043 } 2044 return false; 2045 }, 2046 NewLevel)) 2047 break; 2048 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2049 D, NewLevel, 2050 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2051 OpenMPClauseKind) { return true; })) { 2052 OMPC = OMPC_map; 2053 break; 2054 } 2055 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2056 NewLevel)) { 2057 OMPC = OMPC_map; 2058 if (D->getType()->isScalarType() && 2059 DSAStack->getDefaultDMAAtLevel(NewLevel) != 2060 DefaultMapAttributes::DMA_tofrom_scalar) 2061 OMPC = OMPC_firstprivate; 2062 break; 2063 } 2064 } 2065 if (OMPC != OMPC_unknown) 2066 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2067 } 2068 2069 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2070 unsigned Level) const { 2071 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2072 // Return true if the current level is no longer enclosed in a target region. 2073 2074 const auto *VD = dyn_cast<VarDecl>(D); 2075 return VD && !VD->hasLocalStorage() && 2076 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2077 Level); 2078 } 2079 2080 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2081 2082 void Sema::finalizeOpenMPDelayedAnalysis() { 2083 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2084 // Diagnose implicit declare target functions and their callees. 2085 for (const auto &CallerCallees : DeviceCallGraph) { 2086 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2087 OMPDeclareTargetDeclAttr::getDeviceType( 2088 CallerCallees.getFirst()->getMostRecentDecl()); 2089 // Ignore host functions during device analyzis. 2090 if (LangOpts.OpenMPIsDevice && DevTy && 2091 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2092 continue; 2093 // Ignore nohost functions during host analyzis. 2094 if (!LangOpts.OpenMPIsDevice && DevTy && 2095 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2096 continue; 2097 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2098 &Callee : CallerCallees.getSecond()) { 2099 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2100 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2101 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2102 if (LangOpts.OpenMPIsDevice && DevTy && 2103 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2104 // Diagnose host function called during device codegen. 2105 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2106 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2107 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2108 << HostDevTy << 0; 2109 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2110 diag::note_omp_marked_device_type_here) 2111 << HostDevTy; 2112 continue; 2113 } 2114 if (!LangOpts.OpenMPIsDevice && DevTy && 2115 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2116 // Diagnose nohost function called during host codegen. 2117 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2118 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2119 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2120 << NoHostDevTy << 1; 2121 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2122 diag::note_omp_marked_device_type_here) 2123 << NoHostDevTy; 2124 continue; 2125 } 2126 } 2127 } 2128 } 2129 2130 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2131 const DeclarationNameInfo &DirName, 2132 Scope *CurScope, SourceLocation Loc) { 2133 DSAStack->push(DKind, DirName, CurScope, Loc); 2134 PushExpressionEvaluationContext( 2135 ExpressionEvaluationContext::PotentiallyEvaluated); 2136 } 2137 2138 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2139 DSAStack->setClauseParsingMode(K); 2140 } 2141 2142 void Sema::EndOpenMPClause() { 2143 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2144 } 2145 2146 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2147 ArrayRef<OMPClause *> Clauses); 2148 2149 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2150 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2151 // A variable of class type (or array thereof) that appears in a lastprivate 2152 // clause requires an accessible, unambiguous default constructor for the 2153 // class type, unless the list item is also specified in a firstprivate 2154 // clause. 2155 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2156 for (OMPClause *C : D->clauses()) { 2157 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2158 SmallVector<Expr *, 8> PrivateCopies; 2159 for (Expr *DE : Clause->varlists()) { 2160 if (DE->isValueDependent() || DE->isTypeDependent()) { 2161 PrivateCopies.push_back(nullptr); 2162 continue; 2163 } 2164 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2165 auto *VD = cast<VarDecl>(DRE->getDecl()); 2166 QualType Type = VD->getType().getNonReferenceType(); 2167 const DSAStackTy::DSAVarData DVar = 2168 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2169 if (DVar.CKind == OMPC_lastprivate) { 2170 // Generate helper private variable and initialize it with the 2171 // default value. The address of the original variable is replaced 2172 // by the address of the new private variable in CodeGen. This new 2173 // variable is not added to IdResolver, so the code in the OpenMP 2174 // region uses original variable for proper diagnostics. 2175 VarDecl *VDPrivate = buildVarDecl( 2176 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2177 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2178 ActOnUninitializedDecl(VDPrivate); 2179 if (VDPrivate->isInvalidDecl()) { 2180 PrivateCopies.push_back(nullptr); 2181 continue; 2182 } 2183 PrivateCopies.push_back(buildDeclRefExpr( 2184 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2185 } else { 2186 // The variable is also a firstprivate, so initialization sequence 2187 // for private copy is generated already. 2188 PrivateCopies.push_back(nullptr); 2189 } 2190 } 2191 Clause->setPrivateCopies(PrivateCopies); 2192 } 2193 } 2194 // Check allocate clauses. 2195 if (!CurContext->isDependentContext()) 2196 checkAllocateClauses(*this, DSAStack, D->clauses()); 2197 } 2198 2199 DSAStack->pop(); 2200 DiscardCleanupsInEvaluationContext(); 2201 PopExpressionEvaluationContext(); 2202 } 2203 2204 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2205 Expr *NumIterations, Sema &SemaRef, 2206 Scope *S, DSAStackTy *Stack); 2207 2208 namespace { 2209 2210 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2211 private: 2212 Sema &SemaRef; 2213 2214 public: 2215 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2216 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2217 NamedDecl *ND = Candidate.getCorrectionDecl(); 2218 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2219 return VD->hasGlobalStorage() && 2220 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2221 SemaRef.getCurScope()); 2222 } 2223 return false; 2224 } 2225 2226 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2227 return std::make_unique<VarDeclFilterCCC>(*this); 2228 } 2229 2230 }; 2231 2232 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2233 private: 2234 Sema &SemaRef; 2235 2236 public: 2237 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2238 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2239 NamedDecl *ND = Candidate.getCorrectionDecl(); 2240 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2241 isa<FunctionDecl>(ND))) { 2242 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2243 SemaRef.getCurScope()); 2244 } 2245 return false; 2246 } 2247 2248 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2249 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2250 } 2251 }; 2252 2253 } // namespace 2254 2255 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2256 CXXScopeSpec &ScopeSpec, 2257 const DeclarationNameInfo &Id, 2258 OpenMPDirectiveKind Kind) { 2259 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2260 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2261 2262 if (Lookup.isAmbiguous()) 2263 return ExprError(); 2264 2265 VarDecl *VD; 2266 if (!Lookup.isSingleResult()) { 2267 VarDeclFilterCCC CCC(*this); 2268 if (TypoCorrection Corrected = 2269 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2270 CTK_ErrorRecovery)) { 2271 diagnoseTypo(Corrected, 2272 PDiag(Lookup.empty() 2273 ? diag::err_undeclared_var_use_suggest 2274 : diag::err_omp_expected_var_arg_suggest) 2275 << Id.getName()); 2276 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2277 } else { 2278 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2279 : diag::err_omp_expected_var_arg) 2280 << Id.getName(); 2281 return ExprError(); 2282 } 2283 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2284 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2285 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2286 return ExprError(); 2287 } 2288 Lookup.suppressDiagnostics(); 2289 2290 // OpenMP [2.9.2, Syntax, C/C++] 2291 // Variables must be file-scope, namespace-scope, or static block-scope. 2292 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2293 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2294 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2295 bool IsDecl = 2296 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2297 Diag(VD->getLocation(), 2298 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2299 << VD; 2300 return ExprError(); 2301 } 2302 2303 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2304 NamedDecl *ND = CanonicalVD; 2305 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2306 // A threadprivate directive for file-scope variables must appear outside 2307 // any definition or declaration. 2308 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2309 !getCurLexicalContext()->isTranslationUnit()) { 2310 Diag(Id.getLoc(), diag::err_omp_var_scope) 2311 << getOpenMPDirectiveName(Kind) << VD; 2312 bool IsDecl = 2313 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2314 Diag(VD->getLocation(), 2315 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2316 << VD; 2317 return ExprError(); 2318 } 2319 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2320 // A threadprivate directive for static class member variables must appear 2321 // in the class definition, in the same scope in which the member 2322 // variables are declared. 2323 if (CanonicalVD->isStaticDataMember() && 2324 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 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.4] 2335 // A threadprivate directive for namespace-scope variables must appear 2336 // outside any definition or declaration other than the namespace 2337 // definition itself. 2338 if (CanonicalVD->getDeclContext()->isNamespace() && 2339 (!getCurLexicalContext()->isFileContext() || 2340 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2341 Diag(Id.getLoc(), diag::err_omp_var_scope) 2342 << getOpenMPDirectiveName(Kind) << VD; 2343 bool IsDecl = 2344 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2345 Diag(VD->getLocation(), 2346 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2347 << VD; 2348 return ExprError(); 2349 } 2350 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2351 // A threadprivate directive for static block-scope variables must appear 2352 // in the scope of the variable and not in a nested scope. 2353 if (CanonicalVD->isLocalVarDecl() && CurScope && 2354 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2355 Diag(Id.getLoc(), diag::err_omp_var_scope) 2356 << getOpenMPDirectiveName(Kind) << VD; 2357 bool IsDecl = 2358 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2359 Diag(VD->getLocation(), 2360 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2361 << VD; 2362 return ExprError(); 2363 } 2364 2365 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2366 // A threadprivate directive must lexically precede all references to any 2367 // of the variables in its list. 2368 if (Kind == OMPD_threadprivate && VD->isUsed() && 2369 !DSAStack->isThreadPrivate(VD)) { 2370 Diag(Id.getLoc(), diag::err_omp_var_used) 2371 << getOpenMPDirectiveName(Kind) << VD; 2372 return ExprError(); 2373 } 2374 2375 QualType ExprType = VD->getType().getNonReferenceType(); 2376 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2377 SourceLocation(), VD, 2378 /*RefersToEnclosingVariableOrCapture=*/false, 2379 Id.getLoc(), ExprType, VK_LValue); 2380 } 2381 2382 Sema::DeclGroupPtrTy 2383 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2384 ArrayRef<Expr *> VarList) { 2385 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2386 CurContext->addDecl(D); 2387 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2388 } 2389 return nullptr; 2390 } 2391 2392 namespace { 2393 class LocalVarRefChecker final 2394 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2395 Sema &SemaRef; 2396 2397 public: 2398 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2399 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2400 if (VD->hasLocalStorage()) { 2401 SemaRef.Diag(E->getBeginLoc(), 2402 diag::err_omp_local_var_in_threadprivate_init) 2403 << E->getSourceRange(); 2404 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2405 << VD << VD->getSourceRange(); 2406 return true; 2407 } 2408 } 2409 return false; 2410 } 2411 bool VisitStmt(const Stmt *S) { 2412 for (const Stmt *Child : S->children()) { 2413 if (Child && Visit(Child)) 2414 return true; 2415 } 2416 return false; 2417 } 2418 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2419 }; 2420 } // namespace 2421 2422 OMPThreadPrivateDecl * 2423 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2424 SmallVector<Expr *, 8> Vars; 2425 for (Expr *RefExpr : VarList) { 2426 auto *DE = cast<DeclRefExpr>(RefExpr); 2427 auto *VD = cast<VarDecl>(DE->getDecl()); 2428 SourceLocation ILoc = DE->getExprLoc(); 2429 2430 // Mark variable as used. 2431 VD->setReferenced(); 2432 VD->markUsed(Context); 2433 2434 QualType QType = VD->getType(); 2435 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2436 // It will be analyzed later. 2437 Vars.push_back(DE); 2438 continue; 2439 } 2440 2441 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2442 // A threadprivate variable must not have an incomplete type. 2443 if (RequireCompleteType(ILoc, VD->getType(), 2444 diag::err_omp_threadprivate_incomplete_type)) { 2445 continue; 2446 } 2447 2448 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2449 // A threadprivate variable must not have a reference type. 2450 if (VD->getType()->isReferenceType()) { 2451 Diag(ILoc, diag::err_omp_ref_type_arg) 2452 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2453 bool IsDecl = 2454 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2455 Diag(VD->getLocation(), 2456 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2457 << VD; 2458 continue; 2459 } 2460 2461 // Check if this is a TLS variable. If TLS is not being supported, produce 2462 // the corresponding diagnostic. 2463 if ((VD->getTLSKind() != VarDecl::TLS_None && 2464 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2465 getLangOpts().OpenMPUseTLS && 2466 getASTContext().getTargetInfo().isTLSSupported())) || 2467 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2468 !VD->isLocalVarDecl())) { 2469 Diag(ILoc, diag::err_omp_var_thread_local) 2470 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2471 bool IsDecl = 2472 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2473 Diag(VD->getLocation(), 2474 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2475 << VD; 2476 continue; 2477 } 2478 2479 // Check if initial value of threadprivate variable reference variable with 2480 // local storage (it is not supported by runtime). 2481 if (const Expr *Init = VD->getAnyInitializer()) { 2482 LocalVarRefChecker Checker(*this); 2483 if (Checker.Visit(Init)) 2484 continue; 2485 } 2486 2487 Vars.push_back(RefExpr); 2488 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2489 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2490 Context, SourceRange(Loc, Loc))); 2491 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2492 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2493 } 2494 OMPThreadPrivateDecl *D = nullptr; 2495 if (!Vars.empty()) { 2496 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2497 Vars); 2498 D->setAccess(AS_public); 2499 } 2500 return D; 2501 } 2502 2503 static OMPAllocateDeclAttr::AllocatorTypeTy 2504 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2505 if (!Allocator) 2506 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2507 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2508 Allocator->isInstantiationDependent() || 2509 Allocator->containsUnexpandedParameterPack()) 2510 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2511 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2512 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2513 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2514 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2515 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2516 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2517 llvm::FoldingSetNodeID AEId, DAEId; 2518 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2519 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2520 if (AEId == DAEId) { 2521 AllocatorKindRes = AllocatorKind; 2522 break; 2523 } 2524 } 2525 return AllocatorKindRes; 2526 } 2527 2528 static bool checkPreviousOMPAllocateAttribute( 2529 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2530 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2531 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2532 return false; 2533 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2534 Expr *PrevAllocator = A->getAllocator(); 2535 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2536 getAllocatorKind(S, Stack, PrevAllocator); 2537 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2538 if (AllocatorsMatch && 2539 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2540 Allocator && PrevAllocator) { 2541 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2542 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2543 llvm::FoldingSetNodeID AEId, PAEId; 2544 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2545 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2546 AllocatorsMatch = AEId == PAEId; 2547 } 2548 if (!AllocatorsMatch) { 2549 SmallString<256> AllocatorBuffer; 2550 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2551 if (Allocator) 2552 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2553 SmallString<256> PrevAllocatorBuffer; 2554 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2555 if (PrevAllocator) 2556 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2557 S.getPrintingPolicy()); 2558 2559 SourceLocation AllocatorLoc = 2560 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2561 SourceRange AllocatorRange = 2562 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2563 SourceLocation PrevAllocatorLoc = 2564 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2565 SourceRange PrevAllocatorRange = 2566 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2567 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2568 << (Allocator ? 1 : 0) << AllocatorStream.str() 2569 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2570 << AllocatorRange; 2571 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2572 << PrevAllocatorRange; 2573 return true; 2574 } 2575 return false; 2576 } 2577 2578 static void 2579 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2580 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2581 Expr *Allocator, SourceRange SR) { 2582 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2583 return; 2584 if (Allocator && 2585 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2586 Allocator->isInstantiationDependent() || 2587 Allocator->containsUnexpandedParameterPack())) 2588 return; 2589 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2590 Allocator, SR); 2591 VD->addAttr(A); 2592 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2593 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2594 } 2595 2596 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2597 SourceLocation Loc, ArrayRef<Expr *> VarList, 2598 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2599 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2600 Expr *Allocator = nullptr; 2601 if (Clauses.empty()) { 2602 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2603 // allocate directives that appear in a target region must specify an 2604 // allocator clause unless a requires directive with the dynamic_allocators 2605 // clause is present in the same compilation unit. 2606 if (LangOpts.OpenMPIsDevice && 2607 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2608 targetDiag(Loc, diag::err_expected_allocator_clause); 2609 } else { 2610 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2611 } 2612 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2613 getAllocatorKind(*this, DSAStack, Allocator); 2614 SmallVector<Expr *, 8> Vars; 2615 for (Expr *RefExpr : VarList) { 2616 auto *DE = cast<DeclRefExpr>(RefExpr); 2617 auto *VD = cast<VarDecl>(DE->getDecl()); 2618 2619 // Check if this is a TLS variable or global register. 2620 if (VD->getTLSKind() != VarDecl::TLS_None || 2621 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2622 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2623 !VD->isLocalVarDecl())) 2624 continue; 2625 2626 // If the used several times in the allocate directive, the same allocator 2627 // must be used. 2628 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2629 AllocatorKind, Allocator)) 2630 continue; 2631 2632 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2633 // If a list item has a static storage type, the allocator expression in the 2634 // allocator clause must be a constant expression that evaluates to one of 2635 // the predefined memory allocator values. 2636 if (Allocator && VD->hasGlobalStorage()) { 2637 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2638 Diag(Allocator->getExprLoc(), 2639 diag::err_omp_expected_predefined_allocator) 2640 << Allocator->getSourceRange(); 2641 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2642 VarDecl::DeclarationOnly; 2643 Diag(VD->getLocation(), 2644 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2645 << VD; 2646 continue; 2647 } 2648 } 2649 2650 Vars.push_back(RefExpr); 2651 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2652 DE->getSourceRange()); 2653 } 2654 if (Vars.empty()) 2655 return nullptr; 2656 if (!Owner) 2657 Owner = getCurLexicalContext(); 2658 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2659 D->setAccess(AS_public); 2660 Owner->addDecl(D); 2661 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2662 } 2663 2664 Sema::DeclGroupPtrTy 2665 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2666 ArrayRef<OMPClause *> ClauseList) { 2667 OMPRequiresDecl *D = nullptr; 2668 if (!CurContext->isFileContext()) { 2669 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2670 } else { 2671 D = CheckOMPRequiresDecl(Loc, ClauseList); 2672 if (D) { 2673 CurContext->addDecl(D); 2674 DSAStack->addRequiresDecl(D); 2675 } 2676 } 2677 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2678 } 2679 2680 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2681 ArrayRef<OMPClause *> ClauseList) { 2682 /// For target specific clauses, the requires directive cannot be 2683 /// specified after the handling of any of the target regions in the 2684 /// current compilation unit. 2685 ArrayRef<SourceLocation> TargetLocations = 2686 DSAStack->getEncounteredTargetLocs(); 2687 if (!TargetLocations.empty()) { 2688 for (const OMPClause *CNew : ClauseList) { 2689 // Check if any of the requires clauses affect target regions. 2690 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2691 isa<OMPUnifiedAddressClause>(CNew) || 2692 isa<OMPReverseOffloadClause>(CNew) || 2693 isa<OMPDynamicAllocatorsClause>(CNew)) { 2694 Diag(Loc, diag::err_omp_target_before_requires) 2695 << getOpenMPClauseName(CNew->getClauseKind()); 2696 for (SourceLocation TargetLoc : TargetLocations) { 2697 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2698 } 2699 } 2700 } 2701 } 2702 2703 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2704 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2705 ClauseList); 2706 return nullptr; 2707 } 2708 2709 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2710 const ValueDecl *D, 2711 const DSAStackTy::DSAVarData &DVar, 2712 bool IsLoopIterVar = false) { 2713 if (DVar.RefExpr) { 2714 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2715 << getOpenMPClauseName(DVar.CKind); 2716 return; 2717 } 2718 enum { 2719 PDSA_StaticMemberShared, 2720 PDSA_StaticLocalVarShared, 2721 PDSA_LoopIterVarPrivate, 2722 PDSA_LoopIterVarLinear, 2723 PDSA_LoopIterVarLastprivate, 2724 PDSA_ConstVarShared, 2725 PDSA_GlobalVarShared, 2726 PDSA_TaskVarFirstprivate, 2727 PDSA_LocalVarPrivate, 2728 PDSA_Implicit 2729 } Reason = PDSA_Implicit; 2730 bool ReportHint = false; 2731 auto ReportLoc = D->getLocation(); 2732 auto *VD = dyn_cast<VarDecl>(D); 2733 if (IsLoopIterVar) { 2734 if (DVar.CKind == OMPC_private) 2735 Reason = PDSA_LoopIterVarPrivate; 2736 else if (DVar.CKind == OMPC_lastprivate) 2737 Reason = PDSA_LoopIterVarLastprivate; 2738 else 2739 Reason = PDSA_LoopIterVarLinear; 2740 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2741 DVar.CKind == OMPC_firstprivate) { 2742 Reason = PDSA_TaskVarFirstprivate; 2743 ReportLoc = DVar.ImplicitDSALoc; 2744 } else if (VD && VD->isStaticLocal()) 2745 Reason = PDSA_StaticLocalVarShared; 2746 else if (VD && VD->isStaticDataMember()) 2747 Reason = PDSA_StaticMemberShared; 2748 else if (VD && VD->isFileVarDecl()) 2749 Reason = PDSA_GlobalVarShared; 2750 else if (D->getType().isConstant(SemaRef.getASTContext())) 2751 Reason = PDSA_ConstVarShared; 2752 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2753 ReportHint = true; 2754 Reason = PDSA_LocalVarPrivate; 2755 } 2756 if (Reason != PDSA_Implicit) { 2757 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2758 << Reason << ReportHint 2759 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2760 } else if (DVar.ImplicitDSALoc.isValid()) { 2761 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2762 << getOpenMPClauseName(DVar.CKind); 2763 } 2764 } 2765 2766 namespace { 2767 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2768 DSAStackTy *Stack; 2769 Sema &SemaRef; 2770 bool ErrorFound = false; 2771 bool TryCaptureCXXThisMembers = false; 2772 CapturedStmt *CS = nullptr; 2773 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2774 llvm::SmallVector<Expr *, 4> ImplicitMap; 2775 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2776 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2777 2778 void VisitSubCaptures(OMPExecutableDirective *S) { 2779 // Check implicitly captured variables. 2780 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2781 return; 2782 visitSubCaptures(S->getInnermostCapturedStmt()); 2783 // Try to capture inner this->member references to generate correct mappings 2784 // and diagnostics. 2785 if (TryCaptureCXXThisMembers || 2786 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2787 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2788 [](const CapturedStmt::Capture &C) { 2789 return C.capturesThis(); 2790 }))) { 2791 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2792 TryCaptureCXXThisMembers = true; 2793 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2794 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2795 } 2796 } 2797 2798 public: 2799 void VisitDeclRefExpr(DeclRefExpr *E) { 2800 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 2801 E->isValueDependent() || E->containsUnexpandedParameterPack() || 2802 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 if (!TryCaptureCXXThisMembers) { 3037 Visit(E->getBase()); 3038 } 3039 } 3040 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3041 for (OMPClause *C : S->clauses()) { 3042 // Skip analysis of arguments of implicitly defined firstprivate clause 3043 // for task|target directives. 3044 // Skip analysis of arguments of implicitly defined map clause for target 3045 // directives. 3046 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3047 C->isImplicit())) { 3048 for (Stmt *CC : C->children()) { 3049 if (CC) 3050 Visit(CC); 3051 } 3052 } 3053 } 3054 // Check implicitly captured variables. 3055 VisitSubCaptures(S); 3056 } 3057 void VisitStmt(Stmt *S) { 3058 for (Stmt *C : S->children()) { 3059 if (C) { 3060 // Check implicitly captured variables in the task-based directives to 3061 // check if they must be firstprivatized. 3062 Visit(C); 3063 } 3064 } 3065 } 3066 3067 void visitSubCaptures(CapturedStmt *S) { 3068 for (const CapturedStmt::Capture &Cap : S->captures()) { 3069 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3070 continue; 3071 VarDecl *VD = Cap.getCapturedVar(); 3072 // Do not try to map the variable if it or its sub-component was mapped 3073 // already. 3074 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3075 Stack->checkMappableExprComponentListsForDecl( 3076 VD, /*CurrentRegionOnly=*/true, 3077 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3078 OpenMPClauseKind) { return true; })) 3079 continue; 3080 DeclRefExpr *DRE = buildDeclRefExpr( 3081 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3082 Cap.getLocation(), /*RefersToCapture=*/true); 3083 Visit(DRE); 3084 } 3085 } 3086 bool isErrorFound() const { return ErrorFound; } 3087 ArrayRef<Expr *> getImplicitFirstprivate() const { 3088 return ImplicitFirstprivate; 3089 } 3090 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 3091 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3092 return VarsWithInheritedDSA; 3093 } 3094 3095 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3096 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3097 // Process declare target link variables for the target directives. 3098 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3099 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3100 Visit(E); 3101 } 3102 } 3103 }; 3104 } // namespace 3105 3106 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3107 switch (DKind) { 3108 case OMPD_parallel: 3109 case OMPD_parallel_for: 3110 case OMPD_parallel_for_simd: 3111 case OMPD_parallel_sections: 3112 case OMPD_teams: 3113 case OMPD_teams_distribute: 3114 case OMPD_teams_distribute_simd: { 3115 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3116 QualType KmpInt32PtrTy = 3117 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3118 Sema::CapturedParamNameType Params[] = { 3119 std::make_pair(".global_tid.", KmpInt32PtrTy), 3120 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3121 std::make_pair(StringRef(), QualType()) // __context with shared vars 3122 }; 3123 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3124 Params); 3125 break; 3126 } 3127 case OMPD_target_teams: 3128 case OMPD_target_parallel: 3129 case OMPD_target_parallel_for: 3130 case OMPD_target_parallel_for_simd: 3131 case OMPD_target_teams_distribute: 3132 case OMPD_target_teams_distribute_simd: { 3133 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3134 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3135 QualType KmpInt32PtrTy = 3136 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3137 QualType Args[] = {VoidPtrTy}; 3138 FunctionProtoType::ExtProtoInfo EPI; 3139 EPI.Variadic = true; 3140 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3141 Sema::CapturedParamNameType Params[] = { 3142 std::make_pair(".global_tid.", KmpInt32Ty), 3143 std::make_pair(".part_id.", KmpInt32PtrTy), 3144 std::make_pair(".privates.", VoidPtrTy), 3145 std::make_pair( 3146 ".copy_fn.", 3147 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3148 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3149 std::make_pair(StringRef(), QualType()) // __context with shared vars 3150 }; 3151 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3152 Params, /*OpenMPCaptureLevel=*/0); 3153 // Mark this captured region as inlined, because we don't use outlined 3154 // function directly. 3155 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3156 AlwaysInlineAttr::CreateImplicit( 3157 Context, {}, AttributeCommonInfo::AS_Keyword, 3158 AlwaysInlineAttr::Keyword_forceinline)); 3159 Sema::CapturedParamNameType ParamsTarget[] = { 3160 std::make_pair(StringRef(), QualType()) // __context with shared vars 3161 }; 3162 // Start a captured region for 'target' with no implicit parameters. 3163 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3164 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3165 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3166 std::make_pair(".global_tid.", KmpInt32PtrTy), 3167 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3168 std::make_pair(StringRef(), QualType()) // __context with shared vars 3169 }; 3170 // Start a captured region for 'teams' or 'parallel'. Both regions have 3171 // the same implicit parameters. 3172 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3173 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3174 break; 3175 } 3176 case OMPD_target: 3177 case OMPD_target_simd: { 3178 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3179 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3180 QualType KmpInt32PtrTy = 3181 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3182 QualType Args[] = {VoidPtrTy}; 3183 FunctionProtoType::ExtProtoInfo EPI; 3184 EPI.Variadic = true; 3185 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3186 Sema::CapturedParamNameType Params[] = { 3187 std::make_pair(".global_tid.", KmpInt32Ty), 3188 std::make_pair(".part_id.", KmpInt32PtrTy), 3189 std::make_pair(".privates.", VoidPtrTy), 3190 std::make_pair( 3191 ".copy_fn.", 3192 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3193 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3194 std::make_pair(StringRef(), QualType()) // __context with shared vars 3195 }; 3196 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3197 Params, /*OpenMPCaptureLevel=*/0); 3198 // Mark this captured region as inlined, because we don't use outlined 3199 // function directly. 3200 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3201 AlwaysInlineAttr::CreateImplicit( 3202 Context, {}, AttributeCommonInfo::AS_Keyword, 3203 AlwaysInlineAttr::Keyword_forceinline)); 3204 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3205 std::make_pair(StringRef(), QualType()), 3206 /*OpenMPCaptureLevel=*/1); 3207 break; 3208 } 3209 case OMPD_simd: 3210 case OMPD_for: 3211 case OMPD_for_simd: 3212 case OMPD_sections: 3213 case OMPD_section: 3214 case OMPD_single: 3215 case OMPD_master: 3216 case OMPD_critical: 3217 case OMPD_taskgroup: 3218 case OMPD_distribute: 3219 case OMPD_distribute_simd: 3220 case OMPD_ordered: 3221 case OMPD_atomic: 3222 case OMPD_target_data: { 3223 Sema::CapturedParamNameType Params[] = { 3224 std::make_pair(StringRef(), QualType()) // __context with shared vars 3225 }; 3226 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3227 Params); 3228 break; 3229 } 3230 case OMPD_task: { 3231 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3232 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3233 QualType KmpInt32PtrTy = 3234 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3235 QualType Args[] = {VoidPtrTy}; 3236 FunctionProtoType::ExtProtoInfo EPI; 3237 EPI.Variadic = true; 3238 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3239 Sema::CapturedParamNameType Params[] = { 3240 std::make_pair(".global_tid.", KmpInt32Ty), 3241 std::make_pair(".part_id.", KmpInt32PtrTy), 3242 std::make_pair(".privates.", VoidPtrTy), 3243 std::make_pair( 3244 ".copy_fn.", 3245 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3246 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3247 std::make_pair(StringRef(), QualType()) // __context with shared vars 3248 }; 3249 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3250 Params); 3251 // Mark this captured region as inlined, because we don't use outlined 3252 // function directly. 3253 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3254 AlwaysInlineAttr::CreateImplicit( 3255 Context, {}, AttributeCommonInfo::AS_Keyword, 3256 AlwaysInlineAttr::Keyword_forceinline)); 3257 break; 3258 } 3259 case OMPD_taskloop: 3260 case OMPD_taskloop_simd: 3261 case OMPD_master_taskloop: 3262 case OMPD_master_taskloop_simd: { 3263 QualType KmpInt32Ty = 3264 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3265 .withConst(); 3266 QualType KmpUInt64Ty = 3267 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3268 .withConst(); 3269 QualType KmpInt64Ty = 3270 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3271 .withConst(); 3272 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3273 QualType KmpInt32PtrTy = 3274 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3275 QualType Args[] = {VoidPtrTy}; 3276 FunctionProtoType::ExtProtoInfo EPI; 3277 EPI.Variadic = true; 3278 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3279 Sema::CapturedParamNameType Params[] = { 3280 std::make_pair(".global_tid.", KmpInt32Ty), 3281 std::make_pair(".part_id.", KmpInt32PtrTy), 3282 std::make_pair(".privates.", VoidPtrTy), 3283 std::make_pair( 3284 ".copy_fn.", 3285 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3286 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3287 std::make_pair(".lb.", KmpUInt64Ty), 3288 std::make_pair(".ub.", KmpUInt64Ty), 3289 std::make_pair(".st.", KmpInt64Ty), 3290 std::make_pair(".liter.", KmpInt32Ty), 3291 std::make_pair(".reductions.", VoidPtrTy), 3292 std::make_pair(StringRef(), QualType()) // __context with shared vars 3293 }; 3294 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3295 Params); 3296 // Mark this captured region as inlined, because we don't use outlined 3297 // function directly. 3298 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3299 AlwaysInlineAttr::CreateImplicit( 3300 Context, {}, AttributeCommonInfo::AS_Keyword, 3301 AlwaysInlineAttr::Keyword_forceinline)); 3302 break; 3303 } 3304 case OMPD_parallel_master_taskloop: 3305 case OMPD_parallel_master_taskloop_simd: { 3306 QualType KmpInt32Ty = 3307 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3308 .withConst(); 3309 QualType KmpUInt64Ty = 3310 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3311 .withConst(); 3312 QualType KmpInt64Ty = 3313 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3314 .withConst(); 3315 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3316 QualType KmpInt32PtrTy = 3317 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3318 Sema::CapturedParamNameType ParamsParallel[] = { 3319 std::make_pair(".global_tid.", KmpInt32PtrTy), 3320 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3321 std::make_pair(StringRef(), QualType()) // __context with shared vars 3322 }; 3323 // Start a captured region for 'parallel'. 3324 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3325 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3326 QualType Args[] = {VoidPtrTy}; 3327 FunctionProtoType::ExtProtoInfo EPI; 3328 EPI.Variadic = true; 3329 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3330 Sema::CapturedParamNameType Params[] = { 3331 std::make_pair(".global_tid.", KmpInt32Ty), 3332 std::make_pair(".part_id.", KmpInt32PtrTy), 3333 std::make_pair(".privates.", VoidPtrTy), 3334 std::make_pair( 3335 ".copy_fn.", 3336 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3337 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3338 std::make_pair(".lb.", KmpUInt64Ty), 3339 std::make_pair(".ub.", KmpUInt64Ty), 3340 std::make_pair(".st.", KmpInt64Ty), 3341 std::make_pair(".liter.", KmpInt32Ty), 3342 std::make_pair(".reductions.", VoidPtrTy), 3343 std::make_pair(StringRef(), QualType()) // __context with shared vars 3344 }; 3345 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3346 Params, /*OpenMPCaptureLevel=*/2); 3347 // Mark this captured region as inlined, because we don't use outlined 3348 // function directly. 3349 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3350 AlwaysInlineAttr::CreateImplicit( 3351 Context, {}, AttributeCommonInfo::AS_Keyword, 3352 AlwaysInlineAttr::Keyword_forceinline)); 3353 break; 3354 } 3355 case OMPD_distribute_parallel_for_simd: 3356 case OMPD_distribute_parallel_for: { 3357 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3358 QualType KmpInt32PtrTy = 3359 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3360 Sema::CapturedParamNameType Params[] = { 3361 std::make_pair(".global_tid.", KmpInt32PtrTy), 3362 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3363 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3364 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3365 std::make_pair(StringRef(), QualType()) // __context with shared vars 3366 }; 3367 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3368 Params); 3369 break; 3370 } 3371 case OMPD_target_teams_distribute_parallel_for: 3372 case OMPD_target_teams_distribute_parallel_for_simd: { 3373 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3374 QualType KmpInt32PtrTy = 3375 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3376 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3377 3378 QualType Args[] = {VoidPtrTy}; 3379 FunctionProtoType::ExtProtoInfo EPI; 3380 EPI.Variadic = true; 3381 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3382 Sema::CapturedParamNameType Params[] = { 3383 std::make_pair(".global_tid.", KmpInt32Ty), 3384 std::make_pair(".part_id.", KmpInt32PtrTy), 3385 std::make_pair(".privates.", VoidPtrTy), 3386 std::make_pair( 3387 ".copy_fn.", 3388 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3389 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3390 std::make_pair(StringRef(), QualType()) // __context with shared vars 3391 }; 3392 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3393 Params, /*OpenMPCaptureLevel=*/0); 3394 // Mark this captured region as inlined, because we don't use outlined 3395 // function directly. 3396 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3397 AlwaysInlineAttr::CreateImplicit( 3398 Context, {}, AttributeCommonInfo::AS_Keyword, 3399 AlwaysInlineAttr::Keyword_forceinline)); 3400 Sema::CapturedParamNameType ParamsTarget[] = { 3401 std::make_pair(StringRef(), QualType()) // __context with shared vars 3402 }; 3403 // Start a captured region for 'target' with no implicit parameters. 3404 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3405 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3406 3407 Sema::CapturedParamNameType ParamsTeams[] = { 3408 std::make_pair(".global_tid.", KmpInt32PtrTy), 3409 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3410 std::make_pair(StringRef(), QualType()) // __context with shared vars 3411 }; 3412 // Start a captured region for 'target' with no implicit parameters. 3413 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3414 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3415 3416 Sema::CapturedParamNameType ParamsParallel[] = { 3417 std::make_pair(".global_tid.", KmpInt32PtrTy), 3418 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3419 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3420 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3421 std::make_pair(StringRef(), QualType()) // __context with shared vars 3422 }; 3423 // Start a captured region for 'teams' or 'parallel'. Both regions have 3424 // the same implicit parameters. 3425 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3426 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3427 break; 3428 } 3429 3430 case OMPD_teams_distribute_parallel_for: 3431 case OMPD_teams_distribute_parallel_for_simd: { 3432 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3433 QualType KmpInt32PtrTy = 3434 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3435 3436 Sema::CapturedParamNameType ParamsTeams[] = { 3437 std::make_pair(".global_tid.", KmpInt32PtrTy), 3438 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3439 std::make_pair(StringRef(), QualType()) // __context with shared vars 3440 }; 3441 // Start a captured region for 'target' with no implicit parameters. 3442 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3443 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3444 3445 Sema::CapturedParamNameType ParamsParallel[] = { 3446 std::make_pair(".global_tid.", KmpInt32PtrTy), 3447 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3448 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3449 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3450 std::make_pair(StringRef(), QualType()) // __context with shared vars 3451 }; 3452 // Start a captured region for 'teams' or 'parallel'. Both regions have 3453 // the same implicit parameters. 3454 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3455 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3456 break; 3457 } 3458 case OMPD_target_update: 3459 case OMPD_target_enter_data: 3460 case OMPD_target_exit_data: { 3461 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3462 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3463 QualType KmpInt32PtrTy = 3464 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3465 QualType Args[] = {VoidPtrTy}; 3466 FunctionProtoType::ExtProtoInfo EPI; 3467 EPI.Variadic = true; 3468 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3469 Sema::CapturedParamNameType Params[] = { 3470 std::make_pair(".global_tid.", KmpInt32Ty), 3471 std::make_pair(".part_id.", KmpInt32PtrTy), 3472 std::make_pair(".privates.", VoidPtrTy), 3473 std::make_pair( 3474 ".copy_fn.", 3475 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3476 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3477 std::make_pair(StringRef(), QualType()) // __context with shared vars 3478 }; 3479 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3480 Params); 3481 // Mark this captured region as inlined, because we don't use outlined 3482 // function directly. 3483 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3484 AlwaysInlineAttr::CreateImplicit( 3485 Context, {}, AttributeCommonInfo::AS_Keyword, 3486 AlwaysInlineAttr::Keyword_forceinline)); 3487 break; 3488 } 3489 case OMPD_threadprivate: 3490 case OMPD_allocate: 3491 case OMPD_taskyield: 3492 case OMPD_barrier: 3493 case OMPD_taskwait: 3494 case OMPD_cancellation_point: 3495 case OMPD_cancel: 3496 case OMPD_flush: 3497 case OMPD_declare_reduction: 3498 case OMPD_declare_mapper: 3499 case OMPD_declare_simd: 3500 case OMPD_declare_target: 3501 case OMPD_end_declare_target: 3502 case OMPD_requires: 3503 case OMPD_declare_variant: 3504 llvm_unreachable("OpenMP Directive is not allowed"); 3505 case OMPD_unknown: 3506 llvm_unreachable("Unknown OpenMP directive"); 3507 } 3508 } 3509 3510 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3511 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3512 } 3513 3514 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3515 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3516 getOpenMPCaptureRegions(CaptureRegions, DKind); 3517 return CaptureRegions.size(); 3518 } 3519 3520 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3521 Expr *CaptureExpr, bool WithInit, 3522 bool AsExpression) { 3523 assert(CaptureExpr); 3524 ASTContext &C = S.getASTContext(); 3525 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3526 QualType Ty = Init->getType(); 3527 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3528 if (S.getLangOpts().CPlusPlus) { 3529 Ty = C.getLValueReferenceType(Ty); 3530 } else { 3531 Ty = C.getPointerType(Ty); 3532 ExprResult Res = 3533 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3534 if (!Res.isUsable()) 3535 return nullptr; 3536 Init = Res.get(); 3537 } 3538 WithInit = true; 3539 } 3540 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3541 CaptureExpr->getBeginLoc()); 3542 if (!WithInit) 3543 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3544 S.CurContext->addHiddenDecl(CED); 3545 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3546 return CED; 3547 } 3548 3549 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3550 bool WithInit) { 3551 OMPCapturedExprDecl *CD; 3552 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3553 CD = cast<OMPCapturedExprDecl>(VD); 3554 else 3555 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3556 /*AsExpression=*/false); 3557 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3558 CaptureExpr->getExprLoc()); 3559 } 3560 3561 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3562 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3563 if (!Ref) { 3564 OMPCapturedExprDecl *CD = buildCaptureDecl( 3565 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3566 /*WithInit=*/true, /*AsExpression=*/true); 3567 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3568 CaptureExpr->getExprLoc()); 3569 } 3570 ExprResult Res = Ref; 3571 if (!S.getLangOpts().CPlusPlus && 3572 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3573 Ref->getType()->isPointerType()) { 3574 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3575 if (!Res.isUsable()) 3576 return ExprError(); 3577 } 3578 return S.DefaultLvalueConversion(Res.get()); 3579 } 3580 3581 namespace { 3582 // OpenMP directives parsed in this section are represented as a 3583 // CapturedStatement with an associated statement. If a syntax error 3584 // is detected during the parsing of the associated statement, the 3585 // compiler must abort processing and close the CapturedStatement. 3586 // 3587 // Combined directives such as 'target parallel' have more than one 3588 // nested CapturedStatements. This RAII ensures that we unwind out 3589 // of all the nested CapturedStatements when an error is found. 3590 class CaptureRegionUnwinderRAII { 3591 private: 3592 Sema &S; 3593 bool &ErrorFound; 3594 OpenMPDirectiveKind DKind = OMPD_unknown; 3595 3596 public: 3597 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3598 OpenMPDirectiveKind DKind) 3599 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3600 ~CaptureRegionUnwinderRAII() { 3601 if (ErrorFound) { 3602 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3603 while (--ThisCaptureLevel >= 0) 3604 S.ActOnCapturedRegionError(); 3605 } 3606 } 3607 }; 3608 } // namespace 3609 3610 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3611 // Capture variables captured by reference in lambdas for target-based 3612 // directives. 3613 if (!CurContext->isDependentContext() && 3614 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3615 isOpenMPTargetDataManagementDirective( 3616 DSAStack->getCurrentDirective()))) { 3617 QualType Type = V->getType(); 3618 if (const auto *RD = Type.getCanonicalType() 3619 .getNonReferenceType() 3620 ->getAsCXXRecordDecl()) { 3621 bool SavedForceCaptureByReferenceInTargetExecutable = 3622 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3623 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3624 /*V=*/true); 3625 if (RD->isLambda()) { 3626 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3627 FieldDecl *ThisCapture; 3628 RD->getCaptureFields(Captures, ThisCapture); 3629 for (const LambdaCapture &LC : RD->captures()) { 3630 if (LC.getCaptureKind() == LCK_ByRef) { 3631 VarDecl *VD = LC.getCapturedVar(); 3632 DeclContext *VDC = VD->getDeclContext(); 3633 if (!VDC->Encloses(CurContext)) 3634 continue; 3635 MarkVariableReferenced(LC.getLocation(), VD); 3636 } else if (LC.getCaptureKind() == LCK_This) { 3637 QualType ThisTy = getCurrentThisType(); 3638 if (!ThisTy.isNull() && 3639 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3640 CheckCXXThisCapture(LC.getLocation()); 3641 } 3642 } 3643 } 3644 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3645 SavedForceCaptureByReferenceInTargetExecutable); 3646 } 3647 } 3648 } 3649 3650 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3651 ArrayRef<OMPClause *> Clauses) { 3652 bool ErrorFound = false; 3653 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3654 *this, ErrorFound, DSAStack->getCurrentDirective()); 3655 if (!S.isUsable()) { 3656 ErrorFound = true; 3657 return StmtError(); 3658 } 3659 3660 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3661 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3662 OMPOrderedClause *OC = nullptr; 3663 OMPScheduleClause *SC = nullptr; 3664 SmallVector<const OMPLinearClause *, 4> LCs; 3665 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3666 // This is required for proper codegen. 3667 for (OMPClause *Clause : Clauses) { 3668 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3669 Clause->getClauseKind() == OMPC_in_reduction) { 3670 // Capture taskgroup task_reduction descriptors inside the tasking regions 3671 // with the corresponding in_reduction items. 3672 auto *IRC = cast<OMPInReductionClause>(Clause); 3673 for (Expr *E : IRC->taskgroup_descriptors()) 3674 if (E) 3675 MarkDeclarationsReferencedInExpr(E); 3676 } 3677 if (isOpenMPPrivate(Clause->getClauseKind()) || 3678 Clause->getClauseKind() == OMPC_copyprivate || 3679 (getLangOpts().OpenMPUseTLS && 3680 getASTContext().getTargetInfo().isTLSSupported() && 3681 Clause->getClauseKind() == OMPC_copyin)) { 3682 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3683 // Mark all variables in private list clauses as used in inner region. 3684 for (Stmt *VarRef : Clause->children()) { 3685 if (auto *E = cast_or_null<Expr>(VarRef)) { 3686 MarkDeclarationsReferencedInExpr(E); 3687 } 3688 } 3689 DSAStack->setForceVarCapturing(/*V=*/false); 3690 } else if (CaptureRegions.size() > 1 || 3691 CaptureRegions.back() != OMPD_unknown) { 3692 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3693 PICs.push_back(C); 3694 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3695 if (Expr *E = C->getPostUpdateExpr()) 3696 MarkDeclarationsReferencedInExpr(E); 3697 } 3698 } 3699 if (Clause->getClauseKind() == OMPC_schedule) 3700 SC = cast<OMPScheduleClause>(Clause); 3701 else if (Clause->getClauseKind() == OMPC_ordered) 3702 OC = cast<OMPOrderedClause>(Clause); 3703 else if (Clause->getClauseKind() == OMPC_linear) 3704 LCs.push_back(cast<OMPLinearClause>(Clause)); 3705 } 3706 // OpenMP, 2.7.1 Loop Construct, Restrictions 3707 // The nonmonotonic modifier cannot be specified if an ordered clause is 3708 // specified. 3709 if (SC && 3710 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3711 SC->getSecondScheduleModifier() == 3712 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3713 OC) { 3714 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3715 ? SC->getFirstScheduleModifierLoc() 3716 : SC->getSecondScheduleModifierLoc(), 3717 diag::err_omp_schedule_nonmonotonic_ordered) 3718 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3719 ErrorFound = true; 3720 } 3721 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3722 for (const OMPLinearClause *C : LCs) { 3723 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3724 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3725 } 3726 ErrorFound = true; 3727 } 3728 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3729 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3730 OC->getNumForLoops()) { 3731 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3732 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3733 ErrorFound = true; 3734 } 3735 if (ErrorFound) { 3736 return StmtError(); 3737 } 3738 StmtResult SR = S; 3739 unsigned CompletedRegions = 0; 3740 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3741 // Mark all variables in private list clauses as used in inner region. 3742 // Required for proper codegen of combined directives. 3743 // TODO: add processing for other clauses. 3744 if (ThisCaptureRegion != OMPD_unknown) { 3745 for (const clang::OMPClauseWithPreInit *C : PICs) { 3746 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3747 // Find the particular capture region for the clause if the 3748 // directive is a combined one with multiple capture regions. 3749 // If the directive is not a combined one, the capture region 3750 // associated with the clause is OMPD_unknown and is generated 3751 // only once. 3752 if (CaptureRegion == ThisCaptureRegion || 3753 CaptureRegion == OMPD_unknown) { 3754 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3755 for (Decl *D : DS->decls()) 3756 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3757 } 3758 } 3759 } 3760 } 3761 if (++CompletedRegions == CaptureRegions.size()) 3762 DSAStack->setBodyComplete(); 3763 SR = ActOnCapturedRegionEnd(SR.get()); 3764 } 3765 return SR; 3766 } 3767 3768 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3769 OpenMPDirectiveKind CancelRegion, 3770 SourceLocation StartLoc) { 3771 // CancelRegion is only needed for cancel and cancellation_point. 3772 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3773 return false; 3774 3775 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3776 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3777 return false; 3778 3779 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3780 << getOpenMPDirectiveName(CancelRegion); 3781 return true; 3782 } 3783 3784 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3785 OpenMPDirectiveKind CurrentRegion, 3786 const DeclarationNameInfo &CurrentName, 3787 OpenMPDirectiveKind CancelRegion, 3788 SourceLocation StartLoc) { 3789 if (Stack->getCurScope()) { 3790 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3791 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3792 bool NestingProhibited = false; 3793 bool CloseNesting = true; 3794 bool OrphanSeen = false; 3795 enum { 3796 NoRecommend, 3797 ShouldBeInParallelRegion, 3798 ShouldBeInOrderedRegion, 3799 ShouldBeInTargetRegion, 3800 ShouldBeInTeamsRegion 3801 } Recommend = NoRecommend; 3802 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3803 // OpenMP [2.16, Nesting of Regions] 3804 // OpenMP constructs may not be nested inside a simd region. 3805 // OpenMP [2.8.1,simd Construct, Restrictions] 3806 // An ordered construct with the simd clause is the only OpenMP 3807 // construct that can appear in the simd region. 3808 // Allowing a SIMD construct nested in another SIMD construct is an 3809 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3810 // message. 3811 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3812 ? diag::err_omp_prohibited_region_simd 3813 : diag::warn_omp_nesting_simd); 3814 return CurrentRegion != OMPD_simd; 3815 } 3816 if (ParentRegion == OMPD_atomic) { 3817 // OpenMP [2.16, Nesting of Regions] 3818 // OpenMP constructs may not be nested inside an atomic region. 3819 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3820 return true; 3821 } 3822 if (CurrentRegion == OMPD_section) { 3823 // OpenMP [2.7.2, sections Construct, Restrictions] 3824 // Orphaned section directives are prohibited. That is, the section 3825 // directives must appear within the sections construct and must not be 3826 // encountered elsewhere in the sections region. 3827 if (ParentRegion != OMPD_sections && 3828 ParentRegion != OMPD_parallel_sections) { 3829 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3830 << (ParentRegion != OMPD_unknown) 3831 << getOpenMPDirectiveName(ParentRegion); 3832 return true; 3833 } 3834 return false; 3835 } 3836 // Allow some constructs (except teams and cancellation constructs) to be 3837 // orphaned (they could be used in functions, called from OpenMP regions 3838 // with the required preconditions). 3839 if (ParentRegion == OMPD_unknown && 3840 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3841 CurrentRegion != OMPD_cancellation_point && 3842 CurrentRegion != OMPD_cancel) 3843 return false; 3844 if (CurrentRegion == OMPD_cancellation_point || 3845 CurrentRegion == OMPD_cancel) { 3846 // OpenMP [2.16, Nesting of Regions] 3847 // A cancellation point construct for which construct-type-clause is 3848 // taskgroup must be nested inside a task construct. A cancellation 3849 // point construct for which construct-type-clause is not taskgroup must 3850 // be closely nested inside an OpenMP construct that matches the type 3851 // specified in construct-type-clause. 3852 // A cancel construct for which construct-type-clause is taskgroup must be 3853 // nested inside a task construct. A cancel construct for which 3854 // construct-type-clause is not taskgroup must be closely nested inside an 3855 // OpenMP construct that matches the type specified in 3856 // construct-type-clause. 3857 NestingProhibited = 3858 !((CancelRegion == OMPD_parallel && 3859 (ParentRegion == OMPD_parallel || 3860 ParentRegion == OMPD_target_parallel)) || 3861 (CancelRegion == OMPD_for && 3862 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3863 ParentRegion == OMPD_target_parallel_for || 3864 ParentRegion == OMPD_distribute_parallel_for || 3865 ParentRegion == OMPD_teams_distribute_parallel_for || 3866 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3867 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3868 (CancelRegion == OMPD_sections && 3869 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3870 ParentRegion == OMPD_parallel_sections))); 3871 OrphanSeen = ParentRegion == OMPD_unknown; 3872 } else if (CurrentRegion == OMPD_master) { 3873 // OpenMP [2.16, Nesting of Regions] 3874 // A master region may not be closely nested inside a worksharing, 3875 // atomic, or explicit task region. 3876 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3877 isOpenMPTaskingDirective(ParentRegion); 3878 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3879 // OpenMP [2.16, Nesting of Regions] 3880 // A critical region may not be nested (closely or otherwise) inside a 3881 // critical region with the same name. Note that this restriction is not 3882 // sufficient to prevent deadlock. 3883 SourceLocation PreviousCriticalLoc; 3884 bool DeadLock = Stack->hasDirective( 3885 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3886 const DeclarationNameInfo &DNI, 3887 SourceLocation Loc) { 3888 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3889 PreviousCriticalLoc = Loc; 3890 return true; 3891 } 3892 return false; 3893 }, 3894 false /* skip top directive */); 3895 if (DeadLock) { 3896 SemaRef.Diag(StartLoc, 3897 diag::err_omp_prohibited_region_critical_same_name) 3898 << CurrentName.getName(); 3899 if (PreviousCriticalLoc.isValid()) 3900 SemaRef.Diag(PreviousCriticalLoc, 3901 diag::note_omp_previous_critical_region); 3902 return true; 3903 } 3904 } else if (CurrentRegion == OMPD_barrier) { 3905 // OpenMP [2.16, Nesting of Regions] 3906 // A barrier region may not be closely nested inside a worksharing, 3907 // explicit task, critical, ordered, atomic, or master region. 3908 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3909 isOpenMPTaskingDirective(ParentRegion) || 3910 ParentRegion == OMPD_master || 3911 ParentRegion == OMPD_critical || 3912 ParentRegion == OMPD_ordered; 3913 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3914 !isOpenMPParallelDirective(CurrentRegion) && 3915 !isOpenMPTeamsDirective(CurrentRegion)) { 3916 // OpenMP [2.16, Nesting of Regions] 3917 // A worksharing region may not be closely nested inside a worksharing, 3918 // explicit task, critical, ordered, atomic, or master region. 3919 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3920 isOpenMPTaskingDirective(ParentRegion) || 3921 ParentRegion == OMPD_master || 3922 ParentRegion == OMPD_critical || 3923 ParentRegion == OMPD_ordered; 3924 Recommend = ShouldBeInParallelRegion; 3925 } else if (CurrentRegion == OMPD_ordered) { 3926 // OpenMP [2.16, Nesting of Regions] 3927 // An ordered region may not be closely nested inside a critical, 3928 // atomic, or explicit task region. 3929 // An ordered region must be closely nested inside a loop region (or 3930 // parallel loop region) with an ordered clause. 3931 // OpenMP [2.8.1,simd Construct, Restrictions] 3932 // An ordered construct with the simd clause is the only OpenMP construct 3933 // that can appear in the simd region. 3934 NestingProhibited = ParentRegion == OMPD_critical || 3935 isOpenMPTaskingDirective(ParentRegion) || 3936 !(isOpenMPSimdDirective(ParentRegion) || 3937 Stack->isParentOrderedRegion()); 3938 Recommend = ShouldBeInOrderedRegion; 3939 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3940 // OpenMP [2.16, Nesting of Regions] 3941 // If specified, a teams construct must be contained within a target 3942 // construct. 3943 NestingProhibited = 3944 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 3945 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 3946 ParentRegion != OMPD_target); 3947 OrphanSeen = ParentRegion == OMPD_unknown; 3948 Recommend = ShouldBeInTargetRegion; 3949 } 3950 if (!NestingProhibited && 3951 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3952 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3953 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3954 // OpenMP [2.16, Nesting of Regions] 3955 // distribute, parallel, parallel sections, parallel workshare, and the 3956 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3957 // constructs that can be closely nested in the teams region. 3958 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3959 !isOpenMPDistributeDirective(CurrentRegion); 3960 Recommend = ShouldBeInParallelRegion; 3961 } 3962 if (!NestingProhibited && 3963 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3964 // OpenMP 4.5 [2.17 Nesting of Regions] 3965 // The region associated with the distribute construct must be strictly 3966 // nested inside a teams region 3967 NestingProhibited = 3968 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3969 Recommend = ShouldBeInTeamsRegion; 3970 } 3971 if (!NestingProhibited && 3972 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3973 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3974 // OpenMP 4.5 [2.17 Nesting of Regions] 3975 // If a target, target update, target data, target enter data, or 3976 // target exit data construct is encountered during execution of a 3977 // target region, the behavior is unspecified. 3978 NestingProhibited = Stack->hasDirective( 3979 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3980 SourceLocation) { 3981 if (isOpenMPTargetExecutionDirective(K)) { 3982 OffendingRegion = K; 3983 return true; 3984 } 3985 return false; 3986 }, 3987 false /* don't skip top directive */); 3988 CloseNesting = false; 3989 } 3990 if (NestingProhibited) { 3991 if (OrphanSeen) { 3992 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3993 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3994 } else { 3995 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3996 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3997 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3998 } 3999 return true; 4000 } 4001 } 4002 return false; 4003 } 4004 4005 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4006 ArrayRef<OMPClause *> Clauses, 4007 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4008 bool ErrorFound = false; 4009 unsigned NamedModifiersNumber = 0; 4010 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 4011 OMPD_unknown + 1); 4012 SmallVector<SourceLocation, 4> NameModifierLoc; 4013 for (const OMPClause *C : Clauses) { 4014 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4015 // At most one if clause without a directive-name-modifier can appear on 4016 // the directive. 4017 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4018 if (FoundNameModifiers[CurNM]) { 4019 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4020 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4021 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4022 ErrorFound = true; 4023 } else if (CurNM != OMPD_unknown) { 4024 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4025 ++NamedModifiersNumber; 4026 } 4027 FoundNameModifiers[CurNM] = IC; 4028 if (CurNM == OMPD_unknown) 4029 continue; 4030 // Check if the specified name modifier is allowed for the current 4031 // directive. 4032 // At most one if clause with the particular directive-name-modifier can 4033 // appear on the directive. 4034 bool MatchFound = false; 4035 for (auto NM : AllowedNameModifiers) { 4036 if (CurNM == NM) { 4037 MatchFound = true; 4038 break; 4039 } 4040 } 4041 if (!MatchFound) { 4042 S.Diag(IC->getNameModifierLoc(), 4043 diag::err_omp_wrong_if_directive_name_modifier) 4044 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4045 ErrorFound = true; 4046 } 4047 } 4048 } 4049 // If any if clause on the directive includes a directive-name-modifier then 4050 // all if clauses on the directive must include a directive-name-modifier. 4051 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4052 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4053 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4054 diag::err_omp_no_more_if_clause); 4055 } else { 4056 std::string Values; 4057 std::string Sep(", "); 4058 unsigned AllowedCnt = 0; 4059 unsigned TotalAllowedNum = 4060 AllowedNameModifiers.size() - NamedModifiersNumber; 4061 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4062 ++Cnt) { 4063 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4064 if (!FoundNameModifiers[NM]) { 4065 Values += "'"; 4066 Values += getOpenMPDirectiveName(NM); 4067 Values += "'"; 4068 if (AllowedCnt + 2 == TotalAllowedNum) 4069 Values += " or "; 4070 else if (AllowedCnt + 1 != TotalAllowedNum) 4071 Values += Sep; 4072 ++AllowedCnt; 4073 } 4074 } 4075 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4076 diag::err_omp_unnamed_if_clause) 4077 << (TotalAllowedNum > 1) << Values; 4078 } 4079 for (SourceLocation Loc : NameModifierLoc) { 4080 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4081 } 4082 ErrorFound = true; 4083 } 4084 return ErrorFound; 4085 } 4086 4087 static std::pair<ValueDecl *, bool> 4088 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4089 SourceRange &ERange, bool AllowArraySection = false) { 4090 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4091 RefExpr->containsUnexpandedParameterPack()) 4092 return std::make_pair(nullptr, true); 4093 4094 // OpenMP [3.1, C/C++] 4095 // A list item is a variable name. 4096 // OpenMP [2.9.3.3, Restrictions, p.1] 4097 // A variable that is part of another variable (as an array or 4098 // structure element) cannot appear in a private clause. 4099 RefExpr = RefExpr->IgnoreParens(); 4100 enum { 4101 NoArrayExpr = -1, 4102 ArraySubscript = 0, 4103 OMPArraySection = 1 4104 } IsArrayExpr = NoArrayExpr; 4105 if (AllowArraySection) { 4106 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4107 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4108 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4109 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4110 RefExpr = Base; 4111 IsArrayExpr = ArraySubscript; 4112 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4113 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4114 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4115 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4116 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4117 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4118 RefExpr = Base; 4119 IsArrayExpr = OMPArraySection; 4120 } 4121 } 4122 ELoc = RefExpr->getExprLoc(); 4123 ERange = RefExpr->getSourceRange(); 4124 RefExpr = RefExpr->IgnoreParenImpCasts(); 4125 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4126 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4127 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4128 (S.getCurrentThisType().isNull() || !ME || 4129 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4130 !isa<FieldDecl>(ME->getMemberDecl()))) { 4131 if (IsArrayExpr != NoArrayExpr) { 4132 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4133 << ERange; 4134 } else { 4135 S.Diag(ELoc, 4136 AllowArraySection 4137 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4138 : diag::err_omp_expected_var_name_member_expr) 4139 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4140 } 4141 return std::make_pair(nullptr, false); 4142 } 4143 return std::make_pair( 4144 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4145 } 4146 4147 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4148 ArrayRef<OMPClause *> Clauses) { 4149 assert(!S.CurContext->isDependentContext() && 4150 "Expected non-dependent context."); 4151 auto AllocateRange = 4152 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4153 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4154 DeclToCopy; 4155 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4156 return isOpenMPPrivate(C->getClauseKind()); 4157 }); 4158 for (OMPClause *Cl : PrivateRange) { 4159 MutableArrayRef<Expr *>::iterator I, It, Et; 4160 if (Cl->getClauseKind() == OMPC_private) { 4161 auto *PC = cast<OMPPrivateClause>(Cl); 4162 I = PC->private_copies().begin(); 4163 It = PC->varlist_begin(); 4164 Et = PC->varlist_end(); 4165 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4166 auto *PC = cast<OMPFirstprivateClause>(Cl); 4167 I = PC->private_copies().begin(); 4168 It = PC->varlist_begin(); 4169 Et = PC->varlist_end(); 4170 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4171 auto *PC = cast<OMPLastprivateClause>(Cl); 4172 I = PC->private_copies().begin(); 4173 It = PC->varlist_begin(); 4174 Et = PC->varlist_end(); 4175 } else if (Cl->getClauseKind() == OMPC_linear) { 4176 auto *PC = cast<OMPLinearClause>(Cl); 4177 I = PC->privates().begin(); 4178 It = PC->varlist_begin(); 4179 Et = PC->varlist_end(); 4180 } else if (Cl->getClauseKind() == OMPC_reduction) { 4181 auto *PC = cast<OMPReductionClause>(Cl); 4182 I = PC->privates().begin(); 4183 It = PC->varlist_begin(); 4184 Et = PC->varlist_end(); 4185 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4186 auto *PC = cast<OMPTaskReductionClause>(Cl); 4187 I = PC->privates().begin(); 4188 It = PC->varlist_begin(); 4189 Et = PC->varlist_end(); 4190 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4191 auto *PC = cast<OMPInReductionClause>(Cl); 4192 I = PC->privates().begin(); 4193 It = PC->varlist_begin(); 4194 Et = PC->varlist_end(); 4195 } else { 4196 llvm_unreachable("Expected private clause."); 4197 } 4198 for (Expr *E : llvm::make_range(It, Et)) { 4199 if (!*I) { 4200 ++I; 4201 continue; 4202 } 4203 SourceLocation ELoc; 4204 SourceRange ERange; 4205 Expr *SimpleRefExpr = E; 4206 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4207 /*AllowArraySection=*/true); 4208 DeclToCopy.try_emplace(Res.first, 4209 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4210 ++I; 4211 } 4212 } 4213 for (OMPClause *C : AllocateRange) { 4214 auto *AC = cast<OMPAllocateClause>(C); 4215 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4216 getAllocatorKind(S, Stack, AC->getAllocator()); 4217 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4218 // For task, taskloop or target directives, allocation requests to memory 4219 // allocators with the trait access set to thread result in unspecified 4220 // behavior. 4221 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4222 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4223 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4224 S.Diag(AC->getAllocator()->getExprLoc(), 4225 diag::warn_omp_allocate_thread_on_task_target_directive) 4226 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4227 } 4228 for (Expr *E : AC->varlists()) { 4229 SourceLocation ELoc; 4230 SourceRange ERange; 4231 Expr *SimpleRefExpr = E; 4232 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4233 ValueDecl *VD = Res.first; 4234 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4235 if (!isOpenMPPrivate(Data.CKind)) { 4236 S.Diag(E->getExprLoc(), 4237 diag::err_omp_expected_private_copy_for_allocate); 4238 continue; 4239 } 4240 VarDecl *PrivateVD = DeclToCopy[VD]; 4241 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4242 AllocatorKind, AC->getAllocator())) 4243 continue; 4244 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4245 E->getSourceRange()); 4246 } 4247 } 4248 } 4249 4250 StmtResult Sema::ActOnOpenMPExecutableDirective( 4251 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4252 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4253 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4254 StmtResult Res = StmtError(); 4255 // First check CancelRegion which is then used in checkNestingOfRegions. 4256 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4257 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4258 StartLoc)) 4259 return StmtError(); 4260 4261 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4262 VarsWithInheritedDSAType VarsWithInheritedDSA; 4263 bool ErrorFound = false; 4264 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4265 if (AStmt && !CurContext->isDependentContext()) { 4266 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4267 4268 // Check default data sharing attributes for referenced variables. 4269 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4270 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4271 Stmt *S = AStmt; 4272 while (--ThisCaptureLevel >= 0) 4273 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4274 DSAChecker.Visit(S); 4275 if (!isOpenMPTargetDataManagementDirective(Kind) && 4276 !isOpenMPTaskingDirective(Kind)) { 4277 // Visit subcaptures to generate implicit clauses for captured vars. 4278 auto *CS = cast<CapturedStmt>(AStmt); 4279 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4280 getOpenMPCaptureRegions(CaptureRegions, Kind); 4281 // Ignore outer tasking regions for target directives. 4282 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4283 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4284 DSAChecker.visitSubCaptures(CS); 4285 } 4286 if (DSAChecker.isErrorFound()) 4287 return StmtError(); 4288 // Generate list of implicitly defined firstprivate variables. 4289 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4290 4291 SmallVector<Expr *, 4> ImplicitFirstprivates( 4292 DSAChecker.getImplicitFirstprivate().begin(), 4293 DSAChecker.getImplicitFirstprivate().end()); 4294 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4295 DSAChecker.getImplicitMap().end()); 4296 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4297 for (OMPClause *C : Clauses) { 4298 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4299 for (Expr *E : IRC->taskgroup_descriptors()) 4300 if (E) 4301 ImplicitFirstprivates.emplace_back(E); 4302 } 4303 } 4304 if (!ImplicitFirstprivates.empty()) { 4305 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4306 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4307 SourceLocation())) { 4308 ClausesWithImplicit.push_back(Implicit); 4309 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4310 ImplicitFirstprivates.size(); 4311 } else { 4312 ErrorFound = true; 4313 } 4314 } 4315 if (!ImplicitMaps.empty()) { 4316 CXXScopeSpec MapperIdScopeSpec; 4317 DeclarationNameInfo MapperId; 4318 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4319 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4320 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4321 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4322 ClausesWithImplicit.emplace_back(Implicit); 4323 ErrorFound |= 4324 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4325 } else { 4326 ErrorFound = true; 4327 } 4328 } 4329 } 4330 4331 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4332 switch (Kind) { 4333 case OMPD_parallel: 4334 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4335 EndLoc); 4336 AllowedNameModifiers.push_back(OMPD_parallel); 4337 break; 4338 case OMPD_simd: 4339 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4340 VarsWithInheritedDSA); 4341 break; 4342 case OMPD_for: 4343 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4344 VarsWithInheritedDSA); 4345 break; 4346 case OMPD_for_simd: 4347 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4348 EndLoc, VarsWithInheritedDSA); 4349 break; 4350 case OMPD_sections: 4351 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4352 EndLoc); 4353 break; 4354 case OMPD_section: 4355 assert(ClausesWithImplicit.empty() && 4356 "No clauses are allowed for 'omp section' directive"); 4357 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4358 break; 4359 case OMPD_single: 4360 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4361 EndLoc); 4362 break; 4363 case OMPD_master: 4364 assert(ClausesWithImplicit.empty() && 4365 "No clauses are allowed for 'omp master' directive"); 4366 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4367 break; 4368 case OMPD_critical: 4369 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4370 StartLoc, EndLoc); 4371 break; 4372 case OMPD_parallel_for: 4373 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4374 EndLoc, VarsWithInheritedDSA); 4375 AllowedNameModifiers.push_back(OMPD_parallel); 4376 break; 4377 case OMPD_parallel_for_simd: 4378 Res = ActOnOpenMPParallelForSimdDirective( 4379 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4380 AllowedNameModifiers.push_back(OMPD_parallel); 4381 break; 4382 case OMPD_parallel_sections: 4383 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4384 StartLoc, EndLoc); 4385 AllowedNameModifiers.push_back(OMPD_parallel); 4386 break; 4387 case OMPD_task: 4388 Res = 4389 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4390 AllowedNameModifiers.push_back(OMPD_task); 4391 break; 4392 case OMPD_taskyield: 4393 assert(ClausesWithImplicit.empty() && 4394 "No clauses are allowed for 'omp taskyield' directive"); 4395 assert(AStmt == nullptr && 4396 "No associated statement allowed for 'omp taskyield' directive"); 4397 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4398 break; 4399 case OMPD_barrier: 4400 assert(ClausesWithImplicit.empty() && 4401 "No clauses are allowed for 'omp barrier' directive"); 4402 assert(AStmt == nullptr && 4403 "No associated statement allowed for 'omp barrier' directive"); 4404 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4405 break; 4406 case OMPD_taskwait: 4407 assert(ClausesWithImplicit.empty() && 4408 "No clauses are allowed for 'omp taskwait' directive"); 4409 assert(AStmt == nullptr && 4410 "No associated statement allowed for 'omp taskwait' directive"); 4411 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4412 break; 4413 case OMPD_taskgroup: 4414 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4415 EndLoc); 4416 break; 4417 case OMPD_flush: 4418 assert(AStmt == nullptr && 4419 "No associated statement allowed for 'omp flush' directive"); 4420 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4421 break; 4422 case OMPD_ordered: 4423 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4424 EndLoc); 4425 break; 4426 case OMPD_atomic: 4427 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4428 EndLoc); 4429 break; 4430 case OMPD_teams: 4431 Res = 4432 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4433 break; 4434 case OMPD_target: 4435 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4436 EndLoc); 4437 AllowedNameModifiers.push_back(OMPD_target); 4438 break; 4439 case OMPD_target_parallel: 4440 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4441 StartLoc, EndLoc); 4442 AllowedNameModifiers.push_back(OMPD_target); 4443 AllowedNameModifiers.push_back(OMPD_parallel); 4444 break; 4445 case OMPD_target_parallel_for: 4446 Res = ActOnOpenMPTargetParallelForDirective( 4447 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4448 AllowedNameModifiers.push_back(OMPD_target); 4449 AllowedNameModifiers.push_back(OMPD_parallel); 4450 break; 4451 case OMPD_cancellation_point: 4452 assert(ClausesWithImplicit.empty() && 4453 "No clauses are allowed for 'omp cancellation point' directive"); 4454 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4455 "cancellation point' directive"); 4456 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4457 break; 4458 case OMPD_cancel: 4459 assert(AStmt == nullptr && 4460 "No associated statement allowed for 'omp cancel' directive"); 4461 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4462 CancelRegion); 4463 AllowedNameModifiers.push_back(OMPD_cancel); 4464 break; 4465 case OMPD_target_data: 4466 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4467 EndLoc); 4468 AllowedNameModifiers.push_back(OMPD_target_data); 4469 break; 4470 case OMPD_target_enter_data: 4471 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4472 EndLoc, AStmt); 4473 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4474 break; 4475 case OMPD_target_exit_data: 4476 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4477 EndLoc, AStmt); 4478 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4479 break; 4480 case OMPD_taskloop: 4481 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4482 EndLoc, VarsWithInheritedDSA); 4483 AllowedNameModifiers.push_back(OMPD_taskloop); 4484 break; 4485 case OMPD_taskloop_simd: 4486 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4487 EndLoc, VarsWithInheritedDSA); 4488 AllowedNameModifiers.push_back(OMPD_taskloop); 4489 break; 4490 case OMPD_master_taskloop: 4491 Res = ActOnOpenMPMasterTaskLoopDirective( 4492 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4493 AllowedNameModifiers.push_back(OMPD_taskloop); 4494 break; 4495 case OMPD_master_taskloop_simd: 4496 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4497 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4498 AllowedNameModifiers.push_back(OMPD_taskloop); 4499 break; 4500 case OMPD_parallel_master_taskloop: 4501 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4502 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4503 AllowedNameModifiers.push_back(OMPD_taskloop); 4504 AllowedNameModifiers.push_back(OMPD_parallel); 4505 break; 4506 case OMPD_parallel_master_taskloop_simd: 4507 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4508 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4509 AllowedNameModifiers.push_back(OMPD_taskloop); 4510 AllowedNameModifiers.push_back(OMPD_parallel); 4511 break; 4512 case OMPD_distribute: 4513 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4514 EndLoc, VarsWithInheritedDSA); 4515 break; 4516 case OMPD_target_update: 4517 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4518 EndLoc, AStmt); 4519 AllowedNameModifiers.push_back(OMPD_target_update); 4520 break; 4521 case OMPD_distribute_parallel_for: 4522 Res = ActOnOpenMPDistributeParallelForDirective( 4523 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4524 AllowedNameModifiers.push_back(OMPD_parallel); 4525 break; 4526 case OMPD_distribute_parallel_for_simd: 4527 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4528 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4529 AllowedNameModifiers.push_back(OMPD_parallel); 4530 break; 4531 case OMPD_distribute_simd: 4532 Res = ActOnOpenMPDistributeSimdDirective( 4533 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4534 break; 4535 case OMPD_target_parallel_for_simd: 4536 Res = ActOnOpenMPTargetParallelForSimdDirective( 4537 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4538 AllowedNameModifiers.push_back(OMPD_target); 4539 AllowedNameModifiers.push_back(OMPD_parallel); 4540 break; 4541 case OMPD_target_simd: 4542 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4543 EndLoc, VarsWithInheritedDSA); 4544 AllowedNameModifiers.push_back(OMPD_target); 4545 break; 4546 case OMPD_teams_distribute: 4547 Res = ActOnOpenMPTeamsDistributeDirective( 4548 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4549 break; 4550 case OMPD_teams_distribute_simd: 4551 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4552 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4553 break; 4554 case OMPD_teams_distribute_parallel_for_simd: 4555 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4556 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4557 AllowedNameModifiers.push_back(OMPD_parallel); 4558 break; 4559 case OMPD_teams_distribute_parallel_for: 4560 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4561 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4562 AllowedNameModifiers.push_back(OMPD_parallel); 4563 break; 4564 case OMPD_target_teams: 4565 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4566 EndLoc); 4567 AllowedNameModifiers.push_back(OMPD_target); 4568 break; 4569 case OMPD_target_teams_distribute: 4570 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4571 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4572 AllowedNameModifiers.push_back(OMPD_target); 4573 break; 4574 case OMPD_target_teams_distribute_parallel_for: 4575 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4576 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4577 AllowedNameModifiers.push_back(OMPD_target); 4578 AllowedNameModifiers.push_back(OMPD_parallel); 4579 break; 4580 case OMPD_target_teams_distribute_parallel_for_simd: 4581 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4582 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4583 AllowedNameModifiers.push_back(OMPD_target); 4584 AllowedNameModifiers.push_back(OMPD_parallel); 4585 break; 4586 case OMPD_target_teams_distribute_simd: 4587 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4588 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4589 AllowedNameModifiers.push_back(OMPD_target); 4590 break; 4591 case OMPD_declare_target: 4592 case OMPD_end_declare_target: 4593 case OMPD_threadprivate: 4594 case OMPD_allocate: 4595 case OMPD_declare_reduction: 4596 case OMPD_declare_mapper: 4597 case OMPD_declare_simd: 4598 case OMPD_requires: 4599 case OMPD_declare_variant: 4600 llvm_unreachable("OpenMP Directive is not allowed"); 4601 case OMPD_unknown: 4602 llvm_unreachable("Unknown OpenMP directive"); 4603 } 4604 4605 ErrorFound = Res.isInvalid() || ErrorFound; 4606 4607 // Check variables in the clauses if default(none) was specified. 4608 if (DSAStack->getDefaultDSA() == DSA_none) { 4609 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4610 for (OMPClause *C : Clauses) { 4611 switch (C->getClauseKind()) { 4612 case OMPC_num_threads: 4613 case OMPC_dist_schedule: 4614 // Do not analyse if no parent teams directive. 4615 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4616 break; 4617 continue; 4618 case OMPC_if: 4619 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4620 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4621 break; 4622 continue; 4623 case OMPC_schedule: 4624 break; 4625 case OMPC_grainsize: 4626 case OMPC_num_tasks: 4627 case OMPC_final: 4628 case OMPC_priority: 4629 // Do not analyze if no parent parallel directive. 4630 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective())) 4631 break; 4632 continue; 4633 case OMPC_ordered: 4634 case OMPC_device: 4635 case OMPC_num_teams: 4636 case OMPC_thread_limit: 4637 case OMPC_hint: 4638 case OMPC_collapse: 4639 case OMPC_safelen: 4640 case OMPC_simdlen: 4641 case OMPC_default: 4642 case OMPC_proc_bind: 4643 case OMPC_private: 4644 case OMPC_firstprivate: 4645 case OMPC_lastprivate: 4646 case OMPC_shared: 4647 case OMPC_reduction: 4648 case OMPC_task_reduction: 4649 case OMPC_in_reduction: 4650 case OMPC_linear: 4651 case OMPC_aligned: 4652 case OMPC_copyin: 4653 case OMPC_copyprivate: 4654 case OMPC_nowait: 4655 case OMPC_untied: 4656 case OMPC_mergeable: 4657 case OMPC_allocate: 4658 case OMPC_read: 4659 case OMPC_write: 4660 case OMPC_update: 4661 case OMPC_capture: 4662 case OMPC_seq_cst: 4663 case OMPC_depend: 4664 case OMPC_threads: 4665 case OMPC_simd: 4666 case OMPC_map: 4667 case OMPC_nogroup: 4668 case OMPC_defaultmap: 4669 case OMPC_to: 4670 case OMPC_from: 4671 case OMPC_use_device_ptr: 4672 case OMPC_is_device_ptr: 4673 continue; 4674 case OMPC_allocator: 4675 case OMPC_flush: 4676 case OMPC_threadprivate: 4677 case OMPC_uniform: 4678 case OMPC_unknown: 4679 case OMPC_unified_address: 4680 case OMPC_unified_shared_memory: 4681 case OMPC_reverse_offload: 4682 case OMPC_dynamic_allocators: 4683 case OMPC_atomic_default_mem_order: 4684 case OMPC_device_type: 4685 case OMPC_match: 4686 llvm_unreachable("Unexpected clause"); 4687 } 4688 for (Stmt *CC : C->children()) { 4689 if (CC) 4690 DSAChecker.Visit(CC); 4691 } 4692 } 4693 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4694 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4695 } 4696 for (const auto &P : VarsWithInheritedDSA) { 4697 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4698 continue; 4699 ErrorFound = true; 4700 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4701 << P.first << P.second->getSourceRange(); 4702 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4703 } 4704 4705 if (!AllowedNameModifiers.empty()) 4706 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4707 ErrorFound; 4708 4709 if (ErrorFound) 4710 return StmtError(); 4711 4712 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4713 Res.getAs<OMPExecutableDirective>() 4714 ->getStructuredBlock() 4715 ->setIsOMPStructuredBlock(true); 4716 } 4717 4718 if (!CurContext->isDependentContext() && 4719 isOpenMPTargetExecutionDirective(Kind) && 4720 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4721 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4722 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4723 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4724 // Register target to DSA Stack. 4725 DSAStack->addTargetDirLocation(StartLoc); 4726 } 4727 4728 return Res; 4729 } 4730 4731 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4732 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4733 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4734 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4735 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4736 assert(Aligneds.size() == Alignments.size()); 4737 assert(Linears.size() == LinModifiers.size()); 4738 assert(Linears.size() == Steps.size()); 4739 if (!DG || DG.get().isNull()) 4740 return DeclGroupPtrTy(); 4741 4742 const int SimdId = 0; 4743 if (!DG.get().isSingleDecl()) { 4744 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4745 << SimdId; 4746 return DG; 4747 } 4748 Decl *ADecl = DG.get().getSingleDecl(); 4749 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4750 ADecl = FTD->getTemplatedDecl(); 4751 4752 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4753 if (!FD) { 4754 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4755 return DeclGroupPtrTy(); 4756 } 4757 4758 // OpenMP [2.8.2, declare simd construct, Description] 4759 // The parameter of the simdlen clause must be a constant positive integer 4760 // expression. 4761 ExprResult SL; 4762 if (Simdlen) 4763 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4764 // OpenMP [2.8.2, declare simd construct, Description] 4765 // The special this pointer can be used as if was one of the arguments to the 4766 // function in any of the linear, aligned, or uniform clauses. 4767 // The uniform clause declares one or more arguments to have an invariant 4768 // value for all concurrent invocations of the function in the execution of a 4769 // single SIMD loop. 4770 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4771 const Expr *UniformedLinearThis = nullptr; 4772 for (const Expr *E : Uniforms) { 4773 E = E->IgnoreParenImpCasts(); 4774 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4775 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4776 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4777 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4778 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4779 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4780 continue; 4781 } 4782 if (isa<CXXThisExpr>(E)) { 4783 UniformedLinearThis = E; 4784 continue; 4785 } 4786 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4787 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4788 } 4789 // OpenMP [2.8.2, declare simd construct, Description] 4790 // The aligned clause declares that the object to which each list item points 4791 // is aligned to the number of bytes expressed in the optional parameter of 4792 // the aligned clause. 4793 // The special this pointer can be used as if was one of the arguments to the 4794 // function in any of the linear, aligned, or uniform clauses. 4795 // The type of list items appearing in the aligned clause must be array, 4796 // pointer, reference to array, or reference to pointer. 4797 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4798 const Expr *AlignedThis = nullptr; 4799 for (const Expr *E : Aligneds) { 4800 E = E->IgnoreParenImpCasts(); 4801 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4802 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4803 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4804 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4805 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4806 ->getCanonicalDecl() == CanonPVD) { 4807 // OpenMP [2.8.1, simd construct, Restrictions] 4808 // A list-item cannot appear in more than one aligned clause. 4809 if (AlignedArgs.count(CanonPVD) > 0) { 4810 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4811 << 1 << E->getSourceRange(); 4812 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4813 diag::note_omp_explicit_dsa) 4814 << getOpenMPClauseName(OMPC_aligned); 4815 continue; 4816 } 4817 AlignedArgs[CanonPVD] = E; 4818 QualType QTy = PVD->getType() 4819 .getNonReferenceType() 4820 .getUnqualifiedType() 4821 .getCanonicalType(); 4822 const Type *Ty = QTy.getTypePtrOrNull(); 4823 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4824 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4825 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4826 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4827 } 4828 continue; 4829 } 4830 } 4831 if (isa<CXXThisExpr>(E)) { 4832 if (AlignedThis) { 4833 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4834 << 2 << E->getSourceRange(); 4835 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4836 << getOpenMPClauseName(OMPC_aligned); 4837 } 4838 AlignedThis = E; 4839 continue; 4840 } 4841 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4842 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4843 } 4844 // The optional parameter of the aligned clause, alignment, must be a constant 4845 // positive integer expression. If no optional parameter is specified, 4846 // implementation-defined default alignments for SIMD instructions on the 4847 // target platforms are assumed. 4848 SmallVector<const Expr *, 4> NewAligns; 4849 for (Expr *E : Alignments) { 4850 ExprResult Align; 4851 if (E) 4852 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4853 NewAligns.push_back(Align.get()); 4854 } 4855 // OpenMP [2.8.2, declare simd construct, Description] 4856 // The linear clause declares one or more list items to be private to a SIMD 4857 // lane and to have a linear relationship with respect to the iteration space 4858 // of a loop. 4859 // The special this pointer can be used as if was one of the arguments to the 4860 // function in any of the linear, aligned, or uniform clauses. 4861 // When a linear-step expression is specified in a linear clause it must be 4862 // either a constant integer expression or an integer-typed parameter that is 4863 // specified in a uniform clause on the directive. 4864 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4865 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4866 auto MI = LinModifiers.begin(); 4867 for (const Expr *E : Linears) { 4868 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4869 ++MI; 4870 E = E->IgnoreParenImpCasts(); 4871 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4872 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4873 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4874 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4875 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4876 ->getCanonicalDecl() == CanonPVD) { 4877 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4878 // A list-item cannot appear in more than one linear clause. 4879 if (LinearArgs.count(CanonPVD) > 0) { 4880 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4881 << getOpenMPClauseName(OMPC_linear) 4882 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4883 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4884 diag::note_omp_explicit_dsa) 4885 << getOpenMPClauseName(OMPC_linear); 4886 continue; 4887 } 4888 // Each argument can appear in at most one uniform or linear clause. 4889 if (UniformedArgs.count(CanonPVD) > 0) { 4890 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4891 << getOpenMPClauseName(OMPC_linear) 4892 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4893 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4894 diag::note_omp_explicit_dsa) 4895 << getOpenMPClauseName(OMPC_uniform); 4896 continue; 4897 } 4898 LinearArgs[CanonPVD] = E; 4899 if (E->isValueDependent() || E->isTypeDependent() || 4900 E->isInstantiationDependent() || 4901 E->containsUnexpandedParameterPack()) 4902 continue; 4903 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4904 PVD->getOriginalType()); 4905 continue; 4906 } 4907 } 4908 if (isa<CXXThisExpr>(E)) { 4909 if (UniformedLinearThis) { 4910 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4911 << getOpenMPClauseName(OMPC_linear) 4912 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4913 << E->getSourceRange(); 4914 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4915 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4916 : OMPC_linear); 4917 continue; 4918 } 4919 UniformedLinearThis = E; 4920 if (E->isValueDependent() || E->isTypeDependent() || 4921 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4922 continue; 4923 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4924 E->getType()); 4925 continue; 4926 } 4927 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4928 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4929 } 4930 Expr *Step = nullptr; 4931 Expr *NewStep = nullptr; 4932 SmallVector<Expr *, 4> NewSteps; 4933 for (Expr *E : Steps) { 4934 // Skip the same step expression, it was checked already. 4935 if (Step == E || !E) { 4936 NewSteps.push_back(E ? NewStep : nullptr); 4937 continue; 4938 } 4939 Step = E; 4940 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4941 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4942 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4943 if (UniformedArgs.count(CanonPVD) == 0) { 4944 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4945 << Step->getSourceRange(); 4946 } else if (E->isValueDependent() || E->isTypeDependent() || 4947 E->isInstantiationDependent() || 4948 E->containsUnexpandedParameterPack() || 4949 CanonPVD->getType()->hasIntegerRepresentation()) { 4950 NewSteps.push_back(Step); 4951 } else { 4952 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4953 << Step->getSourceRange(); 4954 } 4955 continue; 4956 } 4957 NewStep = Step; 4958 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4959 !Step->isInstantiationDependent() && 4960 !Step->containsUnexpandedParameterPack()) { 4961 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4962 .get(); 4963 if (NewStep) 4964 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4965 } 4966 NewSteps.push_back(NewStep); 4967 } 4968 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4969 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4970 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4971 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4972 const_cast<Expr **>(Linears.data()), Linears.size(), 4973 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4974 NewSteps.data(), NewSteps.size(), SR); 4975 ADecl->addAttr(NewAttr); 4976 return DG; 4977 } 4978 4979 Optional<std::pair<FunctionDecl *, Expr *>> 4980 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 4981 Expr *VariantRef, SourceRange SR) { 4982 if (!DG || DG.get().isNull()) 4983 return None; 4984 4985 const int VariantId = 1; 4986 // Must be applied only to single decl. 4987 if (!DG.get().isSingleDecl()) { 4988 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4989 << VariantId << SR; 4990 return None; 4991 } 4992 Decl *ADecl = DG.get().getSingleDecl(); 4993 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4994 ADecl = FTD->getTemplatedDecl(); 4995 4996 // Decl must be a function. 4997 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4998 if (!FD) { 4999 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5000 << VariantId << SR; 5001 return None; 5002 } 5003 5004 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5005 return FD->hasAttrs() && 5006 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5007 FD->hasAttr<TargetAttr>()); 5008 }; 5009 // OpenMP is not compatible with CPU-specific attributes. 5010 if (HasMultiVersionAttributes(FD)) { 5011 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5012 << SR; 5013 return None; 5014 } 5015 5016 // Allow #pragma omp declare variant only if the function is not used. 5017 if (FD->isUsed(false)) 5018 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5019 << FD->getLocation(); 5020 5021 // Check if the function was emitted already. 5022 const FunctionDecl *Definition; 5023 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5024 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5025 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5026 << FD->getLocation(); 5027 5028 // The VariantRef must point to function. 5029 if (!VariantRef) { 5030 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5031 return None; 5032 } 5033 5034 // Do not check templates, wait until instantiation. 5035 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5036 VariantRef->containsUnexpandedParameterPack() || 5037 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5038 return std::make_pair(FD, VariantRef); 5039 5040 // Convert VariantRef expression to the type of the original function to 5041 // resolve possible conflicts. 5042 ExprResult VariantRefCast; 5043 if (LangOpts.CPlusPlus) { 5044 QualType FnPtrType; 5045 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5046 if (Method && !Method->isStatic()) { 5047 const Type *ClassType = 5048 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5049 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5050 ExprResult ER; 5051 { 5052 // Build adrr_of unary op to correctly handle type checks for member 5053 // functions. 5054 Sema::TentativeAnalysisScope Trap(*this); 5055 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5056 VariantRef); 5057 } 5058 if (!ER.isUsable()) { 5059 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5060 << VariantId << VariantRef->getSourceRange(); 5061 return None; 5062 } 5063 VariantRef = ER.get(); 5064 } else { 5065 FnPtrType = Context.getPointerType(FD->getType()); 5066 } 5067 ImplicitConversionSequence ICS = 5068 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5069 /*SuppressUserConversions=*/false, 5070 /*AllowExplicit=*/false, 5071 /*InOverloadResolution=*/false, 5072 /*CStyle=*/false, 5073 /*AllowObjCWritebackConversion=*/false); 5074 if (ICS.isFailure()) { 5075 Diag(VariantRef->getExprLoc(), 5076 diag::err_omp_declare_variant_incompat_types) 5077 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 5078 return None; 5079 } 5080 VariantRefCast = PerformImplicitConversion( 5081 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5082 if (!VariantRefCast.isUsable()) 5083 return None; 5084 // Drop previously built artificial addr_of unary op for member functions. 5085 if (Method && !Method->isStatic()) { 5086 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5087 if (auto *UO = dyn_cast<UnaryOperator>( 5088 PossibleAddrOfVariantRef->IgnoreImplicit())) 5089 VariantRefCast = UO->getSubExpr(); 5090 } 5091 } else { 5092 VariantRefCast = VariantRef; 5093 } 5094 5095 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5096 if (!ER.isUsable() || 5097 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5098 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5099 << VariantId << VariantRef->getSourceRange(); 5100 return None; 5101 } 5102 5103 // The VariantRef must point to function. 5104 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5105 if (!DRE) { 5106 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5107 << VariantId << VariantRef->getSourceRange(); 5108 return None; 5109 } 5110 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5111 if (!NewFD) { 5112 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5113 << VariantId << VariantRef->getSourceRange(); 5114 return None; 5115 } 5116 5117 // Check if variant function is not marked with declare variant directive. 5118 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5119 Diag(VariantRef->getExprLoc(), 5120 diag::warn_omp_declare_variant_marked_as_declare_variant) 5121 << VariantRef->getSourceRange(); 5122 SourceRange SR = 5123 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5124 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5125 return None; 5126 } 5127 5128 enum DoesntSupport { 5129 VirtFuncs = 1, 5130 Constructors = 3, 5131 Destructors = 4, 5132 DeletedFuncs = 5, 5133 DefaultedFuncs = 6, 5134 ConstexprFuncs = 7, 5135 ConstevalFuncs = 8, 5136 }; 5137 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5138 if (CXXFD->isVirtual()) { 5139 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5140 << VirtFuncs; 5141 return None; 5142 } 5143 5144 if (isa<CXXConstructorDecl>(FD)) { 5145 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5146 << Constructors; 5147 return None; 5148 } 5149 5150 if (isa<CXXDestructorDecl>(FD)) { 5151 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5152 << Destructors; 5153 return None; 5154 } 5155 } 5156 5157 if (FD->isDeleted()) { 5158 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5159 << DeletedFuncs; 5160 return None; 5161 } 5162 5163 if (FD->isDefaulted()) { 5164 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5165 << DefaultedFuncs; 5166 return None; 5167 } 5168 5169 if (FD->isConstexpr()) { 5170 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5171 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5172 return None; 5173 } 5174 5175 // Check general compatibility. 5176 if (areMultiversionVariantFunctionsCompatible( 5177 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5178 PartialDiagnosticAt( 5179 SR.getBegin(), 5180 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5181 PartialDiagnosticAt( 5182 VariantRef->getExprLoc(), 5183 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5184 PartialDiagnosticAt(VariantRef->getExprLoc(), 5185 PDiag(diag::err_omp_declare_variant_diff) 5186 << FD->getLocation()), 5187 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5188 /*CLinkageMayDiffer=*/true)) 5189 return None; 5190 return std::make_pair(FD, cast<Expr>(DRE)); 5191 } 5192 5193 void Sema::ActOnOpenMPDeclareVariantDirective( 5194 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5195 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { 5196 if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || 5197 Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) 5198 return; 5199 Expr *Score = nullptr; 5200 if (Data.CtxScore.isUsable()) { 5201 Score = Data.CtxScore.get(); 5202 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5203 !Score->isInstantiationDependent() && 5204 !Score->containsUnexpandedParameterPack()) { 5205 llvm::APSInt Result; 5206 ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result); 5207 if (ICE.isInvalid()) 5208 return; 5209 } 5210 } else { 5211 Score = ActOnIntegerConstant(SourceLocation(), 0).get(); 5212 } 5213 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5214 Context, VariantRef, Score, Data.CtxSet, Data.Ctx, 5215 Data.ImplVendors.begin(), Data.ImplVendors.size(), SR); 5216 FD->addAttr(NewAttr); 5217 } 5218 5219 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5220 FunctionDecl *Func, 5221 bool MightBeOdrUse) { 5222 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5223 5224 if (!Func->isDependentContext() && Func->hasAttrs()) { 5225 for (OMPDeclareVariantAttr *A : 5226 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5227 // TODO: add checks for active OpenMP context where possible. 5228 Expr *VariantRef = A->getVariantFuncRef(); 5229 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5230 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5231 if (!F->isDefined() && F->isTemplateInstantiation()) 5232 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5233 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5234 } 5235 } 5236 } 5237 5238 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5239 Stmt *AStmt, 5240 SourceLocation StartLoc, 5241 SourceLocation EndLoc) { 5242 if (!AStmt) 5243 return StmtError(); 5244 5245 auto *CS = cast<CapturedStmt>(AStmt); 5246 // 1.2.2 OpenMP Language Terminology 5247 // Structured block - An executable statement with a single entry at the 5248 // top and a single exit at the bottom. 5249 // The point of exit cannot be a branch out of the structured block. 5250 // longjmp() and throw() must not violate the entry/exit criteria. 5251 CS->getCapturedDecl()->setNothrow(); 5252 5253 setFunctionHasBranchProtectedScope(); 5254 5255 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5256 DSAStack->isCancelRegion()); 5257 } 5258 5259 namespace { 5260 /// Iteration space of a single for loop. 5261 struct LoopIterationSpace final { 5262 /// True if the condition operator is the strict compare operator (<, > or 5263 /// !=). 5264 bool IsStrictCompare = false; 5265 /// Condition of the loop. 5266 Expr *PreCond = nullptr; 5267 /// This expression calculates the number of iterations in the loop. 5268 /// It is always possible to calculate it before starting the loop. 5269 Expr *NumIterations = nullptr; 5270 /// The loop counter variable. 5271 Expr *CounterVar = nullptr; 5272 /// Private loop counter variable. 5273 Expr *PrivateCounterVar = nullptr; 5274 /// This is initializer for the initial value of #CounterVar. 5275 Expr *CounterInit = nullptr; 5276 /// This is step for the #CounterVar used to generate its update: 5277 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5278 Expr *CounterStep = nullptr; 5279 /// Should step be subtracted? 5280 bool Subtract = false; 5281 /// Source range of the loop init. 5282 SourceRange InitSrcRange; 5283 /// Source range of the loop condition. 5284 SourceRange CondSrcRange; 5285 /// Source range of the loop increment. 5286 SourceRange IncSrcRange; 5287 /// Minimum value that can have the loop control variable. Used to support 5288 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5289 /// since only such variables can be used in non-loop invariant expressions. 5290 Expr *MinValue = nullptr; 5291 /// Maximum value that can have the loop control variable. Used to support 5292 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5293 /// since only such variables can be used in non-loop invariant expressions. 5294 Expr *MaxValue = nullptr; 5295 /// true, if the lower bound depends on the outer loop control var. 5296 bool IsNonRectangularLB = false; 5297 /// true, if the upper bound depends on the outer loop control var. 5298 bool IsNonRectangularUB = false; 5299 /// Index of the loop this loop depends on and forms non-rectangular loop 5300 /// nest. 5301 unsigned LoopDependentIdx = 0; 5302 /// Final condition for the non-rectangular loop nest support. It is used to 5303 /// check that the number of iterations for this particular counter must be 5304 /// finished. 5305 Expr *FinalCondition = nullptr; 5306 }; 5307 5308 /// Helper class for checking canonical form of the OpenMP loops and 5309 /// extracting iteration space of each loop in the loop nest, that will be used 5310 /// for IR generation. 5311 class OpenMPIterationSpaceChecker { 5312 /// Reference to Sema. 5313 Sema &SemaRef; 5314 /// Data-sharing stack. 5315 DSAStackTy &Stack; 5316 /// A location for diagnostics (when there is no some better location). 5317 SourceLocation DefaultLoc; 5318 /// A location for diagnostics (when increment is not compatible). 5319 SourceLocation ConditionLoc; 5320 /// A source location for referring to loop init later. 5321 SourceRange InitSrcRange; 5322 /// A source location for referring to condition later. 5323 SourceRange ConditionSrcRange; 5324 /// A source location for referring to increment later. 5325 SourceRange IncrementSrcRange; 5326 /// Loop variable. 5327 ValueDecl *LCDecl = nullptr; 5328 /// Reference to loop variable. 5329 Expr *LCRef = nullptr; 5330 /// Lower bound (initializer for the var). 5331 Expr *LB = nullptr; 5332 /// Upper bound. 5333 Expr *UB = nullptr; 5334 /// Loop step (increment). 5335 Expr *Step = nullptr; 5336 /// This flag is true when condition is one of: 5337 /// Var < UB 5338 /// Var <= UB 5339 /// UB > Var 5340 /// UB >= Var 5341 /// This will have no value when the condition is != 5342 llvm::Optional<bool> TestIsLessOp; 5343 /// This flag is true when condition is strict ( < or > ). 5344 bool TestIsStrictOp = false; 5345 /// This flag is true when step is subtracted on each iteration. 5346 bool SubtractStep = false; 5347 /// The outer loop counter this loop depends on (if any). 5348 const ValueDecl *DepDecl = nullptr; 5349 /// Contains number of loop (starts from 1) on which loop counter init 5350 /// expression of this loop depends on. 5351 Optional<unsigned> InitDependOnLC; 5352 /// Contains number of loop (starts from 1) on which loop counter condition 5353 /// expression of this loop depends on. 5354 Optional<unsigned> CondDependOnLC; 5355 /// Checks if the provide statement depends on the loop counter. 5356 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5357 /// Original condition required for checking of the exit condition for 5358 /// non-rectangular loop. 5359 Expr *Condition = nullptr; 5360 5361 public: 5362 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5363 SourceLocation DefaultLoc) 5364 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5365 ConditionLoc(DefaultLoc) {} 5366 /// Check init-expr for canonical loop form and save loop counter 5367 /// variable - #Var and its initialization value - #LB. 5368 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5369 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5370 /// for less/greater and for strict/non-strict comparison. 5371 bool checkAndSetCond(Expr *S); 5372 /// Check incr-expr for canonical loop form and return true if it 5373 /// does not conform, otherwise save loop step (#Step). 5374 bool checkAndSetInc(Expr *S); 5375 /// Return the loop counter variable. 5376 ValueDecl *getLoopDecl() const { return LCDecl; } 5377 /// Return the reference expression to loop counter variable. 5378 Expr *getLoopDeclRefExpr() const { return LCRef; } 5379 /// Source range of the loop init. 5380 SourceRange getInitSrcRange() const { return InitSrcRange; } 5381 /// Source range of the loop condition. 5382 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5383 /// Source range of the loop increment. 5384 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5385 /// True if the step should be subtracted. 5386 bool shouldSubtractStep() const { return SubtractStep; } 5387 /// True, if the compare operator is strict (<, > or !=). 5388 bool isStrictTestOp() const { return TestIsStrictOp; } 5389 /// Build the expression to calculate the number of iterations. 5390 Expr *buildNumIterations( 5391 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5392 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5393 /// Build the precondition expression for the loops. 5394 Expr * 5395 buildPreCond(Scope *S, Expr *Cond, 5396 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5397 /// Build reference expression to the counter be used for codegen. 5398 DeclRefExpr * 5399 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5400 DSAStackTy &DSA) const; 5401 /// Build reference expression to the private counter be used for 5402 /// codegen. 5403 Expr *buildPrivateCounterVar() const; 5404 /// Build initialization of the counter be used for codegen. 5405 Expr *buildCounterInit() const; 5406 /// Build step of the counter be used for codegen. 5407 Expr *buildCounterStep() const; 5408 /// Build loop data with counter value for depend clauses in ordered 5409 /// directives. 5410 Expr * 5411 buildOrderedLoopData(Scope *S, Expr *Counter, 5412 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5413 SourceLocation Loc, Expr *Inc = nullptr, 5414 OverloadedOperatorKind OOK = OO_Amp); 5415 /// Builds the minimum value for the loop counter. 5416 std::pair<Expr *, Expr *> buildMinMaxValues( 5417 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5418 /// Builds final condition for the non-rectangular loops. 5419 Expr *buildFinalCondition(Scope *S) const; 5420 /// Return true if any expression is dependent. 5421 bool dependent() const; 5422 /// Returns true if the initializer forms non-rectangular loop. 5423 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5424 /// Returns true if the condition forms non-rectangular loop. 5425 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5426 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5427 unsigned getLoopDependentIdx() const { 5428 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5429 } 5430 5431 private: 5432 /// Check the right-hand side of an assignment in the increment 5433 /// expression. 5434 bool checkAndSetIncRHS(Expr *RHS); 5435 /// Helper to set loop counter variable and its initializer. 5436 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5437 bool EmitDiags); 5438 /// Helper to set upper bound. 5439 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5440 SourceRange SR, SourceLocation SL); 5441 /// Helper to set loop increment. 5442 bool setStep(Expr *NewStep, bool Subtract); 5443 }; 5444 5445 bool OpenMPIterationSpaceChecker::dependent() const { 5446 if (!LCDecl) { 5447 assert(!LB && !UB && !Step); 5448 return false; 5449 } 5450 return LCDecl->getType()->isDependentType() || 5451 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5452 (Step && Step->isValueDependent()); 5453 } 5454 5455 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5456 Expr *NewLCRefExpr, 5457 Expr *NewLB, bool EmitDiags) { 5458 // State consistency checking to ensure correct usage. 5459 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5460 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5461 if (!NewLCDecl || !NewLB) 5462 return true; 5463 LCDecl = getCanonicalDecl(NewLCDecl); 5464 LCRef = NewLCRefExpr; 5465 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5466 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5467 if ((Ctor->isCopyOrMoveConstructor() || 5468 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5469 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5470 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5471 LB = NewLB; 5472 if (EmitDiags) 5473 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5474 return false; 5475 } 5476 5477 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5478 llvm::Optional<bool> LessOp, 5479 bool StrictOp, SourceRange SR, 5480 SourceLocation SL) { 5481 // State consistency checking to ensure correct usage. 5482 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5483 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5484 if (!NewUB) 5485 return true; 5486 UB = NewUB; 5487 if (LessOp) 5488 TestIsLessOp = LessOp; 5489 TestIsStrictOp = StrictOp; 5490 ConditionSrcRange = SR; 5491 ConditionLoc = SL; 5492 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5493 return false; 5494 } 5495 5496 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5497 // State consistency checking to ensure correct usage. 5498 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5499 if (!NewStep) 5500 return true; 5501 if (!NewStep->isValueDependent()) { 5502 // Check that the step is integer expression. 5503 SourceLocation StepLoc = NewStep->getBeginLoc(); 5504 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5505 StepLoc, getExprAsWritten(NewStep)); 5506 if (Val.isInvalid()) 5507 return true; 5508 NewStep = Val.get(); 5509 5510 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5511 // If test-expr is of form var relational-op b and relational-op is < or 5512 // <= then incr-expr must cause var to increase on each iteration of the 5513 // loop. If test-expr is of form var relational-op b and relational-op is 5514 // > or >= then incr-expr must cause var to decrease on each iteration of 5515 // the loop. 5516 // If test-expr is of form b relational-op var and relational-op is < or 5517 // <= then incr-expr must cause var to decrease on each iteration of the 5518 // loop. If test-expr is of form b relational-op var and relational-op is 5519 // > or >= then incr-expr must cause var to increase on each iteration of 5520 // the loop. 5521 llvm::APSInt Result; 5522 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5523 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5524 bool IsConstNeg = 5525 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5526 bool IsConstPos = 5527 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5528 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5529 5530 // != with increment is treated as <; != with decrement is treated as > 5531 if (!TestIsLessOp.hasValue()) 5532 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5533 if (UB && (IsConstZero || 5534 (TestIsLessOp.getValue() ? 5535 (IsConstNeg || (IsUnsigned && Subtract)) : 5536 (IsConstPos || (IsUnsigned && !Subtract))))) { 5537 SemaRef.Diag(NewStep->getExprLoc(), 5538 diag::err_omp_loop_incr_not_compatible) 5539 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5540 SemaRef.Diag(ConditionLoc, 5541 diag::note_omp_loop_cond_requres_compatible_incr) 5542 << TestIsLessOp.getValue() << ConditionSrcRange; 5543 return true; 5544 } 5545 if (TestIsLessOp.getValue() == Subtract) { 5546 NewStep = 5547 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5548 .get(); 5549 Subtract = !Subtract; 5550 } 5551 } 5552 5553 Step = NewStep; 5554 SubtractStep = Subtract; 5555 return false; 5556 } 5557 5558 namespace { 5559 /// Checker for the non-rectangular loops. Checks if the initializer or 5560 /// condition expression references loop counter variable. 5561 class LoopCounterRefChecker final 5562 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5563 Sema &SemaRef; 5564 DSAStackTy &Stack; 5565 const ValueDecl *CurLCDecl = nullptr; 5566 const ValueDecl *DepDecl = nullptr; 5567 const ValueDecl *PrevDepDecl = nullptr; 5568 bool IsInitializer = true; 5569 unsigned BaseLoopId = 0; 5570 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5571 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5572 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5573 << (IsInitializer ? 0 : 1); 5574 return false; 5575 } 5576 const auto &&Data = Stack.isLoopControlVariable(VD); 5577 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5578 // The type of the loop iterator on which we depend may not have a random 5579 // access iterator type. 5580 if (Data.first && VD->getType()->isRecordType()) { 5581 SmallString<128> Name; 5582 llvm::raw_svector_ostream OS(Name); 5583 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5584 /*Qualified=*/true); 5585 SemaRef.Diag(E->getExprLoc(), 5586 diag::err_omp_wrong_dependency_iterator_type) 5587 << OS.str(); 5588 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5589 return false; 5590 } 5591 if (Data.first && 5592 (DepDecl || (PrevDepDecl && 5593 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5594 if (!DepDecl && PrevDepDecl) 5595 DepDecl = PrevDepDecl; 5596 SmallString<128> Name; 5597 llvm::raw_svector_ostream OS(Name); 5598 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5599 /*Qualified=*/true); 5600 SemaRef.Diag(E->getExprLoc(), 5601 diag::err_omp_invariant_or_linear_dependency) 5602 << OS.str(); 5603 return false; 5604 } 5605 if (Data.first) { 5606 DepDecl = VD; 5607 BaseLoopId = Data.first; 5608 } 5609 return Data.first; 5610 } 5611 5612 public: 5613 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5614 const ValueDecl *VD = E->getDecl(); 5615 if (isa<VarDecl>(VD)) 5616 return checkDecl(E, VD); 5617 return false; 5618 } 5619 bool VisitMemberExpr(const MemberExpr *E) { 5620 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5621 const ValueDecl *VD = E->getMemberDecl(); 5622 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5623 return checkDecl(E, VD); 5624 } 5625 return false; 5626 } 5627 bool VisitStmt(const Stmt *S) { 5628 bool Res = false; 5629 for (const Stmt *Child : S->children()) 5630 Res = (Child && Visit(Child)) || Res; 5631 return Res; 5632 } 5633 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5634 const ValueDecl *CurLCDecl, bool IsInitializer, 5635 const ValueDecl *PrevDepDecl = nullptr) 5636 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5637 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5638 unsigned getBaseLoopId() const { 5639 assert(CurLCDecl && "Expected loop dependency."); 5640 return BaseLoopId; 5641 } 5642 const ValueDecl *getDepDecl() const { 5643 assert(CurLCDecl && "Expected loop dependency."); 5644 return DepDecl; 5645 } 5646 }; 5647 } // namespace 5648 5649 Optional<unsigned> 5650 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5651 bool IsInitializer) { 5652 // Check for the non-rectangular loops. 5653 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5654 DepDecl); 5655 if (LoopStmtChecker.Visit(S)) { 5656 DepDecl = LoopStmtChecker.getDepDecl(); 5657 return LoopStmtChecker.getBaseLoopId(); 5658 } 5659 return llvm::None; 5660 } 5661 5662 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5663 // Check init-expr for canonical loop form and save loop counter 5664 // variable - #Var and its initialization value - #LB. 5665 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5666 // var = lb 5667 // integer-type var = lb 5668 // random-access-iterator-type var = lb 5669 // pointer-type var = lb 5670 // 5671 if (!S) { 5672 if (EmitDiags) { 5673 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5674 } 5675 return true; 5676 } 5677 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5678 if (!ExprTemp->cleanupsHaveSideEffects()) 5679 S = ExprTemp->getSubExpr(); 5680 5681 InitSrcRange = S->getSourceRange(); 5682 if (Expr *E = dyn_cast<Expr>(S)) 5683 S = E->IgnoreParens(); 5684 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5685 if (BO->getOpcode() == BO_Assign) { 5686 Expr *LHS = BO->getLHS()->IgnoreParens(); 5687 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5688 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5689 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5690 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5691 EmitDiags); 5692 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5693 } 5694 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5695 if (ME->isArrow() && 5696 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5697 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5698 EmitDiags); 5699 } 5700 } 5701 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5702 if (DS->isSingleDecl()) { 5703 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5704 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5705 // Accept non-canonical init form here but emit ext. warning. 5706 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5707 SemaRef.Diag(S->getBeginLoc(), 5708 diag::ext_omp_loop_not_canonical_init) 5709 << S->getSourceRange(); 5710 return setLCDeclAndLB( 5711 Var, 5712 buildDeclRefExpr(SemaRef, Var, 5713 Var->getType().getNonReferenceType(), 5714 DS->getBeginLoc()), 5715 Var->getInit(), EmitDiags); 5716 } 5717 } 5718 } 5719 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5720 if (CE->getOperator() == OO_Equal) { 5721 Expr *LHS = CE->getArg(0); 5722 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5723 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5724 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5725 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5726 EmitDiags); 5727 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5728 } 5729 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5730 if (ME->isArrow() && 5731 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5732 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5733 EmitDiags); 5734 } 5735 } 5736 } 5737 5738 if (dependent() || SemaRef.CurContext->isDependentContext()) 5739 return false; 5740 if (EmitDiags) { 5741 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5742 << S->getSourceRange(); 5743 } 5744 return true; 5745 } 5746 5747 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5748 /// variable (which may be the loop variable) if possible. 5749 static const ValueDecl *getInitLCDecl(const Expr *E) { 5750 if (!E) 5751 return nullptr; 5752 E = getExprAsWritten(E); 5753 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5754 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5755 if ((Ctor->isCopyOrMoveConstructor() || 5756 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5757 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5758 E = CE->getArg(0)->IgnoreParenImpCasts(); 5759 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5760 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5761 return getCanonicalDecl(VD); 5762 } 5763 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5764 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5765 return getCanonicalDecl(ME->getMemberDecl()); 5766 return nullptr; 5767 } 5768 5769 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5770 // Check test-expr for canonical form, save upper-bound UB, flags for 5771 // less/greater and for strict/non-strict comparison. 5772 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5773 // var relational-op b 5774 // b relational-op var 5775 // 5776 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5777 if (!S) { 5778 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5779 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5780 return true; 5781 } 5782 Condition = S; 5783 S = getExprAsWritten(S); 5784 SourceLocation CondLoc = S->getBeginLoc(); 5785 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5786 if (BO->isRelationalOp()) { 5787 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5788 return setUB(BO->getRHS(), 5789 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5790 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5791 BO->getSourceRange(), BO->getOperatorLoc()); 5792 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5793 return setUB(BO->getLHS(), 5794 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5795 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5796 BO->getSourceRange(), BO->getOperatorLoc()); 5797 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5798 return setUB( 5799 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5800 /*LessOp=*/llvm::None, 5801 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5802 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5803 if (CE->getNumArgs() == 2) { 5804 auto Op = CE->getOperator(); 5805 switch (Op) { 5806 case OO_Greater: 5807 case OO_GreaterEqual: 5808 case OO_Less: 5809 case OO_LessEqual: 5810 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5811 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5812 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5813 CE->getOperatorLoc()); 5814 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5815 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5816 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5817 CE->getOperatorLoc()); 5818 break; 5819 case OO_ExclaimEqual: 5820 if (IneqCondIsCanonical) 5821 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5822 : CE->getArg(0), 5823 /*LessOp=*/llvm::None, 5824 /*StrictOp=*/true, CE->getSourceRange(), 5825 CE->getOperatorLoc()); 5826 break; 5827 default: 5828 break; 5829 } 5830 } 5831 } 5832 if (dependent() || SemaRef.CurContext->isDependentContext()) 5833 return false; 5834 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5835 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5836 return true; 5837 } 5838 5839 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5840 // RHS of canonical loop form increment can be: 5841 // var + incr 5842 // incr + var 5843 // var - incr 5844 // 5845 RHS = RHS->IgnoreParenImpCasts(); 5846 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5847 if (BO->isAdditiveOp()) { 5848 bool IsAdd = BO->getOpcode() == BO_Add; 5849 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5850 return setStep(BO->getRHS(), !IsAdd); 5851 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5852 return setStep(BO->getLHS(), /*Subtract=*/false); 5853 } 5854 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5855 bool IsAdd = CE->getOperator() == OO_Plus; 5856 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5857 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5858 return setStep(CE->getArg(1), !IsAdd); 5859 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5860 return setStep(CE->getArg(0), /*Subtract=*/false); 5861 } 5862 } 5863 if (dependent() || SemaRef.CurContext->isDependentContext()) 5864 return false; 5865 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5866 << RHS->getSourceRange() << LCDecl; 5867 return true; 5868 } 5869 5870 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5871 // Check incr-expr for canonical loop form and return true if it 5872 // does not conform. 5873 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5874 // ++var 5875 // var++ 5876 // --var 5877 // var-- 5878 // var += incr 5879 // var -= incr 5880 // var = var + incr 5881 // var = incr + var 5882 // var = var - incr 5883 // 5884 if (!S) { 5885 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5886 return true; 5887 } 5888 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5889 if (!ExprTemp->cleanupsHaveSideEffects()) 5890 S = ExprTemp->getSubExpr(); 5891 5892 IncrementSrcRange = S->getSourceRange(); 5893 S = S->IgnoreParens(); 5894 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5895 if (UO->isIncrementDecrementOp() && 5896 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5897 return setStep(SemaRef 5898 .ActOnIntegerConstant(UO->getBeginLoc(), 5899 (UO->isDecrementOp() ? -1 : 1)) 5900 .get(), 5901 /*Subtract=*/false); 5902 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5903 switch (BO->getOpcode()) { 5904 case BO_AddAssign: 5905 case BO_SubAssign: 5906 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5907 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5908 break; 5909 case BO_Assign: 5910 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5911 return checkAndSetIncRHS(BO->getRHS()); 5912 break; 5913 default: 5914 break; 5915 } 5916 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5917 switch (CE->getOperator()) { 5918 case OO_PlusPlus: 5919 case OO_MinusMinus: 5920 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5921 return setStep(SemaRef 5922 .ActOnIntegerConstant( 5923 CE->getBeginLoc(), 5924 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5925 .get(), 5926 /*Subtract=*/false); 5927 break; 5928 case OO_PlusEqual: 5929 case OO_MinusEqual: 5930 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5931 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5932 break; 5933 case OO_Equal: 5934 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5935 return checkAndSetIncRHS(CE->getArg(1)); 5936 break; 5937 default: 5938 break; 5939 } 5940 } 5941 if (dependent() || SemaRef.CurContext->isDependentContext()) 5942 return false; 5943 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5944 << S->getSourceRange() << LCDecl; 5945 return true; 5946 } 5947 5948 static ExprResult 5949 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5950 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5951 if (SemaRef.CurContext->isDependentContext()) 5952 return ExprResult(Capture); 5953 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5954 return SemaRef.PerformImplicitConversion( 5955 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5956 /*AllowExplicit=*/true); 5957 auto I = Captures.find(Capture); 5958 if (I != Captures.end()) 5959 return buildCapture(SemaRef, Capture, I->second); 5960 DeclRefExpr *Ref = nullptr; 5961 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5962 Captures[Capture] = Ref; 5963 return Res; 5964 } 5965 5966 /// Build the expression to calculate the number of iterations. 5967 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5968 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5969 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5970 ExprResult Diff; 5971 QualType VarType = LCDecl->getType().getNonReferenceType(); 5972 if (VarType->isIntegerType() || VarType->isPointerType() || 5973 SemaRef.getLangOpts().CPlusPlus) { 5974 Expr *LBVal = LB; 5975 Expr *UBVal = UB; 5976 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5977 // max(LB(MinVal), LB(MaxVal)) 5978 if (InitDependOnLC) { 5979 const LoopIterationSpace &IS = 5980 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5981 InitDependOnLC.getValueOr( 5982 CondDependOnLC.getValueOr(0))]; 5983 if (!IS.MinValue || !IS.MaxValue) 5984 return nullptr; 5985 // OuterVar = Min 5986 ExprResult MinValue = 5987 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5988 if (!MinValue.isUsable()) 5989 return nullptr; 5990 5991 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5992 IS.CounterVar, MinValue.get()); 5993 if (!LBMinVal.isUsable()) 5994 return nullptr; 5995 // OuterVar = Min, LBVal 5996 LBMinVal = 5997 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5998 if (!LBMinVal.isUsable()) 5999 return nullptr; 6000 // (OuterVar = Min, LBVal) 6001 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6002 if (!LBMinVal.isUsable()) 6003 return nullptr; 6004 6005 // OuterVar = Max 6006 ExprResult MaxValue = 6007 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6008 if (!MaxValue.isUsable()) 6009 return nullptr; 6010 6011 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6012 IS.CounterVar, MaxValue.get()); 6013 if (!LBMaxVal.isUsable()) 6014 return nullptr; 6015 // OuterVar = Max, LBVal 6016 LBMaxVal = 6017 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6018 if (!LBMaxVal.isUsable()) 6019 return nullptr; 6020 // (OuterVar = Max, LBVal) 6021 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6022 if (!LBMaxVal.isUsable()) 6023 return nullptr; 6024 6025 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6026 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6027 if (!LBMin || !LBMax) 6028 return nullptr; 6029 // LB(MinVal) < LB(MaxVal) 6030 ExprResult MinLessMaxRes = 6031 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6032 if (!MinLessMaxRes.isUsable()) 6033 return nullptr; 6034 Expr *MinLessMax = 6035 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6036 if (!MinLessMax) 6037 return nullptr; 6038 if (TestIsLessOp.getValue()) { 6039 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6040 // LB(MaxVal)) 6041 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6042 MinLessMax, LBMin, LBMax); 6043 if (!MinLB.isUsable()) 6044 return nullptr; 6045 LBVal = MinLB.get(); 6046 } else { 6047 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6048 // LB(MaxVal)) 6049 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6050 MinLessMax, LBMax, LBMin); 6051 if (!MaxLB.isUsable()) 6052 return nullptr; 6053 LBVal = MaxLB.get(); 6054 } 6055 } 6056 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6057 // min(UB(MinVal), UB(MaxVal)) 6058 if (CondDependOnLC) { 6059 const LoopIterationSpace &IS = 6060 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6061 InitDependOnLC.getValueOr( 6062 CondDependOnLC.getValueOr(0))]; 6063 if (!IS.MinValue || !IS.MaxValue) 6064 return nullptr; 6065 // OuterVar = Min 6066 ExprResult MinValue = 6067 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6068 if (!MinValue.isUsable()) 6069 return nullptr; 6070 6071 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6072 IS.CounterVar, MinValue.get()); 6073 if (!UBMinVal.isUsable()) 6074 return nullptr; 6075 // OuterVar = Min, UBVal 6076 UBMinVal = 6077 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6078 if (!UBMinVal.isUsable()) 6079 return nullptr; 6080 // (OuterVar = Min, UBVal) 6081 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6082 if (!UBMinVal.isUsable()) 6083 return nullptr; 6084 6085 // OuterVar = Max 6086 ExprResult MaxValue = 6087 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6088 if (!MaxValue.isUsable()) 6089 return nullptr; 6090 6091 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6092 IS.CounterVar, MaxValue.get()); 6093 if (!UBMaxVal.isUsable()) 6094 return nullptr; 6095 // OuterVar = Max, UBVal 6096 UBMaxVal = 6097 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6098 if (!UBMaxVal.isUsable()) 6099 return nullptr; 6100 // (OuterVar = Max, UBVal) 6101 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6102 if (!UBMaxVal.isUsable()) 6103 return nullptr; 6104 6105 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6106 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6107 if (!UBMin || !UBMax) 6108 return nullptr; 6109 // UB(MinVal) > UB(MaxVal) 6110 ExprResult MinGreaterMaxRes = 6111 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6112 if (!MinGreaterMaxRes.isUsable()) 6113 return nullptr; 6114 Expr *MinGreaterMax = 6115 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6116 if (!MinGreaterMax) 6117 return nullptr; 6118 if (TestIsLessOp.getValue()) { 6119 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6120 // UB(MaxVal)) 6121 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6122 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6123 if (!MaxUB.isUsable()) 6124 return nullptr; 6125 UBVal = MaxUB.get(); 6126 } else { 6127 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6128 // UB(MaxVal)) 6129 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6130 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6131 if (!MinUB.isUsable()) 6132 return nullptr; 6133 UBVal = MinUB.get(); 6134 } 6135 } 6136 // Upper - Lower 6137 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6138 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6139 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6140 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6141 if (!Upper || !Lower) 6142 return nullptr; 6143 6144 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6145 6146 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6147 // BuildBinOp already emitted error, this one is to point user to upper 6148 // and lower bound, and to tell what is passed to 'operator-'. 6149 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6150 << Upper->getSourceRange() << Lower->getSourceRange(); 6151 return nullptr; 6152 } 6153 } 6154 6155 if (!Diff.isUsable()) 6156 return nullptr; 6157 6158 // Upper - Lower [- 1] 6159 if (TestIsStrictOp) 6160 Diff = SemaRef.BuildBinOp( 6161 S, DefaultLoc, BO_Sub, Diff.get(), 6162 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6163 if (!Diff.isUsable()) 6164 return nullptr; 6165 6166 // Upper - Lower [- 1] + Step 6167 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6168 if (!NewStep.isUsable()) 6169 return nullptr; 6170 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6171 if (!Diff.isUsable()) 6172 return nullptr; 6173 6174 // Parentheses (for dumping/debugging purposes only). 6175 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6176 if (!Diff.isUsable()) 6177 return nullptr; 6178 6179 // (Upper - Lower [- 1] + Step) / Step 6180 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6181 if (!Diff.isUsable()) 6182 return nullptr; 6183 6184 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6185 QualType Type = Diff.get()->getType(); 6186 ASTContext &C = SemaRef.Context; 6187 bool UseVarType = VarType->hasIntegerRepresentation() && 6188 C.getTypeSize(Type) > C.getTypeSize(VarType); 6189 if (!Type->isIntegerType() || UseVarType) { 6190 unsigned NewSize = 6191 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6192 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6193 : Type->hasSignedIntegerRepresentation(); 6194 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6195 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6196 Diff = SemaRef.PerformImplicitConversion( 6197 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6198 if (!Diff.isUsable()) 6199 return nullptr; 6200 } 6201 } 6202 if (LimitedType) { 6203 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6204 if (NewSize != C.getTypeSize(Type)) { 6205 if (NewSize < C.getTypeSize(Type)) { 6206 assert(NewSize == 64 && "incorrect loop var size"); 6207 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6208 << InitSrcRange << ConditionSrcRange; 6209 } 6210 QualType NewType = C.getIntTypeForBitwidth( 6211 NewSize, Type->hasSignedIntegerRepresentation() || 6212 C.getTypeSize(Type) < NewSize); 6213 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6214 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6215 Sema::AA_Converting, true); 6216 if (!Diff.isUsable()) 6217 return nullptr; 6218 } 6219 } 6220 } 6221 6222 return Diff.get(); 6223 } 6224 6225 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6226 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6227 // Do not build for iterators, they cannot be used in non-rectangular loop 6228 // nests. 6229 if (LCDecl->getType()->isRecordType()) 6230 return std::make_pair(nullptr, nullptr); 6231 // If we subtract, the min is in the condition, otherwise the min is in the 6232 // init value. 6233 Expr *MinExpr = nullptr; 6234 Expr *MaxExpr = nullptr; 6235 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6236 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6237 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6238 : CondDependOnLC.hasValue(); 6239 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6240 : InitDependOnLC.hasValue(); 6241 Expr *Lower = 6242 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6243 Expr *Upper = 6244 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6245 if (!Upper || !Lower) 6246 return std::make_pair(nullptr, nullptr); 6247 6248 if (TestIsLessOp.getValue()) 6249 MinExpr = Lower; 6250 else 6251 MaxExpr = Upper; 6252 6253 // Build minimum/maximum value based on number of iterations. 6254 ExprResult Diff; 6255 QualType VarType = LCDecl->getType().getNonReferenceType(); 6256 6257 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6258 if (!Diff.isUsable()) 6259 return std::make_pair(nullptr, nullptr); 6260 6261 // Upper - Lower [- 1] 6262 if (TestIsStrictOp) 6263 Diff = SemaRef.BuildBinOp( 6264 S, DefaultLoc, BO_Sub, Diff.get(), 6265 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6266 if (!Diff.isUsable()) 6267 return std::make_pair(nullptr, nullptr); 6268 6269 // Upper - Lower [- 1] + Step 6270 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6271 if (!NewStep.isUsable()) 6272 return std::make_pair(nullptr, nullptr); 6273 6274 // Parentheses (for dumping/debugging purposes only). 6275 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6276 if (!Diff.isUsable()) 6277 return std::make_pair(nullptr, nullptr); 6278 6279 // (Upper - Lower [- 1]) / Step 6280 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6281 if (!Diff.isUsable()) 6282 return std::make_pair(nullptr, nullptr); 6283 6284 // ((Upper - Lower [- 1]) / Step) * Step 6285 // Parentheses (for dumping/debugging purposes only). 6286 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6287 if (!Diff.isUsable()) 6288 return std::make_pair(nullptr, nullptr); 6289 6290 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6291 if (!Diff.isUsable()) 6292 return std::make_pair(nullptr, nullptr); 6293 6294 // Convert to the original type or ptrdiff_t, if original type is pointer. 6295 if (!VarType->isAnyPointerType() && 6296 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6297 Diff = SemaRef.PerformImplicitConversion( 6298 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6299 } else if (VarType->isAnyPointerType() && 6300 !SemaRef.Context.hasSameType( 6301 Diff.get()->getType(), 6302 SemaRef.Context.getUnsignedPointerDiffType())) { 6303 Diff = SemaRef.PerformImplicitConversion( 6304 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6305 Sema::AA_Converting, /*AllowExplicit=*/true); 6306 } 6307 if (!Diff.isUsable()) 6308 return std::make_pair(nullptr, nullptr); 6309 6310 // Parentheses (for dumping/debugging purposes only). 6311 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6312 if (!Diff.isUsable()) 6313 return std::make_pair(nullptr, nullptr); 6314 6315 if (TestIsLessOp.getValue()) { 6316 // MinExpr = Lower; 6317 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6318 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6319 if (!Diff.isUsable()) 6320 return std::make_pair(nullptr, nullptr); 6321 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6322 if (!Diff.isUsable()) 6323 return std::make_pair(nullptr, nullptr); 6324 MaxExpr = Diff.get(); 6325 } else { 6326 // MaxExpr = Upper; 6327 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6328 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6329 if (!Diff.isUsable()) 6330 return std::make_pair(nullptr, nullptr); 6331 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6332 if (!Diff.isUsable()) 6333 return std::make_pair(nullptr, nullptr); 6334 MinExpr = Diff.get(); 6335 } 6336 6337 return std::make_pair(MinExpr, MaxExpr); 6338 } 6339 6340 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6341 if (InitDependOnLC || CondDependOnLC) 6342 return Condition; 6343 return nullptr; 6344 } 6345 6346 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6347 Scope *S, Expr *Cond, 6348 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6349 // Do not build a precondition when the condition/initialization is dependent 6350 // to prevent pessimistic early loop exit. 6351 // TODO: this can be improved by calculating min/max values but not sure that 6352 // it will be very effective. 6353 if (CondDependOnLC || InitDependOnLC) 6354 return SemaRef.PerformImplicitConversion( 6355 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6356 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6357 /*AllowExplicit=*/true).get(); 6358 6359 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6360 Sema::TentativeAnalysisScope Trap(SemaRef); 6361 6362 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6363 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6364 if (!NewLB.isUsable() || !NewUB.isUsable()) 6365 return nullptr; 6366 6367 ExprResult CondExpr = 6368 SemaRef.BuildBinOp(S, DefaultLoc, 6369 TestIsLessOp.getValue() ? 6370 (TestIsStrictOp ? BO_LT : BO_LE) : 6371 (TestIsStrictOp ? BO_GT : BO_GE), 6372 NewLB.get(), NewUB.get()); 6373 if (CondExpr.isUsable()) { 6374 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6375 SemaRef.Context.BoolTy)) 6376 CondExpr = SemaRef.PerformImplicitConversion( 6377 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6378 /*AllowExplicit=*/true); 6379 } 6380 6381 // Otherwise use original loop condition and evaluate it in runtime. 6382 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6383 } 6384 6385 /// Build reference expression to the counter be used for codegen. 6386 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6387 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6388 DSAStackTy &DSA) const { 6389 auto *VD = dyn_cast<VarDecl>(LCDecl); 6390 if (!VD) { 6391 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6392 DeclRefExpr *Ref = buildDeclRefExpr( 6393 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6394 const DSAStackTy::DSAVarData Data = 6395 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6396 // If the loop control decl is explicitly marked as private, do not mark it 6397 // as captured again. 6398 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6399 Captures.insert(std::make_pair(LCRef, Ref)); 6400 return Ref; 6401 } 6402 return cast<DeclRefExpr>(LCRef); 6403 } 6404 6405 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6406 if (LCDecl && !LCDecl->isInvalidDecl()) { 6407 QualType Type = LCDecl->getType().getNonReferenceType(); 6408 VarDecl *PrivateVar = buildVarDecl( 6409 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6410 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6411 isa<VarDecl>(LCDecl) 6412 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6413 : nullptr); 6414 if (PrivateVar->isInvalidDecl()) 6415 return nullptr; 6416 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6417 } 6418 return nullptr; 6419 } 6420 6421 /// Build initialization of the counter to be used for codegen. 6422 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6423 6424 /// Build step of the counter be used for codegen. 6425 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6426 6427 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6428 Scope *S, Expr *Counter, 6429 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6430 Expr *Inc, OverloadedOperatorKind OOK) { 6431 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6432 if (!Cnt) 6433 return nullptr; 6434 if (Inc) { 6435 assert((OOK == OO_Plus || OOK == OO_Minus) && 6436 "Expected only + or - operations for depend clauses."); 6437 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6438 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6439 if (!Cnt) 6440 return nullptr; 6441 } 6442 ExprResult Diff; 6443 QualType VarType = LCDecl->getType().getNonReferenceType(); 6444 if (VarType->isIntegerType() || VarType->isPointerType() || 6445 SemaRef.getLangOpts().CPlusPlus) { 6446 // Upper - Lower 6447 Expr *Upper = TestIsLessOp.getValue() 6448 ? Cnt 6449 : tryBuildCapture(SemaRef, UB, Captures).get(); 6450 Expr *Lower = TestIsLessOp.getValue() 6451 ? tryBuildCapture(SemaRef, LB, Captures).get() 6452 : Cnt; 6453 if (!Upper || !Lower) 6454 return nullptr; 6455 6456 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6457 6458 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6459 // BuildBinOp already emitted error, this one is to point user to upper 6460 // and lower bound, and to tell what is passed to 'operator-'. 6461 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6462 << Upper->getSourceRange() << Lower->getSourceRange(); 6463 return nullptr; 6464 } 6465 } 6466 6467 if (!Diff.isUsable()) 6468 return nullptr; 6469 6470 // Parentheses (for dumping/debugging purposes only). 6471 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6472 if (!Diff.isUsable()) 6473 return nullptr; 6474 6475 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6476 if (!NewStep.isUsable()) 6477 return nullptr; 6478 // (Upper - Lower) / Step 6479 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6480 if (!Diff.isUsable()) 6481 return nullptr; 6482 6483 return Diff.get(); 6484 } 6485 } // namespace 6486 6487 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6488 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6489 assert(Init && "Expected loop in canonical form."); 6490 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6491 if (AssociatedLoops > 0 && 6492 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6493 DSAStack->loopStart(); 6494 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6495 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6496 if (ValueDecl *D = ISC.getLoopDecl()) { 6497 auto *VD = dyn_cast<VarDecl>(D); 6498 DeclRefExpr *PrivateRef = nullptr; 6499 if (!VD) { 6500 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6501 VD = Private; 6502 } else { 6503 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6504 /*WithInit=*/false); 6505 VD = cast<VarDecl>(PrivateRef->getDecl()); 6506 } 6507 } 6508 DSAStack->addLoopControlVariable(D, VD); 6509 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6510 if (LD != D->getCanonicalDecl()) { 6511 DSAStack->resetPossibleLoopCounter(); 6512 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6513 MarkDeclarationsReferencedInExpr( 6514 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6515 Var->getType().getNonLValueExprType(Context), 6516 ForLoc, /*RefersToCapture=*/true)); 6517 } 6518 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6519 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6520 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6521 // associated for-loop of a simd construct with just one associated 6522 // for-loop may be listed in a linear clause with a constant-linear-step 6523 // that is the increment of the associated for-loop. The loop iteration 6524 // variable(s) in the associated for-loop(s) of a for or parallel for 6525 // construct may be listed in a private or lastprivate clause. 6526 DSAStackTy::DSAVarData DVar = 6527 DSAStack->getTopDSA(D, /*FromParent=*/false); 6528 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6529 // is declared in the loop and it is predetermined as a private. 6530 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6531 OpenMPClauseKind PredeterminedCKind = 6532 isOpenMPSimdDirective(DKind) 6533 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6534 : OMPC_private; 6535 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6536 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6537 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6538 DVar.CKind != OMPC_private))) || 6539 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6540 DKind == OMPD_master_taskloop || 6541 DKind == OMPD_parallel_master_taskloop || 6542 isOpenMPDistributeDirective(DKind)) && 6543 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6544 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6545 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6546 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6547 << getOpenMPClauseName(DVar.CKind) 6548 << getOpenMPDirectiveName(DKind) 6549 << getOpenMPClauseName(PredeterminedCKind); 6550 if (DVar.RefExpr == nullptr) 6551 DVar.CKind = PredeterminedCKind; 6552 reportOriginalDsa(*this, DSAStack, D, DVar, 6553 /*IsLoopIterVar=*/true); 6554 } else if (LoopDeclRefExpr) { 6555 // Make the loop iteration variable private (for worksharing 6556 // constructs), linear (for simd directives with the only one 6557 // associated loop) or lastprivate (for simd directives with several 6558 // collapsed or ordered loops). 6559 if (DVar.CKind == OMPC_unknown) 6560 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6561 PrivateRef); 6562 } 6563 } 6564 } 6565 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6566 } 6567 } 6568 6569 /// Called on a for stmt to check and extract its iteration space 6570 /// for further processing (such as collapsing). 6571 static bool checkOpenMPIterationSpace( 6572 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6573 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6574 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6575 Expr *OrderedLoopCountExpr, 6576 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6577 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6578 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6579 // OpenMP [2.9.1, Canonical Loop Form] 6580 // for (init-expr; test-expr; incr-expr) structured-block 6581 // for (range-decl: range-expr) structured-block 6582 auto *For = dyn_cast_or_null<ForStmt>(S); 6583 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6584 // Ranged for is supported only in OpenMP 5.0. 6585 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6586 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6587 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6588 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6589 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6590 if (TotalNestedLoopCount > 1) { 6591 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6592 SemaRef.Diag(DSA.getConstructLoc(), 6593 diag::note_omp_collapse_ordered_expr) 6594 << 2 << CollapseLoopCountExpr->getSourceRange() 6595 << OrderedLoopCountExpr->getSourceRange(); 6596 else if (CollapseLoopCountExpr) 6597 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6598 diag::note_omp_collapse_ordered_expr) 6599 << 0 << CollapseLoopCountExpr->getSourceRange(); 6600 else 6601 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6602 diag::note_omp_collapse_ordered_expr) 6603 << 1 << OrderedLoopCountExpr->getSourceRange(); 6604 } 6605 return true; 6606 } 6607 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6608 "No loop body."); 6609 6610 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6611 For ? For->getForLoc() : CXXFor->getForLoc()); 6612 6613 // Check init. 6614 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6615 if (ISC.checkAndSetInit(Init)) 6616 return true; 6617 6618 bool HasErrors = false; 6619 6620 // Check loop variable's type. 6621 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6622 // OpenMP [2.6, Canonical Loop Form] 6623 // Var is one of the following: 6624 // A variable of signed or unsigned integer type. 6625 // For C++, a variable of a random access iterator type. 6626 // For C, a variable of a pointer type. 6627 QualType VarType = LCDecl->getType().getNonReferenceType(); 6628 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6629 !VarType->isPointerType() && 6630 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6631 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6632 << SemaRef.getLangOpts().CPlusPlus; 6633 HasErrors = true; 6634 } 6635 6636 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6637 // a Construct 6638 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6639 // parallel for construct is (are) private. 6640 // The loop iteration variable in the associated for-loop of a simd 6641 // construct with just one associated for-loop is linear with a 6642 // constant-linear-step that is the increment of the associated for-loop. 6643 // Exclude loop var from the list of variables with implicitly defined data 6644 // sharing attributes. 6645 VarsWithImplicitDSA.erase(LCDecl); 6646 6647 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6648 6649 // Check test-expr. 6650 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6651 6652 // Check incr-expr. 6653 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6654 } 6655 6656 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6657 return HasErrors; 6658 6659 // Build the loop's iteration space representation. 6660 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6661 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6662 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6663 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6664 (isOpenMPWorksharingDirective(DKind) || 6665 isOpenMPTaskLoopDirective(DKind) || 6666 isOpenMPDistributeDirective(DKind)), 6667 Captures); 6668 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6669 ISC.buildCounterVar(Captures, DSA); 6670 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6671 ISC.buildPrivateCounterVar(); 6672 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6673 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6674 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6675 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6676 ISC.getConditionSrcRange(); 6677 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6678 ISC.getIncrementSrcRange(); 6679 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6680 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6681 ISC.isStrictTestOp(); 6682 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6683 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6684 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6685 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6686 ISC.buildFinalCondition(DSA.getCurScope()); 6687 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6688 ISC.doesInitDependOnLC(); 6689 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6690 ISC.doesCondDependOnLC(); 6691 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6692 ISC.getLoopDependentIdx(); 6693 6694 HasErrors |= 6695 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6696 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6697 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6698 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6699 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6700 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6701 if (!HasErrors && DSA.isOrderedRegion()) { 6702 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6703 if (CurrentNestedLoopCount < 6704 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6705 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6706 CurrentNestedLoopCount, 6707 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6708 DSA.getOrderedRegionParam().second->setLoopCounter( 6709 CurrentNestedLoopCount, 6710 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6711 } 6712 } 6713 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6714 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6715 // Erroneous case - clause has some problems. 6716 continue; 6717 } 6718 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6719 Pair.second.size() <= CurrentNestedLoopCount) { 6720 // Erroneous case - clause has some problems. 6721 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6722 continue; 6723 } 6724 Expr *CntValue; 6725 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6726 CntValue = ISC.buildOrderedLoopData( 6727 DSA.getCurScope(), 6728 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6729 Pair.first->getDependencyLoc()); 6730 else 6731 CntValue = ISC.buildOrderedLoopData( 6732 DSA.getCurScope(), 6733 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6734 Pair.first->getDependencyLoc(), 6735 Pair.second[CurrentNestedLoopCount].first, 6736 Pair.second[CurrentNestedLoopCount].second); 6737 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6738 } 6739 } 6740 6741 return HasErrors; 6742 } 6743 6744 /// Build 'VarRef = Start. 6745 static ExprResult 6746 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6747 ExprResult Start, bool IsNonRectangularLB, 6748 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6749 // Build 'VarRef = Start. 6750 ExprResult NewStart = IsNonRectangularLB 6751 ? Start.get() 6752 : tryBuildCapture(SemaRef, Start.get(), Captures); 6753 if (!NewStart.isUsable()) 6754 return ExprError(); 6755 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6756 VarRef.get()->getType())) { 6757 NewStart = SemaRef.PerformImplicitConversion( 6758 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6759 /*AllowExplicit=*/true); 6760 if (!NewStart.isUsable()) 6761 return ExprError(); 6762 } 6763 6764 ExprResult Init = 6765 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6766 return Init; 6767 } 6768 6769 /// Build 'VarRef = Start + Iter * Step'. 6770 static ExprResult buildCounterUpdate( 6771 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6772 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6773 bool IsNonRectangularLB, 6774 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6775 // Add parentheses (for debugging purposes only). 6776 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6777 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6778 !Step.isUsable()) 6779 return ExprError(); 6780 6781 ExprResult NewStep = Step; 6782 if (Captures) 6783 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6784 if (NewStep.isInvalid()) 6785 return ExprError(); 6786 ExprResult Update = 6787 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6788 if (!Update.isUsable()) 6789 return ExprError(); 6790 6791 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6792 // 'VarRef = Start (+|-) Iter * Step'. 6793 if (!Start.isUsable()) 6794 return ExprError(); 6795 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6796 if (!NewStart.isUsable()) 6797 return ExprError(); 6798 if (Captures && !IsNonRectangularLB) 6799 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6800 if (NewStart.isInvalid()) 6801 return ExprError(); 6802 6803 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6804 ExprResult SavedUpdate = Update; 6805 ExprResult UpdateVal; 6806 if (VarRef.get()->getType()->isOverloadableType() || 6807 NewStart.get()->getType()->isOverloadableType() || 6808 Update.get()->getType()->isOverloadableType()) { 6809 Sema::TentativeAnalysisScope Trap(SemaRef); 6810 6811 Update = 6812 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6813 if (Update.isUsable()) { 6814 UpdateVal = 6815 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6816 VarRef.get(), SavedUpdate.get()); 6817 if (UpdateVal.isUsable()) { 6818 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6819 UpdateVal.get()); 6820 } 6821 } 6822 } 6823 6824 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6825 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6826 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6827 NewStart.get(), SavedUpdate.get()); 6828 if (!Update.isUsable()) 6829 return ExprError(); 6830 6831 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6832 VarRef.get()->getType())) { 6833 Update = SemaRef.PerformImplicitConversion( 6834 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6835 if (!Update.isUsable()) 6836 return ExprError(); 6837 } 6838 6839 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6840 } 6841 return Update; 6842 } 6843 6844 /// Convert integer expression \a E to make it have at least \a Bits 6845 /// bits. 6846 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6847 if (E == nullptr) 6848 return ExprError(); 6849 ASTContext &C = SemaRef.Context; 6850 QualType OldType = E->getType(); 6851 unsigned HasBits = C.getTypeSize(OldType); 6852 if (HasBits >= Bits) 6853 return ExprResult(E); 6854 // OK to convert to signed, because new type has more bits than old. 6855 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6856 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6857 true); 6858 } 6859 6860 /// Check if the given expression \a E is a constant integer that fits 6861 /// into \a Bits bits. 6862 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6863 if (E == nullptr) 6864 return false; 6865 llvm::APSInt Result; 6866 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6867 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6868 return false; 6869 } 6870 6871 /// Build preinits statement for the given declarations. 6872 static Stmt *buildPreInits(ASTContext &Context, 6873 MutableArrayRef<Decl *> PreInits) { 6874 if (!PreInits.empty()) { 6875 return new (Context) DeclStmt( 6876 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6877 SourceLocation(), SourceLocation()); 6878 } 6879 return nullptr; 6880 } 6881 6882 /// Build preinits statement for the given declarations. 6883 static Stmt * 6884 buildPreInits(ASTContext &Context, 6885 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6886 if (!Captures.empty()) { 6887 SmallVector<Decl *, 16> PreInits; 6888 for (const auto &Pair : Captures) 6889 PreInits.push_back(Pair.second->getDecl()); 6890 return buildPreInits(Context, PreInits); 6891 } 6892 return nullptr; 6893 } 6894 6895 /// Build postupdate expression for the given list of postupdates expressions. 6896 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6897 Expr *PostUpdate = nullptr; 6898 if (!PostUpdates.empty()) { 6899 for (Expr *E : PostUpdates) { 6900 Expr *ConvE = S.BuildCStyleCastExpr( 6901 E->getExprLoc(), 6902 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6903 E->getExprLoc(), E) 6904 .get(); 6905 PostUpdate = PostUpdate 6906 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6907 PostUpdate, ConvE) 6908 .get() 6909 : ConvE; 6910 } 6911 } 6912 return PostUpdate; 6913 } 6914 6915 /// Called on a for stmt to check itself and nested loops (if any). 6916 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6917 /// number of collapsed loops otherwise. 6918 static unsigned 6919 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6920 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6921 DSAStackTy &DSA, 6922 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6923 OMPLoopDirective::HelperExprs &Built) { 6924 unsigned NestedLoopCount = 1; 6925 if (CollapseLoopCountExpr) { 6926 // Found 'collapse' clause - calculate collapse number. 6927 Expr::EvalResult Result; 6928 if (!CollapseLoopCountExpr->isValueDependent() && 6929 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6930 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6931 } else { 6932 Built.clear(/*Size=*/1); 6933 return 1; 6934 } 6935 } 6936 unsigned OrderedLoopCount = 1; 6937 if (OrderedLoopCountExpr) { 6938 // Found 'ordered' clause - calculate collapse number. 6939 Expr::EvalResult EVResult; 6940 if (!OrderedLoopCountExpr->isValueDependent() && 6941 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6942 SemaRef.getASTContext())) { 6943 llvm::APSInt Result = EVResult.Val.getInt(); 6944 if (Result.getLimitedValue() < NestedLoopCount) { 6945 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6946 diag::err_omp_wrong_ordered_loop_count) 6947 << OrderedLoopCountExpr->getSourceRange(); 6948 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6949 diag::note_collapse_loop_count) 6950 << CollapseLoopCountExpr->getSourceRange(); 6951 } 6952 OrderedLoopCount = Result.getLimitedValue(); 6953 } else { 6954 Built.clear(/*Size=*/1); 6955 return 1; 6956 } 6957 } 6958 // This is helper routine for loop directives (e.g., 'for', 'simd', 6959 // 'for simd', etc.). 6960 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6961 SmallVector<LoopIterationSpace, 4> IterSpaces( 6962 std::max(OrderedLoopCount, NestedLoopCount)); 6963 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6964 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6965 if (checkOpenMPIterationSpace( 6966 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6967 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6968 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6969 return 0; 6970 // Move on to the next nested for loop, or to the loop body. 6971 // OpenMP [2.8.1, simd construct, Restrictions] 6972 // All loops associated with the construct must be perfectly nested; that 6973 // is, there must be no intervening code nor any OpenMP directive between 6974 // any two loops. 6975 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6976 CurStmt = For->getBody(); 6977 } else { 6978 assert(isa<CXXForRangeStmt>(CurStmt) && 6979 "Expected canonical for or range-based for loops."); 6980 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6981 } 6982 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 6983 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 6984 } 6985 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6986 if (checkOpenMPIterationSpace( 6987 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6988 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6989 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6990 return 0; 6991 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6992 // Handle initialization of captured loop iterator variables. 6993 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6994 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6995 Captures[DRE] = DRE; 6996 } 6997 } 6998 // Move on to the next nested for loop, or to the loop body. 6999 // OpenMP [2.8.1, simd construct, Restrictions] 7000 // All loops associated with the construct must be perfectly nested; that 7001 // is, there must be no intervening code nor any OpenMP directive between 7002 // any two loops. 7003 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7004 CurStmt = For->getBody(); 7005 } else { 7006 assert(isa<CXXForRangeStmt>(CurStmt) && 7007 "Expected canonical for or range-based for loops."); 7008 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7009 } 7010 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7011 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7012 } 7013 7014 Built.clear(/* size */ NestedLoopCount); 7015 7016 if (SemaRef.CurContext->isDependentContext()) 7017 return NestedLoopCount; 7018 7019 // An example of what is generated for the following code: 7020 // 7021 // #pragma omp simd collapse(2) ordered(2) 7022 // for (i = 0; i < NI; ++i) 7023 // for (k = 0; k < NK; ++k) 7024 // for (j = J0; j < NJ; j+=2) { 7025 // <loop body> 7026 // } 7027 // 7028 // We generate the code below. 7029 // Note: the loop body may be outlined in CodeGen. 7030 // Note: some counters may be C++ classes, operator- is used to find number of 7031 // iterations and operator+= to calculate counter value. 7032 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7033 // or i64 is currently supported). 7034 // 7035 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7036 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7037 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7038 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7039 // // similar updates for vars in clauses (e.g. 'linear') 7040 // <loop body (using local i and j)> 7041 // } 7042 // i = NI; // assign final values of counters 7043 // j = NJ; 7044 // 7045 7046 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7047 // the iteration counts of the collapsed for loops. 7048 // Precondition tests if there is at least one iteration (all conditions are 7049 // true). 7050 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7051 Expr *N0 = IterSpaces[0].NumIterations; 7052 ExprResult LastIteration32 = 7053 widenIterationCount(/*Bits=*/32, 7054 SemaRef 7055 .PerformImplicitConversion( 7056 N0->IgnoreImpCasts(), N0->getType(), 7057 Sema::AA_Converting, /*AllowExplicit=*/true) 7058 .get(), 7059 SemaRef); 7060 ExprResult LastIteration64 = widenIterationCount( 7061 /*Bits=*/64, 7062 SemaRef 7063 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7064 Sema::AA_Converting, 7065 /*AllowExplicit=*/true) 7066 .get(), 7067 SemaRef); 7068 7069 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7070 return NestedLoopCount; 7071 7072 ASTContext &C = SemaRef.Context; 7073 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7074 7075 Scope *CurScope = DSA.getCurScope(); 7076 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7077 if (PreCond.isUsable()) { 7078 PreCond = 7079 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7080 PreCond.get(), IterSpaces[Cnt].PreCond); 7081 } 7082 Expr *N = IterSpaces[Cnt].NumIterations; 7083 SourceLocation Loc = N->getExprLoc(); 7084 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7085 if (LastIteration32.isUsable()) 7086 LastIteration32 = SemaRef.BuildBinOp( 7087 CurScope, Loc, BO_Mul, LastIteration32.get(), 7088 SemaRef 7089 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7090 Sema::AA_Converting, 7091 /*AllowExplicit=*/true) 7092 .get()); 7093 if (LastIteration64.isUsable()) 7094 LastIteration64 = SemaRef.BuildBinOp( 7095 CurScope, Loc, BO_Mul, LastIteration64.get(), 7096 SemaRef 7097 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7098 Sema::AA_Converting, 7099 /*AllowExplicit=*/true) 7100 .get()); 7101 } 7102 7103 // Choose either the 32-bit or 64-bit version. 7104 ExprResult LastIteration = LastIteration64; 7105 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7106 (LastIteration32.isUsable() && 7107 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7108 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7109 fitsInto( 7110 /*Bits=*/32, 7111 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7112 LastIteration64.get(), SemaRef)))) 7113 LastIteration = LastIteration32; 7114 QualType VType = LastIteration.get()->getType(); 7115 QualType RealVType = VType; 7116 QualType StrideVType = VType; 7117 if (isOpenMPTaskLoopDirective(DKind)) { 7118 VType = 7119 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7120 StrideVType = 7121 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7122 } 7123 7124 if (!LastIteration.isUsable()) 7125 return 0; 7126 7127 // Save the number of iterations. 7128 ExprResult NumIterations = LastIteration; 7129 { 7130 LastIteration = SemaRef.BuildBinOp( 7131 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7132 LastIteration.get(), 7133 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7134 if (!LastIteration.isUsable()) 7135 return 0; 7136 } 7137 7138 // Calculate the last iteration number beforehand instead of doing this on 7139 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7140 llvm::APSInt Result; 7141 bool IsConstant = 7142 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7143 ExprResult CalcLastIteration; 7144 if (!IsConstant) { 7145 ExprResult SaveRef = 7146 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7147 LastIteration = SaveRef; 7148 7149 // Prepare SaveRef + 1. 7150 NumIterations = SemaRef.BuildBinOp( 7151 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7152 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7153 if (!NumIterations.isUsable()) 7154 return 0; 7155 } 7156 7157 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7158 7159 // Build variables passed into runtime, necessary for worksharing directives. 7160 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7161 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7162 isOpenMPDistributeDirective(DKind)) { 7163 // Lower bound variable, initialized with zero. 7164 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7165 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7166 SemaRef.AddInitializerToDecl(LBDecl, 7167 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7168 /*DirectInit*/ false); 7169 7170 // Upper bound variable, initialized with last iteration number. 7171 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7172 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7173 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7174 /*DirectInit*/ false); 7175 7176 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7177 // This will be used to implement clause 'lastprivate'. 7178 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7179 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7180 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7181 SemaRef.AddInitializerToDecl(ILDecl, 7182 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7183 /*DirectInit*/ false); 7184 7185 // Stride variable returned by runtime (we initialize it to 1 by default). 7186 VarDecl *STDecl = 7187 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7188 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7189 SemaRef.AddInitializerToDecl(STDecl, 7190 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7191 /*DirectInit*/ false); 7192 7193 // Build expression: UB = min(UB, LastIteration) 7194 // It is necessary for CodeGen of directives with static scheduling. 7195 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7196 UB.get(), LastIteration.get()); 7197 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7198 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7199 LastIteration.get(), UB.get()); 7200 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7201 CondOp.get()); 7202 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7203 7204 // If we have a combined directive that combines 'distribute', 'for' or 7205 // 'simd' we need to be able to access the bounds of the schedule of the 7206 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7207 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7208 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7209 // Lower bound variable, initialized with zero. 7210 VarDecl *CombLBDecl = 7211 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7212 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7213 SemaRef.AddInitializerToDecl( 7214 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7215 /*DirectInit*/ false); 7216 7217 // Upper bound variable, initialized with last iteration number. 7218 VarDecl *CombUBDecl = 7219 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7220 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7221 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7222 /*DirectInit*/ false); 7223 7224 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7225 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7226 ExprResult CombCondOp = 7227 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7228 LastIteration.get(), CombUB.get()); 7229 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7230 CombCondOp.get()); 7231 CombEUB = 7232 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7233 7234 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7235 // We expect to have at least 2 more parameters than the 'parallel' 7236 // directive does - the lower and upper bounds of the previous schedule. 7237 assert(CD->getNumParams() >= 4 && 7238 "Unexpected number of parameters in loop combined directive"); 7239 7240 // Set the proper type for the bounds given what we learned from the 7241 // enclosed loops. 7242 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7243 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7244 7245 // Previous lower and upper bounds are obtained from the region 7246 // parameters. 7247 PrevLB = 7248 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7249 PrevUB = 7250 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7251 } 7252 } 7253 7254 // Build the iteration variable and its initialization before loop. 7255 ExprResult IV; 7256 ExprResult Init, CombInit; 7257 { 7258 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7259 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7260 Expr *RHS = 7261 (isOpenMPWorksharingDirective(DKind) || 7262 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7263 ? LB.get() 7264 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7265 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7266 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7267 7268 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7269 Expr *CombRHS = 7270 (isOpenMPWorksharingDirective(DKind) || 7271 isOpenMPTaskLoopDirective(DKind) || 7272 isOpenMPDistributeDirective(DKind)) 7273 ? CombLB.get() 7274 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7275 CombInit = 7276 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7277 CombInit = 7278 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7279 } 7280 } 7281 7282 bool UseStrictCompare = 7283 RealVType->hasUnsignedIntegerRepresentation() && 7284 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7285 return LIS.IsStrictCompare; 7286 }); 7287 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7288 // unsigned IV)) for worksharing loops. 7289 SourceLocation CondLoc = AStmt->getBeginLoc(); 7290 Expr *BoundUB = UB.get(); 7291 if (UseStrictCompare) { 7292 BoundUB = 7293 SemaRef 7294 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7295 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7296 .get(); 7297 BoundUB = 7298 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7299 } 7300 ExprResult Cond = 7301 (isOpenMPWorksharingDirective(DKind) || 7302 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7303 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7304 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7305 BoundUB) 7306 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7307 NumIterations.get()); 7308 ExprResult CombDistCond; 7309 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7310 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7311 NumIterations.get()); 7312 } 7313 7314 ExprResult CombCond; 7315 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7316 Expr *BoundCombUB = CombUB.get(); 7317 if (UseStrictCompare) { 7318 BoundCombUB = 7319 SemaRef 7320 .BuildBinOp( 7321 CurScope, CondLoc, BO_Add, BoundCombUB, 7322 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7323 .get(); 7324 BoundCombUB = 7325 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7326 .get(); 7327 } 7328 CombCond = 7329 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7330 IV.get(), BoundCombUB); 7331 } 7332 // Loop increment (IV = IV + 1) 7333 SourceLocation IncLoc = AStmt->getBeginLoc(); 7334 ExprResult Inc = 7335 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7336 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7337 if (!Inc.isUsable()) 7338 return 0; 7339 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7340 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7341 if (!Inc.isUsable()) 7342 return 0; 7343 7344 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7345 // Used for directives with static scheduling. 7346 // In combined construct, add combined version that use CombLB and CombUB 7347 // base variables for the update 7348 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7349 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7350 isOpenMPDistributeDirective(DKind)) { 7351 // LB + ST 7352 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7353 if (!NextLB.isUsable()) 7354 return 0; 7355 // LB = LB + ST 7356 NextLB = 7357 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7358 NextLB = 7359 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7360 if (!NextLB.isUsable()) 7361 return 0; 7362 // UB + ST 7363 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7364 if (!NextUB.isUsable()) 7365 return 0; 7366 // UB = UB + ST 7367 NextUB = 7368 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7369 NextUB = 7370 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7371 if (!NextUB.isUsable()) 7372 return 0; 7373 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7374 CombNextLB = 7375 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7376 if (!NextLB.isUsable()) 7377 return 0; 7378 // LB = LB + ST 7379 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7380 CombNextLB.get()); 7381 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7382 /*DiscardedValue*/ false); 7383 if (!CombNextLB.isUsable()) 7384 return 0; 7385 // UB + ST 7386 CombNextUB = 7387 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7388 if (!CombNextUB.isUsable()) 7389 return 0; 7390 // UB = UB + ST 7391 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7392 CombNextUB.get()); 7393 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7394 /*DiscardedValue*/ false); 7395 if (!CombNextUB.isUsable()) 7396 return 0; 7397 } 7398 } 7399 7400 // Create increment expression for distribute loop when combined in a same 7401 // directive with for as IV = IV + ST; ensure upper bound expression based 7402 // on PrevUB instead of NumIterations - used to implement 'for' when found 7403 // in combination with 'distribute', like in 'distribute parallel for' 7404 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7405 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7406 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7407 DistCond = SemaRef.BuildBinOp( 7408 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7409 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7410 7411 DistInc = 7412 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7413 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7414 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7415 DistInc.get()); 7416 DistInc = 7417 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7418 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7419 7420 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7421 // construct 7422 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7423 ExprResult IsUBGreater = 7424 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7425 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7426 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7427 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7428 CondOp.get()); 7429 PrevEUB = 7430 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7431 7432 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7433 // parallel for is in combination with a distribute directive with 7434 // schedule(static, 1) 7435 Expr *BoundPrevUB = PrevUB.get(); 7436 if (UseStrictCompare) { 7437 BoundPrevUB = 7438 SemaRef 7439 .BuildBinOp( 7440 CurScope, CondLoc, BO_Add, BoundPrevUB, 7441 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7442 .get(); 7443 BoundPrevUB = 7444 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7445 .get(); 7446 } 7447 ParForInDistCond = 7448 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7449 IV.get(), BoundPrevUB); 7450 } 7451 7452 // Build updates and final values of the loop counters. 7453 bool HasErrors = false; 7454 Built.Counters.resize(NestedLoopCount); 7455 Built.Inits.resize(NestedLoopCount); 7456 Built.Updates.resize(NestedLoopCount); 7457 Built.Finals.resize(NestedLoopCount); 7458 Built.DependentCounters.resize(NestedLoopCount); 7459 Built.DependentInits.resize(NestedLoopCount); 7460 Built.FinalsConditions.resize(NestedLoopCount); 7461 { 7462 // We implement the following algorithm for obtaining the 7463 // original loop iteration variable values based on the 7464 // value of the collapsed loop iteration variable IV. 7465 // 7466 // Let n+1 be the number of collapsed loops in the nest. 7467 // Iteration variables (I0, I1, .... In) 7468 // Iteration counts (N0, N1, ... Nn) 7469 // 7470 // Acc = IV; 7471 // 7472 // To compute Ik for loop k, 0 <= k <= n, generate: 7473 // Prod = N(k+1) * N(k+2) * ... * Nn; 7474 // Ik = Acc / Prod; 7475 // Acc -= Ik * Prod; 7476 // 7477 ExprResult Acc = IV; 7478 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7479 LoopIterationSpace &IS = IterSpaces[Cnt]; 7480 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7481 ExprResult Iter; 7482 7483 // Compute prod 7484 ExprResult Prod = 7485 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7486 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7487 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7488 IterSpaces[K].NumIterations); 7489 7490 // Iter = Acc / Prod 7491 // If there is at least one more inner loop to avoid 7492 // multiplication by 1. 7493 if (Cnt + 1 < NestedLoopCount) 7494 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7495 Acc.get(), Prod.get()); 7496 else 7497 Iter = Acc; 7498 if (!Iter.isUsable()) { 7499 HasErrors = true; 7500 break; 7501 } 7502 7503 // Update Acc: 7504 // Acc -= Iter * Prod 7505 // Check if there is at least one more inner loop to avoid 7506 // multiplication by 1. 7507 if (Cnt + 1 < NestedLoopCount) 7508 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7509 Iter.get(), Prod.get()); 7510 else 7511 Prod = Iter; 7512 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7513 Acc.get(), Prod.get()); 7514 7515 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7516 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7517 DeclRefExpr *CounterVar = buildDeclRefExpr( 7518 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7519 /*RefersToCapture=*/true); 7520 ExprResult Init = 7521 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7522 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7523 if (!Init.isUsable()) { 7524 HasErrors = true; 7525 break; 7526 } 7527 ExprResult Update = buildCounterUpdate( 7528 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7529 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7530 if (!Update.isUsable()) { 7531 HasErrors = true; 7532 break; 7533 } 7534 7535 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7536 ExprResult Final = 7537 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7538 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7539 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7540 if (!Final.isUsable()) { 7541 HasErrors = true; 7542 break; 7543 } 7544 7545 if (!Update.isUsable() || !Final.isUsable()) { 7546 HasErrors = true; 7547 break; 7548 } 7549 // Save results 7550 Built.Counters[Cnt] = IS.CounterVar; 7551 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7552 Built.Inits[Cnt] = Init.get(); 7553 Built.Updates[Cnt] = Update.get(); 7554 Built.Finals[Cnt] = Final.get(); 7555 Built.DependentCounters[Cnt] = nullptr; 7556 Built.DependentInits[Cnt] = nullptr; 7557 Built.FinalsConditions[Cnt] = nullptr; 7558 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7559 Built.DependentCounters[Cnt] = 7560 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7561 Built.DependentInits[Cnt] = 7562 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7563 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7564 } 7565 } 7566 } 7567 7568 if (HasErrors) 7569 return 0; 7570 7571 // Save results 7572 Built.IterationVarRef = IV.get(); 7573 Built.LastIteration = LastIteration.get(); 7574 Built.NumIterations = NumIterations.get(); 7575 Built.CalcLastIteration = SemaRef 7576 .ActOnFinishFullExpr(CalcLastIteration.get(), 7577 /*DiscardedValue=*/false) 7578 .get(); 7579 Built.PreCond = PreCond.get(); 7580 Built.PreInits = buildPreInits(C, Captures); 7581 Built.Cond = Cond.get(); 7582 Built.Init = Init.get(); 7583 Built.Inc = Inc.get(); 7584 Built.LB = LB.get(); 7585 Built.UB = UB.get(); 7586 Built.IL = IL.get(); 7587 Built.ST = ST.get(); 7588 Built.EUB = EUB.get(); 7589 Built.NLB = NextLB.get(); 7590 Built.NUB = NextUB.get(); 7591 Built.PrevLB = PrevLB.get(); 7592 Built.PrevUB = PrevUB.get(); 7593 Built.DistInc = DistInc.get(); 7594 Built.PrevEUB = PrevEUB.get(); 7595 Built.DistCombinedFields.LB = CombLB.get(); 7596 Built.DistCombinedFields.UB = CombUB.get(); 7597 Built.DistCombinedFields.EUB = CombEUB.get(); 7598 Built.DistCombinedFields.Init = CombInit.get(); 7599 Built.DistCombinedFields.Cond = CombCond.get(); 7600 Built.DistCombinedFields.NLB = CombNextLB.get(); 7601 Built.DistCombinedFields.NUB = CombNextUB.get(); 7602 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7603 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7604 7605 return NestedLoopCount; 7606 } 7607 7608 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7609 auto CollapseClauses = 7610 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7611 if (CollapseClauses.begin() != CollapseClauses.end()) 7612 return (*CollapseClauses.begin())->getNumForLoops(); 7613 return nullptr; 7614 } 7615 7616 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7617 auto OrderedClauses = 7618 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7619 if (OrderedClauses.begin() != OrderedClauses.end()) 7620 return (*OrderedClauses.begin())->getNumForLoops(); 7621 return nullptr; 7622 } 7623 7624 static bool checkSimdlenSafelenSpecified(Sema &S, 7625 const ArrayRef<OMPClause *> Clauses) { 7626 const OMPSafelenClause *Safelen = nullptr; 7627 const OMPSimdlenClause *Simdlen = nullptr; 7628 7629 for (const OMPClause *Clause : Clauses) { 7630 if (Clause->getClauseKind() == OMPC_safelen) 7631 Safelen = cast<OMPSafelenClause>(Clause); 7632 else if (Clause->getClauseKind() == OMPC_simdlen) 7633 Simdlen = cast<OMPSimdlenClause>(Clause); 7634 if (Safelen && Simdlen) 7635 break; 7636 } 7637 7638 if (Simdlen && Safelen) { 7639 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7640 const Expr *SafelenLength = Safelen->getSafelen(); 7641 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7642 SimdlenLength->isInstantiationDependent() || 7643 SimdlenLength->containsUnexpandedParameterPack()) 7644 return false; 7645 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7646 SafelenLength->isInstantiationDependent() || 7647 SafelenLength->containsUnexpandedParameterPack()) 7648 return false; 7649 Expr::EvalResult SimdlenResult, SafelenResult; 7650 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7651 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7652 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7653 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7654 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7655 // If both simdlen and safelen clauses are specified, the value of the 7656 // simdlen parameter must be less than or equal to the value of the safelen 7657 // parameter. 7658 if (SimdlenRes > SafelenRes) { 7659 S.Diag(SimdlenLength->getExprLoc(), 7660 diag::err_omp_wrong_simdlen_safelen_values) 7661 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7662 return true; 7663 } 7664 } 7665 return false; 7666 } 7667 7668 StmtResult 7669 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7670 SourceLocation StartLoc, SourceLocation EndLoc, 7671 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7672 if (!AStmt) 7673 return StmtError(); 7674 7675 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7676 OMPLoopDirective::HelperExprs B; 7677 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7678 // define the nested loops number. 7679 unsigned NestedLoopCount = checkOpenMPLoop( 7680 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7681 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7682 if (NestedLoopCount == 0) 7683 return StmtError(); 7684 7685 assert((CurContext->isDependentContext() || B.builtAll()) && 7686 "omp simd loop exprs were not built"); 7687 7688 if (!CurContext->isDependentContext()) { 7689 // Finalize the clauses that need pre-built expressions for CodeGen. 7690 for (OMPClause *C : Clauses) { 7691 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7692 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7693 B.NumIterations, *this, CurScope, 7694 DSAStack)) 7695 return StmtError(); 7696 } 7697 } 7698 7699 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7700 return StmtError(); 7701 7702 setFunctionHasBranchProtectedScope(); 7703 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7704 Clauses, AStmt, B); 7705 } 7706 7707 StmtResult 7708 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7709 SourceLocation StartLoc, SourceLocation EndLoc, 7710 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7711 if (!AStmt) 7712 return StmtError(); 7713 7714 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7715 OMPLoopDirective::HelperExprs B; 7716 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7717 // define the nested loops number. 7718 unsigned NestedLoopCount = checkOpenMPLoop( 7719 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7720 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7721 if (NestedLoopCount == 0) 7722 return StmtError(); 7723 7724 assert((CurContext->isDependentContext() || B.builtAll()) && 7725 "omp for loop exprs were not built"); 7726 7727 if (!CurContext->isDependentContext()) { 7728 // Finalize the clauses that need pre-built expressions for CodeGen. 7729 for (OMPClause *C : Clauses) { 7730 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7731 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7732 B.NumIterations, *this, CurScope, 7733 DSAStack)) 7734 return StmtError(); 7735 } 7736 } 7737 7738 setFunctionHasBranchProtectedScope(); 7739 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7740 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7741 } 7742 7743 StmtResult Sema::ActOnOpenMPForSimdDirective( 7744 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7745 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7746 if (!AStmt) 7747 return StmtError(); 7748 7749 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7750 OMPLoopDirective::HelperExprs B; 7751 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7752 // define the nested loops number. 7753 unsigned NestedLoopCount = 7754 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7755 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7756 VarsWithImplicitDSA, B); 7757 if (NestedLoopCount == 0) 7758 return StmtError(); 7759 7760 assert((CurContext->isDependentContext() || B.builtAll()) && 7761 "omp for simd loop exprs were not built"); 7762 7763 if (!CurContext->isDependentContext()) { 7764 // Finalize the clauses that need pre-built expressions for CodeGen. 7765 for (OMPClause *C : Clauses) { 7766 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7767 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7768 B.NumIterations, *this, CurScope, 7769 DSAStack)) 7770 return StmtError(); 7771 } 7772 } 7773 7774 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7775 return StmtError(); 7776 7777 setFunctionHasBranchProtectedScope(); 7778 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7779 Clauses, AStmt, B); 7780 } 7781 7782 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7783 Stmt *AStmt, 7784 SourceLocation StartLoc, 7785 SourceLocation EndLoc) { 7786 if (!AStmt) 7787 return StmtError(); 7788 7789 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7790 auto BaseStmt = AStmt; 7791 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7792 BaseStmt = CS->getCapturedStmt(); 7793 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7794 auto S = C->children(); 7795 if (S.begin() == S.end()) 7796 return StmtError(); 7797 // All associated statements must be '#pragma omp section' except for 7798 // the first one. 7799 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7800 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7801 if (SectionStmt) 7802 Diag(SectionStmt->getBeginLoc(), 7803 diag::err_omp_sections_substmt_not_section); 7804 return StmtError(); 7805 } 7806 cast<OMPSectionDirective>(SectionStmt) 7807 ->setHasCancel(DSAStack->isCancelRegion()); 7808 } 7809 } else { 7810 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7811 return StmtError(); 7812 } 7813 7814 setFunctionHasBranchProtectedScope(); 7815 7816 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7817 DSAStack->isCancelRegion()); 7818 } 7819 7820 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7821 SourceLocation StartLoc, 7822 SourceLocation EndLoc) { 7823 if (!AStmt) 7824 return StmtError(); 7825 7826 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7827 7828 setFunctionHasBranchProtectedScope(); 7829 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7830 7831 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7832 DSAStack->isCancelRegion()); 7833 } 7834 7835 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7836 Stmt *AStmt, 7837 SourceLocation StartLoc, 7838 SourceLocation EndLoc) { 7839 if (!AStmt) 7840 return StmtError(); 7841 7842 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7843 7844 setFunctionHasBranchProtectedScope(); 7845 7846 // OpenMP [2.7.3, single Construct, Restrictions] 7847 // The copyprivate clause must not be used with the nowait clause. 7848 const OMPClause *Nowait = nullptr; 7849 const OMPClause *Copyprivate = nullptr; 7850 for (const OMPClause *Clause : Clauses) { 7851 if (Clause->getClauseKind() == OMPC_nowait) 7852 Nowait = Clause; 7853 else if (Clause->getClauseKind() == OMPC_copyprivate) 7854 Copyprivate = Clause; 7855 if (Copyprivate && Nowait) { 7856 Diag(Copyprivate->getBeginLoc(), 7857 diag::err_omp_single_copyprivate_with_nowait); 7858 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7859 return StmtError(); 7860 } 7861 } 7862 7863 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7864 } 7865 7866 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7867 SourceLocation StartLoc, 7868 SourceLocation EndLoc) { 7869 if (!AStmt) 7870 return StmtError(); 7871 7872 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7873 7874 setFunctionHasBranchProtectedScope(); 7875 7876 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7877 } 7878 7879 StmtResult Sema::ActOnOpenMPCriticalDirective( 7880 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7881 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7882 if (!AStmt) 7883 return StmtError(); 7884 7885 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7886 7887 bool ErrorFound = false; 7888 llvm::APSInt Hint; 7889 SourceLocation HintLoc; 7890 bool DependentHint = false; 7891 for (const OMPClause *C : Clauses) { 7892 if (C->getClauseKind() == OMPC_hint) { 7893 if (!DirName.getName()) { 7894 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7895 ErrorFound = true; 7896 } 7897 Expr *E = cast<OMPHintClause>(C)->getHint(); 7898 if (E->isTypeDependent() || E->isValueDependent() || 7899 E->isInstantiationDependent()) { 7900 DependentHint = true; 7901 } else { 7902 Hint = E->EvaluateKnownConstInt(Context); 7903 HintLoc = C->getBeginLoc(); 7904 } 7905 } 7906 } 7907 if (ErrorFound) 7908 return StmtError(); 7909 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7910 if (Pair.first && DirName.getName() && !DependentHint) { 7911 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7912 Diag(StartLoc, diag::err_omp_critical_with_hint); 7913 if (HintLoc.isValid()) 7914 Diag(HintLoc, diag::note_omp_critical_hint_here) 7915 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7916 else 7917 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7918 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7919 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7920 << 1 7921 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7922 /*Radix=*/10, /*Signed=*/false); 7923 } else { 7924 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7925 } 7926 } 7927 } 7928 7929 setFunctionHasBranchProtectedScope(); 7930 7931 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7932 Clauses, AStmt); 7933 if (!Pair.first && DirName.getName() && !DependentHint) 7934 DSAStack->addCriticalWithHint(Dir, Hint); 7935 return Dir; 7936 } 7937 7938 StmtResult Sema::ActOnOpenMPParallelForDirective( 7939 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7940 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7941 if (!AStmt) 7942 return StmtError(); 7943 7944 auto *CS = cast<CapturedStmt>(AStmt); 7945 // 1.2.2 OpenMP Language Terminology 7946 // Structured block - An executable statement with a single entry at the 7947 // top and a single exit at the bottom. 7948 // The point of exit cannot be a branch out of the structured block. 7949 // longjmp() and throw() must not violate the entry/exit criteria. 7950 CS->getCapturedDecl()->setNothrow(); 7951 7952 OMPLoopDirective::HelperExprs B; 7953 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7954 // define the nested loops number. 7955 unsigned NestedLoopCount = 7956 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7957 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7958 VarsWithImplicitDSA, B); 7959 if (NestedLoopCount == 0) 7960 return StmtError(); 7961 7962 assert((CurContext->isDependentContext() || B.builtAll()) && 7963 "omp parallel for loop exprs were not built"); 7964 7965 if (!CurContext->isDependentContext()) { 7966 // Finalize the clauses that need pre-built expressions for CodeGen. 7967 for (OMPClause *C : Clauses) { 7968 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7969 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7970 B.NumIterations, *this, CurScope, 7971 DSAStack)) 7972 return StmtError(); 7973 } 7974 } 7975 7976 setFunctionHasBranchProtectedScope(); 7977 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7978 NestedLoopCount, Clauses, AStmt, B, 7979 DSAStack->isCancelRegion()); 7980 } 7981 7982 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7983 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7984 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7985 if (!AStmt) 7986 return StmtError(); 7987 7988 auto *CS = cast<CapturedStmt>(AStmt); 7989 // 1.2.2 OpenMP Language Terminology 7990 // Structured block - An executable statement with a single entry at the 7991 // top and a single exit at the bottom. 7992 // The point of exit cannot be a branch out of the structured block. 7993 // longjmp() and throw() must not violate the entry/exit criteria. 7994 CS->getCapturedDecl()->setNothrow(); 7995 7996 OMPLoopDirective::HelperExprs B; 7997 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7998 // define the nested loops number. 7999 unsigned NestedLoopCount = 8000 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8001 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8002 VarsWithImplicitDSA, B); 8003 if (NestedLoopCount == 0) 8004 return StmtError(); 8005 8006 if (!CurContext->isDependentContext()) { 8007 // Finalize the clauses that need pre-built expressions for CodeGen. 8008 for (OMPClause *C : Clauses) { 8009 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8010 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8011 B.NumIterations, *this, CurScope, 8012 DSAStack)) 8013 return StmtError(); 8014 } 8015 } 8016 8017 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8018 return StmtError(); 8019 8020 setFunctionHasBranchProtectedScope(); 8021 return OMPParallelForSimdDirective::Create( 8022 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8023 } 8024 8025 StmtResult 8026 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8027 Stmt *AStmt, SourceLocation StartLoc, 8028 SourceLocation EndLoc) { 8029 if (!AStmt) 8030 return StmtError(); 8031 8032 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8033 auto BaseStmt = AStmt; 8034 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8035 BaseStmt = CS->getCapturedStmt(); 8036 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8037 auto S = C->children(); 8038 if (S.begin() == S.end()) 8039 return StmtError(); 8040 // All associated statements must be '#pragma omp section' except for 8041 // the first one. 8042 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8043 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8044 if (SectionStmt) 8045 Diag(SectionStmt->getBeginLoc(), 8046 diag::err_omp_parallel_sections_substmt_not_section); 8047 return StmtError(); 8048 } 8049 cast<OMPSectionDirective>(SectionStmt) 8050 ->setHasCancel(DSAStack->isCancelRegion()); 8051 } 8052 } else { 8053 Diag(AStmt->getBeginLoc(), 8054 diag::err_omp_parallel_sections_not_compound_stmt); 8055 return StmtError(); 8056 } 8057 8058 setFunctionHasBranchProtectedScope(); 8059 8060 return OMPParallelSectionsDirective::Create( 8061 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8062 } 8063 8064 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8065 Stmt *AStmt, SourceLocation StartLoc, 8066 SourceLocation EndLoc) { 8067 if (!AStmt) 8068 return StmtError(); 8069 8070 auto *CS = cast<CapturedStmt>(AStmt); 8071 // 1.2.2 OpenMP Language Terminology 8072 // Structured block - An executable statement with a single entry at the 8073 // top and a single exit at the bottom. 8074 // The point of exit cannot be a branch out of the structured block. 8075 // longjmp() and throw() must not violate the entry/exit criteria. 8076 CS->getCapturedDecl()->setNothrow(); 8077 8078 setFunctionHasBranchProtectedScope(); 8079 8080 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8081 DSAStack->isCancelRegion()); 8082 } 8083 8084 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8085 SourceLocation EndLoc) { 8086 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8087 } 8088 8089 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8090 SourceLocation EndLoc) { 8091 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8092 } 8093 8094 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8095 SourceLocation EndLoc) { 8096 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8097 } 8098 8099 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8100 Stmt *AStmt, 8101 SourceLocation StartLoc, 8102 SourceLocation EndLoc) { 8103 if (!AStmt) 8104 return StmtError(); 8105 8106 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8107 8108 setFunctionHasBranchProtectedScope(); 8109 8110 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8111 AStmt, 8112 DSAStack->getTaskgroupReductionRef()); 8113 } 8114 8115 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8116 SourceLocation StartLoc, 8117 SourceLocation EndLoc) { 8118 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8119 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8120 } 8121 8122 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8123 Stmt *AStmt, 8124 SourceLocation StartLoc, 8125 SourceLocation EndLoc) { 8126 const OMPClause *DependFound = nullptr; 8127 const OMPClause *DependSourceClause = nullptr; 8128 const OMPClause *DependSinkClause = nullptr; 8129 bool ErrorFound = false; 8130 const OMPThreadsClause *TC = nullptr; 8131 const OMPSIMDClause *SC = nullptr; 8132 for (const OMPClause *C : Clauses) { 8133 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8134 DependFound = C; 8135 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8136 if (DependSourceClause) { 8137 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8138 << getOpenMPDirectiveName(OMPD_ordered) 8139 << getOpenMPClauseName(OMPC_depend) << 2; 8140 ErrorFound = true; 8141 } else { 8142 DependSourceClause = C; 8143 } 8144 if (DependSinkClause) { 8145 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8146 << 0; 8147 ErrorFound = true; 8148 } 8149 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8150 if (DependSourceClause) { 8151 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8152 << 1; 8153 ErrorFound = true; 8154 } 8155 DependSinkClause = C; 8156 } 8157 } else if (C->getClauseKind() == OMPC_threads) { 8158 TC = cast<OMPThreadsClause>(C); 8159 } else if (C->getClauseKind() == OMPC_simd) { 8160 SC = cast<OMPSIMDClause>(C); 8161 } 8162 } 8163 if (!ErrorFound && !SC && 8164 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8165 // OpenMP [2.8.1,simd Construct, Restrictions] 8166 // An ordered construct with the simd clause is the only OpenMP construct 8167 // that can appear in the simd region. 8168 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 8169 ErrorFound = true; 8170 } else if (DependFound && (TC || SC)) { 8171 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8172 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8173 ErrorFound = true; 8174 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8175 Diag(DependFound->getBeginLoc(), 8176 diag::err_omp_ordered_directive_without_param); 8177 ErrorFound = true; 8178 } else if (TC || Clauses.empty()) { 8179 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8180 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8181 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8182 << (TC != nullptr); 8183 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8184 ErrorFound = true; 8185 } 8186 } 8187 if ((!AStmt && !DependFound) || ErrorFound) 8188 return StmtError(); 8189 8190 if (AStmt) { 8191 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8192 8193 setFunctionHasBranchProtectedScope(); 8194 } 8195 8196 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8197 } 8198 8199 namespace { 8200 /// Helper class for checking expression in 'omp atomic [update]' 8201 /// construct. 8202 class OpenMPAtomicUpdateChecker { 8203 /// Error results for atomic update expressions. 8204 enum ExprAnalysisErrorCode { 8205 /// A statement is not an expression statement. 8206 NotAnExpression, 8207 /// Expression is not builtin binary or unary operation. 8208 NotABinaryOrUnaryExpression, 8209 /// Unary operation is not post-/pre- increment/decrement operation. 8210 NotAnUnaryIncDecExpression, 8211 /// An expression is not of scalar type. 8212 NotAScalarType, 8213 /// A binary operation is not an assignment operation. 8214 NotAnAssignmentOp, 8215 /// RHS part of the binary operation is not a binary expression. 8216 NotABinaryExpression, 8217 /// RHS part is not additive/multiplicative/shift/biwise binary 8218 /// expression. 8219 NotABinaryOperator, 8220 /// RHS binary operation does not have reference to the updated LHS 8221 /// part. 8222 NotAnUpdateExpression, 8223 /// No errors is found. 8224 NoError 8225 }; 8226 /// Reference to Sema. 8227 Sema &SemaRef; 8228 /// A location for note diagnostics (when error is found). 8229 SourceLocation NoteLoc; 8230 /// 'x' lvalue part of the source atomic expression. 8231 Expr *X; 8232 /// 'expr' rvalue part of the source atomic expression. 8233 Expr *E; 8234 /// Helper expression of the form 8235 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8236 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8237 Expr *UpdateExpr; 8238 /// Is 'x' a LHS in a RHS part of full update expression. It is 8239 /// important for non-associative operations. 8240 bool IsXLHSInRHSPart; 8241 BinaryOperatorKind Op; 8242 SourceLocation OpLoc; 8243 /// true if the source expression is a postfix unary operation, false 8244 /// if it is a prefix unary operation. 8245 bool IsPostfixUpdate; 8246 8247 public: 8248 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8249 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8250 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8251 /// Check specified statement that it is suitable for 'atomic update' 8252 /// constructs and extract 'x', 'expr' and Operation from the original 8253 /// expression. If DiagId and NoteId == 0, then only check is performed 8254 /// without error notification. 8255 /// \param DiagId Diagnostic which should be emitted if error is found. 8256 /// \param NoteId Diagnostic note for the main error message. 8257 /// \return true if statement is not an update expression, false otherwise. 8258 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8259 /// Return the 'x' lvalue part of the source atomic expression. 8260 Expr *getX() const { return X; } 8261 /// Return the 'expr' rvalue part of the source atomic expression. 8262 Expr *getExpr() const { return E; } 8263 /// Return the update expression used in calculation of the updated 8264 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8265 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8266 Expr *getUpdateExpr() const { return UpdateExpr; } 8267 /// Return true if 'x' is LHS in RHS part of full update expression, 8268 /// false otherwise. 8269 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8270 8271 /// true if the source expression is a postfix unary operation, false 8272 /// if it is a prefix unary operation. 8273 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8274 8275 private: 8276 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8277 unsigned NoteId = 0); 8278 }; 8279 } // namespace 8280 8281 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8282 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8283 ExprAnalysisErrorCode ErrorFound = NoError; 8284 SourceLocation ErrorLoc, NoteLoc; 8285 SourceRange ErrorRange, NoteRange; 8286 // Allowed constructs are: 8287 // x = x binop expr; 8288 // x = expr binop x; 8289 if (AtomicBinOp->getOpcode() == BO_Assign) { 8290 X = AtomicBinOp->getLHS(); 8291 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8292 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8293 if (AtomicInnerBinOp->isMultiplicativeOp() || 8294 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8295 AtomicInnerBinOp->isBitwiseOp()) { 8296 Op = AtomicInnerBinOp->getOpcode(); 8297 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8298 Expr *LHS = AtomicInnerBinOp->getLHS(); 8299 Expr *RHS = AtomicInnerBinOp->getRHS(); 8300 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8301 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8302 /*Canonical=*/true); 8303 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8304 /*Canonical=*/true); 8305 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8306 /*Canonical=*/true); 8307 if (XId == LHSId) { 8308 E = RHS; 8309 IsXLHSInRHSPart = true; 8310 } else if (XId == RHSId) { 8311 E = LHS; 8312 IsXLHSInRHSPart = false; 8313 } else { 8314 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8315 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8316 NoteLoc = X->getExprLoc(); 8317 NoteRange = X->getSourceRange(); 8318 ErrorFound = NotAnUpdateExpression; 8319 } 8320 } else { 8321 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8322 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8323 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8324 NoteRange = SourceRange(NoteLoc, NoteLoc); 8325 ErrorFound = NotABinaryOperator; 8326 } 8327 } else { 8328 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8329 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8330 ErrorFound = NotABinaryExpression; 8331 } 8332 } else { 8333 ErrorLoc = AtomicBinOp->getExprLoc(); 8334 ErrorRange = AtomicBinOp->getSourceRange(); 8335 NoteLoc = AtomicBinOp->getOperatorLoc(); 8336 NoteRange = SourceRange(NoteLoc, NoteLoc); 8337 ErrorFound = NotAnAssignmentOp; 8338 } 8339 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8340 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8341 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8342 return true; 8343 } 8344 if (SemaRef.CurContext->isDependentContext()) 8345 E = X = UpdateExpr = nullptr; 8346 return ErrorFound != NoError; 8347 } 8348 8349 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8350 unsigned NoteId) { 8351 ExprAnalysisErrorCode ErrorFound = NoError; 8352 SourceLocation ErrorLoc, NoteLoc; 8353 SourceRange ErrorRange, NoteRange; 8354 // Allowed constructs are: 8355 // x++; 8356 // x--; 8357 // ++x; 8358 // --x; 8359 // x binop= expr; 8360 // x = x binop expr; 8361 // x = expr binop x; 8362 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8363 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8364 if (AtomicBody->getType()->isScalarType() || 8365 AtomicBody->isInstantiationDependent()) { 8366 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8367 AtomicBody->IgnoreParenImpCasts())) { 8368 // Check for Compound Assignment Operation 8369 Op = BinaryOperator::getOpForCompoundAssignment( 8370 AtomicCompAssignOp->getOpcode()); 8371 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8372 E = AtomicCompAssignOp->getRHS(); 8373 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8374 IsXLHSInRHSPart = true; 8375 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8376 AtomicBody->IgnoreParenImpCasts())) { 8377 // Check for Binary Operation 8378 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8379 return true; 8380 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8381 AtomicBody->IgnoreParenImpCasts())) { 8382 // Check for Unary Operation 8383 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8384 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8385 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8386 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8387 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8388 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8389 IsXLHSInRHSPart = true; 8390 } else { 8391 ErrorFound = NotAnUnaryIncDecExpression; 8392 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8393 ErrorRange = AtomicUnaryOp->getSourceRange(); 8394 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8395 NoteRange = SourceRange(NoteLoc, NoteLoc); 8396 } 8397 } else if (!AtomicBody->isInstantiationDependent()) { 8398 ErrorFound = NotABinaryOrUnaryExpression; 8399 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8400 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8401 } 8402 } else { 8403 ErrorFound = NotAScalarType; 8404 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8405 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8406 } 8407 } else { 8408 ErrorFound = NotAnExpression; 8409 NoteLoc = ErrorLoc = S->getBeginLoc(); 8410 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8411 } 8412 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8413 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8414 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8415 return true; 8416 } 8417 if (SemaRef.CurContext->isDependentContext()) 8418 E = X = UpdateExpr = nullptr; 8419 if (ErrorFound == NoError && E && X) { 8420 // Build an update expression of form 'OpaqueValueExpr(x) binop 8421 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8422 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8423 auto *OVEX = new (SemaRef.getASTContext()) 8424 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8425 auto *OVEExpr = new (SemaRef.getASTContext()) 8426 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8427 ExprResult Update = 8428 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8429 IsXLHSInRHSPart ? OVEExpr : OVEX); 8430 if (Update.isInvalid()) 8431 return true; 8432 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8433 Sema::AA_Casting); 8434 if (Update.isInvalid()) 8435 return true; 8436 UpdateExpr = Update.get(); 8437 } 8438 return ErrorFound != NoError; 8439 } 8440 8441 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8442 Stmt *AStmt, 8443 SourceLocation StartLoc, 8444 SourceLocation EndLoc) { 8445 if (!AStmt) 8446 return StmtError(); 8447 8448 auto *CS = cast<CapturedStmt>(AStmt); 8449 // 1.2.2 OpenMP Language Terminology 8450 // Structured block - An executable statement with a single entry at the 8451 // top and a single exit at the bottom. 8452 // The point of exit cannot be a branch out of the structured block. 8453 // longjmp() and throw() must not violate the entry/exit criteria. 8454 OpenMPClauseKind AtomicKind = OMPC_unknown; 8455 SourceLocation AtomicKindLoc; 8456 for (const OMPClause *C : Clauses) { 8457 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8458 C->getClauseKind() == OMPC_update || 8459 C->getClauseKind() == OMPC_capture) { 8460 if (AtomicKind != OMPC_unknown) { 8461 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8462 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8463 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8464 << getOpenMPClauseName(AtomicKind); 8465 } else { 8466 AtomicKind = C->getClauseKind(); 8467 AtomicKindLoc = C->getBeginLoc(); 8468 } 8469 } 8470 } 8471 8472 Stmt *Body = CS->getCapturedStmt(); 8473 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8474 Body = EWC->getSubExpr(); 8475 8476 Expr *X = nullptr; 8477 Expr *V = nullptr; 8478 Expr *E = nullptr; 8479 Expr *UE = nullptr; 8480 bool IsXLHSInRHSPart = false; 8481 bool IsPostfixUpdate = false; 8482 // OpenMP [2.12.6, atomic Construct] 8483 // In the next expressions: 8484 // * x and v (as applicable) are both l-value expressions with scalar type. 8485 // * During the execution of an atomic region, multiple syntactic 8486 // occurrences of x must designate the same storage location. 8487 // * Neither of v and expr (as applicable) may access the storage location 8488 // designated by x. 8489 // * Neither of x and expr (as applicable) may access the storage location 8490 // designated by v. 8491 // * expr is an expression with scalar type. 8492 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8493 // * binop, binop=, ++, and -- are not overloaded operators. 8494 // * The expression x binop expr must be numerically equivalent to x binop 8495 // (expr). This requirement is satisfied if the operators in expr have 8496 // precedence greater than binop, or by using parentheses around expr or 8497 // subexpressions of expr. 8498 // * The expression expr binop x must be numerically equivalent to (expr) 8499 // binop x. This requirement is satisfied if the operators in expr have 8500 // precedence equal to or greater than binop, or by using parentheses around 8501 // expr or subexpressions of expr. 8502 // * For forms that allow multiple occurrences of x, the number of times 8503 // that x is evaluated is unspecified. 8504 if (AtomicKind == OMPC_read) { 8505 enum { 8506 NotAnExpression, 8507 NotAnAssignmentOp, 8508 NotAScalarType, 8509 NotAnLValue, 8510 NoError 8511 } ErrorFound = NoError; 8512 SourceLocation ErrorLoc, NoteLoc; 8513 SourceRange ErrorRange, NoteRange; 8514 // If clause is read: 8515 // v = x; 8516 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8517 const auto *AtomicBinOp = 8518 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8519 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8520 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8521 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8522 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8523 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8524 if (!X->isLValue() || !V->isLValue()) { 8525 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8526 ErrorFound = NotAnLValue; 8527 ErrorLoc = AtomicBinOp->getExprLoc(); 8528 ErrorRange = AtomicBinOp->getSourceRange(); 8529 NoteLoc = NotLValueExpr->getExprLoc(); 8530 NoteRange = NotLValueExpr->getSourceRange(); 8531 } 8532 } else if (!X->isInstantiationDependent() || 8533 !V->isInstantiationDependent()) { 8534 const Expr *NotScalarExpr = 8535 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8536 ? V 8537 : X; 8538 ErrorFound = NotAScalarType; 8539 ErrorLoc = AtomicBinOp->getExprLoc(); 8540 ErrorRange = AtomicBinOp->getSourceRange(); 8541 NoteLoc = NotScalarExpr->getExprLoc(); 8542 NoteRange = NotScalarExpr->getSourceRange(); 8543 } 8544 } else if (!AtomicBody->isInstantiationDependent()) { 8545 ErrorFound = NotAnAssignmentOp; 8546 ErrorLoc = AtomicBody->getExprLoc(); 8547 ErrorRange = AtomicBody->getSourceRange(); 8548 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8549 : AtomicBody->getExprLoc(); 8550 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8551 : AtomicBody->getSourceRange(); 8552 } 8553 } else { 8554 ErrorFound = NotAnExpression; 8555 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8556 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8557 } 8558 if (ErrorFound != NoError) { 8559 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8560 << ErrorRange; 8561 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8562 << NoteRange; 8563 return StmtError(); 8564 } 8565 if (CurContext->isDependentContext()) 8566 V = X = nullptr; 8567 } else if (AtomicKind == OMPC_write) { 8568 enum { 8569 NotAnExpression, 8570 NotAnAssignmentOp, 8571 NotAScalarType, 8572 NotAnLValue, 8573 NoError 8574 } ErrorFound = NoError; 8575 SourceLocation ErrorLoc, NoteLoc; 8576 SourceRange ErrorRange, NoteRange; 8577 // If clause is write: 8578 // x = expr; 8579 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8580 const auto *AtomicBinOp = 8581 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8582 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8583 X = AtomicBinOp->getLHS(); 8584 E = AtomicBinOp->getRHS(); 8585 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8586 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8587 if (!X->isLValue()) { 8588 ErrorFound = NotAnLValue; 8589 ErrorLoc = AtomicBinOp->getExprLoc(); 8590 ErrorRange = AtomicBinOp->getSourceRange(); 8591 NoteLoc = X->getExprLoc(); 8592 NoteRange = X->getSourceRange(); 8593 } 8594 } else if (!X->isInstantiationDependent() || 8595 !E->isInstantiationDependent()) { 8596 const Expr *NotScalarExpr = 8597 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8598 ? E 8599 : X; 8600 ErrorFound = NotAScalarType; 8601 ErrorLoc = AtomicBinOp->getExprLoc(); 8602 ErrorRange = AtomicBinOp->getSourceRange(); 8603 NoteLoc = NotScalarExpr->getExprLoc(); 8604 NoteRange = NotScalarExpr->getSourceRange(); 8605 } 8606 } else if (!AtomicBody->isInstantiationDependent()) { 8607 ErrorFound = NotAnAssignmentOp; 8608 ErrorLoc = AtomicBody->getExprLoc(); 8609 ErrorRange = AtomicBody->getSourceRange(); 8610 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8611 : AtomicBody->getExprLoc(); 8612 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8613 : AtomicBody->getSourceRange(); 8614 } 8615 } else { 8616 ErrorFound = NotAnExpression; 8617 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8618 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8619 } 8620 if (ErrorFound != NoError) { 8621 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8622 << ErrorRange; 8623 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8624 << NoteRange; 8625 return StmtError(); 8626 } 8627 if (CurContext->isDependentContext()) 8628 E = X = nullptr; 8629 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8630 // If clause is update: 8631 // x++; 8632 // x--; 8633 // ++x; 8634 // --x; 8635 // x binop= expr; 8636 // x = x binop expr; 8637 // x = expr binop x; 8638 OpenMPAtomicUpdateChecker Checker(*this); 8639 if (Checker.checkStatement( 8640 Body, (AtomicKind == OMPC_update) 8641 ? diag::err_omp_atomic_update_not_expression_statement 8642 : diag::err_omp_atomic_not_expression_statement, 8643 diag::note_omp_atomic_update)) 8644 return StmtError(); 8645 if (!CurContext->isDependentContext()) { 8646 E = Checker.getExpr(); 8647 X = Checker.getX(); 8648 UE = Checker.getUpdateExpr(); 8649 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8650 } 8651 } else if (AtomicKind == OMPC_capture) { 8652 enum { 8653 NotAnAssignmentOp, 8654 NotACompoundStatement, 8655 NotTwoSubstatements, 8656 NotASpecificExpression, 8657 NoError 8658 } ErrorFound = NoError; 8659 SourceLocation ErrorLoc, NoteLoc; 8660 SourceRange ErrorRange, NoteRange; 8661 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8662 // If clause is a capture: 8663 // v = x++; 8664 // v = x--; 8665 // v = ++x; 8666 // v = --x; 8667 // v = x binop= expr; 8668 // v = x = x binop expr; 8669 // v = x = expr binop x; 8670 const auto *AtomicBinOp = 8671 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8672 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8673 V = AtomicBinOp->getLHS(); 8674 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8675 OpenMPAtomicUpdateChecker Checker(*this); 8676 if (Checker.checkStatement( 8677 Body, diag::err_omp_atomic_capture_not_expression_statement, 8678 diag::note_omp_atomic_update)) 8679 return StmtError(); 8680 E = Checker.getExpr(); 8681 X = Checker.getX(); 8682 UE = Checker.getUpdateExpr(); 8683 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8684 IsPostfixUpdate = Checker.isPostfixUpdate(); 8685 } else if (!AtomicBody->isInstantiationDependent()) { 8686 ErrorLoc = AtomicBody->getExprLoc(); 8687 ErrorRange = AtomicBody->getSourceRange(); 8688 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8689 : AtomicBody->getExprLoc(); 8690 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8691 : AtomicBody->getSourceRange(); 8692 ErrorFound = NotAnAssignmentOp; 8693 } 8694 if (ErrorFound != NoError) { 8695 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8696 << ErrorRange; 8697 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8698 return StmtError(); 8699 } 8700 if (CurContext->isDependentContext()) 8701 UE = V = E = X = nullptr; 8702 } else { 8703 // If clause is a capture: 8704 // { v = x; x = expr; } 8705 // { v = x; x++; } 8706 // { v = x; x--; } 8707 // { v = x; ++x; } 8708 // { v = x; --x; } 8709 // { v = x; x binop= expr; } 8710 // { v = x; x = x binop expr; } 8711 // { v = x; x = expr binop x; } 8712 // { x++; v = x; } 8713 // { x--; v = x; } 8714 // { ++x; v = x; } 8715 // { --x; v = x; } 8716 // { x binop= expr; v = x; } 8717 // { x = x binop expr; v = x; } 8718 // { x = expr binop x; v = x; } 8719 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8720 // Check that this is { expr1; expr2; } 8721 if (CS->size() == 2) { 8722 Stmt *First = CS->body_front(); 8723 Stmt *Second = CS->body_back(); 8724 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8725 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8726 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8727 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8728 // Need to find what subexpression is 'v' and what is 'x'. 8729 OpenMPAtomicUpdateChecker Checker(*this); 8730 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8731 BinaryOperator *BinOp = nullptr; 8732 if (IsUpdateExprFound) { 8733 BinOp = dyn_cast<BinaryOperator>(First); 8734 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8735 } 8736 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8737 // { v = x; x++; } 8738 // { v = x; x--; } 8739 // { v = x; ++x; } 8740 // { v = x; --x; } 8741 // { v = x; x binop= expr; } 8742 // { v = x; x = x binop expr; } 8743 // { v = x; x = expr binop x; } 8744 // Check that the first expression has form v = x. 8745 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8746 llvm::FoldingSetNodeID XId, PossibleXId; 8747 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8748 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8749 IsUpdateExprFound = XId == PossibleXId; 8750 if (IsUpdateExprFound) { 8751 V = BinOp->getLHS(); 8752 X = Checker.getX(); 8753 E = Checker.getExpr(); 8754 UE = Checker.getUpdateExpr(); 8755 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8756 IsPostfixUpdate = true; 8757 } 8758 } 8759 if (!IsUpdateExprFound) { 8760 IsUpdateExprFound = !Checker.checkStatement(First); 8761 BinOp = nullptr; 8762 if (IsUpdateExprFound) { 8763 BinOp = dyn_cast<BinaryOperator>(Second); 8764 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8765 } 8766 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8767 // { x++; v = x; } 8768 // { x--; v = x; } 8769 // { ++x; v = x; } 8770 // { --x; v = x; } 8771 // { x binop= expr; v = x; } 8772 // { x = x binop expr; v = x; } 8773 // { x = expr binop x; v = x; } 8774 // Check that the second expression has form v = x. 8775 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8776 llvm::FoldingSetNodeID XId, PossibleXId; 8777 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8778 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8779 IsUpdateExprFound = XId == PossibleXId; 8780 if (IsUpdateExprFound) { 8781 V = BinOp->getLHS(); 8782 X = Checker.getX(); 8783 E = Checker.getExpr(); 8784 UE = Checker.getUpdateExpr(); 8785 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8786 IsPostfixUpdate = false; 8787 } 8788 } 8789 } 8790 if (!IsUpdateExprFound) { 8791 // { v = x; x = expr; } 8792 auto *FirstExpr = dyn_cast<Expr>(First); 8793 auto *SecondExpr = dyn_cast<Expr>(Second); 8794 if (!FirstExpr || !SecondExpr || 8795 !(FirstExpr->isInstantiationDependent() || 8796 SecondExpr->isInstantiationDependent())) { 8797 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8798 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8799 ErrorFound = NotAnAssignmentOp; 8800 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8801 : First->getBeginLoc(); 8802 NoteRange = ErrorRange = FirstBinOp 8803 ? FirstBinOp->getSourceRange() 8804 : SourceRange(ErrorLoc, ErrorLoc); 8805 } else { 8806 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8807 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8808 ErrorFound = NotAnAssignmentOp; 8809 NoteLoc = ErrorLoc = SecondBinOp 8810 ? SecondBinOp->getOperatorLoc() 8811 : Second->getBeginLoc(); 8812 NoteRange = ErrorRange = 8813 SecondBinOp ? SecondBinOp->getSourceRange() 8814 : SourceRange(ErrorLoc, ErrorLoc); 8815 } else { 8816 Expr *PossibleXRHSInFirst = 8817 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8818 Expr *PossibleXLHSInSecond = 8819 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8820 llvm::FoldingSetNodeID X1Id, X2Id; 8821 PossibleXRHSInFirst->Profile(X1Id, Context, 8822 /*Canonical=*/true); 8823 PossibleXLHSInSecond->Profile(X2Id, Context, 8824 /*Canonical=*/true); 8825 IsUpdateExprFound = X1Id == X2Id; 8826 if (IsUpdateExprFound) { 8827 V = FirstBinOp->getLHS(); 8828 X = SecondBinOp->getLHS(); 8829 E = SecondBinOp->getRHS(); 8830 UE = nullptr; 8831 IsXLHSInRHSPart = false; 8832 IsPostfixUpdate = true; 8833 } else { 8834 ErrorFound = NotASpecificExpression; 8835 ErrorLoc = FirstBinOp->getExprLoc(); 8836 ErrorRange = FirstBinOp->getSourceRange(); 8837 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8838 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8839 } 8840 } 8841 } 8842 } 8843 } 8844 } else { 8845 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8846 NoteRange = ErrorRange = 8847 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8848 ErrorFound = NotTwoSubstatements; 8849 } 8850 } else { 8851 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8852 NoteRange = ErrorRange = 8853 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8854 ErrorFound = NotACompoundStatement; 8855 } 8856 if (ErrorFound != NoError) { 8857 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8858 << ErrorRange; 8859 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8860 return StmtError(); 8861 } 8862 if (CurContext->isDependentContext()) 8863 UE = V = E = X = nullptr; 8864 } 8865 } 8866 8867 setFunctionHasBranchProtectedScope(); 8868 8869 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8870 X, V, E, UE, IsXLHSInRHSPart, 8871 IsPostfixUpdate); 8872 } 8873 8874 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8875 Stmt *AStmt, 8876 SourceLocation StartLoc, 8877 SourceLocation EndLoc) { 8878 if (!AStmt) 8879 return StmtError(); 8880 8881 auto *CS = cast<CapturedStmt>(AStmt); 8882 // 1.2.2 OpenMP Language Terminology 8883 // Structured block - An executable statement with a single entry at the 8884 // top and a single exit at the bottom. 8885 // The point of exit cannot be a branch out of the structured block. 8886 // longjmp() and throw() must not violate the entry/exit criteria. 8887 CS->getCapturedDecl()->setNothrow(); 8888 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8889 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8890 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8891 // 1.2.2 OpenMP Language Terminology 8892 // Structured block - An executable statement with a single entry at the 8893 // top and a single exit at the bottom. 8894 // The point of exit cannot be a branch out of the structured block. 8895 // longjmp() and throw() must not violate the entry/exit criteria. 8896 CS->getCapturedDecl()->setNothrow(); 8897 } 8898 8899 // OpenMP [2.16, Nesting of Regions] 8900 // If specified, a teams construct must be contained within a target 8901 // construct. That target construct must contain no statements or directives 8902 // outside of the teams construct. 8903 if (DSAStack->hasInnerTeamsRegion()) { 8904 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8905 bool OMPTeamsFound = true; 8906 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8907 auto I = CS->body_begin(); 8908 while (I != CS->body_end()) { 8909 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8910 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8911 OMPTeamsFound) { 8912 8913 OMPTeamsFound = false; 8914 break; 8915 } 8916 ++I; 8917 } 8918 assert(I != CS->body_end() && "Not found statement"); 8919 S = *I; 8920 } else { 8921 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8922 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8923 } 8924 if (!OMPTeamsFound) { 8925 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8926 Diag(DSAStack->getInnerTeamsRegionLoc(), 8927 diag::note_omp_nested_teams_construct_here); 8928 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8929 << isa<OMPExecutableDirective>(S); 8930 return StmtError(); 8931 } 8932 } 8933 8934 setFunctionHasBranchProtectedScope(); 8935 8936 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8937 } 8938 8939 StmtResult 8940 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8941 Stmt *AStmt, SourceLocation StartLoc, 8942 SourceLocation EndLoc) { 8943 if (!AStmt) 8944 return StmtError(); 8945 8946 auto *CS = cast<CapturedStmt>(AStmt); 8947 // 1.2.2 OpenMP Language Terminology 8948 // Structured block - An executable statement with a single entry at the 8949 // top and a single exit at the bottom. 8950 // The point of exit cannot be a branch out of the structured block. 8951 // longjmp() and throw() must not violate the entry/exit criteria. 8952 CS->getCapturedDecl()->setNothrow(); 8953 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8954 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8955 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8956 // 1.2.2 OpenMP Language Terminology 8957 // Structured block - An executable statement with a single entry at the 8958 // top and a single exit at the bottom. 8959 // The point of exit cannot be a branch out of the structured block. 8960 // longjmp() and throw() must not violate the entry/exit criteria. 8961 CS->getCapturedDecl()->setNothrow(); 8962 } 8963 8964 setFunctionHasBranchProtectedScope(); 8965 8966 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8967 AStmt); 8968 } 8969 8970 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8971 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8972 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8973 if (!AStmt) 8974 return StmtError(); 8975 8976 auto *CS = cast<CapturedStmt>(AStmt); 8977 // 1.2.2 OpenMP Language Terminology 8978 // Structured block - An executable statement with a single entry at the 8979 // top and a single exit at the bottom. 8980 // The point of exit cannot be a branch out of the structured block. 8981 // longjmp() and throw() must not violate the entry/exit criteria. 8982 CS->getCapturedDecl()->setNothrow(); 8983 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8984 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8985 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8986 // 1.2.2 OpenMP Language Terminology 8987 // Structured block - An executable statement with a single entry at the 8988 // top and a single exit at the bottom. 8989 // The point of exit cannot be a branch out of the structured block. 8990 // longjmp() and throw() must not violate the entry/exit criteria. 8991 CS->getCapturedDecl()->setNothrow(); 8992 } 8993 8994 OMPLoopDirective::HelperExprs B; 8995 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8996 // define the nested loops number. 8997 unsigned NestedLoopCount = 8998 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8999 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9000 VarsWithImplicitDSA, B); 9001 if (NestedLoopCount == 0) 9002 return StmtError(); 9003 9004 assert((CurContext->isDependentContext() || B.builtAll()) && 9005 "omp target parallel for loop exprs were not built"); 9006 9007 if (!CurContext->isDependentContext()) { 9008 // Finalize the clauses that need pre-built expressions for CodeGen. 9009 for (OMPClause *C : Clauses) { 9010 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9011 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9012 B.NumIterations, *this, CurScope, 9013 DSAStack)) 9014 return StmtError(); 9015 } 9016 } 9017 9018 setFunctionHasBranchProtectedScope(); 9019 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9020 NestedLoopCount, Clauses, AStmt, 9021 B, DSAStack->isCancelRegion()); 9022 } 9023 9024 /// Check for existence of a map clause in the list of clauses. 9025 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9026 const OpenMPClauseKind K) { 9027 return llvm::any_of( 9028 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9029 } 9030 9031 template <typename... Params> 9032 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9033 const Params... ClauseTypes) { 9034 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9035 } 9036 9037 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9038 Stmt *AStmt, 9039 SourceLocation StartLoc, 9040 SourceLocation EndLoc) { 9041 if (!AStmt) 9042 return StmtError(); 9043 9044 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9045 9046 // OpenMP [2.10.1, Restrictions, p. 97] 9047 // At least one map clause must appear on the directive. 9048 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9049 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9050 << "'map' or 'use_device_ptr'" 9051 << getOpenMPDirectiveName(OMPD_target_data); 9052 return StmtError(); 9053 } 9054 9055 setFunctionHasBranchProtectedScope(); 9056 9057 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9058 AStmt); 9059 } 9060 9061 StmtResult 9062 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9063 SourceLocation StartLoc, 9064 SourceLocation EndLoc, Stmt *AStmt) { 9065 if (!AStmt) 9066 return StmtError(); 9067 9068 auto *CS = cast<CapturedStmt>(AStmt); 9069 // 1.2.2 OpenMP Language Terminology 9070 // Structured block - An executable statement with a single entry at the 9071 // top and a single exit at the bottom. 9072 // The point of exit cannot be a branch out of the structured block. 9073 // longjmp() and throw() must not violate the entry/exit criteria. 9074 CS->getCapturedDecl()->setNothrow(); 9075 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9076 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9077 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9078 // 1.2.2 OpenMP Language Terminology 9079 // Structured block - An executable statement with a single entry at the 9080 // top and a single exit at the bottom. 9081 // The point of exit cannot be a branch out of the structured block. 9082 // longjmp() and throw() must not violate the entry/exit criteria. 9083 CS->getCapturedDecl()->setNothrow(); 9084 } 9085 9086 // OpenMP [2.10.2, Restrictions, p. 99] 9087 // At least one map clause must appear on the directive. 9088 if (!hasClauses(Clauses, OMPC_map)) { 9089 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9090 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9091 return StmtError(); 9092 } 9093 9094 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9095 AStmt); 9096 } 9097 9098 StmtResult 9099 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9100 SourceLocation StartLoc, 9101 SourceLocation EndLoc, Stmt *AStmt) { 9102 if (!AStmt) 9103 return StmtError(); 9104 9105 auto *CS = cast<CapturedStmt>(AStmt); 9106 // 1.2.2 OpenMP Language Terminology 9107 // Structured block - An executable statement with a single entry at the 9108 // top and a single exit at the bottom. 9109 // The point of exit cannot be a branch out of the structured block. 9110 // longjmp() and throw() must not violate the entry/exit criteria. 9111 CS->getCapturedDecl()->setNothrow(); 9112 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9113 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9114 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9115 // 1.2.2 OpenMP Language Terminology 9116 // Structured block - An executable statement with a single entry at the 9117 // top and a single exit at the bottom. 9118 // The point of exit cannot be a branch out of the structured block. 9119 // longjmp() and throw() must not violate the entry/exit criteria. 9120 CS->getCapturedDecl()->setNothrow(); 9121 } 9122 9123 // OpenMP [2.10.3, Restrictions, p. 102] 9124 // At least one map clause must appear on the directive. 9125 if (!hasClauses(Clauses, OMPC_map)) { 9126 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9127 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9128 return StmtError(); 9129 } 9130 9131 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9132 AStmt); 9133 } 9134 9135 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9136 SourceLocation StartLoc, 9137 SourceLocation EndLoc, 9138 Stmt *AStmt) { 9139 if (!AStmt) 9140 return StmtError(); 9141 9142 auto *CS = cast<CapturedStmt>(AStmt); 9143 // 1.2.2 OpenMP Language Terminology 9144 // Structured block - An executable statement with a single entry at the 9145 // top and a single exit at the bottom. 9146 // The point of exit cannot be a branch out of the structured block. 9147 // longjmp() and throw() must not violate the entry/exit criteria. 9148 CS->getCapturedDecl()->setNothrow(); 9149 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9150 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9151 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9152 // 1.2.2 OpenMP Language Terminology 9153 // Structured block - An executable statement with a single entry at the 9154 // top and a single exit at the bottom. 9155 // The point of exit cannot be a branch out of the structured block. 9156 // longjmp() and throw() must not violate the entry/exit criteria. 9157 CS->getCapturedDecl()->setNothrow(); 9158 } 9159 9160 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9161 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9162 return StmtError(); 9163 } 9164 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9165 AStmt); 9166 } 9167 9168 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9169 Stmt *AStmt, SourceLocation StartLoc, 9170 SourceLocation EndLoc) { 9171 if (!AStmt) 9172 return StmtError(); 9173 9174 auto *CS = cast<CapturedStmt>(AStmt); 9175 // 1.2.2 OpenMP Language Terminology 9176 // Structured block - An executable statement with a single entry at the 9177 // top and a single exit at the bottom. 9178 // The point of exit cannot be a branch out of the structured block. 9179 // longjmp() and throw() must not violate the entry/exit criteria. 9180 CS->getCapturedDecl()->setNothrow(); 9181 9182 setFunctionHasBranchProtectedScope(); 9183 9184 DSAStack->setParentTeamsRegionLoc(StartLoc); 9185 9186 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9187 } 9188 9189 StmtResult 9190 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9191 SourceLocation EndLoc, 9192 OpenMPDirectiveKind CancelRegion) { 9193 if (DSAStack->isParentNowaitRegion()) { 9194 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9195 return StmtError(); 9196 } 9197 if (DSAStack->isParentOrderedRegion()) { 9198 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9199 return StmtError(); 9200 } 9201 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9202 CancelRegion); 9203 } 9204 9205 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9206 SourceLocation StartLoc, 9207 SourceLocation EndLoc, 9208 OpenMPDirectiveKind CancelRegion) { 9209 if (DSAStack->isParentNowaitRegion()) { 9210 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9211 return StmtError(); 9212 } 9213 if (DSAStack->isParentOrderedRegion()) { 9214 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9215 return StmtError(); 9216 } 9217 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9218 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9219 CancelRegion); 9220 } 9221 9222 static bool checkGrainsizeNumTasksClauses(Sema &S, 9223 ArrayRef<OMPClause *> Clauses) { 9224 const OMPClause *PrevClause = nullptr; 9225 bool ErrorFound = false; 9226 for (const OMPClause *C : Clauses) { 9227 if (C->getClauseKind() == OMPC_grainsize || 9228 C->getClauseKind() == OMPC_num_tasks) { 9229 if (!PrevClause) 9230 PrevClause = C; 9231 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9232 S.Diag(C->getBeginLoc(), 9233 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9234 << getOpenMPClauseName(C->getClauseKind()) 9235 << getOpenMPClauseName(PrevClause->getClauseKind()); 9236 S.Diag(PrevClause->getBeginLoc(), 9237 diag::note_omp_previous_grainsize_num_tasks) 9238 << getOpenMPClauseName(PrevClause->getClauseKind()); 9239 ErrorFound = true; 9240 } 9241 } 9242 } 9243 return ErrorFound; 9244 } 9245 9246 static bool checkReductionClauseWithNogroup(Sema &S, 9247 ArrayRef<OMPClause *> Clauses) { 9248 const OMPClause *ReductionClause = nullptr; 9249 const OMPClause *NogroupClause = nullptr; 9250 for (const OMPClause *C : Clauses) { 9251 if (C->getClauseKind() == OMPC_reduction) { 9252 ReductionClause = C; 9253 if (NogroupClause) 9254 break; 9255 continue; 9256 } 9257 if (C->getClauseKind() == OMPC_nogroup) { 9258 NogroupClause = C; 9259 if (ReductionClause) 9260 break; 9261 continue; 9262 } 9263 } 9264 if (ReductionClause && NogroupClause) { 9265 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9266 << SourceRange(NogroupClause->getBeginLoc(), 9267 NogroupClause->getEndLoc()); 9268 return true; 9269 } 9270 return false; 9271 } 9272 9273 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9274 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9275 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9276 if (!AStmt) 9277 return StmtError(); 9278 9279 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9280 OMPLoopDirective::HelperExprs B; 9281 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9282 // define the nested loops number. 9283 unsigned NestedLoopCount = 9284 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9285 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9286 VarsWithImplicitDSA, B); 9287 if (NestedLoopCount == 0) 9288 return StmtError(); 9289 9290 assert((CurContext->isDependentContext() || B.builtAll()) && 9291 "omp for loop exprs were not built"); 9292 9293 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9294 // The grainsize clause and num_tasks clause are mutually exclusive and may 9295 // not appear on the same taskloop directive. 9296 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9297 return StmtError(); 9298 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9299 // If a reduction clause is present on the taskloop directive, the nogroup 9300 // clause must not be specified. 9301 if (checkReductionClauseWithNogroup(*this, Clauses)) 9302 return StmtError(); 9303 9304 setFunctionHasBranchProtectedScope(); 9305 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9306 NestedLoopCount, Clauses, AStmt, B); 9307 } 9308 9309 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9310 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9311 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9312 if (!AStmt) 9313 return StmtError(); 9314 9315 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9316 OMPLoopDirective::HelperExprs B; 9317 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9318 // define the nested loops number. 9319 unsigned NestedLoopCount = 9320 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9321 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9322 VarsWithImplicitDSA, B); 9323 if (NestedLoopCount == 0) 9324 return StmtError(); 9325 9326 assert((CurContext->isDependentContext() || B.builtAll()) && 9327 "omp for loop exprs were not built"); 9328 9329 if (!CurContext->isDependentContext()) { 9330 // Finalize the clauses that need pre-built expressions for CodeGen. 9331 for (OMPClause *C : Clauses) { 9332 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9333 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9334 B.NumIterations, *this, CurScope, 9335 DSAStack)) 9336 return StmtError(); 9337 } 9338 } 9339 9340 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9341 // The grainsize clause and num_tasks clause are mutually exclusive and may 9342 // not appear on the same taskloop directive. 9343 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9344 return StmtError(); 9345 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9346 // If a reduction clause is present on the taskloop directive, the nogroup 9347 // clause must not be specified. 9348 if (checkReductionClauseWithNogroup(*this, Clauses)) 9349 return StmtError(); 9350 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9351 return StmtError(); 9352 9353 setFunctionHasBranchProtectedScope(); 9354 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9355 NestedLoopCount, Clauses, AStmt, B); 9356 } 9357 9358 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9359 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9360 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9361 if (!AStmt) 9362 return StmtError(); 9363 9364 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9365 OMPLoopDirective::HelperExprs B; 9366 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9367 // define the nested loops number. 9368 unsigned NestedLoopCount = 9369 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9370 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9371 VarsWithImplicitDSA, B); 9372 if (NestedLoopCount == 0) 9373 return StmtError(); 9374 9375 assert((CurContext->isDependentContext() || B.builtAll()) && 9376 "omp for loop exprs were not built"); 9377 9378 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9379 // The grainsize clause and num_tasks clause are mutually exclusive and may 9380 // not appear on the same taskloop directive. 9381 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9382 return StmtError(); 9383 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9384 // If a reduction clause is present on the taskloop directive, the nogroup 9385 // clause must not be specified. 9386 if (checkReductionClauseWithNogroup(*this, Clauses)) 9387 return StmtError(); 9388 9389 setFunctionHasBranchProtectedScope(); 9390 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9391 NestedLoopCount, Clauses, AStmt, B); 9392 } 9393 9394 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9395 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9396 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9397 if (!AStmt) 9398 return StmtError(); 9399 9400 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9401 OMPLoopDirective::HelperExprs B; 9402 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9403 // define the nested loops number. 9404 unsigned NestedLoopCount = 9405 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9406 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9407 VarsWithImplicitDSA, B); 9408 if (NestedLoopCount == 0) 9409 return StmtError(); 9410 9411 assert((CurContext->isDependentContext() || B.builtAll()) && 9412 "omp for loop exprs were not built"); 9413 9414 if (!CurContext->isDependentContext()) { 9415 // Finalize the clauses that need pre-built expressions for CodeGen. 9416 for (OMPClause *C : Clauses) { 9417 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9418 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9419 B.NumIterations, *this, CurScope, 9420 DSAStack)) 9421 return StmtError(); 9422 } 9423 } 9424 9425 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9426 // The grainsize clause and num_tasks clause are mutually exclusive and may 9427 // not appear on the same taskloop directive. 9428 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9429 return StmtError(); 9430 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9431 // If a reduction clause is present on the taskloop directive, the nogroup 9432 // clause must not be specified. 9433 if (checkReductionClauseWithNogroup(*this, Clauses)) 9434 return StmtError(); 9435 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9436 return StmtError(); 9437 9438 setFunctionHasBranchProtectedScope(); 9439 return OMPMasterTaskLoopSimdDirective::Create( 9440 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9441 } 9442 9443 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9444 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9445 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9446 if (!AStmt) 9447 return StmtError(); 9448 9449 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9450 auto *CS = cast<CapturedStmt>(AStmt); 9451 // 1.2.2 OpenMP Language Terminology 9452 // Structured block - An executable statement with a single entry at the 9453 // top and a single exit at the bottom. 9454 // The point of exit cannot be a branch out of the structured block. 9455 // longjmp() and throw() must not violate the entry/exit criteria. 9456 CS->getCapturedDecl()->setNothrow(); 9457 for (int ThisCaptureLevel = 9458 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9459 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9460 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9461 // 1.2.2 OpenMP Language Terminology 9462 // Structured block - An executable statement with a single entry at the 9463 // top and a single exit at the bottom. 9464 // The point of exit cannot be a branch out of the structured block. 9465 // longjmp() and throw() must not violate the entry/exit criteria. 9466 CS->getCapturedDecl()->setNothrow(); 9467 } 9468 9469 OMPLoopDirective::HelperExprs B; 9470 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9471 // define the nested loops number. 9472 unsigned NestedLoopCount = checkOpenMPLoop( 9473 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9474 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9475 VarsWithImplicitDSA, B); 9476 if (NestedLoopCount == 0) 9477 return StmtError(); 9478 9479 assert((CurContext->isDependentContext() || B.builtAll()) && 9480 "omp for loop exprs were not built"); 9481 9482 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9483 // The grainsize clause and num_tasks clause are mutually exclusive and may 9484 // not appear on the same taskloop directive. 9485 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9486 return StmtError(); 9487 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9488 // If a reduction clause is present on the taskloop directive, the nogroup 9489 // clause must not be specified. 9490 if (checkReductionClauseWithNogroup(*this, Clauses)) 9491 return StmtError(); 9492 9493 setFunctionHasBranchProtectedScope(); 9494 return OMPParallelMasterTaskLoopDirective::Create( 9495 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9496 } 9497 9498 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 9499 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9500 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9501 if (!AStmt) 9502 return StmtError(); 9503 9504 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9505 auto *CS = cast<CapturedStmt>(AStmt); 9506 // 1.2.2 OpenMP Language Terminology 9507 // Structured block - An executable statement with a single entry at the 9508 // top and a single exit at the bottom. 9509 // The point of exit cannot be a branch out of the structured block. 9510 // longjmp() and throw() must not violate the entry/exit criteria. 9511 CS->getCapturedDecl()->setNothrow(); 9512 for (int ThisCaptureLevel = 9513 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 9514 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9515 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9516 // 1.2.2 OpenMP Language Terminology 9517 // Structured block - An executable statement with a single entry at the 9518 // top and a single exit at the bottom. 9519 // The point of exit cannot be a branch out of the structured block. 9520 // longjmp() and throw() must not violate the entry/exit criteria. 9521 CS->getCapturedDecl()->setNothrow(); 9522 } 9523 9524 OMPLoopDirective::HelperExprs B; 9525 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9526 // define the nested loops number. 9527 unsigned NestedLoopCount = checkOpenMPLoop( 9528 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9529 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9530 VarsWithImplicitDSA, B); 9531 if (NestedLoopCount == 0) 9532 return StmtError(); 9533 9534 assert((CurContext->isDependentContext() || B.builtAll()) && 9535 "omp for loop exprs were not built"); 9536 9537 if (!CurContext->isDependentContext()) { 9538 // Finalize the clauses that need pre-built expressions for CodeGen. 9539 for (OMPClause *C : Clauses) { 9540 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9541 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9542 B.NumIterations, *this, CurScope, 9543 DSAStack)) 9544 return StmtError(); 9545 } 9546 } 9547 9548 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9549 // The grainsize clause and num_tasks clause are mutually exclusive and may 9550 // not appear on the same taskloop directive. 9551 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9552 return StmtError(); 9553 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9554 // If a reduction clause is present on the taskloop directive, the nogroup 9555 // clause must not be specified. 9556 if (checkReductionClauseWithNogroup(*this, Clauses)) 9557 return StmtError(); 9558 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9559 return StmtError(); 9560 9561 setFunctionHasBranchProtectedScope(); 9562 return OMPParallelMasterTaskLoopSimdDirective::Create( 9563 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9564 } 9565 9566 StmtResult Sema::ActOnOpenMPDistributeDirective( 9567 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9568 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9569 if (!AStmt) 9570 return StmtError(); 9571 9572 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9573 OMPLoopDirective::HelperExprs B; 9574 // In presence of clause 'collapse' with number of loops, it will 9575 // define the nested loops number. 9576 unsigned NestedLoopCount = 9577 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9578 nullptr /*ordered not a clause on distribute*/, AStmt, 9579 *this, *DSAStack, VarsWithImplicitDSA, B); 9580 if (NestedLoopCount == 0) 9581 return StmtError(); 9582 9583 assert((CurContext->isDependentContext() || B.builtAll()) && 9584 "omp for loop exprs were not built"); 9585 9586 setFunctionHasBranchProtectedScope(); 9587 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9588 NestedLoopCount, Clauses, AStmt, B); 9589 } 9590 9591 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9592 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9593 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9594 if (!AStmt) 9595 return StmtError(); 9596 9597 auto *CS = cast<CapturedStmt>(AStmt); 9598 // 1.2.2 OpenMP Language Terminology 9599 // Structured block - An executable statement with a single entry at the 9600 // top and a single exit at the bottom. 9601 // The point of exit cannot be a branch out of the structured block. 9602 // longjmp() and throw() must not violate the entry/exit criteria. 9603 CS->getCapturedDecl()->setNothrow(); 9604 for (int ThisCaptureLevel = 9605 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9606 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9607 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9608 // 1.2.2 OpenMP Language Terminology 9609 // Structured block - An executable statement with a single entry at the 9610 // top and a single exit at the bottom. 9611 // The point of exit cannot be a branch out of the structured block. 9612 // longjmp() and throw() must not violate the entry/exit criteria. 9613 CS->getCapturedDecl()->setNothrow(); 9614 } 9615 9616 OMPLoopDirective::HelperExprs B; 9617 // In presence of clause 'collapse' with number of loops, it will 9618 // define the nested loops number. 9619 unsigned NestedLoopCount = checkOpenMPLoop( 9620 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9621 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9622 VarsWithImplicitDSA, B); 9623 if (NestedLoopCount == 0) 9624 return StmtError(); 9625 9626 assert((CurContext->isDependentContext() || B.builtAll()) && 9627 "omp for loop exprs were not built"); 9628 9629 setFunctionHasBranchProtectedScope(); 9630 return OMPDistributeParallelForDirective::Create( 9631 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9632 DSAStack->isCancelRegion()); 9633 } 9634 9635 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9636 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9637 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9638 if (!AStmt) 9639 return StmtError(); 9640 9641 auto *CS = cast<CapturedStmt>(AStmt); 9642 // 1.2.2 OpenMP Language Terminology 9643 // Structured block - An executable statement with a single entry at the 9644 // top and a single exit at the bottom. 9645 // The point of exit cannot be a branch out of the structured block. 9646 // longjmp() and throw() must not violate the entry/exit criteria. 9647 CS->getCapturedDecl()->setNothrow(); 9648 for (int ThisCaptureLevel = 9649 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9650 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9651 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9652 // 1.2.2 OpenMP Language Terminology 9653 // Structured block - An executable statement with a single entry at the 9654 // top and a single exit at the bottom. 9655 // The point of exit cannot be a branch out of the structured block. 9656 // longjmp() and throw() must not violate the entry/exit criteria. 9657 CS->getCapturedDecl()->setNothrow(); 9658 } 9659 9660 OMPLoopDirective::HelperExprs B; 9661 // In presence of clause 'collapse' with number of loops, it will 9662 // define the nested loops number. 9663 unsigned NestedLoopCount = checkOpenMPLoop( 9664 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9665 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9666 VarsWithImplicitDSA, B); 9667 if (NestedLoopCount == 0) 9668 return StmtError(); 9669 9670 assert((CurContext->isDependentContext() || B.builtAll()) && 9671 "omp for loop exprs were not built"); 9672 9673 if (!CurContext->isDependentContext()) { 9674 // Finalize the clauses that need pre-built expressions for CodeGen. 9675 for (OMPClause *C : Clauses) { 9676 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9677 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9678 B.NumIterations, *this, CurScope, 9679 DSAStack)) 9680 return StmtError(); 9681 } 9682 } 9683 9684 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9685 return StmtError(); 9686 9687 setFunctionHasBranchProtectedScope(); 9688 return OMPDistributeParallelForSimdDirective::Create( 9689 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9690 } 9691 9692 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9693 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9694 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9695 if (!AStmt) 9696 return StmtError(); 9697 9698 auto *CS = cast<CapturedStmt>(AStmt); 9699 // 1.2.2 OpenMP Language Terminology 9700 // Structured block - An executable statement with a single entry at the 9701 // top and a single exit at the bottom. 9702 // The point of exit cannot be a branch out of the structured block. 9703 // longjmp() and throw() must not violate the entry/exit criteria. 9704 CS->getCapturedDecl()->setNothrow(); 9705 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9706 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9707 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9708 // 1.2.2 OpenMP Language Terminology 9709 // Structured block - An executable statement with a single entry at the 9710 // top and a single exit at the bottom. 9711 // The point of exit cannot be a branch out of the structured block. 9712 // longjmp() and throw() must not violate the entry/exit criteria. 9713 CS->getCapturedDecl()->setNothrow(); 9714 } 9715 9716 OMPLoopDirective::HelperExprs B; 9717 // In presence of clause 'collapse' with number of loops, it will 9718 // define the nested loops number. 9719 unsigned NestedLoopCount = 9720 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9721 nullptr /*ordered not a clause on distribute*/, CS, *this, 9722 *DSAStack, VarsWithImplicitDSA, B); 9723 if (NestedLoopCount == 0) 9724 return StmtError(); 9725 9726 assert((CurContext->isDependentContext() || B.builtAll()) && 9727 "omp for loop exprs were not built"); 9728 9729 if (!CurContext->isDependentContext()) { 9730 // Finalize the clauses that need pre-built expressions for CodeGen. 9731 for (OMPClause *C : Clauses) { 9732 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9733 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9734 B.NumIterations, *this, CurScope, 9735 DSAStack)) 9736 return StmtError(); 9737 } 9738 } 9739 9740 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9741 return StmtError(); 9742 9743 setFunctionHasBranchProtectedScope(); 9744 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9745 NestedLoopCount, Clauses, AStmt, B); 9746 } 9747 9748 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9749 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9750 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9751 if (!AStmt) 9752 return StmtError(); 9753 9754 auto *CS = cast<CapturedStmt>(AStmt); 9755 // 1.2.2 OpenMP Language Terminology 9756 // Structured block - An executable statement with a single entry at the 9757 // top and a single exit at the bottom. 9758 // The point of exit cannot be a branch out of the structured block. 9759 // longjmp() and throw() must not violate the entry/exit criteria. 9760 CS->getCapturedDecl()->setNothrow(); 9761 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9762 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9763 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9764 // 1.2.2 OpenMP Language Terminology 9765 // Structured block - An executable statement with a single entry at the 9766 // top and a single exit at the bottom. 9767 // The point of exit cannot be a branch out of the structured block. 9768 // longjmp() and throw() must not violate the entry/exit criteria. 9769 CS->getCapturedDecl()->setNothrow(); 9770 } 9771 9772 OMPLoopDirective::HelperExprs B; 9773 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9774 // define the nested loops number. 9775 unsigned NestedLoopCount = checkOpenMPLoop( 9776 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9777 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9778 VarsWithImplicitDSA, B); 9779 if (NestedLoopCount == 0) 9780 return StmtError(); 9781 9782 assert((CurContext->isDependentContext() || B.builtAll()) && 9783 "omp target parallel for simd loop exprs were not built"); 9784 9785 if (!CurContext->isDependentContext()) { 9786 // Finalize the clauses that need pre-built expressions for CodeGen. 9787 for (OMPClause *C : Clauses) { 9788 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9789 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9790 B.NumIterations, *this, CurScope, 9791 DSAStack)) 9792 return StmtError(); 9793 } 9794 } 9795 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9796 return StmtError(); 9797 9798 setFunctionHasBranchProtectedScope(); 9799 return OMPTargetParallelForSimdDirective::Create( 9800 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9801 } 9802 9803 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9804 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9805 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9806 if (!AStmt) 9807 return StmtError(); 9808 9809 auto *CS = cast<CapturedStmt>(AStmt); 9810 // 1.2.2 OpenMP Language Terminology 9811 // Structured block - An executable statement with a single entry at the 9812 // top and a single exit at the bottom. 9813 // The point of exit cannot be a branch out of the structured block. 9814 // longjmp() and throw() must not violate the entry/exit criteria. 9815 CS->getCapturedDecl()->setNothrow(); 9816 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9817 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9818 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9819 // 1.2.2 OpenMP Language Terminology 9820 // Structured block - An executable statement with a single entry at the 9821 // top and a single exit at the bottom. 9822 // The point of exit cannot be a branch out of the structured block. 9823 // longjmp() and throw() must not violate the entry/exit criteria. 9824 CS->getCapturedDecl()->setNothrow(); 9825 } 9826 9827 OMPLoopDirective::HelperExprs B; 9828 // In presence of clause 'collapse' with number of loops, it will define the 9829 // nested loops number. 9830 unsigned NestedLoopCount = 9831 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9832 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9833 VarsWithImplicitDSA, B); 9834 if (NestedLoopCount == 0) 9835 return StmtError(); 9836 9837 assert((CurContext->isDependentContext() || B.builtAll()) && 9838 "omp target simd loop exprs were not built"); 9839 9840 if (!CurContext->isDependentContext()) { 9841 // Finalize the clauses that need pre-built expressions for CodeGen. 9842 for (OMPClause *C : Clauses) { 9843 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9844 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9845 B.NumIterations, *this, CurScope, 9846 DSAStack)) 9847 return StmtError(); 9848 } 9849 } 9850 9851 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9852 return StmtError(); 9853 9854 setFunctionHasBranchProtectedScope(); 9855 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9856 NestedLoopCount, Clauses, AStmt, B); 9857 } 9858 9859 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9860 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9861 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9862 if (!AStmt) 9863 return StmtError(); 9864 9865 auto *CS = cast<CapturedStmt>(AStmt); 9866 // 1.2.2 OpenMP Language Terminology 9867 // Structured block - An executable statement with a single entry at the 9868 // top and a single exit at the bottom. 9869 // The point of exit cannot be a branch out of the structured block. 9870 // longjmp() and throw() must not violate the entry/exit criteria. 9871 CS->getCapturedDecl()->setNothrow(); 9872 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9873 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9874 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9875 // 1.2.2 OpenMP Language Terminology 9876 // Structured block - An executable statement with a single entry at the 9877 // top and a single exit at the bottom. 9878 // The point of exit cannot be a branch out of the structured block. 9879 // longjmp() and throw() must not violate the entry/exit criteria. 9880 CS->getCapturedDecl()->setNothrow(); 9881 } 9882 9883 OMPLoopDirective::HelperExprs B; 9884 // In presence of clause 'collapse' with number of loops, it will 9885 // define the nested loops number. 9886 unsigned NestedLoopCount = 9887 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9888 nullptr /*ordered not a clause on distribute*/, CS, *this, 9889 *DSAStack, VarsWithImplicitDSA, B); 9890 if (NestedLoopCount == 0) 9891 return StmtError(); 9892 9893 assert((CurContext->isDependentContext() || B.builtAll()) && 9894 "omp teams distribute loop exprs were not built"); 9895 9896 setFunctionHasBranchProtectedScope(); 9897 9898 DSAStack->setParentTeamsRegionLoc(StartLoc); 9899 9900 return OMPTeamsDistributeDirective::Create( 9901 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9902 } 9903 9904 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9905 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9906 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9907 if (!AStmt) 9908 return StmtError(); 9909 9910 auto *CS = cast<CapturedStmt>(AStmt); 9911 // 1.2.2 OpenMP Language Terminology 9912 // Structured block - An executable statement with a single entry at the 9913 // top and a single exit at the bottom. 9914 // The point of exit cannot be a branch out of the structured block. 9915 // longjmp() and throw() must not violate the entry/exit criteria. 9916 CS->getCapturedDecl()->setNothrow(); 9917 for (int ThisCaptureLevel = 9918 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9919 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9920 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9921 // 1.2.2 OpenMP Language Terminology 9922 // Structured block - An executable statement with a single entry at the 9923 // top and a single exit at the bottom. 9924 // The point of exit cannot be a branch out of the structured block. 9925 // longjmp() and throw() must not violate the entry/exit criteria. 9926 CS->getCapturedDecl()->setNothrow(); 9927 } 9928 9929 9930 OMPLoopDirective::HelperExprs B; 9931 // In presence of clause 'collapse' with number of loops, it will 9932 // define the nested loops number. 9933 unsigned NestedLoopCount = checkOpenMPLoop( 9934 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9935 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9936 VarsWithImplicitDSA, B); 9937 9938 if (NestedLoopCount == 0) 9939 return StmtError(); 9940 9941 assert((CurContext->isDependentContext() || B.builtAll()) && 9942 "omp teams distribute simd loop exprs were not built"); 9943 9944 if (!CurContext->isDependentContext()) { 9945 // Finalize the clauses that need pre-built expressions for CodeGen. 9946 for (OMPClause *C : Clauses) { 9947 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9948 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9949 B.NumIterations, *this, CurScope, 9950 DSAStack)) 9951 return StmtError(); 9952 } 9953 } 9954 9955 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9956 return StmtError(); 9957 9958 setFunctionHasBranchProtectedScope(); 9959 9960 DSAStack->setParentTeamsRegionLoc(StartLoc); 9961 9962 return OMPTeamsDistributeSimdDirective::Create( 9963 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9964 } 9965 9966 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9967 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9968 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9969 if (!AStmt) 9970 return StmtError(); 9971 9972 auto *CS = cast<CapturedStmt>(AStmt); 9973 // 1.2.2 OpenMP Language Terminology 9974 // Structured block - An executable statement with a single entry at the 9975 // top and a single exit at the bottom. 9976 // The point of exit cannot be a branch out of the structured block. 9977 // longjmp() and throw() must not violate the entry/exit criteria. 9978 CS->getCapturedDecl()->setNothrow(); 9979 9980 for (int ThisCaptureLevel = 9981 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9982 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9983 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9984 // 1.2.2 OpenMP Language Terminology 9985 // Structured block - An executable statement with a single entry at the 9986 // top and a single exit at the bottom. 9987 // The point of exit cannot be a branch out of the structured block. 9988 // longjmp() and throw() must not violate the entry/exit criteria. 9989 CS->getCapturedDecl()->setNothrow(); 9990 } 9991 9992 OMPLoopDirective::HelperExprs B; 9993 // In presence of clause 'collapse' with number of loops, it will 9994 // define the nested loops number. 9995 unsigned NestedLoopCount = checkOpenMPLoop( 9996 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9997 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9998 VarsWithImplicitDSA, B); 9999 10000 if (NestedLoopCount == 0) 10001 return StmtError(); 10002 10003 assert((CurContext->isDependentContext() || B.builtAll()) && 10004 "omp for loop exprs were not built"); 10005 10006 if (!CurContext->isDependentContext()) { 10007 // Finalize the clauses that need pre-built expressions for CodeGen. 10008 for (OMPClause *C : Clauses) { 10009 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10010 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10011 B.NumIterations, *this, CurScope, 10012 DSAStack)) 10013 return StmtError(); 10014 } 10015 } 10016 10017 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10018 return StmtError(); 10019 10020 setFunctionHasBranchProtectedScope(); 10021 10022 DSAStack->setParentTeamsRegionLoc(StartLoc); 10023 10024 return OMPTeamsDistributeParallelForSimdDirective::Create( 10025 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10026 } 10027 10028 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10029 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10030 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10031 if (!AStmt) 10032 return StmtError(); 10033 10034 auto *CS = cast<CapturedStmt>(AStmt); 10035 // 1.2.2 OpenMP Language Terminology 10036 // Structured block - An executable statement with a single entry at the 10037 // top and a single exit at the bottom. 10038 // The point of exit cannot be a branch out of the structured block. 10039 // longjmp() and throw() must not violate the entry/exit criteria. 10040 CS->getCapturedDecl()->setNothrow(); 10041 10042 for (int ThisCaptureLevel = 10043 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10044 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10045 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10046 // 1.2.2 OpenMP Language Terminology 10047 // Structured block - An executable statement with a single entry at the 10048 // top and a single exit at the bottom. 10049 // The point of exit cannot be a branch out of the structured block. 10050 // longjmp() and throw() must not violate the entry/exit criteria. 10051 CS->getCapturedDecl()->setNothrow(); 10052 } 10053 10054 OMPLoopDirective::HelperExprs B; 10055 // In presence of clause 'collapse' with number of loops, it will 10056 // define the nested loops number. 10057 unsigned NestedLoopCount = checkOpenMPLoop( 10058 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10059 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10060 VarsWithImplicitDSA, B); 10061 10062 if (NestedLoopCount == 0) 10063 return StmtError(); 10064 10065 assert((CurContext->isDependentContext() || B.builtAll()) && 10066 "omp for loop exprs were not built"); 10067 10068 setFunctionHasBranchProtectedScope(); 10069 10070 DSAStack->setParentTeamsRegionLoc(StartLoc); 10071 10072 return OMPTeamsDistributeParallelForDirective::Create( 10073 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10074 DSAStack->isCancelRegion()); 10075 } 10076 10077 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10078 Stmt *AStmt, 10079 SourceLocation StartLoc, 10080 SourceLocation EndLoc) { 10081 if (!AStmt) 10082 return StmtError(); 10083 10084 auto *CS = cast<CapturedStmt>(AStmt); 10085 // 1.2.2 OpenMP Language Terminology 10086 // Structured block - An executable statement with a single entry at the 10087 // top and a single exit at the bottom. 10088 // The point of exit cannot be a branch out of the structured block. 10089 // longjmp() and throw() must not violate the entry/exit criteria. 10090 CS->getCapturedDecl()->setNothrow(); 10091 10092 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10093 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10094 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10095 // 1.2.2 OpenMP Language Terminology 10096 // Structured block - An executable statement with a single entry at the 10097 // top and a single exit at the bottom. 10098 // The point of exit cannot be a branch out of the structured block. 10099 // longjmp() and throw() must not violate the entry/exit criteria. 10100 CS->getCapturedDecl()->setNothrow(); 10101 } 10102 setFunctionHasBranchProtectedScope(); 10103 10104 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10105 AStmt); 10106 } 10107 10108 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10109 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10110 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10111 if (!AStmt) 10112 return StmtError(); 10113 10114 auto *CS = cast<CapturedStmt>(AStmt); 10115 // 1.2.2 OpenMP Language Terminology 10116 // Structured block - An executable statement with a single entry at the 10117 // top and a single exit at the bottom. 10118 // The point of exit cannot be a branch out of the structured block. 10119 // longjmp() and throw() must not violate the entry/exit criteria. 10120 CS->getCapturedDecl()->setNothrow(); 10121 for (int ThisCaptureLevel = 10122 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10123 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10124 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10125 // 1.2.2 OpenMP Language Terminology 10126 // Structured block - An executable statement with a single entry at the 10127 // top and a single exit at the bottom. 10128 // The point of exit cannot be a branch out of the structured block. 10129 // longjmp() and throw() must not violate the entry/exit criteria. 10130 CS->getCapturedDecl()->setNothrow(); 10131 } 10132 10133 OMPLoopDirective::HelperExprs B; 10134 // In presence of clause 'collapse' with number of loops, it will 10135 // define the nested loops number. 10136 unsigned NestedLoopCount = checkOpenMPLoop( 10137 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10138 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10139 VarsWithImplicitDSA, B); 10140 if (NestedLoopCount == 0) 10141 return StmtError(); 10142 10143 assert((CurContext->isDependentContext() || B.builtAll()) && 10144 "omp target teams distribute loop exprs were not built"); 10145 10146 setFunctionHasBranchProtectedScope(); 10147 return OMPTargetTeamsDistributeDirective::Create( 10148 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10149 } 10150 10151 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10152 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10153 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10154 if (!AStmt) 10155 return StmtError(); 10156 10157 auto *CS = cast<CapturedStmt>(AStmt); 10158 // 1.2.2 OpenMP Language Terminology 10159 // Structured block - An executable statement with a single entry at the 10160 // top and a single exit at the bottom. 10161 // The point of exit cannot be a branch out of the structured block. 10162 // longjmp() and throw() must not violate the entry/exit criteria. 10163 CS->getCapturedDecl()->setNothrow(); 10164 for (int ThisCaptureLevel = 10165 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10166 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10167 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10168 // 1.2.2 OpenMP Language Terminology 10169 // Structured block - An executable statement with a single entry at the 10170 // top and a single exit at the bottom. 10171 // The point of exit cannot be a branch out of the structured block. 10172 // longjmp() and throw() must not violate the entry/exit criteria. 10173 CS->getCapturedDecl()->setNothrow(); 10174 } 10175 10176 OMPLoopDirective::HelperExprs B; 10177 // In presence of clause 'collapse' with number of loops, it will 10178 // define the nested loops number. 10179 unsigned NestedLoopCount = checkOpenMPLoop( 10180 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10181 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10182 VarsWithImplicitDSA, B); 10183 if (NestedLoopCount == 0) 10184 return StmtError(); 10185 10186 assert((CurContext->isDependentContext() || B.builtAll()) && 10187 "omp target teams distribute parallel for loop exprs were not built"); 10188 10189 if (!CurContext->isDependentContext()) { 10190 // Finalize the clauses that need pre-built expressions for CodeGen. 10191 for (OMPClause *C : Clauses) { 10192 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10193 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10194 B.NumIterations, *this, CurScope, 10195 DSAStack)) 10196 return StmtError(); 10197 } 10198 } 10199 10200 setFunctionHasBranchProtectedScope(); 10201 return OMPTargetTeamsDistributeParallelForDirective::Create( 10202 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10203 DSAStack->isCancelRegion()); 10204 } 10205 10206 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10207 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10208 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10209 if (!AStmt) 10210 return StmtError(); 10211 10212 auto *CS = cast<CapturedStmt>(AStmt); 10213 // 1.2.2 OpenMP Language Terminology 10214 // Structured block - An executable statement with a single entry at the 10215 // top and a single exit at the bottom. 10216 // The point of exit cannot be a branch out of the structured block. 10217 // longjmp() and throw() must not violate the entry/exit criteria. 10218 CS->getCapturedDecl()->setNothrow(); 10219 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10220 OMPD_target_teams_distribute_parallel_for_simd); 10221 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10222 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10223 // 1.2.2 OpenMP Language Terminology 10224 // Structured block - An executable statement with a single entry at the 10225 // top and a single exit at the bottom. 10226 // The point of exit cannot be a branch out of the structured block. 10227 // longjmp() and throw() must not violate the entry/exit criteria. 10228 CS->getCapturedDecl()->setNothrow(); 10229 } 10230 10231 OMPLoopDirective::HelperExprs B; 10232 // In presence of clause 'collapse' with number of loops, it will 10233 // define the nested loops number. 10234 unsigned NestedLoopCount = 10235 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10236 getCollapseNumberExpr(Clauses), 10237 nullptr /*ordered not a clause on distribute*/, CS, *this, 10238 *DSAStack, VarsWithImplicitDSA, B); 10239 if (NestedLoopCount == 0) 10240 return StmtError(); 10241 10242 assert((CurContext->isDependentContext() || B.builtAll()) && 10243 "omp target teams distribute parallel for simd loop exprs were not " 10244 "built"); 10245 10246 if (!CurContext->isDependentContext()) { 10247 // Finalize the clauses that need pre-built expressions for CodeGen. 10248 for (OMPClause *C : Clauses) { 10249 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10250 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10251 B.NumIterations, *this, CurScope, 10252 DSAStack)) 10253 return StmtError(); 10254 } 10255 } 10256 10257 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10258 return StmtError(); 10259 10260 setFunctionHasBranchProtectedScope(); 10261 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10262 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10263 } 10264 10265 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10266 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10267 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10268 if (!AStmt) 10269 return StmtError(); 10270 10271 auto *CS = cast<CapturedStmt>(AStmt); 10272 // 1.2.2 OpenMP Language Terminology 10273 // Structured block - An executable statement with a single entry at the 10274 // top and a single exit at the bottom. 10275 // The point of exit cannot be a branch out of the structured block. 10276 // longjmp() and throw() must not violate the entry/exit criteria. 10277 CS->getCapturedDecl()->setNothrow(); 10278 for (int ThisCaptureLevel = 10279 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10280 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10281 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10282 // 1.2.2 OpenMP Language Terminology 10283 // Structured block - An executable statement with a single entry at the 10284 // top and a single exit at the bottom. 10285 // The point of exit cannot be a branch out of the structured block. 10286 // longjmp() and throw() must not violate the entry/exit criteria. 10287 CS->getCapturedDecl()->setNothrow(); 10288 } 10289 10290 OMPLoopDirective::HelperExprs B; 10291 // In presence of clause 'collapse' with number of loops, it will 10292 // define the nested loops number. 10293 unsigned NestedLoopCount = checkOpenMPLoop( 10294 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10295 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10296 VarsWithImplicitDSA, B); 10297 if (NestedLoopCount == 0) 10298 return StmtError(); 10299 10300 assert((CurContext->isDependentContext() || B.builtAll()) && 10301 "omp target teams distribute simd loop exprs were not built"); 10302 10303 if (!CurContext->isDependentContext()) { 10304 // Finalize the clauses that need pre-built expressions for CodeGen. 10305 for (OMPClause *C : Clauses) { 10306 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10307 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10308 B.NumIterations, *this, CurScope, 10309 DSAStack)) 10310 return StmtError(); 10311 } 10312 } 10313 10314 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10315 return StmtError(); 10316 10317 setFunctionHasBranchProtectedScope(); 10318 return OMPTargetTeamsDistributeSimdDirective::Create( 10319 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10320 } 10321 10322 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10323 SourceLocation StartLoc, 10324 SourceLocation LParenLoc, 10325 SourceLocation EndLoc) { 10326 OMPClause *Res = nullptr; 10327 switch (Kind) { 10328 case OMPC_final: 10329 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10330 break; 10331 case OMPC_num_threads: 10332 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10333 break; 10334 case OMPC_safelen: 10335 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10336 break; 10337 case OMPC_simdlen: 10338 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10339 break; 10340 case OMPC_allocator: 10341 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10342 break; 10343 case OMPC_collapse: 10344 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10345 break; 10346 case OMPC_ordered: 10347 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10348 break; 10349 case OMPC_device: 10350 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10351 break; 10352 case OMPC_num_teams: 10353 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10354 break; 10355 case OMPC_thread_limit: 10356 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10357 break; 10358 case OMPC_priority: 10359 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10360 break; 10361 case OMPC_grainsize: 10362 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10363 break; 10364 case OMPC_num_tasks: 10365 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10366 break; 10367 case OMPC_hint: 10368 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10369 break; 10370 case OMPC_if: 10371 case OMPC_default: 10372 case OMPC_proc_bind: 10373 case OMPC_schedule: 10374 case OMPC_private: 10375 case OMPC_firstprivate: 10376 case OMPC_lastprivate: 10377 case OMPC_shared: 10378 case OMPC_reduction: 10379 case OMPC_task_reduction: 10380 case OMPC_in_reduction: 10381 case OMPC_linear: 10382 case OMPC_aligned: 10383 case OMPC_copyin: 10384 case OMPC_copyprivate: 10385 case OMPC_nowait: 10386 case OMPC_untied: 10387 case OMPC_mergeable: 10388 case OMPC_threadprivate: 10389 case OMPC_allocate: 10390 case OMPC_flush: 10391 case OMPC_read: 10392 case OMPC_write: 10393 case OMPC_update: 10394 case OMPC_capture: 10395 case OMPC_seq_cst: 10396 case OMPC_depend: 10397 case OMPC_threads: 10398 case OMPC_simd: 10399 case OMPC_map: 10400 case OMPC_nogroup: 10401 case OMPC_dist_schedule: 10402 case OMPC_defaultmap: 10403 case OMPC_unknown: 10404 case OMPC_uniform: 10405 case OMPC_to: 10406 case OMPC_from: 10407 case OMPC_use_device_ptr: 10408 case OMPC_is_device_ptr: 10409 case OMPC_unified_address: 10410 case OMPC_unified_shared_memory: 10411 case OMPC_reverse_offload: 10412 case OMPC_dynamic_allocators: 10413 case OMPC_atomic_default_mem_order: 10414 case OMPC_device_type: 10415 case OMPC_match: 10416 llvm_unreachable("Clause is not allowed."); 10417 } 10418 return Res; 10419 } 10420 10421 // An OpenMP directive such as 'target parallel' has two captured regions: 10422 // for the 'target' and 'parallel' respectively. This function returns 10423 // the region in which to capture expressions associated with a clause. 10424 // A return value of OMPD_unknown signifies that the expression should not 10425 // be captured. 10426 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10427 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10428 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10429 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10430 switch (CKind) { 10431 case OMPC_if: 10432 switch (DKind) { 10433 case OMPD_target_parallel: 10434 case OMPD_target_parallel_for: 10435 case OMPD_target_parallel_for_simd: 10436 // If this clause applies to the nested 'parallel' region, capture within 10437 // the 'target' region, otherwise do not capture. 10438 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10439 CaptureRegion = OMPD_target; 10440 break; 10441 case OMPD_target_teams_distribute_parallel_for: 10442 case OMPD_target_teams_distribute_parallel_for_simd: 10443 // If this clause applies to the nested 'parallel' region, capture within 10444 // the 'teams' region, otherwise do not capture. 10445 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10446 CaptureRegion = OMPD_teams; 10447 break; 10448 case OMPD_teams_distribute_parallel_for: 10449 case OMPD_teams_distribute_parallel_for_simd: 10450 CaptureRegion = OMPD_teams; 10451 break; 10452 case OMPD_target_update: 10453 case OMPD_target_enter_data: 10454 case OMPD_target_exit_data: 10455 CaptureRegion = OMPD_task; 10456 break; 10457 case OMPD_parallel_master_taskloop: 10458 case OMPD_parallel_master_taskloop_simd: 10459 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10460 CaptureRegion = OMPD_parallel; 10461 break; 10462 case OMPD_cancel: 10463 case OMPD_parallel: 10464 case OMPD_parallel_sections: 10465 case OMPD_parallel_for: 10466 case OMPD_parallel_for_simd: 10467 case OMPD_target: 10468 case OMPD_target_simd: 10469 case OMPD_target_teams: 10470 case OMPD_target_teams_distribute: 10471 case OMPD_target_teams_distribute_simd: 10472 case OMPD_distribute_parallel_for: 10473 case OMPD_distribute_parallel_for_simd: 10474 case OMPD_task: 10475 case OMPD_taskloop: 10476 case OMPD_taskloop_simd: 10477 case OMPD_master_taskloop: 10478 case OMPD_master_taskloop_simd: 10479 case OMPD_target_data: 10480 // Do not capture if-clause expressions. 10481 break; 10482 case OMPD_threadprivate: 10483 case OMPD_allocate: 10484 case OMPD_taskyield: 10485 case OMPD_barrier: 10486 case OMPD_taskwait: 10487 case OMPD_cancellation_point: 10488 case OMPD_flush: 10489 case OMPD_declare_reduction: 10490 case OMPD_declare_mapper: 10491 case OMPD_declare_simd: 10492 case OMPD_declare_variant: 10493 case OMPD_declare_target: 10494 case OMPD_end_declare_target: 10495 case OMPD_teams: 10496 case OMPD_simd: 10497 case OMPD_for: 10498 case OMPD_for_simd: 10499 case OMPD_sections: 10500 case OMPD_section: 10501 case OMPD_single: 10502 case OMPD_master: 10503 case OMPD_critical: 10504 case OMPD_taskgroup: 10505 case OMPD_distribute: 10506 case OMPD_ordered: 10507 case OMPD_atomic: 10508 case OMPD_distribute_simd: 10509 case OMPD_teams_distribute: 10510 case OMPD_teams_distribute_simd: 10511 case OMPD_requires: 10512 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10513 case OMPD_unknown: 10514 llvm_unreachable("Unknown OpenMP directive"); 10515 } 10516 break; 10517 case OMPC_num_threads: 10518 switch (DKind) { 10519 case OMPD_target_parallel: 10520 case OMPD_target_parallel_for: 10521 case OMPD_target_parallel_for_simd: 10522 CaptureRegion = OMPD_target; 10523 break; 10524 case OMPD_teams_distribute_parallel_for: 10525 case OMPD_teams_distribute_parallel_for_simd: 10526 case OMPD_target_teams_distribute_parallel_for: 10527 case OMPD_target_teams_distribute_parallel_for_simd: 10528 CaptureRegion = OMPD_teams; 10529 break; 10530 case OMPD_parallel: 10531 case OMPD_parallel_sections: 10532 case OMPD_parallel_for: 10533 case OMPD_parallel_for_simd: 10534 case OMPD_distribute_parallel_for: 10535 case OMPD_distribute_parallel_for_simd: 10536 case OMPD_parallel_master_taskloop: 10537 case OMPD_parallel_master_taskloop_simd: 10538 // Do not capture num_threads-clause expressions. 10539 break; 10540 case OMPD_target_data: 10541 case OMPD_target_enter_data: 10542 case OMPD_target_exit_data: 10543 case OMPD_target_update: 10544 case OMPD_target: 10545 case OMPD_target_simd: 10546 case OMPD_target_teams: 10547 case OMPD_target_teams_distribute: 10548 case OMPD_target_teams_distribute_simd: 10549 case OMPD_cancel: 10550 case OMPD_task: 10551 case OMPD_taskloop: 10552 case OMPD_taskloop_simd: 10553 case OMPD_master_taskloop: 10554 case OMPD_master_taskloop_simd: 10555 case OMPD_threadprivate: 10556 case OMPD_allocate: 10557 case OMPD_taskyield: 10558 case OMPD_barrier: 10559 case OMPD_taskwait: 10560 case OMPD_cancellation_point: 10561 case OMPD_flush: 10562 case OMPD_declare_reduction: 10563 case OMPD_declare_mapper: 10564 case OMPD_declare_simd: 10565 case OMPD_declare_variant: 10566 case OMPD_declare_target: 10567 case OMPD_end_declare_target: 10568 case OMPD_teams: 10569 case OMPD_simd: 10570 case OMPD_for: 10571 case OMPD_for_simd: 10572 case OMPD_sections: 10573 case OMPD_section: 10574 case OMPD_single: 10575 case OMPD_master: 10576 case OMPD_critical: 10577 case OMPD_taskgroup: 10578 case OMPD_distribute: 10579 case OMPD_ordered: 10580 case OMPD_atomic: 10581 case OMPD_distribute_simd: 10582 case OMPD_teams_distribute: 10583 case OMPD_teams_distribute_simd: 10584 case OMPD_requires: 10585 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10586 case OMPD_unknown: 10587 llvm_unreachable("Unknown OpenMP directive"); 10588 } 10589 break; 10590 case OMPC_num_teams: 10591 switch (DKind) { 10592 case OMPD_target_teams: 10593 case OMPD_target_teams_distribute: 10594 case OMPD_target_teams_distribute_simd: 10595 case OMPD_target_teams_distribute_parallel_for: 10596 case OMPD_target_teams_distribute_parallel_for_simd: 10597 CaptureRegion = OMPD_target; 10598 break; 10599 case OMPD_teams_distribute_parallel_for: 10600 case OMPD_teams_distribute_parallel_for_simd: 10601 case OMPD_teams: 10602 case OMPD_teams_distribute: 10603 case OMPD_teams_distribute_simd: 10604 // Do not capture num_teams-clause expressions. 10605 break; 10606 case OMPD_distribute_parallel_for: 10607 case OMPD_distribute_parallel_for_simd: 10608 case OMPD_task: 10609 case OMPD_taskloop: 10610 case OMPD_taskloop_simd: 10611 case OMPD_master_taskloop: 10612 case OMPD_master_taskloop_simd: 10613 case OMPD_parallel_master_taskloop: 10614 case OMPD_parallel_master_taskloop_simd: 10615 case OMPD_target_data: 10616 case OMPD_target_enter_data: 10617 case OMPD_target_exit_data: 10618 case OMPD_target_update: 10619 case OMPD_cancel: 10620 case OMPD_parallel: 10621 case OMPD_parallel_sections: 10622 case OMPD_parallel_for: 10623 case OMPD_parallel_for_simd: 10624 case OMPD_target: 10625 case OMPD_target_simd: 10626 case OMPD_target_parallel: 10627 case OMPD_target_parallel_for: 10628 case OMPD_target_parallel_for_simd: 10629 case OMPD_threadprivate: 10630 case OMPD_allocate: 10631 case OMPD_taskyield: 10632 case OMPD_barrier: 10633 case OMPD_taskwait: 10634 case OMPD_cancellation_point: 10635 case OMPD_flush: 10636 case OMPD_declare_reduction: 10637 case OMPD_declare_mapper: 10638 case OMPD_declare_simd: 10639 case OMPD_declare_variant: 10640 case OMPD_declare_target: 10641 case OMPD_end_declare_target: 10642 case OMPD_simd: 10643 case OMPD_for: 10644 case OMPD_for_simd: 10645 case OMPD_sections: 10646 case OMPD_section: 10647 case OMPD_single: 10648 case OMPD_master: 10649 case OMPD_critical: 10650 case OMPD_taskgroup: 10651 case OMPD_distribute: 10652 case OMPD_ordered: 10653 case OMPD_atomic: 10654 case OMPD_distribute_simd: 10655 case OMPD_requires: 10656 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10657 case OMPD_unknown: 10658 llvm_unreachable("Unknown OpenMP directive"); 10659 } 10660 break; 10661 case OMPC_thread_limit: 10662 switch (DKind) { 10663 case OMPD_target_teams: 10664 case OMPD_target_teams_distribute: 10665 case OMPD_target_teams_distribute_simd: 10666 case OMPD_target_teams_distribute_parallel_for: 10667 case OMPD_target_teams_distribute_parallel_for_simd: 10668 CaptureRegion = OMPD_target; 10669 break; 10670 case OMPD_teams_distribute_parallel_for: 10671 case OMPD_teams_distribute_parallel_for_simd: 10672 case OMPD_teams: 10673 case OMPD_teams_distribute: 10674 case OMPD_teams_distribute_simd: 10675 // Do not capture thread_limit-clause expressions. 10676 break; 10677 case OMPD_distribute_parallel_for: 10678 case OMPD_distribute_parallel_for_simd: 10679 case OMPD_task: 10680 case OMPD_taskloop: 10681 case OMPD_taskloop_simd: 10682 case OMPD_master_taskloop: 10683 case OMPD_master_taskloop_simd: 10684 case OMPD_parallel_master_taskloop: 10685 case OMPD_parallel_master_taskloop_simd: 10686 case OMPD_target_data: 10687 case OMPD_target_enter_data: 10688 case OMPD_target_exit_data: 10689 case OMPD_target_update: 10690 case OMPD_cancel: 10691 case OMPD_parallel: 10692 case OMPD_parallel_sections: 10693 case OMPD_parallel_for: 10694 case OMPD_parallel_for_simd: 10695 case OMPD_target: 10696 case OMPD_target_simd: 10697 case OMPD_target_parallel: 10698 case OMPD_target_parallel_for: 10699 case OMPD_target_parallel_for_simd: 10700 case OMPD_threadprivate: 10701 case OMPD_allocate: 10702 case OMPD_taskyield: 10703 case OMPD_barrier: 10704 case OMPD_taskwait: 10705 case OMPD_cancellation_point: 10706 case OMPD_flush: 10707 case OMPD_declare_reduction: 10708 case OMPD_declare_mapper: 10709 case OMPD_declare_simd: 10710 case OMPD_declare_variant: 10711 case OMPD_declare_target: 10712 case OMPD_end_declare_target: 10713 case OMPD_simd: 10714 case OMPD_for: 10715 case OMPD_for_simd: 10716 case OMPD_sections: 10717 case OMPD_section: 10718 case OMPD_single: 10719 case OMPD_master: 10720 case OMPD_critical: 10721 case OMPD_taskgroup: 10722 case OMPD_distribute: 10723 case OMPD_ordered: 10724 case OMPD_atomic: 10725 case OMPD_distribute_simd: 10726 case OMPD_requires: 10727 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10728 case OMPD_unknown: 10729 llvm_unreachable("Unknown OpenMP directive"); 10730 } 10731 break; 10732 case OMPC_schedule: 10733 switch (DKind) { 10734 case OMPD_parallel_for: 10735 case OMPD_parallel_for_simd: 10736 case OMPD_distribute_parallel_for: 10737 case OMPD_distribute_parallel_for_simd: 10738 case OMPD_teams_distribute_parallel_for: 10739 case OMPD_teams_distribute_parallel_for_simd: 10740 case OMPD_target_parallel_for: 10741 case OMPD_target_parallel_for_simd: 10742 case OMPD_target_teams_distribute_parallel_for: 10743 case OMPD_target_teams_distribute_parallel_for_simd: 10744 CaptureRegion = OMPD_parallel; 10745 break; 10746 case OMPD_for: 10747 case OMPD_for_simd: 10748 // Do not capture schedule-clause expressions. 10749 break; 10750 case OMPD_task: 10751 case OMPD_taskloop: 10752 case OMPD_taskloop_simd: 10753 case OMPD_master_taskloop: 10754 case OMPD_master_taskloop_simd: 10755 case OMPD_parallel_master_taskloop: 10756 case OMPD_parallel_master_taskloop_simd: 10757 case OMPD_target_data: 10758 case OMPD_target_enter_data: 10759 case OMPD_target_exit_data: 10760 case OMPD_target_update: 10761 case OMPD_teams: 10762 case OMPD_teams_distribute: 10763 case OMPD_teams_distribute_simd: 10764 case OMPD_target_teams_distribute: 10765 case OMPD_target_teams_distribute_simd: 10766 case OMPD_target: 10767 case OMPD_target_simd: 10768 case OMPD_target_parallel: 10769 case OMPD_cancel: 10770 case OMPD_parallel: 10771 case OMPD_parallel_sections: 10772 case OMPD_threadprivate: 10773 case OMPD_allocate: 10774 case OMPD_taskyield: 10775 case OMPD_barrier: 10776 case OMPD_taskwait: 10777 case OMPD_cancellation_point: 10778 case OMPD_flush: 10779 case OMPD_declare_reduction: 10780 case OMPD_declare_mapper: 10781 case OMPD_declare_simd: 10782 case OMPD_declare_variant: 10783 case OMPD_declare_target: 10784 case OMPD_end_declare_target: 10785 case OMPD_simd: 10786 case OMPD_sections: 10787 case OMPD_section: 10788 case OMPD_single: 10789 case OMPD_master: 10790 case OMPD_critical: 10791 case OMPD_taskgroup: 10792 case OMPD_distribute: 10793 case OMPD_ordered: 10794 case OMPD_atomic: 10795 case OMPD_distribute_simd: 10796 case OMPD_target_teams: 10797 case OMPD_requires: 10798 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10799 case OMPD_unknown: 10800 llvm_unreachable("Unknown OpenMP directive"); 10801 } 10802 break; 10803 case OMPC_dist_schedule: 10804 switch (DKind) { 10805 case OMPD_teams_distribute_parallel_for: 10806 case OMPD_teams_distribute_parallel_for_simd: 10807 case OMPD_teams_distribute: 10808 case OMPD_teams_distribute_simd: 10809 case OMPD_target_teams_distribute_parallel_for: 10810 case OMPD_target_teams_distribute_parallel_for_simd: 10811 case OMPD_target_teams_distribute: 10812 case OMPD_target_teams_distribute_simd: 10813 CaptureRegion = OMPD_teams; 10814 break; 10815 case OMPD_distribute_parallel_for: 10816 case OMPD_distribute_parallel_for_simd: 10817 case OMPD_distribute: 10818 case OMPD_distribute_simd: 10819 // Do not capture thread_limit-clause expressions. 10820 break; 10821 case OMPD_parallel_for: 10822 case OMPD_parallel_for_simd: 10823 case OMPD_target_parallel_for_simd: 10824 case OMPD_target_parallel_for: 10825 case OMPD_task: 10826 case OMPD_taskloop: 10827 case OMPD_taskloop_simd: 10828 case OMPD_master_taskloop: 10829 case OMPD_master_taskloop_simd: 10830 case OMPD_parallel_master_taskloop: 10831 case OMPD_parallel_master_taskloop_simd: 10832 case OMPD_target_data: 10833 case OMPD_target_enter_data: 10834 case OMPD_target_exit_data: 10835 case OMPD_target_update: 10836 case OMPD_teams: 10837 case OMPD_target: 10838 case OMPD_target_simd: 10839 case OMPD_target_parallel: 10840 case OMPD_cancel: 10841 case OMPD_parallel: 10842 case OMPD_parallel_sections: 10843 case OMPD_threadprivate: 10844 case OMPD_allocate: 10845 case OMPD_taskyield: 10846 case OMPD_barrier: 10847 case OMPD_taskwait: 10848 case OMPD_cancellation_point: 10849 case OMPD_flush: 10850 case OMPD_declare_reduction: 10851 case OMPD_declare_mapper: 10852 case OMPD_declare_simd: 10853 case OMPD_declare_variant: 10854 case OMPD_declare_target: 10855 case OMPD_end_declare_target: 10856 case OMPD_simd: 10857 case OMPD_for: 10858 case OMPD_for_simd: 10859 case OMPD_sections: 10860 case OMPD_section: 10861 case OMPD_single: 10862 case OMPD_master: 10863 case OMPD_critical: 10864 case OMPD_taskgroup: 10865 case OMPD_ordered: 10866 case OMPD_atomic: 10867 case OMPD_target_teams: 10868 case OMPD_requires: 10869 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10870 case OMPD_unknown: 10871 llvm_unreachable("Unknown OpenMP directive"); 10872 } 10873 break; 10874 case OMPC_device: 10875 switch (DKind) { 10876 case OMPD_target_update: 10877 case OMPD_target_enter_data: 10878 case OMPD_target_exit_data: 10879 case OMPD_target: 10880 case OMPD_target_simd: 10881 case OMPD_target_teams: 10882 case OMPD_target_parallel: 10883 case OMPD_target_teams_distribute: 10884 case OMPD_target_teams_distribute_simd: 10885 case OMPD_target_parallel_for: 10886 case OMPD_target_parallel_for_simd: 10887 case OMPD_target_teams_distribute_parallel_for: 10888 case OMPD_target_teams_distribute_parallel_for_simd: 10889 CaptureRegion = OMPD_task; 10890 break; 10891 case OMPD_target_data: 10892 // Do not capture device-clause expressions. 10893 break; 10894 case OMPD_teams_distribute_parallel_for: 10895 case OMPD_teams_distribute_parallel_for_simd: 10896 case OMPD_teams: 10897 case OMPD_teams_distribute: 10898 case OMPD_teams_distribute_simd: 10899 case OMPD_distribute_parallel_for: 10900 case OMPD_distribute_parallel_for_simd: 10901 case OMPD_task: 10902 case OMPD_taskloop: 10903 case OMPD_taskloop_simd: 10904 case OMPD_master_taskloop: 10905 case OMPD_master_taskloop_simd: 10906 case OMPD_parallel_master_taskloop: 10907 case OMPD_parallel_master_taskloop_simd: 10908 case OMPD_cancel: 10909 case OMPD_parallel: 10910 case OMPD_parallel_sections: 10911 case OMPD_parallel_for: 10912 case OMPD_parallel_for_simd: 10913 case OMPD_threadprivate: 10914 case OMPD_allocate: 10915 case OMPD_taskyield: 10916 case OMPD_barrier: 10917 case OMPD_taskwait: 10918 case OMPD_cancellation_point: 10919 case OMPD_flush: 10920 case OMPD_declare_reduction: 10921 case OMPD_declare_mapper: 10922 case OMPD_declare_simd: 10923 case OMPD_declare_variant: 10924 case OMPD_declare_target: 10925 case OMPD_end_declare_target: 10926 case OMPD_simd: 10927 case OMPD_for: 10928 case OMPD_for_simd: 10929 case OMPD_sections: 10930 case OMPD_section: 10931 case OMPD_single: 10932 case OMPD_master: 10933 case OMPD_critical: 10934 case OMPD_taskgroup: 10935 case OMPD_distribute: 10936 case OMPD_ordered: 10937 case OMPD_atomic: 10938 case OMPD_distribute_simd: 10939 case OMPD_requires: 10940 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10941 case OMPD_unknown: 10942 llvm_unreachable("Unknown OpenMP directive"); 10943 } 10944 break; 10945 case OMPC_grainsize: 10946 case OMPC_num_tasks: 10947 case OMPC_final: 10948 case OMPC_priority: 10949 switch (DKind) { 10950 case OMPD_task: 10951 case OMPD_taskloop: 10952 case OMPD_taskloop_simd: 10953 case OMPD_master_taskloop: 10954 case OMPD_master_taskloop_simd: 10955 break; 10956 case OMPD_parallel_master_taskloop: 10957 case OMPD_parallel_master_taskloop_simd: 10958 CaptureRegion = OMPD_parallel; 10959 break; 10960 case OMPD_target_update: 10961 case OMPD_target_enter_data: 10962 case OMPD_target_exit_data: 10963 case OMPD_target: 10964 case OMPD_target_simd: 10965 case OMPD_target_teams: 10966 case OMPD_target_parallel: 10967 case OMPD_target_teams_distribute: 10968 case OMPD_target_teams_distribute_simd: 10969 case OMPD_target_parallel_for: 10970 case OMPD_target_parallel_for_simd: 10971 case OMPD_target_teams_distribute_parallel_for: 10972 case OMPD_target_teams_distribute_parallel_for_simd: 10973 case OMPD_target_data: 10974 case OMPD_teams_distribute_parallel_for: 10975 case OMPD_teams_distribute_parallel_for_simd: 10976 case OMPD_teams: 10977 case OMPD_teams_distribute: 10978 case OMPD_teams_distribute_simd: 10979 case OMPD_distribute_parallel_for: 10980 case OMPD_distribute_parallel_for_simd: 10981 case OMPD_cancel: 10982 case OMPD_parallel: 10983 case OMPD_parallel_sections: 10984 case OMPD_parallel_for: 10985 case OMPD_parallel_for_simd: 10986 case OMPD_threadprivate: 10987 case OMPD_allocate: 10988 case OMPD_taskyield: 10989 case OMPD_barrier: 10990 case OMPD_taskwait: 10991 case OMPD_cancellation_point: 10992 case OMPD_flush: 10993 case OMPD_declare_reduction: 10994 case OMPD_declare_mapper: 10995 case OMPD_declare_simd: 10996 case OMPD_declare_variant: 10997 case OMPD_declare_target: 10998 case OMPD_end_declare_target: 10999 case OMPD_simd: 11000 case OMPD_for: 11001 case OMPD_for_simd: 11002 case OMPD_sections: 11003 case OMPD_section: 11004 case OMPD_single: 11005 case OMPD_master: 11006 case OMPD_critical: 11007 case OMPD_taskgroup: 11008 case OMPD_distribute: 11009 case OMPD_ordered: 11010 case OMPD_atomic: 11011 case OMPD_distribute_simd: 11012 case OMPD_requires: 11013 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11014 case OMPD_unknown: 11015 llvm_unreachable("Unknown OpenMP directive"); 11016 } 11017 break; 11018 case OMPC_firstprivate: 11019 case OMPC_lastprivate: 11020 case OMPC_reduction: 11021 case OMPC_task_reduction: 11022 case OMPC_in_reduction: 11023 case OMPC_linear: 11024 case OMPC_default: 11025 case OMPC_proc_bind: 11026 case OMPC_safelen: 11027 case OMPC_simdlen: 11028 case OMPC_allocator: 11029 case OMPC_collapse: 11030 case OMPC_private: 11031 case OMPC_shared: 11032 case OMPC_aligned: 11033 case OMPC_copyin: 11034 case OMPC_copyprivate: 11035 case OMPC_ordered: 11036 case OMPC_nowait: 11037 case OMPC_untied: 11038 case OMPC_mergeable: 11039 case OMPC_threadprivate: 11040 case OMPC_allocate: 11041 case OMPC_flush: 11042 case OMPC_read: 11043 case OMPC_write: 11044 case OMPC_update: 11045 case OMPC_capture: 11046 case OMPC_seq_cst: 11047 case OMPC_depend: 11048 case OMPC_threads: 11049 case OMPC_simd: 11050 case OMPC_map: 11051 case OMPC_nogroup: 11052 case OMPC_hint: 11053 case OMPC_defaultmap: 11054 case OMPC_unknown: 11055 case OMPC_uniform: 11056 case OMPC_to: 11057 case OMPC_from: 11058 case OMPC_use_device_ptr: 11059 case OMPC_is_device_ptr: 11060 case OMPC_unified_address: 11061 case OMPC_unified_shared_memory: 11062 case OMPC_reverse_offload: 11063 case OMPC_dynamic_allocators: 11064 case OMPC_atomic_default_mem_order: 11065 case OMPC_device_type: 11066 case OMPC_match: 11067 llvm_unreachable("Unexpected OpenMP clause."); 11068 } 11069 return CaptureRegion; 11070 } 11071 11072 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11073 Expr *Condition, SourceLocation StartLoc, 11074 SourceLocation LParenLoc, 11075 SourceLocation NameModifierLoc, 11076 SourceLocation ColonLoc, 11077 SourceLocation EndLoc) { 11078 Expr *ValExpr = Condition; 11079 Stmt *HelperValStmt = nullptr; 11080 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11081 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11082 !Condition->isInstantiationDependent() && 11083 !Condition->containsUnexpandedParameterPack()) { 11084 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11085 if (Val.isInvalid()) 11086 return nullptr; 11087 11088 ValExpr = Val.get(); 11089 11090 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11091 CaptureRegion = 11092 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 11093 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11094 ValExpr = MakeFullExpr(ValExpr).get(); 11095 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11096 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11097 HelperValStmt = buildPreInits(Context, Captures); 11098 } 11099 } 11100 11101 return new (Context) 11102 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11103 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11104 } 11105 11106 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11107 SourceLocation StartLoc, 11108 SourceLocation LParenLoc, 11109 SourceLocation EndLoc) { 11110 Expr *ValExpr = Condition; 11111 Stmt *HelperValStmt = nullptr; 11112 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11113 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11114 !Condition->isInstantiationDependent() && 11115 !Condition->containsUnexpandedParameterPack()) { 11116 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11117 if (Val.isInvalid()) 11118 return nullptr; 11119 11120 ValExpr = MakeFullExpr(Val.get()).get(); 11121 11122 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11123 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final); 11124 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11125 ValExpr = MakeFullExpr(ValExpr).get(); 11126 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11127 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11128 HelperValStmt = buildPreInits(Context, Captures); 11129 } 11130 } 11131 11132 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11133 StartLoc, LParenLoc, EndLoc); 11134 } 11135 11136 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11137 Expr *Op) { 11138 if (!Op) 11139 return ExprError(); 11140 11141 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11142 public: 11143 IntConvertDiagnoser() 11144 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11145 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11146 QualType T) override { 11147 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11148 } 11149 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11150 QualType T) override { 11151 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11152 } 11153 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11154 QualType T, 11155 QualType ConvTy) override { 11156 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11157 } 11158 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11159 QualType ConvTy) override { 11160 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11161 << ConvTy->isEnumeralType() << ConvTy; 11162 } 11163 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11164 QualType T) override { 11165 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11166 } 11167 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11168 QualType ConvTy) override { 11169 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11170 << ConvTy->isEnumeralType() << ConvTy; 11171 } 11172 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11173 QualType) override { 11174 llvm_unreachable("conversion functions are permitted"); 11175 } 11176 } ConvertDiagnoser; 11177 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11178 } 11179 11180 static bool 11181 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11182 bool StrictlyPositive, bool BuildCapture = false, 11183 OpenMPDirectiveKind DKind = OMPD_unknown, 11184 OpenMPDirectiveKind *CaptureRegion = nullptr, 11185 Stmt **HelperValStmt = nullptr) { 11186 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11187 !ValExpr->isInstantiationDependent()) { 11188 SourceLocation Loc = ValExpr->getExprLoc(); 11189 ExprResult Value = 11190 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11191 if (Value.isInvalid()) 11192 return false; 11193 11194 ValExpr = Value.get(); 11195 // The expression must evaluate to a non-negative integer value. 11196 llvm::APSInt Result; 11197 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11198 Result.isSigned() && 11199 !((!StrictlyPositive && Result.isNonNegative()) || 11200 (StrictlyPositive && Result.isStrictlyPositive()))) { 11201 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11202 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11203 << ValExpr->getSourceRange(); 11204 return false; 11205 } 11206 if (!BuildCapture) 11207 return true; 11208 *CaptureRegion = getOpenMPCaptureRegionForClause(DKind, CKind); 11209 if (*CaptureRegion != OMPD_unknown && 11210 !SemaRef.CurContext->isDependentContext()) { 11211 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11212 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11213 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11214 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11215 } 11216 } 11217 return true; 11218 } 11219 11220 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11221 SourceLocation StartLoc, 11222 SourceLocation LParenLoc, 11223 SourceLocation EndLoc) { 11224 Expr *ValExpr = NumThreads; 11225 Stmt *HelperValStmt = nullptr; 11226 11227 // OpenMP [2.5, Restrictions] 11228 // The num_threads expression must evaluate to a positive integer value. 11229 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11230 /*StrictlyPositive=*/true)) 11231 return nullptr; 11232 11233 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11234 OpenMPDirectiveKind CaptureRegion = 11235 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 11236 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11237 ValExpr = MakeFullExpr(ValExpr).get(); 11238 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11239 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11240 HelperValStmt = buildPreInits(Context, Captures); 11241 } 11242 11243 return new (Context) OMPNumThreadsClause( 11244 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11245 } 11246 11247 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11248 OpenMPClauseKind CKind, 11249 bool StrictlyPositive) { 11250 if (!E) 11251 return ExprError(); 11252 if (E->isValueDependent() || E->isTypeDependent() || 11253 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11254 return E; 11255 llvm::APSInt Result; 11256 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11257 if (ICE.isInvalid()) 11258 return ExprError(); 11259 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11260 (!StrictlyPositive && !Result.isNonNegative())) { 11261 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11262 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11263 << E->getSourceRange(); 11264 return ExprError(); 11265 } 11266 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11267 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11268 << E->getSourceRange(); 11269 return ExprError(); 11270 } 11271 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11272 DSAStack->setAssociatedLoops(Result.getExtValue()); 11273 else if (CKind == OMPC_ordered) 11274 DSAStack->setAssociatedLoops(Result.getExtValue()); 11275 return ICE; 11276 } 11277 11278 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11279 SourceLocation LParenLoc, 11280 SourceLocation EndLoc) { 11281 // OpenMP [2.8.1, simd construct, Description] 11282 // The parameter of the safelen clause must be a constant 11283 // positive integer expression. 11284 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11285 if (Safelen.isInvalid()) 11286 return nullptr; 11287 return new (Context) 11288 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11289 } 11290 11291 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11292 SourceLocation LParenLoc, 11293 SourceLocation EndLoc) { 11294 // OpenMP [2.8.1, simd construct, Description] 11295 // The parameter of the simdlen clause must be a constant 11296 // positive integer expression. 11297 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11298 if (Simdlen.isInvalid()) 11299 return nullptr; 11300 return new (Context) 11301 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11302 } 11303 11304 /// Tries to find omp_allocator_handle_t type. 11305 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11306 DSAStackTy *Stack) { 11307 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11308 if (!OMPAllocatorHandleT.isNull()) 11309 return true; 11310 // Build the predefined allocator expressions. 11311 bool ErrorFound = false; 11312 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11313 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11314 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11315 StringRef Allocator = 11316 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11317 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11318 auto *VD = dyn_cast_or_null<ValueDecl>( 11319 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11320 if (!VD) { 11321 ErrorFound = true; 11322 break; 11323 } 11324 QualType AllocatorType = 11325 VD->getType().getNonLValueExprType(S.getASTContext()); 11326 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11327 if (!Res.isUsable()) { 11328 ErrorFound = true; 11329 break; 11330 } 11331 if (OMPAllocatorHandleT.isNull()) 11332 OMPAllocatorHandleT = AllocatorType; 11333 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11334 ErrorFound = true; 11335 break; 11336 } 11337 Stack->setAllocator(AllocatorKind, Res.get()); 11338 } 11339 if (ErrorFound) { 11340 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11341 return false; 11342 } 11343 OMPAllocatorHandleT.addConst(); 11344 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11345 return true; 11346 } 11347 11348 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11349 SourceLocation LParenLoc, 11350 SourceLocation EndLoc) { 11351 // OpenMP [2.11.3, allocate Directive, Description] 11352 // allocator is an expression of omp_allocator_handle_t type. 11353 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11354 return nullptr; 11355 11356 ExprResult Allocator = DefaultLvalueConversion(A); 11357 if (Allocator.isInvalid()) 11358 return nullptr; 11359 Allocator = PerformImplicitConversion(Allocator.get(), 11360 DSAStack->getOMPAllocatorHandleT(), 11361 Sema::AA_Initializing, 11362 /*AllowExplicit=*/true); 11363 if (Allocator.isInvalid()) 11364 return nullptr; 11365 return new (Context) 11366 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11367 } 11368 11369 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11370 SourceLocation StartLoc, 11371 SourceLocation LParenLoc, 11372 SourceLocation EndLoc) { 11373 // OpenMP [2.7.1, loop construct, Description] 11374 // OpenMP [2.8.1, simd construct, Description] 11375 // OpenMP [2.9.6, distribute construct, Description] 11376 // The parameter of the collapse clause must be a constant 11377 // positive integer expression. 11378 ExprResult NumForLoopsResult = 11379 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11380 if (NumForLoopsResult.isInvalid()) 11381 return nullptr; 11382 return new (Context) 11383 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11384 } 11385 11386 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11387 SourceLocation EndLoc, 11388 SourceLocation LParenLoc, 11389 Expr *NumForLoops) { 11390 // OpenMP [2.7.1, loop construct, Description] 11391 // OpenMP [2.8.1, simd construct, Description] 11392 // OpenMP [2.9.6, distribute construct, Description] 11393 // The parameter of the ordered clause must be a constant 11394 // positive integer expression if any. 11395 if (NumForLoops && LParenLoc.isValid()) { 11396 ExprResult NumForLoopsResult = 11397 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11398 if (NumForLoopsResult.isInvalid()) 11399 return nullptr; 11400 NumForLoops = NumForLoopsResult.get(); 11401 } else { 11402 NumForLoops = nullptr; 11403 } 11404 auto *Clause = OMPOrderedClause::Create( 11405 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11406 StartLoc, LParenLoc, EndLoc); 11407 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11408 return Clause; 11409 } 11410 11411 OMPClause *Sema::ActOnOpenMPSimpleClause( 11412 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11413 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11414 OMPClause *Res = nullptr; 11415 switch (Kind) { 11416 case OMPC_default: 11417 Res = 11418 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11419 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11420 break; 11421 case OMPC_proc_bind: 11422 Res = ActOnOpenMPProcBindClause( 11423 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11424 LParenLoc, EndLoc); 11425 break; 11426 case OMPC_atomic_default_mem_order: 11427 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11428 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11429 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11430 break; 11431 case OMPC_if: 11432 case OMPC_final: 11433 case OMPC_num_threads: 11434 case OMPC_safelen: 11435 case OMPC_simdlen: 11436 case OMPC_allocator: 11437 case OMPC_collapse: 11438 case OMPC_schedule: 11439 case OMPC_private: 11440 case OMPC_firstprivate: 11441 case OMPC_lastprivate: 11442 case OMPC_shared: 11443 case OMPC_reduction: 11444 case OMPC_task_reduction: 11445 case OMPC_in_reduction: 11446 case OMPC_linear: 11447 case OMPC_aligned: 11448 case OMPC_copyin: 11449 case OMPC_copyprivate: 11450 case OMPC_ordered: 11451 case OMPC_nowait: 11452 case OMPC_untied: 11453 case OMPC_mergeable: 11454 case OMPC_threadprivate: 11455 case OMPC_allocate: 11456 case OMPC_flush: 11457 case OMPC_read: 11458 case OMPC_write: 11459 case OMPC_update: 11460 case OMPC_capture: 11461 case OMPC_seq_cst: 11462 case OMPC_depend: 11463 case OMPC_device: 11464 case OMPC_threads: 11465 case OMPC_simd: 11466 case OMPC_map: 11467 case OMPC_num_teams: 11468 case OMPC_thread_limit: 11469 case OMPC_priority: 11470 case OMPC_grainsize: 11471 case OMPC_nogroup: 11472 case OMPC_num_tasks: 11473 case OMPC_hint: 11474 case OMPC_dist_schedule: 11475 case OMPC_defaultmap: 11476 case OMPC_unknown: 11477 case OMPC_uniform: 11478 case OMPC_to: 11479 case OMPC_from: 11480 case OMPC_use_device_ptr: 11481 case OMPC_is_device_ptr: 11482 case OMPC_unified_address: 11483 case OMPC_unified_shared_memory: 11484 case OMPC_reverse_offload: 11485 case OMPC_dynamic_allocators: 11486 case OMPC_device_type: 11487 case OMPC_match: 11488 llvm_unreachable("Clause is not allowed."); 11489 } 11490 return Res; 11491 } 11492 11493 static std::string 11494 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11495 ArrayRef<unsigned> Exclude = llvm::None) { 11496 SmallString<256> Buffer; 11497 llvm::raw_svector_ostream Out(Buffer); 11498 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11499 unsigned Skipped = Exclude.size(); 11500 auto S = Exclude.begin(), E = Exclude.end(); 11501 for (unsigned I = First; I < Last; ++I) { 11502 if (std::find(S, E, I) != E) { 11503 --Skipped; 11504 continue; 11505 } 11506 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11507 if (I == Bound - Skipped) 11508 Out << " or "; 11509 else if (I != Bound + 1 - Skipped) 11510 Out << ", "; 11511 } 11512 return Out.str(); 11513 } 11514 11515 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11516 SourceLocation KindKwLoc, 11517 SourceLocation StartLoc, 11518 SourceLocation LParenLoc, 11519 SourceLocation EndLoc) { 11520 if (Kind == OMPC_DEFAULT_unknown) { 11521 static_assert(OMPC_DEFAULT_unknown > 0, 11522 "OMPC_DEFAULT_unknown not greater than 0"); 11523 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11524 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11525 /*Last=*/OMPC_DEFAULT_unknown) 11526 << getOpenMPClauseName(OMPC_default); 11527 return nullptr; 11528 } 11529 switch (Kind) { 11530 case OMPC_DEFAULT_none: 11531 DSAStack->setDefaultDSANone(KindKwLoc); 11532 break; 11533 case OMPC_DEFAULT_shared: 11534 DSAStack->setDefaultDSAShared(KindKwLoc); 11535 break; 11536 case OMPC_DEFAULT_unknown: 11537 llvm_unreachable("Clause kind is not allowed."); 11538 break; 11539 } 11540 return new (Context) 11541 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11542 } 11543 11544 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11545 SourceLocation KindKwLoc, 11546 SourceLocation StartLoc, 11547 SourceLocation LParenLoc, 11548 SourceLocation EndLoc) { 11549 if (Kind == OMPC_PROC_BIND_unknown) { 11550 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11551 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11552 /*Last=*/OMPC_PROC_BIND_unknown) 11553 << getOpenMPClauseName(OMPC_proc_bind); 11554 return nullptr; 11555 } 11556 return new (Context) 11557 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11558 } 11559 11560 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11561 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11562 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11563 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11564 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11565 << getListOfPossibleValues( 11566 OMPC_atomic_default_mem_order, /*First=*/0, 11567 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11568 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11569 return nullptr; 11570 } 11571 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11572 LParenLoc, EndLoc); 11573 } 11574 11575 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11576 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11577 SourceLocation StartLoc, SourceLocation LParenLoc, 11578 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11579 SourceLocation EndLoc) { 11580 OMPClause *Res = nullptr; 11581 switch (Kind) { 11582 case OMPC_schedule: 11583 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11584 assert(Argument.size() == NumberOfElements && 11585 ArgumentLoc.size() == NumberOfElements); 11586 Res = ActOnOpenMPScheduleClause( 11587 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11588 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11589 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11590 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11591 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11592 break; 11593 case OMPC_if: 11594 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11595 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11596 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11597 DelimLoc, EndLoc); 11598 break; 11599 case OMPC_dist_schedule: 11600 Res = ActOnOpenMPDistScheduleClause( 11601 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11602 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11603 break; 11604 case OMPC_defaultmap: 11605 enum { Modifier, DefaultmapKind }; 11606 Res = ActOnOpenMPDefaultmapClause( 11607 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11608 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11609 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11610 EndLoc); 11611 break; 11612 case OMPC_final: 11613 case OMPC_num_threads: 11614 case OMPC_safelen: 11615 case OMPC_simdlen: 11616 case OMPC_allocator: 11617 case OMPC_collapse: 11618 case OMPC_default: 11619 case OMPC_proc_bind: 11620 case OMPC_private: 11621 case OMPC_firstprivate: 11622 case OMPC_lastprivate: 11623 case OMPC_shared: 11624 case OMPC_reduction: 11625 case OMPC_task_reduction: 11626 case OMPC_in_reduction: 11627 case OMPC_linear: 11628 case OMPC_aligned: 11629 case OMPC_copyin: 11630 case OMPC_copyprivate: 11631 case OMPC_ordered: 11632 case OMPC_nowait: 11633 case OMPC_untied: 11634 case OMPC_mergeable: 11635 case OMPC_threadprivate: 11636 case OMPC_allocate: 11637 case OMPC_flush: 11638 case OMPC_read: 11639 case OMPC_write: 11640 case OMPC_update: 11641 case OMPC_capture: 11642 case OMPC_seq_cst: 11643 case OMPC_depend: 11644 case OMPC_device: 11645 case OMPC_threads: 11646 case OMPC_simd: 11647 case OMPC_map: 11648 case OMPC_num_teams: 11649 case OMPC_thread_limit: 11650 case OMPC_priority: 11651 case OMPC_grainsize: 11652 case OMPC_nogroup: 11653 case OMPC_num_tasks: 11654 case OMPC_hint: 11655 case OMPC_unknown: 11656 case OMPC_uniform: 11657 case OMPC_to: 11658 case OMPC_from: 11659 case OMPC_use_device_ptr: 11660 case OMPC_is_device_ptr: 11661 case OMPC_unified_address: 11662 case OMPC_unified_shared_memory: 11663 case OMPC_reverse_offload: 11664 case OMPC_dynamic_allocators: 11665 case OMPC_atomic_default_mem_order: 11666 case OMPC_device_type: 11667 case OMPC_match: 11668 llvm_unreachable("Clause is not allowed."); 11669 } 11670 return Res; 11671 } 11672 11673 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11674 OpenMPScheduleClauseModifier M2, 11675 SourceLocation M1Loc, SourceLocation M2Loc) { 11676 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11677 SmallVector<unsigned, 2> Excluded; 11678 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11679 Excluded.push_back(M2); 11680 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11681 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11682 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11683 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11684 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11685 << getListOfPossibleValues(OMPC_schedule, 11686 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11687 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11688 Excluded) 11689 << getOpenMPClauseName(OMPC_schedule); 11690 return true; 11691 } 11692 return false; 11693 } 11694 11695 OMPClause *Sema::ActOnOpenMPScheduleClause( 11696 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11697 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11698 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11699 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11700 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11701 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11702 return nullptr; 11703 // OpenMP, 2.7.1, Loop Construct, Restrictions 11704 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11705 // but not both. 11706 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11707 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11708 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11709 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11710 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11711 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11712 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11713 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11714 return nullptr; 11715 } 11716 if (Kind == OMPC_SCHEDULE_unknown) { 11717 std::string Values; 11718 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11719 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11720 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11721 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11722 Exclude); 11723 } else { 11724 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11725 /*Last=*/OMPC_SCHEDULE_unknown); 11726 } 11727 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11728 << Values << getOpenMPClauseName(OMPC_schedule); 11729 return nullptr; 11730 } 11731 // OpenMP, 2.7.1, Loop Construct, Restrictions 11732 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11733 // schedule(guided). 11734 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11735 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11736 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11737 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11738 diag::err_omp_schedule_nonmonotonic_static); 11739 return nullptr; 11740 } 11741 Expr *ValExpr = ChunkSize; 11742 Stmt *HelperValStmt = nullptr; 11743 if (ChunkSize) { 11744 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11745 !ChunkSize->isInstantiationDependent() && 11746 !ChunkSize->containsUnexpandedParameterPack()) { 11747 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11748 ExprResult Val = 11749 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11750 if (Val.isInvalid()) 11751 return nullptr; 11752 11753 ValExpr = Val.get(); 11754 11755 // OpenMP [2.7.1, Restrictions] 11756 // chunk_size must be a loop invariant integer expression with a positive 11757 // value. 11758 llvm::APSInt Result; 11759 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11760 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11761 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11762 << "schedule" << 1 << ChunkSize->getSourceRange(); 11763 return nullptr; 11764 } 11765 } else if (getOpenMPCaptureRegionForClause( 11766 DSAStack->getCurrentDirective(), OMPC_schedule) != 11767 OMPD_unknown && 11768 !CurContext->isDependentContext()) { 11769 ValExpr = MakeFullExpr(ValExpr).get(); 11770 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11771 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11772 HelperValStmt = buildPreInits(Context, Captures); 11773 } 11774 } 11775 } 11776 11777 return new (Context) 11778 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11779 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11780 } 11781 11782 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11783 SourceLocation StartLoc, 11784 SourceLocation EndLoc) { 11785 OMPClause *Res = nullptr; 11786 switch (Kind) { 11787 case OMPC_ordered: 11788 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11789 break; 11790 case OMPC_nowait: 11791 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11792 break; 11793 case OMPC_untied: 11794 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11795 break; 11796 case OMPC_mergeable: 11797 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11798 break; 11799 case OMPC_read: 11800 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11801 break; 11802 case OMPC_write: 11803 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11804 break; 11805 case OMPC_update: 11806 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11807 break; 11808 case OMPC_capture: 11809 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11810 break; 11811 case OMPC_seq_cst: 11812 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11813 break; 11814 case OMPC_threads: 11815 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11816 break; 11817 case OMPC_simd: 11818 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11819 break; 11820 case OMPC_nogroup: 11821 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11822 break; 11823 case OMPC_unified_address: 11824 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11825 break; 11826 case OMPC_unified_shared_memory: 11827 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11828 break; 11829 case OMPC_reverse_offload: 11830 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11831 break; 11832 case OMPC_dynamic_allocators: 11833 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11834 break; 11835 case OMPC_if: 11836 case OMPC_final: 11837 case OMPC_num_threads: 11838 case OMPC_safelen: 11839 case OMPC_simdlen: 11840 case OMPC_allocator: 11841 case OMPC_collapse: 11842 case OMPC_schedule: 11843 case OMPC_private: 11844 case OMPC_firstprivate: 11845 case OMPC_lastprivate: 11846 case OMPC_shared: 11847 case OMPC_reduction: 11848 case OMPC_task_reduction: 11849 case OMPC_in_reduction: 11850 case OMPC_linear: 11851 case OMPC_aligned: 11852 case OMPC_copyin: 11853 case OMPC_copyprivate: 11854 case OMPC_default: 11855 case OMPC_proc_bind: 11856 case OMPC_threadprivate: 11857 case OMPC_allocate: 11858 case OMPC_flush: 11859 case OMPC_depend: 11860 case OMPC_device: 11861 case OMPC_map: 11862 case OMPC_num_teams: 11863 case OMPC_thread_limit: 11864 case OMPC_priority: 11865 case OMPC_grainsize: 11866 case OMPC_num_tasks: 11867 case OMPC_hint: 11868 case OMPC_dist_schedule: 11869 case OMPC_defaultmap: 11870 case OMPC_unknown: 11871 case OMPC_uniform: 11872 case OMPC_to: 11873 case OMPC_from: 11874 case OMPC_use_device_ptr: 11875 case OMPC_is_device_ptr: 11876 case OMPC_atomic_default_mem_order: 11877 case OMPC_device_type: 11878 case OMPC_match: 11879 llvm_unreachable("Clause is not allowed."); 11880 } 11881 return Res; 11882 } 11883 11884 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11885 SourceLocation EndLoc) { 11886 DSAStack->setNowaitRegion(); 11887 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11888 } 11889 11890 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11891 SourceLocation EndLoc) { 11892 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11893 } 11894 11895 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11896 SourceLocation EndLoc) { 11897 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11898 } 11899 11900 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11901 SourceLocation EndLoc) { 11902 return new (Context) OMPReadClause(StartLoc, EndLoc); 11903 } 11904 11905 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11906 SourceLocation EndLoc) { 11907 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11908 } 11909 11910 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11911 SourceLocation EndLoc) { 11912 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11913 } 11914 11915 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11916 SourceLocation EndLoc) { 11917 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11918 } 11919 11920 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11921 SourceLocation EndLoc) { 11922 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11923 } 11924 11925 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11926 SourceLocation EndLoc) { 11927 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11928 } 11929 11930 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11931 SourceLocation EndLoc) { 11932 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11933 } 11934 11935 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11936 SourceLocation EndLoc) { 11937 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11938 } 11939 11940 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11941 SourceLocation EndLoc) { 11942 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11943 } 11944 11945 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11946 SourceLocation EndLoc) { 11947 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11948 } 11949 11950 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11951 SourceLocation EndLoc) { 11952 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11953 } 11954 11955 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11956 SourceLocation EndLoc) { 11957 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11958 } 11959 11960 OMPClause *Sema::ActOnOpenMPVarListClause( 11961 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11962 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11963 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11964 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11965 OpenMPLinearClauseKind LinKind, 11966 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11967 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11968 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11969 SourceLocation StartLoc = Locs.StartLoc; 11970 SourceLocation LParenLoc = Locs.LParenLoc; 11971 SourceLocation EndLoc = Locs.EndLoc; 11972 OMPClause *Res = nullptr; 11973 switch (Kind) { 11974 case OMPC_private: 11975 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11976 break; 11977 case OMPC_firstprivate: 11978 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11979 break; 11980 case OMPC_lastprivate: 11981 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11982 break; 11983 case OMPC_shared: 11984 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11985 break; 11986 case OMPC_reduction: 11987 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11988 EndLoc, ReductionOrMapperIdScopeSpec, 11989 ReductionOrMapperId); 11990 break; 11991 case OMPC_task_reduction: 11992 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11993 EndLoc, ReductionOrMapperIdScopeSpec, 11994 ReductionOrMapperId); 11995 break; 11996 case OMPC_in_reduction: 11997 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11998 EndLoc, ReductionOrMapperIdScopeSpec, 11999 ReductionOrMapperId); 12000 break; 12001 case OMPC_linear: 12002 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 12003 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 12004 break; 12005 case OMPC_aligned: 12006 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12007 ColonLoc, EndLoc); 12008 break; 12009 case OMPC_copyin: 12010 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12011 break; 12012 case OMPC_copyprivate: 12013 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12014 break; 12015 case OMPC_flush: 12016 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12017 break; 12018 case OMPC_depend: 12019 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 12020 StartLoc, LParenLoc, EndLoc); 12021 break; 12022 case OMPC_map: 12023 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 12024 ReductionOrMapperIdScopeSpec, 12025 ReductionOrMapperId, MapType, IsMapTypeImplicit, 12026 DepLinMapLoc, ColonLoc, VarList, Locs); 12027 break; 12028 case OMPC_to: 12029 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12030 ReductionOrMapperId, Locs); 12031 break; 12032 case OMPC_from: 12033 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12034 ReductionOrMapperId, Locs); 12035 break; 12036 case OMPC_use_device_ptr: 12037 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12038 break; 12039 case OMPC_is_device_ptr: 12040 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12041 break; 12042 case OMPC_allocate: 12043 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12044 ColonLoc, EndLoc); 12045 break; 12046 case OMPC_if: 12047 case OMPC_final: 12048 case OMPC_num_threads: 12049 case OMPC_safelen: 12050 case OMPC_simdlen: 12051 case OMPC_allocator: 12052 case OMPC_collapse: 12053 case OMPC_default: 12054 case OMPC_proc_bind: 12055 case OMPC_schedule: 12056 case OMPC_ordered: 12057 case OMPC_nowait: 12058 case OMPC_untied: 12059 case OMPC_mergeable: 12060 case OMPC_threadprivate: 12061 case OMPC_read: 12062 case OMPC_write: 12063 case OMPC_update: 12064 case OMPC_capture: 12065 case OMPC_seq_cst: 12066 case OMPC_device: 12067 case OMPC_threads: 12068 case OMPC_simd: 12069 case OMPC_num_teams: 12070 case OMPC_thread_limit: 12071 case OMPC_priority: 12072 case OMPC_grainsize: 12073 case OMPC_nogroup: 12074 case OMPC_num_tasks: 12075 case OMPC_hint: 12076 case OMPC_dist_schedule: 12077 case OMPC_defaultmap: 12078 case OMPC_unknown: 12079 case OMPC_uniform: 12080 case OMPC_unified_address: 12081 case OMPC_unified_shared_memory: 12082 case OMPC_reverse_offload: 12083 case OMPC_dynamic_allocators: 12084 case OMPC_atomic_default_mem_order: 12085 case OMPC_device_type: 12086 case OMPC_match: 12087 llvm_unreachable("Clause is not allowed."); 12088 } 12089 return Res; 12090 } 12091 12092 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12093 ExprObjectKind OK, SourceLocation Loc) { 12094 ExprResult Res = BuildDeclRefExpr( 12095 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12096 if (!Res.isUsable()) 12097 return ExprError(); 12098 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12099 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12100 if (!Res.isUsable()) 12101 return ExprError(); 12102 } 12103 if (VK != VK_LValue && Res.get()->isGLValue()) { 12104 Res = DefaultLvalueConversion(Res.get()); 12105 if (!Res.isUsable()) 12106 return ExprError(); 12107 } 12108 return Res; 12109 } 12110 12111 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12112 SourceLocation StartLoc, 12113 SourceLocation LParenLoc, 12114 SourceLocation EndLoc) { 12115 SmallVector<Expr *, 8> Vars; 12116 SmallVector<Expr *, 8> PrivateCopies; 12117 for (Expr *RefExpr : VarList) { 12118 assert(RefExpr && "NULL expr in OpenMP private clause."); 12119 SourceLocation ELoc; 12120 SourceRange ERange; 12121 Expr *SimpleRefExpr = RefExpr; 12122 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12123 if (Res.second) { 12124 // It will be analyzed later. 12125 Vars.push_back(RefExpr); 12126 PrivateCopies.push_back(nullptr); 12127 } 12128 ValueDecl *D = Res.first; 12129 if (!D) 12130 continue; 12131 12132 QualType Type = D->getType(); 12133 auto *VD = dyn_cast<VarDecl>(D); 12134 12135 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12136 // A variable that appears in a private clause must not have an incomplete 12137 // type or a reference type. 12138 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12139 continue; 12140 Type = Type.getNonReferenceType(); 12141 12142 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12143 // A variable that is privatized must not have a const-qualified type 12144 // unless it is of class type with a mutable member. This restriction does 12145 // not apply to the firstprivate clause. 12146 // 12147 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12148 // A variable that appears in a private clause must not have a 12149 // const-qualified type unless it is of class type with a mutable member. 12150 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12151 continue; 12152 12153 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12154 // in a Construct] 12155 // Variables with the predetermined data-sharing attributes may not be 12156 // listed in data-sharing attributes clauses, except for the cases 12157 // listed below. For these exceptions only, listing a predetermined 12158 // variable in a data-sharing attribute clause is allowed and overrides 12159 // the variable's predetermined data-sharing attributes. 12160 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12161 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12162 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12163 << getOpenMPClauseName(OMPC_private); 12164 reportOriginalDsa(*this, DSAStack, D, DVar); 12165 continue; 12166 } 12167 12168 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12169 // Variably modified types are not supported for tasks. 12170 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12171 isOpenMPTaskingDirective(CurrDir)) { 12172 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12173 << getOpenMPClauseName(OMPC_private) << Type 12174 << getOpenMPDirectiveName(CurrDir); 12175 bool IsDecl = 12176 !VD || 12177 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12178 Diag(D->getLocation(), 12179 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12180 << D; 12181 continue; 12182 } 12183 12184 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12185 // A list item cannot appear in both a map clause and a data-sharing 12186 // attribute clause on the same construct 12187 // 12188 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12189 // A list item cannot appear in both a map clause and a data-sharing 12190 // attribute clause on the same construct unless the construct is a 12191 // combined construct. 12192 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12193 CurrDir == OMPD_target) { 12194 OpenMPClauseKind ConflictKind; 12195 if (DSAStack->checkMappableExprComponentListsForDecl( 12196 VD, /*CurrentRegionOnly=*/true, 12197 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12198 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12199 ConflictKind = WhereFoundClauseKind; 12200 return true; 12201 })) { 12202 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12203 << getOpenMPClauseName(OMPC_private) 12204 << getOpenMPClauseName(ConflictKind) 12205 << getOpenMPDirectiveName(CurrDir); 12206 reportOriginalDsa(*this, DSAStack, D, DVar); 12207 continue; 12208 } 12209 } 12210 12211 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12212 // A variable of class type (or array thereof) that appears in a private 12213 // clause requires an accessible, unambiguous default constructor for the 12214 // class type. 12215 // Generate helper private variable and initialize it with the default 12216 // value. The address of the original variable is replaced by the address of 12217 // the new private variable in CodeGen. This new variable is not added to 12218 // IdResolver, so the code in the OpenMP region uses original variable for 12219 // proper diagnostics. 12220 Type = Type.getUnqualifiedType(); 12221 VarDecl *VDPrivate = 12222 buildVarDecl(*this, ELoc, Type, D->getName(), 12223 D->hasAttrs() ? &D->getAttrs() : nullptr, 12224 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12225 ActOnUninitializedDecl(VDPrivate); 12226 if (VDPrivate->isInvalidDecl()) 12227 continue; 12228 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12229 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12230 12231 DeclRefExpr *Ref = nullptr; 12232 if (!VD && !CurContext->isDependentContext()) 12233 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12234 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12235 Vars.push_back((VD || CurContext->isDependentContext()) 12236 ? RefExpr->IgnoreParens() 12237 : Ref); 12238 PrivateCopies.push_back(VDPrivateRefExpr); 12239 } 12240 12241 if (Vars.empty()) 12242 return nullptr; 12243 12244 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12245 PrivateCopies); 12246 } 12247 12248 namespace { 12249 class DiagsUninitializedSeveretyRAII { 12250 private: 12251 DiagnosticsEngine &Diags; 12252 SourceLocation SavedLoc; 12253 bool IsIgnored = false; 12254 12255 public: 12256 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12257 bool IsIgnored) 12258 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12259 if (!IsIgnored) { 12260 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12261 /*Map*/ diag::Severity::Ignored, Loc); 12262 } 12263 } 12264 ~DiagsUninitializedSeveretyRAII() { 12265 if (!IsIgnored) 12266 Diags.popMappings(SavedLoc); 12267 } 12268 }; 12269 } 12270 12271 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12272 SourceLocation StartLoc, 12273 SourceLocation LParenLoc, 12274 SourceLocation EndLoc) { 12275 SmallVector<Expr *, 8> Vars; 12276 SmallVector<Expr *, 8> PrivateCopies; 12277 SmallVector<Expr *, 8> Inits; 12278 SmallVector<Decl *, 4> ExprCaptures; 12279 bool IsImplicitClause = 12280 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12281 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12282 12283 for (Expr *RefExpr : VarList) { 12284 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12285 SourceLocation ELoc; 12286 SourceRange ERange; 12287 Expr *SimpleRefExpr = RefExpr; 12288 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12289 if (Res.second) { 12290 // It will be analyzed later. 12291 Vars.push_back(RefExpr); 12292 PrivateCopies.push_back(nullptr); 12293 Inits.push_back(nullptr); 12294 } 12295 ValueDecl *D = Res.first; 12296 if (!D) 12297 continue; 12298 12299 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12300 QualType Type = D->getType(); 12301 auto *VD = dyn_cast<VarDecl>(D); 12302 12303 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12304 // A variable that appears in a private clause must not have an incomplete 12305 // type or a reference type. 12306 if (RequireCompleteType(ELoc, Type, 12307 diag::err_omp_firstprivate_incomplete_type)) 12308 continue; 12309 Type = Type.getNonReferenceType(); 12310 12311 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12312 // A variable of class type (or array thereof) that appears in a private 12313 // clause requires an accessible, unambiguous copy constructor for the 12314 // class type. 12315 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12316 12317 // If an implicit firstprivate variable found it was checked already. 12318 DSAStackTy::DSAVarData TopDVar; 12319 if (!IsImplicitClause) { 12320 DSAStackTy::DSAVarData DVar = 12321 DSAStack->getTopDSA(D, /*FromParent=*/false); 12322 TopDVar = DVar; 12323 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12324 bool IsConstant = ElemType.isConstant(Context); 12325 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12326 // A list item that specifies a given variable may not appear in more 12327 // than one clause on the same directive, except that a variable may be 12328 // specified in both firstprivate and lastprivate clauses. 12329 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12330 // A list item may appear in a firstprivate or lastprivate clause but not 12331 // both. 12332 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12333 (isOpenMPDistributeDirective(CurrDir) || 12334 DVar.CKind != OMPC_lastprivate) && 12335 DVar.RefExpr) { 12336 Diag(ELoc, diag::err_omp_wrong_dsa) 12337 << getOpenMPClauseName(DVar.CKind) 12338 << getOpenMPClauseName(OMPC_firstprivate); 12339 reportOriginalDsa(*this, DSAStack, D, DVar); 12340 continue; 12341 } 12342 12343 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12344 // in a Construct] 12345 // Variables with the predetermined data-sharing attributes may not be 12346 // listed in data-sharing attributes clauses, except for the cases 12347 // listed below. For these exceptions only, listing a predetermined 12348 // variable in a data-sharing attribute clause is allowed and overrides 12349 // the variable's predetermined data-sharing attributes. 12350 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12351 // in a Construct, C/C++, p.2] 12352 // Variables with const-qualified type having no mutable member may be 12353 // listed in a firstprivate clause, even if they are static data members. 12354 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12355 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12356 Diag(ELoc, diag::err_omp_wrong_dsa) 12357 << getOpenMPClauseName(DVar.CKind) 12358 << getOpenMPClauseName(OMPC_firstprivate); 12359 reportOriginalDsa(*this, DSAStack, D, DVar); 12360 continue; 12361 } 12362 12363 // OpenMP [2.9.3.4, Restrictions, p.2] 12364 // A list item that is private within a parallel region must not appear 12365 // in a firstprivate clause on a worksharing construct if any of the 12366 // worksharing regions arising from the worksharing construct ever bind 12367 // to any of the parallel regions arising from the parallel construct. 12368 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12369 // A list item that is private within a teams region must not appear in a 12370 // firstprivate clause on a distribute construct if any of the distribute 12371 // regions arising from the distribute construct ever bind to any of the 12372 // teams regions arising from the teams construct. 12373 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12374 // A list item that appears in a reduction clause of a teams construct 12375 // must not appear in a firstprivate clause on a distribute construct if 12376 // any of the distribute regions arising from the distribute construct 12377 // ever bind to any of the teams regions arising from the teams construct. 12378 if ((isOpenMPWorksharingDirective(CurrDir) || 12379 isOpenMPDistributeDirective(CurrDir)) && 12380 !isOpenMPParallelDirective(CurrDir) && 12381 !isOpenMPTeamsDirective(CurrDir)) { 12382 DVar = DSAStack->getImplicitDSA(D, true); 12383 if (DVar.CKind != OMPC_shared && 12384 (isOpenMPParallelDirective(DVar.DKind) || 12385 isOpenMPTeamsDirective(DVar.DKind) || 12386 DVar.DKind == OMPD_unknown)) { 12387 Diag(ELoc, diag::err_omp_required_access) 12388 << getOpenMPClauseName(OMPC_firstprivate) 12389 << getOpenMPClauseName(OMPC_shared); 12390 reportOriginalDsa(*this, DSAStack, D, DVar); 12391 continue; 12392 } 12393 } 12394 // OpenMP [2.9.3.4, Restrictions, p.3] 12395 // A list item that appears in a reduction clause of a parallel construct 12396 // must not appear in a firstprivate clause on a worksharing or task 12397 // construct if any of the worksharing or task regions arising from the 12398 // worksharing or task construct ever bind to any of the parallel regions 12399 // arising from the parallel construct. 12400 // OpenMP [2.9.3.4, Restrictions, p.4] 12401 // A list item that appears in a reduction clause in worksharing 12402 // construct must not appear in a firstprivate clause in a task construct 12403 // encountered during execution of any of the worksharing regions arising 12404 // from the worksharing construct. 12405 if (isOpenMPTaskingDirective(CurrDir)) { 12406 DVar = DSAStack->hasInnermostDSA( 12407 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12408 [](OpenMPDirectiveKind K) { 12409 return isOpenMPParallelDirective(K) || 12410 isOpenMPWorksharingDirective(K) || 12411 isOpenMPTeamsDirective(K); 12412 }, 12413 /*FromParent=*/true); 12414 if (DVar.CKind == OMPC_reduction && 12415 (isOpenMPParallelDirective(DVar.DKind) || 12416 isOpenMPWorksharingDirective(DVar.DKind) || 12417 isOpenMPTeamsDirective(DVar.DKind))) { 12418 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12419 << getOpenMPDirectiveName(DVar.DKind); 12420 reportOriginalDsa(*this, DSAStack, D, DVar); 12421 continue; 12422 } 12423 } 12424 12425 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12426 // A list item cannot appear in both a map clause and a data-sharing 12427 // attribute clause on the same construct 12428 // 12429 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12430 // A list item cannot appear in both a map clause and a data-sharing 12431 // attribute clause on the same construct unless the construct is a 12432 // combined construct. 12433 if ((LangOpts.OpenMP <= 45 && 12434 isOpenMPTargetExecutionDirective(CurrDir)) || 12435 CurrDir == OMPD_target) { 12436 OpenMPClauseKind ConflictKind; 12437 if (DSAStack->checkMappableExprComponentListsForDecl( 12438 VD, /*CurrentRegionOnly=*/true, 12439 [&ConflictKind]( 12440 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12441 OpenMPClauseKind WhereFoundClauseKind) { 12442 ConflictKind = WhereFoundClauseKind; 12443 return true; 12444 })) { 12445 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12446 << getOpenMPClauseName(OMPC_firstprivate) 12447 << getOpenMPClauseName(ConflictKind) 12448 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12449 reportOriginalDsa(*this, DSAStack, D, DVar); 12450 continue; 12451 } 12452 } 12453 } 12454 12455 // Variably modified types are not supported for tasks. 12456 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12457 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12458 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12459 << getOpenMPClauseName(OMPC_firstprivate) << Type 12460 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12461 bool IsDecl = 12462 !VD || 12463 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12464 Diag(D->getLocation(), 12465 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12466 << D; 12467 continue; 12468 } 12469 12470 Type = Type.getUnqualifiedType(); 12471 VarDecl *VDPrivate = 12472 buildVarDecl(*this, ELoc, Type, D->getName(), 12473 D->hasAttrs() ? &D->getAttrs() : nullptr, 12474 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12475 // Generate helper private variable and initialize it with the value of the 12476 // original variable. The address of the original variable is replaced by 12477 // the address of the new private variable in the CodeGen. This new variable 12478 // is not added to IdResolver, so the code in the OpenMP region uses 12479 // original variable for proper diagnostics and variable capturing. 12480 Expr *VDInitRefExpr = nullptr; 12481 // For arrays generate initializer for single element and replace it by the 12482 // original array element in CodeGen. 12483 if (Type->isArrayType()) { 12484 VarDecl *VDInit = 12485 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12486 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12487 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12488 ElemType = ElemType.getUnqualifiedType(); 12489 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12490 ".firstprivate.temp"); 12491 InitializedEntity Entity = 12492 InitializedEntity::InitializeVariable(VDInitTemp); 12493 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12494 12495 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12496 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12497 if (Result.isInvalid()) 12498 VDPrivate->setInvalidDecl(); 12499 else 12500 VDPrivate->setInit(Result.getAs<Expr>()); 12501 // Remove temp variable declaration. 12502 Context.Deallocate(VDInitTemp); 12503 } else { 12504 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12505 ".firstprivate.temp"); 12506 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12507 RefExpr->getExprLoc()); 12508 AddInitializerToDecl(VDPrivate, 12509 DefaultLvalueConversion(VDInitRefExpr).get(), 12510 /*DirectInit=*/false); 12511 } 12512 if (VDPrivate->isInvalidDecl()) { 12513 if (IsImplicitClause) { 12514 Diag(RefExpr->getExprLoc(), 12515 diag::note_omp_task_predetermined_firstprivate_here); 12516 } 12517 continue; 12518 } 12519 CurContext->addDecl(VDPrivate); 12520 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12521 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12522 RefExpr->getExprLoc()); 12523 DeclRefExpr *Ref = nullptr; 12524 if (!VD && !CurContext->isDependentContext()) { 12525 if (TopDVar.CKind == OMPC_lastprivate) { 12526 Ref = TopDVar.PrivateCopy; 12527 } else { 12528 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12529 if (!isOpenMPCapturedDecl(D)) 12530 ExprCaptures.push_back(Ref->getDecl()); 12531 } 12532 } 12533 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12534 Vars.push_back((VD || CurContext->isDependentContext()) 12535 ? RefExpr->IgnoreParens() 12536 : Ref); 12537 PrivateCopies.push_back(VDPrivateRefExpr); 12538 Inits.push_back(VDInitRefExpr); 12539 } 12540 12541 if (Vars.empty()) 12542 return nullptr; 12543 12544 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12545 Vars, PrivateCopies, Inits, 12546 buildPreInits(Context, ExprCaptures)); 12547 } 12548 12549 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12550 SourceLocation StartLoc, 12551 SourceLocation LParenLoc, 12552 SourceLocation EndLoc) { 12553 SmallVector<Expr *, 8> Vars; 12554 SmallVector<Expr *, 8> SrcExprs; 12555 SmallVector<Expr *, 8> DstExprs; 12556 SmallVector<Expr *, 8> AssignmentOps; 12557 SmallVector<Decl *, 4> ExprCaptures; 12558 SmallVector<Expr *, 4> ExprPostUpdates; 12559 for (Expr *RefExpr : VarList) { 12560 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12561 SourceLocation ELoc; 12562 SourceRange ERange; 12563 Expr *SimpleRefExpr = RefExpr; 12564 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12565 if (Res.second) { 12566 // It will be analyzed later. 12567 Vars.push_back(RefExpr); 12568 SrcExprs.push_back(nullptr); 12569 DstExprs.push_back(nullptr); 12570 AssignmentOps.push_back(nullptr); 12571 } 12572 ValueDecl *D = Res.first; 12573 if (!D) 12574 continue; 12575 12576 QualType Type = D->getType(); 12577 auto *VD = dyn_cast<VarDecl>(D); 12578 12579 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12580 // A variable that appears in a lastprivate clause must not have an 12581 // incomplete type or a reference type. 12582 if (RequireCompleteType(ELoc, Type, 12583 diag::err_omp_lastprivate_incomplete_type)) 12584 continue; 12585 Type = Type.getNonReferenceType(); 12586 12587 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12588 // A variable that is privatized must not have a const-qualified type 12589 // unless it is of class type with a mutable member. This restriction does 12590 // not apply to the firstprivate clause. 12591 // 12592 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12593 // A variable that appears in a lastprivate clause must not have a 12594 // const-qualified type unless it is of class type with a mutable member. 12595 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12596 continue; 12597 12598 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12599 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12600 // in a Construct] 12601 // Variables with the predetermined data-sharing attributes may not be 12602 // listed in data-sharing attributes clauses, except for the cases 12603 // listed below. 12604 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12605 // A list item may appear in a firstprivate or lastprivate clause but not 12606 // both. 12607 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12608 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12609 (isOpenMPDistributeDirective(CurrDir) || 12610 DVar.CKind != OMPC_firstprivate) && 12611 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12612 Diag(ELoc, diag::err_omp_wrong_dsa) 12613 << getOpenMPClauseName(DVar.CKind) 12614 << getOpenMPClauseName(OMPC_lastprivate); 12615 reportOriginalDsa(*this, DSAStack, D, DVar); 12616 continue; 12617 } 12618 12619 // OpenMP [2.14.3.5, Restrictions, p.2] 12620 // A list item that is private within a parallel region, or that appears in 12621 // the reduction clause of a parallel construct, must not appear in a 12622 // lastprivate clause on a worksharing construct if any of the corresponding 12623 // worksharing regions ever binds to any of the corresponding parallel 12624 // regions. 12625 DSAStackTy::DSAVarData TopDVar = DVar; 12626 if (isOpenMPWorksharingDirective(CurrDir) && 12627 !isOpenMPParallelDirective(CurrDir) && 12628 !isOpenMPTeamsDirective(CurrDir)) { 12629 DVar = DSAStack->getImplicitDSA(D, true); 12630 if (DVar.CKind != OMPC_shared) { 12631 Diag(ELoc, diag::err_omp_required_access) 12632 << getOpenMPClauseName(OMPC_lastprivate) 12633 << getOpenMPClauseName(OMPC_shared); 12634 reportOriginalDsa(*this, DSAStack, D, DVar); 12635 continue; 12636 } 12637 } 12638 12639 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12640 // A variable of class type (or array thereof) that appears in a 12641 // lastprivate clause requires an accessible, unambiguous default 12642 // constructor for the class type, unless the list item is also specified 12643 // in a firstprivate clause. 12644 // A variable of class type (or array thereof) that appears in a 12645 // lastprivate clause requires an accessible, unambiguous copy assignment 12646 // operator for the class type. 12647 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12648 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12649 Type.getUnqualifiedType(), ".lastprivate.src", 12650 D->hasAttrs() ? &D->getAttrs() : nullptr); 12651 DeclRefExpr *PseudoSrcExpr = 12652 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12653 VarDecl *DstVD = 12654 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12655 D->hasAttrs() ? &D->getAttrs() : nullptr); 12656 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12657 // For arrays generate assignment operation for single element and replace 12658 // it by the original array element in CodeGen. 12659 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12660 PseudoDstExpr, PseudoSrcExpr); 12661 if (AssignmentOp.isInvalid()) 12662 continue; 12663 AssignmentOp = 12664 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12665 if (AssignmentOp.isInvalid()) 12666 continue; 12667 12668 DeclRefExpr *Ref = nullptr; 12669 if (!VD && !CurContext->isDependentContext()) { 12670 if (TopDVar.CKind == OMPC_firstprivate) { 12671 Ref = TopDVar.PrivateCopy; 12672 } else { 12673 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12674 if (!isOpenMPCapturedDecl(D)) 12675 ExprCaptures.push_back(Ref->getDecl()); 12676 } 12677 if (TopDVar.CKind == OMPC_firstprivate || 12678 (!isOpenMPCapturedDecl(D) && 12679 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12680 ExprResult RefRes = DefaultLvalueConversion(Ref); 12681 if (!RefRes.isUsable()) 12682 continue; 12683 ExprResult PostUpdateRes = 12684 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12685 RefRes.get()); 12686 if (!PostUpdateRes.isUsable()) 12687 continue; 12688 ExprPostUpdates.push_back( 12689 IgnoredValueConversions(PostUpdateRes.get()).get()); 12690 } 12691 } 12692 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12693 Vars.push_back((VD || CurContext->isDependentContext()) 12694 ? RefExpr->IgnoreParens() 12695 : Ref); 12696 SrcExprs.push_back(PseudoSrcExpr); 12697 DstExprs.push_back(PseudoDstExpr); 12698 AssignmentOps.push_back(AssignmentOp.get()); 12699 } 12700 12701 if (Vars.empty()) 12702 return nullptr; 12703 12704 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12705 Vars, SrcExprs, DstExprs, AssignmentOps, 12706 buildPreInits(Context, ExprCaptures), 12707 buildPostUpdate(*this, ExprPostUpdates)); 12708 } 12709 12710 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12711 SourceLocation StartLoc, 12712 SourceLocation LParenLoc, 12713 SourceLocation EndLoc) { 12714 SmallVector<Expr *, 8> Vars; 12715 for (Expr *RefExpr : VarList) { 12716 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12717 SourceLocation ELoc; 12718 SourceRange ERange; 12719 Expr *SimpleRefExpr = RefExpr; 12720 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12721 if (Res.second) { 12722 // It will be analyzed later. 12723 Vars.push_back(RefExpr); 12724 } 12725 ValueDecl *D = Res.first; 12726 if (!D) 12727 continue; 12728 12729 auto *VD = dyn_cast<VarDecl>(D); 12730 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12731 // in a Construct] 12732 // Variables with the predetermined data-sharing attributes may not be 12733 // listed in data-sharing attributes clauses, except for the cases 12734 // listed below. For these exceptions only, listing a predetermined 12735 // variable in a data-sharing attribute clause is allowed and overrides 12736 // the variable's predetermined data-sharing attributes. 12737 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12738 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12739 DVar.RefExpr) { 12740 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12741 << getOpenMPClauseName(OMPC_shared); 12742 reportOriginalDsa(*this, DSAStack, D, DVar); 12743 continue; 12744 } 12745 12746 DeclRefExpr *Ref = nullptr; 12747 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12748 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12749 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12750 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12751 ? RefExpr->IgnoreParens() 12752 : Ref); 12753 } 12754 12755 if (Vars.empty()) 12756 return nullptr; 12757 12758 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12759 } 12760 12761 namespace { 12762 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12763 DSAStackTy *Stack; 12764 12765 public: 12766 bool VisitDeclRefExpr(DeclRefExpr *E) { 12767 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12768 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12769 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12770 return false; 12771 if (DVar.CKind != OMPC_unknown) 12772 return true; 12773 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12774 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12775 /*FromParent=*/true); 12776 return DVarPrivate.CKind != OMPC_unknown; 12777 } 12778 return false; 12779 } 12780 bool VisitStmt(Stmt *S) { 12781 for (Stmt *Child : S->children()) { 12782 if (Child && Visit(Child)) 12783 return true; 12784 } 12785 return false; 12786 } 12787 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12788 }; 12789 } // namespace 12790 12791 namespace { 12792 // Transform MemberExpression for specified FieldDecl of current class to 12793 // DeclRefExpr to specified OMPCapturedExprDecl. 12794 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12795 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12796 ValueDecl *Field = nullptr; 12797 DeclRefExpr *CapturedExpr = nullptr; 12798 12799 public: 12800 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12801 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12802 12803 ExprResult TransformMemberExpr(MemberExpr *E) { 12804 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12805 E->getMemberDecl() == Field) { 12806 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12807 return CapturedExpr; 12808 } 12809 return BaseTransform::TransformMemberExpr(E); 12810 } 12811 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12812 }; 12813 } // namespace 12814 12815 template <typename T, typename U> 12816 static T filterLookupForUDReductionAndMapper( 12817 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12818 for (U &Set : Lookups) { 12819 for (auto *D : Set) { 12820 if (T Res = Gen(cast<ValueDecl>(D))) 12821 return Res; 12822 } 12823 } 12824 return T(); 12825 } 12826 12827 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12828 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12829 12830 for (auto RD : D->redecls()) { 12831 // Don't bother with extra checks if we already know this one isn't visible. 12832 if (RD == D) 12833 continue; 12834 12835 auto ND = cast<NamedDecl>(RD); 12836 if (LookupResult::isVisible(SemaRef, ND)) 12837 return ND; 12838 } 12839 12840 return nullptr; 12841 } 12842 12843 static void 12844 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12845 SourceLocation Loc, QualType Ty, 12846 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12847 // Find all of the associated namespaces and classes based on the 12848 // arguments we have. 12849 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12850 Sema::AssociatedClassSet AssociatedClasses; 12851 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12852 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12853 AssociatedClasses); 12854 12855 // C++ [basic.lookup.argdep]p3: 12856 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12857 // and let Y be the lookup set produced by argument dependent 12858 // lookup (defined as follows). If X contains [...] then Y is 12859 // empty. Otherwise Y is the set of declarations found in the 12860 // namespaces associated with the argument types as described 12861 // below. The set of declarations found by the lookup of the name 12862 // is the union of X and Y. 12863 // 12864 // Here, we compute Y and add its members to the overloaded 12865 // candidate set. 12866 for (auto *NS : AssociatedNamespaces) { 12867 // When considering an associated namespace, the lookup is the 12868 // same as the lookup performed when the associated namespace is 12869 // used as a qualifier (3.4.3.2) except that: 12870 // 12871 // -- Any using-directives in the associated namespace are 12872 // ignored. 12873 // 12874 // -- Any namespace-scope friend functions declared in 12875 // associated classes are visible within their respective 12876 // namespaces even if they are not visible during an ordinary 12877 // lookup (11.4). 12878 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12879 for (auto *D : R) { 12880 auto *Underlying = D; 12881 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12882 Underlying = USD->getTargetDecl(); 12883 12884 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12885 !isa<OMPDeclareMapperDecl>(Underlying)) 12886 continue; 12887 12888 if (!SemaRef.isVisible(D)) { 12889 D = findAcceptableDecl(SemaRef, D); 12890 if (!D) 12891 continue; 12892 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12893 Underlying = USD->getTargetDecl(); 12894 } 12895 Lookups.emplace_back(); 12896 Lookups.back().addDecl(Underlying); 12897 } 12898 } 12899 } 12900 12901 static ExprResult 12902 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12903 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12904 const DeclarationNameInfo &ReductionId, QualType Ty, 12905 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12906 if (ReductionIdScopeSpec.isInvalid()) 12907 return ExprError(); 12908 SmallVector<UnresolvedSet<8>, 4> Lookups; 12909 if (S) { 12910 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12911 Lookup.suppressDiagnostics(); 12912 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12913 NamedDecl *D = Lookup.getRepresentativeDecl(); 12914 do { 12915 S = S->getParent(); 12916 } while (S && !S->isDeclScope(D)); 12917 if (S) 12918 S = S->getParent(); 12919 Lookups.emplace_back(); 12920 Lookups.back().append(Lookup.begin(), Lookup.end()); 12921 Lookup.clear(); 12922 } 12923 } else if (auto *ULE = 12924 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12925 Lookups.push_back(UnresolvedSet<8>()); 12926 Decl *PrevD = nullptr; 12927 for (NamedDecl *D : ULE->decls()) { 12928 if (D == PrevD) 12929 Lookups.push_back(UnresolvedSet<8>()); 12930 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12931 Lookups.back().addDecl(DRD); 12932 PrevD = D; 12933 } 12934 } 12935 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12936 Ty->isInstantiationDependentType() || 12937 Ty->containsUnexpandedParameterPack() || 12938 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12939 return !D->isInvalidDecl() && 12940 (D->getType()->isDependentType() || 12941 D->getType()->isInstantiationDependentType() || 12942 D->getType()->containsUnexpandedParameterPack()); 12943 })) { 12944 UnresolvedSet<8> ResSet; 12945 for (const UnresolvedSet<8> &Set : Lookups) { 12946 if (Set.empty()) 12947 continue; 12948 ResSet.append(Set.begin(), Set.end()); 12949 // The last item marks the end of all declarations at the specified scope. 12950 ResSet.addDecl(Set[Set.size() - 1]); 12951 } 12952 return UnresolvedLookupExpr::Create( 12953 SemaRef.Context, /*NamingClass=*/nullptr, 12954 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12955 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12956 } 12957 // Lookup inside the classes. 12958 // C++ [over.match.oper]p3: 12959 // For a unary operator @ with an operand of a type whose 12960 // cv-unqualified version is T1, and for a binary operator @ with 12961 // a left operand of a type whose cv-unqualified version is T1 and 12962 // a right operand of a type whose cv-unqualified version is T2, 12963 // three sets of candidate functions, designated member 12964 // candidates, non-member candidates and built-in candidates, are 12965 // constructed as follows: 12966 // -- If T1 is a complete class type or a class currently being 12967 // defined, the set of member candidates is the result of the 12968 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12969 // the set of member candidates is empty. 12970 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12971 Lookup.suppressDiagnostics(); 12972 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12973 // Complete the type if it can be completed. 12974 // If the type is neither complete nor being defined, bail out now. 12975 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12976 TyRec->getDecl()->getDefinition()) { 12977 Lookup.clear(); 12978 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12979 if (Lookup.empty()) { 12980 Lookups.emplace_back(); 12981 Lookups.back().append(Lookup.begin(), Lookup.end()); 12982 } 12983 } 12984 } 12985 // Perform ADL. 12986 if (SemaRef.getLangOpts().CPlusPlus) 12987 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12988 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12989 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12990 if (!D->isInvalidDecl() && 12991 SemaRef.Context.hasSameType(D->getType(), Ty)) 12992 return D; 12993 return nullptr; 12994 })) 12995 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12996 VK_LValue, Loc); 12997 if (SemaRef.getLangOpts().CPlusPlus) { 12998 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12999 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13000 if (!D->isInvalidDecl() && 13001 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13002 !Ty.isMoreQualifiedThan(D->getType())) 13003 return D; 13004 return nullptr; 13005 })) { 13006 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13007 /*DetectVirtual=*/false); 13008 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13009 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13010 VD->getType().getUnqualifiedType()))) { 13011 if (SemaRef.CheckBaseClassAccess( 13012 Loc, VD->getType(), Ty, Paths.front(), 13013 /*DiagID=*/0) != Sema::AR_inaccessible) { 13014 SemaRef.BuildBasePathArray(Paths, BasePath); 13015 return SemaRef.BuildDeclRefExpr( 13016 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13017 } 13018 } 13019 } 13020 } 13021 } 13022 if (ReductionIdScopeSpec.isSet()) { 13023 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 13024 return ExprError(); 13025 } 13026 return ExprEmpty(); 13027 } 13028 13029 namespace { 13030 /// Data for the reduction-based clauses. 13031 struct ReductionData { 13032 /// List of original reduction items. 13033 SmallVector<Expr *, 8> Vars; 13034 /// List of private copies of the reduction items. 13035 SmallVector<Expr *, 8> Privates; 13036 /// LHS expressions for the reduction_op expressions. 13037 SmallVector<Expr *, 8> LHSs; 13038 /// RHS expressions for the reduction_op expressions. 13039 SmallVector<Expr *, 8> RHSs; 13040 /// Reduction operation expression. 13041 SmallVector<Expr *, 8> ReductionOps; 13042 /// Taskgroup descriptors for the corresponding reduction items in 13043 /// in_reduction clauses. 13044 SmallVector<Expr *, 8> TaskgroupDescriptors; 13045 /// List of captures for clause. 13046 SmallVector<Decl *, 4> ExprCaptures; 13047 /// List of postupdate expressions. 13048 SmallVector<Expr *, 4> ExprPostUpdates; 13049 ReductionData() = delete; 13050 /// Reserves required memory for the reduction data. 13051 ReductionData(unsigned Size) { 13052 Vars.reserve(Size); 13053 Privates.reserve(Size); 13054 LHSs.reserve(Size); 13055 RHSs.reserve(Size); 13056 ReductionOps.reserve(Size); 13057 TaskgroupDescriptors.reserve(Size); 13058 ExprCaptures.reserve(Size); 13059 ExprPostUpdates.reserve(Size); 13060 } 13061 /// Stores reduction item and reduction operation only (required for dependent 13062 /// reduction item). 13063 void push(Expr *Item, Expr *ReductionOp) { 13064 Vars.emplace_back(Item); 13065 Privates.emplace_back(nullptr); 13066 LHSs.emplace_back(nullptr); 13067 RHSs.emplace_back(nullptr); 13068 ReductionOps.emplace_back(ReductionOp); 13069 TaskgroupDescriptors.emplace_back(nullptr); 13070 } 13071 /// Stores reduction data. 13072 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13073 Expr *TaskgroupDescriptor) { 13074 Vars.emplace_back(Item); 13075 Privates.emplace_back(Private); 13076 LHSs.emplace_back(LHS); 13077 RHSs.emplace_back(RHS); 13078 ReductionOps.emplace_back(ReductionOp); 13079 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13080 } 13081 }; 13082 } // namespace 13083 13084 static bool checkOMPArraySectionConstantForReduction( 13085 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13086 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13087 const Expr *Length = OASE->getLength(); 13088 if (Length == nullptr) { 13089 // For array sections of the form [1:] or [:], we would need to analyze 13090 // the lower bound... 13091 if (OASE->getColonLoc().isValid()) 13092 return false; 13093 13094 // This is an array subscript which has implicit length 1! 13095 SingleElement = true; 13096 ArraySizes.push_back(llvm::APSInt::get(1)); 13097 } else { 13098 Expr::EvalResult Result; 13099 if (!Length->EvaluateAsInt(Result, Context)) 13100 return false; 13101 13102 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13103 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13104 ArraySizes.push_back(ConstantLengthValue); 13105 } 13106 13107 // Get the base of this array section and walk up from there. 13108 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13109 13110 // We require length = 1 for all array sections except the right-most to 13111 // guarantee that the memory region is contiguous and has no holes in it. 13112 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13113 Length = TempOASE->getLength(); 13114 if (Length == nullptr) { 13115 // For array sections of the form [1:] or [:], we would need to analyze 13116 // the lower bound... 13117 if (OASE->getColonLoc().isValid()) 13118 return false; 13119 13120 // This is an array subscript which has implicit length 1! 13121 ArraySizes.push_back(llvm::APSInt::get(1)); 13122 } else { 13123 Expr::EvalResult Result; 13124 if (!Length->EvaluateAsInt(Result, Context)) 13125 return false; 13126 13127 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13128 if (ConstantLengthValue.getSExtValue() != 1) 13129 return false; 13130 13131 ArraySizes.push_back(ConstantLengthValue); 13132 } 13133 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13134 } 13135 13136 // If we have a single element, we don't need to add the implicit lengths. 13137 if (!SingleElement) { 13138 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13139 // Has implicit length 1! 13140 ArraySizes.push_back(llvm::APSInt::get(1)); 13141 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13142 } 13143 } 13144 13145 // This array section can be privatized as a single value or as a constant 13146 // sized array. 13147 return true; 13148 } 13149 13150 static bool actOnOMPReductionKindClause( 13151 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13152 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13153 SourceLocation ColonLoc, SourceLocation EndLoc, 13154 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13155 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13156 DeclarationName DN = ReductionId.getName(); 13157 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13158 BinaryOperatorKind BOK = BO_Comma; 13159 13160 ASTContext &Context = S.Context; 13161 // OpenMP [2.14.3.6, reduction clause] 13162 // C 13163 // reduction-identifier is either an identifier or one of the following 13164 // operators: +, -, *, &, |, ^, && and || 13165 // C++ 13166 // reduction-identifier is either an id-expression or one of the following 13167 // operators: +, -, *, &, |, ^, && and || 13168 switch (OOK) { 13169 case OO_Plus: 13170 case OO_Minus: 13171 BOK = BO_Add; 13172 break; 13173 case OO_Star: 13174 BOK = BO_Mul; 13175 break; 13176 case OO_Amp: 13177 BOK = BO_And; 13178 break; 13179 case OO_Pipe: 13180 BOK = BO_Or; 13181 break; 13182 case OO_Caret: 13183 BOK = BO_Xor; 13184 break; 13185 case OO_AmpAmp: 13186 BOK = BO_LAnd; 13187 break; 13188 case OO_PipePipe: 13189 BOK = BO_LOr; 13190 break; 13191 case OO_New: 13192 case OO_Delete: 13193 case OO_Array_New: 13194 case OO_Array_Delete: 13195 case OO_Slash: 13196 case OO_Percent: 13197 case OO_Tilde: 13198 case OO_Exclaim: 13199 case OO_Equal: 13200 case OO_Less: 13201 case OO_Greater: 13202 case OO_LessEqual: 13203 case OO_GreaterEqual: 13204 case OO_PlusEqual: 13205 case OO_MinusEqual: 13206 case OO_StarEqual: 13207 case OO_SlashEqual: 13208 case OO_PercentEqual: 13209 case OO_CaretEqual: 13210 case OO_AmpEqual: 13211 case OO_PipeEqual: 13212 case OO_LessLess: 13213 case OO_GreaterGreater: 13214 case OO_LessLessEqual: 13215 case OO_GreaterGreaterEqual: 13216 case OO_EqualEqual: 13217 case OO_ExclaimEqual: 13218 case OO_Spaceship: 13219 case OO_PlusPlus: 13220 case OO_MinusMinus: 13221 case OO_Comma: 13222 case OO_ArrowStar: 13223 case OO_Arrow: 13224 case OO_Call: 13225 case OO_Subscript: 13226 case OO_Conditional: 13227 case OO_Coawait: 13228 case NUM_OVERLOADED_OPERATORS: 13229 llvm_unreachable("Unexpected reduction identifier"); 13230 case OO_None: 13231 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13232 if (II->isStr("max")) 13233 BOK = BO_GT; 13234 else if (II->isStr("min")) 13235 BOK = BO_LT; 13236 } 13237 break; 13238 } 13239 SourceRange ReductionIdRange; 13240 if (ReductionIdScopeSpec.isValid()) 13241 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13242 else 13243 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13244 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13245 13246 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13247 bool FirstIter = true; 13248 for (Expr *RefExpr : VarList) { 13249 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13250 // OpenMP [2.1, C/C++] 13251 // A list item is a variable or array section, subject to the restrictions 13252 // specified in Section 2.4 on page 42 and in each of the sections 13253 // describing clauses and directives for which a list appears. 13254 // OpenMP [2.14.3.3, Restrictions, p.1] 13255 // A variable that is part of another variable (as an array or 13256 // structure element) cannot appear in a private clause. 13257 if (!FirstIter && IR != ER) 13258 ++IR; 13259 FirstIter = false; 13260 SourceLocation ELoc; 13261 SourceRange ERange; 13262 Expr *SimpleRefExpr = RefExpr; 13263 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13264 /*AllowArraySection=*/true); 13265 if (Res.second) { 13266 // Try to find 'declare reduction' corresponding construct before using 13267 // builtin/overloaded operators. 13268 QualType Type = Context.DependentTy; 13269 CXXCastPath BasePath; 13270 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13271 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13272 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13273 Expr *ReductionOp = nullptr; 13274 if (S.CurContext->isDependentContext() && 13275 (DeclareReductionRef.isUnset() || 13276 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13277 ReductionOp = DeclareReductionRef.get(); 13278 // It will be analyzed later. 13279 RD.push(RefExpr, ReductionOp); 13280 } 13281 ValueDecl *D = Res.first; 13282 if (!D) 13283 continue; 13284 13285 Expr *TaskgroupDescriptor = nullptr; 13286 QualType Type; 13287 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13288 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13289 if (ASE) { 13290 Type = ASE->getType().getNonReferenceType(); 13291 } else if (OASE) { 13292 QualType BaseType = 13293 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13294 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13295 Type = ATy->getElementType(); 13296 else 13297 Type = BaseType->getPointeeType(); 13298 Type = Type.getNonReferenceType(); 13299 } else { 13300 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13301 } 13302 auto *VD = dyn_cast<VarDecl>(D); 13303 13304 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13305 // A variable that appears in a private clause must not have an incomplete 13306 // type or a reference type. 13307 if (S.RequireCompleteType(ELoc, D->getType(), 13308 diag::err_omp_reduction_incomplete_type)) 13309 continue; 13310 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13311 // A list item that appears in a reduction clause must not be 13312 // const-qualified. 13313 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13314 /*AcceptIfMutable*/ false, ASE || OASE)) 13315 continue; 13316 13317 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13318 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13319 // If a list-item is a reference type then it must bind to the same object 13320 // for all threads of the team. 13321 if (!ASE && !OASE) { 13322 if (VD) { 13323 VarDecl *VDDef = VD->getDefinition(); 13324 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13325 DSARefChecker Check(Stack); 13326 if (Check.Visit(VDDef->getInit())) { 13327 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13328 << getOpenMPClauseName(ClauseKind) << ERange; 13329 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13330 continue; 13331 } 13332 } 13333 } 13334 13335 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13336 // in a Construct] 13337 // Variables with the predetermined data-sharing attributes may not be 13338 // listed in data-sharing attributes clauses, except for the cases 13339 // listed below. For these exceptions only, listing a predetermined 13340 // variable in a data-sharing attribute clause is allowed and overrides 13341 // the variable's predetermined data-sharing attributes. 13342 // OpenMP [2.14.3.6, Restrictions, p.3] 13343 // Any number of reduction clauses can be specified on the directive, 13344 // but a list item can appear only once in the reduction clauses for that 13345 // directive. 13346 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13347 if (DVar.CKind == OMPC_reduction) { 13348 S.Diag(ELoc, diag::err_omp_once_referenced) 13349 << getOpenMPClauseName(ClauseKind); 13350 if (DVar.RefExpr) 13351 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13352 continue; 13353 } 13354 if (DVar.CKind != OMPC_unknown) { 13355 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13356 << getOpenMPClauseName(DVar.CKind) 13357 << getOpenMPClauseName(OMPC_reduction); 13358 reportOriginalDsa(S, Stack, D, DVar); 13359 continue; 13360 } 13361 13362 // OpenMP [2.14.3.6, Restrictions, p.1] 13363 // A list item that appears in a reduction clause of a worksharing 13364 // construct must be shared in the parallel regions to which any of the 13365 // worksharing regions arising from the worksharing construct bind. 13366 if (isOpenMPWorksharingDirective(CurrDir) && 13367 !isOpenMPParallelDirective(CurrDir) && 13368 !isOpenMPTeamsDirective(CurrDir)) { 13369 DVar = Stack->getImplicitDSA(D, true); 13370 if (DVar.CKind != OMPC_shared) { 13371 S.Diag(ELoc, diag::err_omp_required_access) 13372 << getOpenMPClauseName(OMPC_reduction) 13373 << getOpenMPClauseName(OMPC_shared); 13374 reportOriginalDsa(S, Stack, D, DVar); 13375 continue; 13376 } 13377 } 13378 } 13379 13380 // Try to find 'declare reduction' corresponding construct before using 13381 // builtin/overloaded operators. 13382 CXXCastPath BasePath; 13383 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13384 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13385 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13386 if (DeclareReductionRef.isInvalid()) 13387 continue; 13388 if (S.CurContext->isDependentContext() && 13389 (DeclareReductionRef.isUnset() || 13390 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13391 RD.push(RefExpr, DeclareReductionRef.get()); 13392 continue; 13393 } 13394 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13395 // Not allowed reduction identifier is found. 13396 S.Diag(ReductionId.getBeginLoc(), 13397 diag::err_omp_unknown_reduction_identifier) 13398 << Type << ReductionIdRange; 13399 continue; 13400 } 13401 13402 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13403 // The type of a list item that appears in a reduction clause must be valid 13404 // for the reduction-identifier. For a max or min reduction in C, the type 13405 // of the list item must be an allowed arithmetic data type: char, int, 13406 // float, double, or _Bool, possibly modified with long, short, signed, or 13407 // unsigned. For a max or min reduction in C++, the type of the list item 13408 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13409 // double, or bool, possibly modified with long, short, signed, or unsigned. 13410 if (DeclareReductionRef.isUnset()) { 13411 if ((BOK == BO_GT || BOK == BO_LT) && 13412 !(Type->isScalarType() || 13413 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13414 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13415 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13416 if (!ASE && !OASE) { 13417 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13418 VarDecl::DeclarationOnly; 13419 S.Diag(D->getLocation(), 13420 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13421 << D; 13422 } 13423 continue; 13424 } 13425 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13426 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13427 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13428 << getOpenMPClauseName(ClauseKind); 13429 if (!ASE && !OASE) { 13430 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13431 VarDecl::DeclarationOnly; 13432 S.Diag(D->getLocation(), 13433 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13434 << D; 13435 } 13436 continue; 13437 } 13438 } 13439 13440 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13441 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13442 D->hasAttrs() ? &D->getAttrs() : nullptr); 13443 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13444 D->hasAttrs() ? &D->getAttrs() : nullptr); 13445 QualType PrivateTy = Type; 13446 13447 // Try if we can determine constant lengths for all array sections and avoid 13448 // the VLA. 13449 bool ConstantLengthOASE = false; 13450 if (OASE) { 13451 bool SingleElement; 13452 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13453 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13454 Context, OASE, SingleElement, ArraySizes); 13455 13456 // If we don't have a single element, we must emit a constant array type. 13457 if (ConstantLengthOASE && !SingleElement) { 13458 for (llvm::APSInt &Size : ArraySizes) 13459 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13460 ArrayType::Normal, 13461 /*IndexTypeQuals=*/0); 13462 } 13463 } 13464 13465 if ((OASE && !ConstantLengthOASE) || 13466 (!OASE && !ASE && 13467 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13468 if (!Context.getTargetInfo().isVLASupported()) { 13469 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13470 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13471 S.Diag(ELoc, diag::note_vla_unsupported); 13472 } else { 13473 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13474 S.targetDiag(ELoc, diag::note_vla_unsupported); 13475 } 13476 continue; 13477 } 13478 // For arrays/array sections only: 13479 // Create pseudo array type for private copy. The size for this array will 13480 // be generated during codegen. 13481 // For array subscripts or single variables Private Ty is the same as Type 13482 // (type of the variable or single array element). 13483 PrivateTy = Context.getVariableArrayType( 13484 Type, 13485 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13486 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13487 } else if (!ASE && !OASE && 13488 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13489 PrivateTy = D->getType().getNonReferenceType(); 13490 } 13491 // Private copy. 13492 VarDecl *PrivateVD = 13493 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13494 D->hasAttrs() ? &D->getAttrs() : nullptr, 13495 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13496 // Add initializer for private variable. 13497 Expr *Init = nullptr; 13498 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13499 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13500 if (DeclareReductionRef.isUsable()) { 13501 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13502 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13503 if (DRD->getInitializer()) { 13504 Init = DRDRef; 13505 RHSVD->setInit(DRDRef); 13506 RHSVD->setInitStyle(VarDecl::CallInit); 13507 } 13508 } else { 13509 switch (BOK) { 13510 case BO_Add: 13511 case BO_Xor: 13512 case BO_Or: 13513 case BO_LOr: 13514 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13515 if (Type->isScalarType() || Type->isAnyComplexType()) 13516 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13517 break; 13518 case BO_Mul: 13519 case BO_LAnd: 13520 if (Type->isScalarType() || Type->isAnyComplexType()) { 13521 // '*' and '&&' reduction ops - initializer is '1'. 13522 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13523 } 13524 break; 13525 case BO_And: { 13526 // '&' reduction op - initializer is '~0'. 13527 QualType OrigType = Type; 13528 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13529 Type = ComplexTy->getElementType(); 13530 if (Type->isRealFloatingType()) { 13531 llvm::APFloat InitValue = 13532 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13533 /*isIEEE=*/true); 13534 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13535 Type, ELoc); 13536 } else if (Type->isScalarType()) { 13537 uint64_t Size = Context.getTypeSize(Type); 13538 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13539 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13540 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13541 } 13542 if (Init && OrigType->isAnyComplexType()) { 13543 // Init = 0xFFFF + 0xFFFFi; 13544 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13545 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13546 } 13547 Type = OrigType; 13548 break; 13549 } 13550 case BO_LT: 13551 case BO_GT: { 13552 // 'min' reduction op - initializer is 'Largest representable number in 13553 // the reduction list item type'. 13554 // 'max' reduction op - initializer is 'Least representable number in 13555 // the reduction list item type'. 13556 if (Type->isIntegerType() || Type->isPointerType()) { 13557 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13558 uint64_t Size = Context.getTypeSize(Type); 13559 QualType IntTy = 13560 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13561 llvm::APInt InitValue = 13562 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13563 : llvm::APInt::getMinValue(Size) 13564 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13565 : llvm::APInt::getMaxValue(Size); 13566 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13567 if (Type->isPointerType()) { 13568 // Cast to pointer type. 13569 ExprResult CastExpr = S.BuildCStyleCastExpr( 13570 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13571 if (CastExpr.isInvalid()) 13572 continue; 13573 Init = CastExpr.get(); 13574 } 13575 } else if (Type->isRealFloatingType()) { 13576 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13577 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13578 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13579 Type, ELoc); 13580 } 13581 break; 13582 } 13583 case BO_PtrMemD: 13584 case BO_PtrMemI: 13585 case BO_MulAssign: 13586 case BO_Div: 13587 case BO_Rem: 13588 case BO_Sub: 13589 case BO_Shl: 13590 case BO_Shr: 13591 case BO_LE: 13592 case BO_GE: 13593 case BO_EQ: 13594 case BO_NE: 13595 case BO_Cmp: 13596 case BO_AndAssign: 13597 case BO_XorAssign: 13598 case BO_OrAssign: 13599 case BO_Assign: 13600 case BO_AddAssign: 13601 case BO_SubAssign: 13602 case BO_DivAssign: 13603 case BO_RemAssign: 13604 case BO_ShlAssign: 13605 case BO_ShrAssign: 13606 case BO_Comma: 13607 llvm_unreachable("Unexpected reduction operation"); 13608 } 13609 } 13610 if (Init && DeclareReductionRef.isUnset()) 13611 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13612 else if (!Init) 13613 S.ActOnUninitializedDecl(RHSVD); 13614 if (RHSVD->isInvalidDecl()) 13615 continue; 13616 if (!RHSVD->hasInit() && 13617 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13618 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13619 << Type << ReductionIdRange; 13620 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13621 VarDecl::DeclarationOnly; 13622 S.Diag(D->getLocation(), 13623 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13624 << D; 13625 continue; 13626 } 13627 // Store initializer for single element in private copy. Will be used during 13628 // codegen. 13629 PrivateVD->setInit(RHSVD->getInit()); 13630 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13631 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13632 ExprResult ReductionOp; 13633 if (DeclareReductionRef.isUsable()) { 13634 QualType RedTy = DeclareReductionRef.get()->getType(); 13635 QualType PtrRedTy = Context.getPointerType(RedTy); 13636 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13637 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13638 if (!BasePath.empty()) { 13639 LHS = S.DefaultLvalueConversion(LHS.get()); 13640 RHS = S.DefaultLvalueConversion(RHS.get()); 13641 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13642 CK_UncheckedDerivedToBase, LHS.get(), 13643 &BasePath, LHS.get()->getValueKind()); 13644 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13645 CK_UncheckedDerivedToBase, RHS.get(), 13646 &BasePath, RHS.get()->getValueKind()); 13647 } 13648 FunctionProtoType::ExtProtoInfo EPI; 13649 QualType Params[] = {PtrRedTy, PtrRedTy}; 13650 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13651 auto *OVE = new (Context) OpaqueValueExpr( 13652 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13653 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13654 Expr *Args[] = {LHS.get(), RHS.get()}; 13655 ReductionOp = 13656 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13657 } else { 13658 ReductionOp = S.BuildBinOp( 13659 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13660 if (ReductionOp.isUsable()) { 13661 if (BOK != BO_LT && BOK != BO_GT) { 13662 ReductionOp = 13663 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13664 BO_Assign, LHSDRE, ReductionOp.get()); 13665 } else { 13666 auto *ConditionalOp = new (Context) 13667 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13668 Type, VK_LValue, OK_Ordinary); 13669 ReductionOp = 13670 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13671 BO_Assign, LHSDRE, ConditionalOp); 13672 } 13673 if (ReductionOp.isUsable()) 13674 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13675 /*DiscardedValue*/ false); 13676 } 13677 if (!ReductionOp.isUsable()) 13678 continue; 13679 } 13680 13681 // OpenMP [2.15.4.6, Restrictions, p.2] 13682 // A list item that appears in an in_reduction clause of a task construct 13683 // must appear in a task_reduction clause of a construct associated with a 13684 // taskgroup region that includes the participating task in its taskgroup 13685 // set. The construct associated with the innermost region that meets this 13686 // condition must specify the same reduction-identifier as the in_reduction 13687 // clause. 13688 if (ClauseKind == OMPC_in_reduction) { 13689 SourceRange ParentSR; 13690 BinaryOperatorKind ParentBOK; 13691 const Expr *ParentReductionOp; 13692 Expr *ParentBOKTD, *ParentReductionOpTD; 13693 DSAStackTy::DSAVarData ParentBOKDSA = 13694 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13695 ParentBOKTD); 13696 DSAStackTy::DSAVarData ParentReductionOpDSA = 13697 Stack->getTopMostTaskgroupReductionData( 13698 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13699 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13700 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13701 if (!IsParentBOK && !IsParentReductionOp) { 13702 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13703 continue; 13704 } 13705 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13706 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13707 IsParentReductionOp) { 13708 bool EmitError = true; 13709 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13710 llvm::FoldingSetNodeID RedId, ParentRedId; 13711 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13712 DeclareReductionRef.get()->Profile(RedId, Context, 13713 /*Canonical=*/true); 13714 EmitError = RedId != ParentRedId; 13715 } 13716 if (EmitError) { 13717 S.Diag(ReductionId.getBeginLoc(), 13718 diag::err_omp_reduction_identifier_mismatch) 13719 << ReductionIdRange << RefExpr->getSourceRange(); 13720 S.Diag(ParentSR.getBegin(), 13721 diag::note_omp_previous_reduction_identifier) 13722 << ParentSR 13723 << (IsParentBOK ? ParentBOKDSA.RefExpr 13724 : ParentReductionOpDSA.RefExpr) 13725 ->getSourceRange(); 13726 continue; 13727 } 13728 } 13729 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13730 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13731 } 13732 13733 DeclRefExpr *Ref = nullptr; 13734 Expr *VarsExpr = RefExpr->IgnoreParens(); 13735 if (!VD && !S.CurContext->isDependentContext()) { 13736 if (ASE || OASE) { 13737 TransformExprToCaptures RebuildToCapture(S, D); 13738 VarsExpr = 13739 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13740 Ref = RebuildToCapture.getCapturedExpr(); 13741 } else { 13742 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13743 } 13744 if (!S.isOpenMPCapturedDecl(D)) { 13745 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13746 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13747 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13748 if (!RefRes.isUsable()) 13749 continue; 13750 ExprResult PostUpdateRes = 13751 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13752 RefRes.get()); 13753 if (!PostUpdateRes.isUsable()) 13754 continue; 13755 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13756 Stack->getCurrentDirective() == OMPD_taskgroup) { 13757 S.Diag(RefExpr->getExprLoc(), 13758 diag::err_omp_reduction_non_addressable_expression) 13759 << RefExpr->getSourceRange(); 13760 continue; 13761 } 13762 RD.ExprPostUpdates.emplace_back( 13763 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13764 } 13765 } 13766 } 13767 // All reduction items are still marked as reduction (to do not increase 13768 // code base size). 13769 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13770 if (CurrDir == OMPD_taskgroup) { 13771 if (DeclareReductionRef.isUsable()) 13772 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13773 DeclareReductionRef.get()); 13774 else 13775 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13776 } 13777 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13778 TaskgroupDescriptor); 13779 } 13780 return RD.Vars.empty(); 13781 } 13782 13783 OMPClause *Sema::ActOnOpenMPReductionClause( 13784 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13785 SourceLocation ColonLoc, SourceLocation EndLoc, 13786 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13787 ArrayRef<Expr *> UnresolvedReductions) { 13788 ReductionData RD(VarList.size()); 13789 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13790 StartLoc, LParenLoc, ColonLoc, EndLoc, 13791 ReductionIdScopeSpec, ReductionId, 13792 UnresolvedReductions, RD)) 13793 return nullptr; 13794 13795 return OMPReductionClause::Create( 13796 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13797 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13798 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13799 buildPreInits(Context, RD.ExprCaptures), 13800 buildPostUpdate(*this, RD.ExprPostUpdates)); 13801 } 13802 13803 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13804 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13805 SourceLocation ColonLoc, SourceLocation EndLoc, 13806 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13807 ArrayRef<Expr *> UnresolvedReductions) { 13808 ReductionData RD(VarList.size()); 13809 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13810 StartLoc, LParenLoc, ColonLoc, EndLoc, 13811 ReductionIdScopeSpec, ReductionId, 13812 UnresolvedReductions, RD)) 13813 return nullptr; 13814 13815 return OMPTaskReductionClause::Create( 13816 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13817 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13818 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13819 buildPreInits(Context, RD.ExprCaptures), 13820 buildPostUpdate(*this, RD.ExprPostUpdates)); 13821 } 13822 13823 OMPClause *Sema::ActOnOpenMPInReductionClause( 13824 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13825 SourceLocation ColonLoc, SourceLocation EndLoc, 13826 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13827 ArrayRef<Expr *> UnresolvedReductions) { 13828 ReductionData RD(VarList.size()); 13829 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13830 StartLoc, LParenLoc, ColonLoc, EndLoc, 13831 ReductionIdScopeSpec, ReductionId, 13832 UnresolvedReductions, RD)) 13833 return nullptr; 13834 13835 return OMPInReductionClause::Create( 13836 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13837 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13838 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13839 buildPreInits(Context, RD.ExprCaptures), 13840 buildPostUpdate(*this, RD.ExprPostUpdates)); 13841 } 13842 13843 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13844 SourceLocation LinLoc) { 13845 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13846 LinKind == OMPC_LINEAR_unknown) { 13847 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13848 return true; 13849 } 13850 return false; 13851 } 13852 13853 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13854 OpenMPLinearClauseKind LinKind, 13855 QualType Type) { 13856 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13857 // A variable must not have an incomplete type or a reference type. 13858 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13859 return true; 13860 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13861 !Type->isReferenceType()) { 13862 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13863 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13864 return true; 13865 } 13866 Type = Type.getNonReferenceType(); 13867 13868 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13869 // A variable that is privatized must not have a const-qualified type 13870 // unless it is of class type with a mutable member. This restriction does 13871 // not apply to the firstprivate clause. 13872 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13873 return true; 13874 13875 // A list item must be of integral or pointer type. 13876 Type = Type.getUnqualifiedType().getCanonicalType(); 13877 const auto *Ty = Type.getTypePtrOrNull(); 13878 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13879 !Ty->isPointerType())) { 13880 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13881 if (D) { 13882 bool IsDecl = 13883 !VD || 13884 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13885 Diag(D->getLocation(), 13886 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13887 << D; 13888 } 13889 return true; 13890 } 13891 return false; 13892 } 13893 13894 OMPClause *Sema::ActOnOpenMPLinearClause( 13895 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13896 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13897 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13898 SmallVector<Expr *, 8> Vars; 13899 SmallVector<Expr *, 8> Privates; 13900 SmallVector<Expr *, 8> Inits; 13901 SmallVector<Decl *, 4> ExprCaptures; 13902 SmallVector<Expr *, 4> ExprPostUpdates; 13903 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13904 LinKind = OMPC_LINEAR_val; 13905 for (Expr *RefExpr : VarList) { 13906 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13907 SourceLocation ELoc; 13908 SourceRange ERange; 13909 Expr *SimpleRefExpr = RefExpr; 13910 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13911 if (Res.second) { 13912 // It will be analyzed later. 13913 Vars.push_back(RefExpr); 13914 Privates.push_back(nullptr); 13915 Inits.push_back(nullptr); 13916 } 13917 ValueDecl *D = Res.first; 13918 if (!D) 13919 continue; 13920 13921 QualType Type = D->getType(); 13922 auto *VD = dyn_cast<VarDecl>(D); 13923 13924 // OpenMP [2.14.3.7, linear clause] 13925 // A list-item cannot appear in more than one linear clause. 13926 // A list-item that appears in a linear clause cannot appear in any 13927 // other data-sharing attribute clause. 13928 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13929 if (DVar.RefExpr) { 13930 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13931 << getOpenMPClauseName(OMPC_linear); 13932 reportOriginalDsa(*this, DSAStack, D, DVar); 13933 continue; 13934 } 13935 13936 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13937 continue; 13938 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13939 13940 // Build private copy of original var. 13941 VarDecl *Private = 13942 buildVarDecl(*this, ELoc, Type, D->getName(), 13943 D->hasAttrs() ? &D->getAttrs() : nullptr, 13944 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13945 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13946 // Build var to save initial value. 13947 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13948 Expr *InitExpr; 13949 DeclRefExpr *Ref = nullptr; 13950 if (!VD && !CurContext->isDependentContext()) { 13951 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13952 if (!isOpenMPCapturedDecl(D)) { 13953 ExprCaptures.push_back(Ref->getDecl()); 13954 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13955 ExprResult RefRes = DefaultLvalueConversion(Ref); 13956 if (!RefRes.isUsable()) 13957 continue; 13958 ExprResult PostUpdateRes = 13959 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13960 SimpleRefExpr, RefRes.get()); 13961 if (!PostUpdateRes.isUsable()) 13962 continue; 13963 ExprPostUpdates.push_back( 13964 IgnoredValueConversions(PostUpdateRes.get()).get()); 13965 } 13966 } 13967 } 13968 if (LinKind == OMPC_LINEAR_uval) 13969 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13970 else 13971 InitExpr = VD ? SimpleRefExpr : Ref; 13972 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13973 /*DirectInit=*/false); 13974 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13975 13976 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13977 Vars.push_back((VD || CurContext->isDependentContext()) 13978 ? RefExpr->IgnoreParens() 13979 : Ref); 13980 Privates.push_back(PrivateRef); 13981 Inits.push_back(InitRef); 13982 } 13983 13984 if (Vars.empty()) 13985 return nullptr; 13986 13987 Expr *StepExpr = Step; 13988 Expr *CalcStepExpr = nullptr; 13989 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13990 !Step->isInstantiationDependent() && 13991 !Step->containsUnexpandedParameterPack()) { 13992 SourceLocation StepLoc = Step->getBeginLoc(); 13993 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13994 if (Val.isInvalid()) 13995 return nullptr; 13996 StepExpr = Val.get(); 13997 13998 // Build var to save the step value. 13999 VarDecl *SaveVar = 14000 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14001 ExprResult SaveRef = 14002 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14003 ExprResult CalcStep = 14004 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14005 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14006 14007 // Warn about zero linear step (it would be probably better specified as 14008 // making corresponding variables 'const'). 14009 llvm::APSInt Result; 14010 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14011 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14012 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14013 << (Vars.size() > 1); 14014 if (!IsConstant && CalcStep.isUsable()) { 14015 // Calculate the step beforehand instead of doing this on each iteration. 14016 // (This is not used if the number of iterations may be kfold-ed). 14017 CalcStepExpr = CalcStep.get(); 14018 } 14019 } 14020 14021 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14022 ColonLoc, EndLoc, Vars, Privates, Inits, 14023 StepExpr, CalcStepExpr, 14024 buildPreInits(Context, ExprCaptures), 14025 buildPostUpdate(*this, ExprPostUpdates)); 14026 } 14027 14028 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14029 Expr *NumIterations, Sema &SemaRef, 14030 Scope *S, DSAStackTy *Stack) { 14031 // Walk the vars and build update/final expressions for the CodeGen. 14032 SmallVector<Expr *, 8> Updates; 14033 SmallVector<Expr *, 8> Finals; 14034 SmallVector<Expr *, 8> UsedExprs; 14035 Expr *Step = Clause.getStep(); 14036 Expr *CalcStep = Clause.getCalcStep(); 14037 // OpenMP [2.14.3.7, linear clause] 14038 // If linear-step is not specified it is assumed to be 1. 14039 if (!Step) 14040 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14041 else if (CalcStep) 14042 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14043 bool HasErrors = false; 14044 auto CurInit = Clause.inits().begin(); 14045 auto CurPrivate = Clause.privates().begin(); 14046 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14047 for (Expr *RefExpr : Clause.varlists()) { 14048 SourceLocation ELoc; 14049 SourceRange ERange; 14050 Expr *SimpleRefExpr = RefExpr; 14051 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14052 ValueDecl *D = Res.first; 14053 if (Res.second || !D) { 14054 Updates.push_back(nullptr); 14055 Finals.push_back(nullptr); 14056 HasErrors = true; 14057 continue; 14058 } 14059 auto &&Info = Stack->isLoopControlVariable(D); 14060 // OpenMP [2.15.11, distribute simd Construct] 14061 // A list item may not appear in a linear clause, unless it is the loop 14062 // iteration variable. 14063 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14064 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14065 SemaRef.Diag(ELoc, 14066 diag::err_omp_linear_distribute_var_non_loop_iteration); 14067 Updates.push_back(nullptr); 14068 Finals.push_back(nullptr); 14069 HasErrors = true; 14070 continue; 14071 } 14072 Expr *InitExpr = *CurInit; 14073 14074 // Build privatized reference to the current linear var. 14075 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14076 Expr *CapturedRef; 14077 if (LinKind == OMPC_LINEAR_uval) 14078 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14079 else 14080 CapturedRef = 14081 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14082 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14083 /*RefersToCapture=*/true); 14084 14085 // Build update: Var = InitExpr + IV * Step 14086 ExprResult Update; 14087 if (!Info.first) 14088 Update = buildCounterUpdate( 14089 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14090 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14091 else 14092 Update = *CurPrivate; 14093 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14094 /*DiscardedValue*/ false); 14095 14096 // Build final: Var = InitExpr + NumIterations * Step 14097 ExprResult Final; 14098 if (!Info.first) 14099 Final = 14100 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14101 InitExpr, NumIterations, Step, /*Subtract=*/false, 14102 /*IsNonRectangularLB=*/false); 14103 else 14104 Final = *CurPrivate; 14105 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14106 /*DiscardedValue*/ false); 14107 14108 if (!Update.isUsable() || !Final.isUsable()) { 14109 Updates.push_back(nullptr); 14110 Finals.push_back(nullptr); 14111 UsedExprs.push_back(nullptr); 14112 HasErrors = true; 14113 } else { 14114 Updates.push_back(Update.get()); 14115 Finals.push_back(Final.get()); 14116 if (!Info.first) 14117 UsedExprs.push_back(SimpleRefExpr); 14118 } 14119 ++CurInit; 14120 ++CurPrivate; 14121 } 14122 if (Expr *S = Clause.getStep()) 14123 UsedExprs.push_back(S); 14124 // Fill the remaining part with the nullptr. 14125 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14126 Clause.setUpdates(Updates); 14127 Clause.setFinals(Finals); 14128 Clause.setUsedExprs(UsedExprs); 14129 return HasErrors; 14130 } 14131 14132 OMPClause *Sema::ActOnOpenMPAlignedClause( 14133 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14134 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14135 SmallVector<Expr *, 8> Vars; 14136 for (Expr *RefExpr : VarList) { 14137 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14138 SourceLocation ELoc; 14139 SourceRange ERange; 14140 Expr *SimpleRefExpr = RefExpr; 14141 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14142 if (Res.second) { 14143 // It will be analyzed later. 14144 Vars.push_back(RefExpr); 14145 } 14146 ValueDecl *D = Res.first; 14147 if (!D) 14148 continue; 14149 14150 QualType QType = D->getType(); 14151 auto *VD = dyn_cast<VarDecl>(D); 14152 14153 // OpenMP [2.8.1, simd construct, Restrictions] 14154 // The type of list items appearing in the aligned clause must be 14155 // array, pointer, reference to array, or reference to pointer. 14156 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14157 const Type *Ty = QType.getTypePtrOrNull(); 14158 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14159 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14160 << QType << getLangOpts().CPlusPlus << ERange; 14161 bool IsDecl = 14162 !VD || 14163 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14164 Diag(D->getLocation(), 14165 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14166 << D; 14167 continue; 14168 } 14169 14170 // OpenMP [2.8.1, simd construct, Restrictions] 14171 // A list-item cannot appear in more than one aligned clause. 14172 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14173 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 14174 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14175 << getOpenMPClauseName(OMPC_aligned); 14176 continue; 14177 } 14178 14179 DeclRefExpr *Ref = nullptr; 14180 if (!VD && isOpenMPCapturedDecl(D)) 14181 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14182 Vars.push_back(DefaultFunctionArrayConversion( 14183 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14184 .get()); 14185 } 14186 14187 // OpenMP [2.8.1, simd construct, Description] 14188 // The parameter of the aligned clause, alignment, must be a constant 14189 // positive integer expression. 14190 // If no optional parameter is specified, implementation-defined default 14191 // alignments for SIMD instructions on the target platforms are assumed. 14192 if (Alignment != nullptr) { 14193 ExprResult AlignResult = 14194 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14195 if (AlignResult.isInvalid()) 14196 return nullptr; 14197 Alignment = AlignResult.get(); 14198 } 14199 if (Vars.empty()) 14200 return nullptr; 14201 14202 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14203 EndLoc, Vars, Alignment); 14204 } 14205 14206 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14207 SourceLocation StartLoc, 14208 SourceLocation LParenLoc, 14209 SourceLocation EndLoc) { 14210 SmallVector<Expr *, 8> Vars; 14211 SmallVector<Expr *, 8> SrcExprs; 14212 SmallVector<Expr *, 8> DstExprs; 14213 SmallVector<Expr *, 8> AssignmentOps; 14214 for (Expr *RefExpr : VarList) { 14215 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14216 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14217 // It will be analyzed later. 14218 Vars.push_back(RefExpr); 14219 SrcExprs.push_back(nullptr); 14220 DstExprs.push_back(nullptr); 14221 AssignmentOps.push_back(nullptr); 14222 continue; 14223 } 14224 14225 SourceLocation ELoc = RefExpr->getExprLoc(); 14226 // OpenMP [2.1, C/C++] 14227 // A list item is a variable name. 14228 // OpenMP [2.14.4.1, Restrictions, p.1] 14229 // A list item that appears in a copyin clause must be threadprivate. 14230 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14231 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14232 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14233 << 0 << RefExpr->getSourceRange(); 14234 continue; 14235 } 14236 14237 Decl *D = DE->getDecl(); 14238 auto *VD = cast<VarDecl>(D); 14239 14240 QualType Type = VD->getType(); 14241 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14242 // It will be analyzed later. 14243 Vars.push_back(DE); 14244 SrcExprs.push_back(nullptr); 14245 DstExprs.push_back(nullptr); 14246 AssignmentOps.push_back(nullptr); 14247 continue; 14248 } 14249 14250 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14251 // A list item that appears in a copyin clause must be threadprivate. 14252 if (!DSAStack->isThreadPrivate(VD)) { 14253 Diag(ELoc, diag::err_omp_required_access) 14254 << getOpenMPClauseName(OMPC_copyin) 14255 << getOpenMPDirectiveName(OMPD_threadprivate); 14256 continue; 14257 } 14258 14259 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14260 // A variable of class type (or array thereof) that appears in a 14261 // copyin clause requires an accessible, unambiguous copy assignment 14262 // operator for the class type. 14263 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14264 VarDecl *SrcVD = 14265 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14266 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14267 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14268 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14269 VarDecl *DstVD = 14270 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14271 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14272 DeclRefExpr *PseudoDstExpr = 14273 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14274 // For arrays generate assignment operation for single element and replace 14275 // it by the original array element in CodeGen. 14276 ExprResult AssignmentOp = 14277 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14278 PseudoSrcExpr); 14279 if (AssignmentOp.isInvalid()) 14280 continue; 14281 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14282 /*DiscardedValue*/ false); 14283 if (AssignmentOp.isInvalid()) 14284 continue; 14285 14286 DSAStack->addDSA(VD, DE, OMPC_copyin); 14287 Vars.push_back(DE); 14288 SrcExprs.push_back(PseudoSrcExpr); 14289 DstExprs.push_back(PseudoDstExpr); 14290 AssignmentOps.push_back(AssignmentOp.get()); 14291 } 14292 14293 if (Vars.empty()) 14294 return nullptr; 14295 14296 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14297 SrcExprs, DstExprs, AssignmentOps); 14298 } 14299 14300 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14301 SourceLocation StartLoc, 14302 SourceLocation LParenLoc, 14303 SourceLocation EndLoc) { 14304 SmallVector<Expr *, 8> Vars; 14305 SmallVector<Expr *, 8> SrcExprs; 14306 SmallVector<Expr *, 8> DstExprs; 14307 SmallVector<Expr *, 8> AssignmentOps; 14308 for (Expr *RefExpr : VarList) { 14309 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14310 SourceLocation ELoc; 14311 SourceRange ERange; 14312 Expr *SimpleRefExpr = RefExpr; 14313 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14314 if (Res.second) { 14315 // It will be analyzed later. 14316 Vars.push_back(RefExpr); 14317 SrcExprs.push_back(nullptr); 14318 DstExprs.push_back(nullptr); 14319 AssignmentOps.push_back(nullptr); 14320 } 14321 ValueDecl *D = Res.first; 14322 if (!D) 14323 continue; 14324 14325 QualType Type = D->getType(); 14326 auto *VD = dyn_cast<VarDecl>(D); 14327 14328 // OpenMP [2.14.4.2, Restrictions, p.2] 14329 // A list item that appears in a copyprivate clause may not appear in a 14330 // private or firstprivate clause on the single construct. 14331 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14332 DSAStackTy::DSAVarData DVar = 14333 DSAStack->getTopDSA(D, /*FromParent=*/false); 14334 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14335 DVar.RefExpr) { 14336 Diag(ELoc, diag::err_omp_wrong_dsa) 14337 << getOpenMPClauseName(DVar.CKind) 14338 << getOpenMPClauseName(OMPC_copyprivate); 14339 reportOriginalDsa(*this, DSAStack, D, DVar); 14340 continue; 14341 } 14342 14343 // OpenMP [2.11.4.2, Restrictions, p.1] 14344 // All list items that appear in a copyprivate clause must be either 14345 // threadprivate or private in the enclosing context. 14346 if (DVar.CKind == OMPC_unknown) { 14347 DVar = DSAStack->getImplicitDSA(D, false); 14348 if (DVar.CKind == OMPC_shared) { 14349 Diag(ELoc, diag::err_omp_required_access) 14350 << getOpenMPClauseName(OMPC_copyprivate) 14351 << "threadprivate or private in the enclosing context"; 14352 reportOriginalDsa(*this, DSAStack, D, DVar); 14353 continue; 14354 } 14355 } 14356 } 14357 14358 // Variably modified types are not supported. 14359 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14360 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14361 << getOpenMPClauseName(OMPC_copyprivate) << Type 14362 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14363 bool IsDecl = 14364 !VD || 14365 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14366 Diag(D->getLocation(), 14367 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14368 << D; 14369 continue; 14370 } 14371 14372 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14373 // A variable of class type (or array thereof) that appears in a 14374 // copyin clause requires an accessible, unambiguous copy assignment 14375 // operator for the class type. 14376 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14377 .getUnqualifiedType(); 14378 VarDecl *SrcVD = 14379 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14380 D->hasAttrs() ? &D->getAttrs() : nullptr); 14381 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14382 VarDecl *DstVD = 14383 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14384 D->hasAttrs() ? &D->getAttrs() : nullptr); 14385 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14386 ExprResult AssignmentOp = BuildBinOp( 14387 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14388 if (AssignmentOp.isInvalid()) 14389 continue; 14390 AssignmentOp = 14391 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14392 if (AssignmentOp.isInvalid()) 14393 continue; 14394 14395 // No need to mark vars as copyprivate, they are already threadprivate or 14396 // implicitly private. 14397 assert(VD || isOpenMPCapturedDecl(D)); 14398 Vars.push_back( 14399 VD ? RefExpr->IgnoreParens() 14400 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14401 SrcExprs.push_back(PseudoSrcExpr); 14402 DstExprs.push_back(PseudoDstExpr); 14403 AssignmentOps.push_back(AssignmentOp.get()); 14404 } 14405 14406 if (Vars.empty()) 14407 return nullptr; 14408 14409 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14410 Vars, SrcExprs, DstExprs, AssignmentOps); 14411 } 14412 14413 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14414 SourceLocation StartLoc, 14415 SourceLocation LParenLoc, 14416 SourceLocation EndLoc) { 14417 if (VarList.empty()) 14418 return nullptr; 14419 14420 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14421 } 14422 14423 OMPClause * 14424 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14425 SourceLocation DepLoc, SourceLocation ColonLoc, 14426 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14427 SourceLocation LParenLoc, SourceLocation EndLoc) { 14428 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14429 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14430 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14431 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14432 return nullptr; 14433 } 14434 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14435 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14436 DepKind == OMPC_DEPEND_sink)) { 14437 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14438 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14439 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14440 /*Last=*/OMPC_DEPEND_unknown, Except) 14441 << getOpenMPClauseName(OMPC_depend); 14442 return nullptr; 14443 } 14444 SmallVector<Expr *, 8> Vars; 14445 DSAStackTy::OperatorOffsetTy OpsOffs; 14446 llvm::APSInt DepCounter(/*BitWidth=*/32); 14447 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14448 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14449 if (const Expr *OrderedCountExpr = 14450 DSAStack->getParentOrderedRegionParam().first) { 14451 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14452 TotalDepCount.setIsUnsigned(/*Val=*/true); 14453 } 14454 } 14455 for (Expr *RefExpr : VarList) { 14456 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14457 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14458 // It will be analyzed later. 14459 Vars.push_back(RefExpr); 14460 continue; 14461 } 14462 14463 SourceLocation ELoc = RefExpr->getExprLoc(); 14464 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14465 if (DepKind == OMPC_DEPEND_sink) { 14466 if (DSAStack->getParentOrderedRegionParam().first && 14467 DepCounter >= TotalDepCount) { 14468 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14469 continue; 14470 } 14471 ++DepCounter; 14472 // OpenMP [2.13.9, Summary] 14473 // depend(dependence-type : vec), where dependence-type is: 14474 // 'sink' and where vec is the iteration vector, which has the form: 14475 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14476 // where n is the value specified by the ordered clause in the loop 14477 // directive, xi denotes the loop iteration variable of the i-th nested 14478 // loop associated with the loop directive, and di is a constant 14479 // non-negative integer. 14480 if (CurContext->isDependentContext()) { 14481 // It will be analyzed later. 14482 Vars.push_back(RefExpr); 14483 continue; 14484 } 14485 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14486 OverloadedOperatorKind OOK = OO_None; 14487 SourceLocation OOLoc; 14488 Expr *LHS = SimpleExpr; 14489 Expr *RHS = nullptr; 14490 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14491 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14492 OOLoc = BO->getOperatorLoc(); 14493 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14494 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14495 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14496 OOK = OCE->getOperator(); 14497 OOLoc = OCE->getOperatorLoc(); 14498 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14499 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14500 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14501 OOK = MCE->getMethodDecl() 14502 ->getNameInfo() 14503 .getName() 14504 .getCXXOverloadedOperator(); 14505 OOLoc = MCE->getCallee()->getExprLoc(); 14506 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14507 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14508 } 14509 SourceLocation ELoc; 14510 SourceRange ERange; 14511 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14512 if (Res.second) { 14513 // It will be analyzed later. 14514 Vars.push_back(RefExpr); 14515 } 14516 ValueDecl *D = Res.first; 14517 if (!D) 14518 continue; 14519 14520 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14521 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14522 continue; 14523 } 14524 if (RHS) { 14525 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14526 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14527 if (RHSRes.isInvalid()) 14528 continue; 14529 } 14530 if (!CurContext->isDependentContext() && 14531 DSAStack->getParentOrderedRegionParam().first && 14532 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14533 const ValueDecl *VD = 14534 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14535 if (VD) 14536 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14537 << 1 << VD; 14538 else 14539 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14540 continue; 14541 } 14542 OpsOffs.emplace_back(RHS, OOK); 14543 } else { 14544 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14545 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14546 (ASE && 14547 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14548 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14549 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14550 << RefExpr->getSourceRange(); 14551 continue; 14552 } 14553 14554 ExprResult Res; 14555 { 14556 Sema::TentativeAnalysisScope Trap(*this); 14557 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14558 RefExpr->IgnoreParenImpCasts()); 14559 } 14560 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14561 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14562 << RefExpr->getSourceRange(); 14563 continue; 14564 } 14565 } 14566 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14567 } 14568 14569 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14570 TotalDepCount > VarList.size() && 14571 DSAStack->getParentOrderedRegionParam().first && 14572 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14573 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14574 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14575 } 14576 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14577 Vars.empty()) 14578 return nullptr; 14579 14580 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14581 DepKind, DepLoc, ColonLoc, Vars, 14582 TotalDepCount.getZExtValue()); 14583 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14584 DSAStack->isParentOrderedRegion()) 14585 DSAStack->addDoacrossDependClause(C, OpsOffs); 14586 return C; 14587 } 14588 14589 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14590 SourceLocation LParenLoc, 14591 SourceLocation EndLoc) { 14592 Expr *ValExpr = Device; 14593 Stmt *HelperValStmt = nullptr; 14594 14595 // OpenMP [2.9.1, Restrictions] 14596 // The device expression must evaluate to a non-negative integer value. 14597 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14598 /*StrictlyPositive=*/false)) 14599 return nullptr; 14600 14601 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14602 OpenMPDirectiveKind CaptureRegion = 14603 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14604 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14605 ValExpr = MakeFullExpr(ValExpr).get(); 14606 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14607 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14608 HelperValStmt = buildPreInits(Context, Captures); 14609 } 14610 14611 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14612 StartLoc, LParenLoc, EndLoc); 14613 } 14614 14615 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14616 DSAStackTy *Stack, QualType QTy, 14617 bool FullCheck = true) { 14618 NamedDecl *ND; 14619 if (QTy->isIncompleteType(&ND)) { 14620 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14621 return false; 14622 } 14623 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14624 !QTy.isTrivialType(SemaRef.Context)) 14625 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14626 return true; 14627 } 14628 14629 /// Return true if it can be proven that the provided array expression 14630 /// (array section or array subscript) does NOT specify the whole size of the 14631 /// array whose base type is \a BaseQTy. 14632 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14633 const Expr *E, 14634 QualType BaseQTy) { 14635 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14636 14637 // If this is an array subscript, it refers to the whole size if the size of 14638 // the dimension is constant and equals 1. Also, an array section assumes the 14639 // format of an array subscript if no colon is used. 14640 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14641 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14642 return ATy->getSize().getSExtValue() != 1; 14643 // Size can't be evaluated statically. 14644 return false; 14645 } 14646 14647 assert(OASE && "Expecting array section if not an array subscript."); 14648 const Expr *LowerBound = OASE->getLowerBound(); 14649 const Expr *Length = OASE->getLength(); 14650 14651 // If there is a lower bound that does not evaluates to zero, we are not 14652 // covering the whole dimension. 14653 if (LowerBound) { 14654 Expr::EvalResult Result; 14655 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14656 return false; // Can't get the integer value as a constant. 14657 14658 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14659 if (ConstLowerBound.getSExtValue()) 14660 return true; 14661 } 14662 14663 // If we don't have a length we covering the whole dimension. 14664 if (!Length) 14665 return false; 14666 14667 // If the base is a pointer, we don't have a way to get the size of the 14668 // pointee. 14669 if (BaseQTy->isPointerType()) 14670 return false; 14671 14672 // We can only check if the length is the same as the size of the dimension 14673 // if we have a constant array. 14674 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14675 if (!CATy) 14676 return false; 14677 14678 Expr::EvalResult Result; 14679 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14680 return false; // Can't get the integer value as a constant. 14681 14682 llvm::APSInt ConstLength = Result.Val.getInt(); 14683 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14684 } 14685 14686 // Return true if it can be proven that the provided array expression (array 14687 // section or array subscript) does NOT specify a single element of the array 14688 // whose base type is \a BaseQTy. 14689 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14690 const Expr *E, 14691 QualType BaseQTy) { 14692 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14693 14694 // An array subscript always refer to a single element. Also, an array section 14695 // assumes the format of an array subscript if no colon is used. 14696 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14697 return false; 14698 14699 assert(OASE && "Expecting array section if not an array subscript."); 14700 const Expr *Length = OASE->getLength(); 14701 14702 // If we don't have a length we have to check if the array has unitary size 14703 // for this dimension. Also, we should always expect a length if the base type 14704 // is pointer. 14705 if (!Length) { 14706 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14707 return ATy->getSize().getSExtValue() != 1; 14708 // We cannot assume anything. 14709 return false; 14710 } 14711 14712 // Check if the length evaluates to 1. 14713 Expr::EvalResult Result; 14714 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14715 return false; // Can't get the integer value as a constant. 14716 14717 llvm::APSInt ConstLength = Result.Val.getInt(); 14718 return ConstLength.getSExtValue() != 1; 14719 } 14720 14721 // Return the expression of the base of the mappable expression or null if it 14722 // cannot be determined and do all the necessary checks to see if the expression 14723 // is valid as a standalone mappable expression. In the process, record all the 14724 // components of the expression. 14725 static const Expr *checkMapClauseExpressionBase( 14726 Sema &SemaRef, Expr *E, 14727 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14728 OpenMPClauseKind CKind, bool NoDiagnose) { 14729 SourceLocation ELoc = E->getExprLoc(); 14730 SourceRange ERange = E->getSourceRange(); 14731 14732 // The base of elements of list in a map clause have to be either: 14733 // - a reference to variable or field. 14734 // - a member expression. 14735 // - an array expression. 14736 // 14737 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14738 // reference to 'r'. 14739 // 14740 // If we have: 14741 // 14742 // struct SS { 14743 // Bla S; 14744 // foo() { 14745 // #pragma omp target map (S.Arr[:12]); 14746 // } 14747 // } 14748 // 14749 // We want to retrieve the member expression 'this->S'; 14750 14751 const Expr *RelevantExpr = nullptr; 14752 14753 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14754 // If a list item is an array section, it must specify contiguous storage. 14755 // 14756 // For this restriction it is sufficient that we make sure only references 14757 // to variables or fields and array expressions, and that no array sections 14758 // exist except in the rightmost expression (unless they cover the whole 14759 // dimension of the array). E.g. these would be invalid: 14760 // 14761 // r.ArrS[3:5].Arr[6:7] 14762 // 14763 // r.ArrS[3:5].x 14764 // 14765 // but these would be valid: 14766 // r.ArrS[3].Arr[6:7] 14767 // 14768 // r.ArrS[3].x 14769 14770 bool AllowUnitySizeArraySection = true; 14771 bool AllowWholeSizeArraySection = true; 14772 14773 while (!RelevantExpr) { 14774 E = E->IgnoreParenImpCasts(); 14775 14776 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14777 if (!isa<VarDecl>(CurE->getDecl())) 14778 return nullptr; 14779 14780 RelevantExpr = CurE; 14781 14782 // If we got a reference to a declaration, we should not expect any array 14783 // section before that. 14784 AllowUnitySizeArraySection = false; 14785 AllowWholeSizeArraySection = false; 14786 14787 // Record the component. 14788 CurComponents.emplace_back(CurE, CurE->getDecl()); 14789 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14790 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14791 14792 if (isa<CXXThisExpr>(BaseE)) 14793 // We found a base expression: this->Val. 14794 RelevantExpr = CurE; 14795 else 14796 E = BaseE; 14797 14798 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14799 if (!NoDiagnose) { 14800 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14801 << CurE->getSourceRange(); 14802 return nullptr; 14803 } 14804 if (RelevantExpr) 14805 return nullptr; 14806 continue; 14807 } 14808 14809 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14810 14811 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14812 // A bit-field cannot appear in a map clause. 14813 // 14814 if (FD->isBitField()) { 14815 if (!NoDiagnose) { 14816 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14817 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14818 return nullptr; 14819 } 14820 if (RelevantExpr) 14821 return nullptr; 14822 continue; 14823 } 14824 14825 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14826 // If the type of a list item is a reference to a type T then the type 14827 // will be considered to be T for all purposes of this clause. 14828 QualType CurType = BaseE->getType().getNonReferenceType(); 14829 14830 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14831 // A list item cannot be a variable that is a member of a structure with 14832 // a union type. 14833 // 14834 if (CurType->isUnionType()) { 14835 if (!NoDiagnose) { 14836 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14837 << CurE->getSourceRange(); 14838 return nullptr; 14839 } 14840 continue; 14841 } 14842 14843 // If we got a member expression, we should not expect any array section 14844 // before that: 14845 // 14846 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14847 // If a list item is an element of a structure, only the rightmost symbol 14848 // of the variable reference can be an array section. 14849 // 14850 AllowUnitySizeArraySection = false; 14851 AllowWholeSizeArraySection = false; 14852 14853 // Record the component. 14854 CurComponents.emplace_back(CurE, FD); 14855 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14856 E = CurE->getBase()->IgnoreParenImpCasts(); 14857 14858 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14859 if (!NoDiagnose) { 14860 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14861 << 0 << CurE->getSourceRange(); 14862 return nullptr; 14863 } 14864 continue; 14865 } 14866 14867 // If we got an array subscript that express the whole dimension we 14868 // can have any array expressions before. If it only expressing part of 14869 // the dimension, we can only have unitary-size array expressions. 14870 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14871 E->getType())) 14872 AllowWholeSizeArraySection = false; 14873 14874 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14875 Expr::EvalResult Result; 14876 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14877 if (!Result.Val.getInt().isNullValue()) { 14878 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14879 diag::err_omp_invalid_map_this_expr); 14880 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14881 diag::note_omp_invalid_subscript_on_this_ptr_map); 14882 } 14883 } 14884 RelevantExpr = TE; 14885 } 14886 14887 // Record the component - we don't have any declaration associated. 14888 CurComponents.emplace_back(CurE, nullptr); 14889 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14890 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14891 E = CurE->getBase()->IgnoreParenImpCasts(); 14892 14893 QualType CurType = 14894 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14895 14896 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14897 // If the type of a list item is a reference to a type T then the type 14898 // will be considered to be T for all purposes of this clause. 14899 if (CurType->isReferenceType()) 14900 CurType = CurType->getPointeeType(); 14901 14902 bool IsPointer = CurType->isAnyPointerType(); 14903 14904 if (!IsPointer && !CurType->isArrayType()) { 14905 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14906 << 0 << CurE->getSourceRange(); 14907 return nullptr; 14908 } 14909 14910 bool NotWhole = 14911 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14912 bool NotUnity = 14913 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14914 14915 if (AllowWholeSizeArraySection) { 14916 // Any array section is currently allowed. Allowing a whole size array 14917 // section implies allowing a unity array section as well. 14918 // 14919 // If this array section refers to the whole dimension we can still 14920 // accept other array sections before this one, except if the base is a 14921 // pointer. Otherwise, only unitary sections are accepted. 14922 if (NotWhole || IsPointer) 14923 AllowWholeSizeArraySection = false; 14924 } else if (AllowUnitySizeArraySection && NotUnity) { 14925 // A unity or whole array section is not allowed and that is not 14926 // compatible with the properties of the current array section. 14927 SemaRef.Diag( 14928 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14929 << CurE->getSourceRange(); 14930 return nullptr; 14931 } 14932 14933 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14934 Expr::EvalResult ResultR; 14935 Expr::EvalResult ResultL; 14936 if (CurE->getLength()->EvaluateAsInt(ResultR, 14937 SemaRef.getASTContext())) { 14938 if (!ResultR.Val.getInt().isOneValue()) { 14939 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14940 diag::err_omp_invalid_map_this_expr); 14941 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14942 diag::note_omp_invalid_length_on_this_ptr_mapping); 14943 } 14944 } 14945 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14946 ResultL, SemaRef.getASTContext())) { 14947 if (!ResultL.Val.getInt().isNullValue()) { 14948 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14949 diag::err_omp_invalid_map_this_expr); 14950 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14951 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14952 } 14953 } 14954 RelevantExpr = TE; 14955 } 14956 14957 // Record the component - we don't have any declaration associated. 14958 CurComponents.emplace_back(CurE, nullptr); 14959 } else { 14960 if (!NoDiagnose) { 14961 // If nothing else worked, this is not a valid map clause expression. 14962 SemaRef.Diag( 14963 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14964 << ERange; 14965 } 14966 return nullptr; 14967 } 14968 } 14969 14970 return RelevantExpr; 14971 } 14972 14973 // Return true if expression E associated with value VD has conflicts with other 14974 // map information. 14975 static bool checkMapConflicts( 14976 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14977 bool CurrentRegionOnly, 14978 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14979 OpenMPClauseKind CKind) { 14980 assert(VD && E); 14981 SourceLocation ELoc = E->getExprLoc(); 14982 SourceRange ERange = E->getSourceRange(); 14983 14984 // In order to easily check the conflicts we need to match each component of 14985 // the expression under test with the components of the expressions that are 14986 // already in the stack. 14987 14988 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14989 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14990 "Map clause expression with unexpected base!"); 14991 14992 // Variables to help detecting enclosing problems in data environment nests. 14993 bool IsEnclosedByDataEnvironmentExpr = false; 14994 const Expr *EnclosingExpr = nullptr; 14995 14996 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14997 VD, CurrentRegionOnly, 14998 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14999 ERange, CKind, &EnclosingExpr, 15000 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15001 StackComponents, 15002 OpenMPClauseKind) { 15003 assert(!StackComponents.empty() && 15004 "Map clause expression with no components!"); 15005 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15006 "Map clause expression with unexpected base!"); 15007 (void)VD; 15008 15009 // The whole expression in the stack. 15010 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15011 15012 // Expressions must start from the same base. Here we detect at which 15013 // point both expressions diverge from each other and see if we can 15014 // detect if the memory referred to both expressions is contiguous and 15015 // do not overlap. 15016 auto CI = CurComponents.rbegin(); 15017 auto CE = CurComponents.rend(); 15018 auto SI = StackComponents.rbegin(); 15019 auto SE = StackComponents.rend(); 15020 for (; CI != CE && SI != SE; ++CI, ++SI) { 15021 15022 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15023 // At most one list item can be an array item derived from a given 15024 // variable in map clauses of the same construct. 15025 if (CurrentRegionOnly && 15026 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15027 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15028 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15029 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15030 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15031 diag::err_omp_multiple_array_items_in_map_clause) 15032 << CI->getAssociatedExpression()->getSourceRange(); 15033 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15034 diag::note_used_here) 15035 << SI->getAssociatedExpression()->getSourceRange(); 15036 return true; 15037 } 15038 15039 // Do both expressions have the same kind? 15040 if (CI->getAssociatedExpression()->getStmtClass() != 15041 SI->getAssociatedExpression()->getStmtClass()) 15042 break; 15043 15044 // Are we dealing with different variables/fields? 15045 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15046 break; 15047 } 15048 // Check if the extra components of the expressions in the enclosing 15049 // data environment are redundant for the current base declaration. 15050 // If they are, the maps completely overlap, which is legal. 15051 for (; SI != SE; ++SI) { 15052 QualType Type; 15053 if (const auto *ASE = 15054 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15055 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15056 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15057 SI->getAssociatedExpression())) { 15058 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15059 Type = 15060 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15061 } 15062 if (Type.isNull() || Type->isAnyPointerType() || 15063 checkArrayExpressionDoesNotReferToWholeSize( 15064 SemaRef, SI->getAssociatedExpression(), Type)) 15065 break; 15066 } 15067 15068 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15069 // List items of map clauses in the same construct must not share 15070 // original storage. 15071 // 15072 // If the expressions are exactly the same or one is a subset of the 15073 // other, it means they are sharing storage. 15074 if (CI == CE && SI == SE) { 15075 if (CurrentRegionOnly) { 15076 if (CKind == OMPC_map) { 15077 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15078 } else { 15079 assert(CKind == OMPC_to || CKind == OMPC_from); 15080 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15081 << ERange; 15082 } 15083 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15084 << RE->getSourceRange(); 15085 return true; 15086 } 15087 // If we find the same expression in the enclosing data environment, 15088 // that is legal. 15089 IsEnclosedByDataEnvironmentExpr = true; 15090 return false; 15091 } 15092 15093 QualType DerivedType = 15094 std::prev(CI)->getAssociatedDeclaration()->getType(); 15095 SourceLocation DerivedLoc = 15096 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15097 15098 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15099 // If the type of a list item is a reference to a type T then the type 15100 // will be considered to be T for all purposes of this clause. 15101 DerivedType = DerivedType.getNonReferenceType(); 15102 15103 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15104 // A variable for which the type is pointer and an array section 15105 // derived from that variable must not appear as list items of map 15106 // clauses of the same construct. 15107 // 15108 // Also, cover one of the cases in: 15109 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15110 // If any part of the original storage of a list item has corresponding 15111 // storage in the device data environment, all of the original storage 15112 // must have corresponding storage in the device data environment. 15113 // 15114 if (DerivedType->isAnyPointerType()) { 15115 if (CI == CE || SI == SE) { 15116 SemaRef.Diag( 15117 DerivedLoc, 15118 diag::err_omp_pointer_mapped_along_with_derived_section) 15119 << DerivedLoc; 15120 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15121 << RE->getSourceRange(); 15122 return true; 15123 } 15124 if (CI->getAssociatedExpression()->getStmtClass() != 15125 SI->getAssociatedExpression()->getStmtClass() || 15126 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15127 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15128 assert(CI != CE && SI != SE); 15129 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15130 << DerivedLoc; 15131 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15132 << RE->getSourceRange(); 15133 return true; 15134 } 15135 } 15136 15137 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15138 // List items of map clauses in the same construct must not share 15139 // original storage. 15140 // 15141 // An expression is a subset of the other. 15142 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15143 if (CKind == OMPC_map) { 15144 if (CI != CE || SI != SE) { 15145 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15146 // a pointer. 15147 auto Begin = 15148 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15149 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15150 auto It = Begin; 15151 while (It != End && !It->getAssociatedDeclaration()) 15152 std::advance(It, 1); 15153 assert(It != End && 15154 "Expected at least one component with the declaration."); 15155 if (It != Begin && It->getAssociatedDeclaration() 15156 ->getType() 15157 .getCanonicalType() 15158 ->isAnyPointerType()) { 15159 IsEnclosedByDataEnvironmentExpr = false; 15160 EnclosingExpr = nullptr; 15161 return false; 15162 } 15163 } 15164 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15165 } else { 15166 assert(CKind == OMPC_to || CKind == OMPC_from); 15167 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15168 << ERange; 15169 } 15170 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15171 << RE->getSourceRange(); 15172 return true; 15173 } 15174 15175 // The current expression uses the same base as other expression in the 15176 // data environment but does not contain it completely. 15177 if (!CurrentRegionOnly && SI != SE) 15178 EnclosingExpr = RE; 15179 15180 // The current expression is a subset of the expression in the data 15181 // environment. 15182 IsEnclosedByDataEnvironmentExpr |= 15183 (!CurrentRegionOnly && CI != CE && SI == SE); 15184 15185 return false; 15186 }); 15187 15188 if (CurrentRegionOnly) 15189 return FoundError; 15190 15191 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15192 // If any part of the original storage of a list item has corresponding 15193 // storage in the device data environment, all of the original storage must 15194 // have corresponding storage in the device data environment. 15195 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15196 // If a list item is an element of a structure, and a different element of 15197 // the structure has a corresponding list item in the device data environment 15198 // prior to a task encountering the construct associated with the map clause, 15199 // then the list item must also have a corresponding list item in the device 15200 // data environment prior to the task encountering the construct. 15201 // 15202 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15203 SemaRef.Diag(ELoc, 15204 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15205 << ERange; 15206 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15207 << EnclosingExpr->getSourceRange(); 15208 return true; 15209 } 15210 15211 return FoundError; 15212 } 15213 15214 // Look up the user-defined mapper given the mapper name and mapped type, and 15215 // build a reference to it. 15216 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15217 CXXScopeSpec &MapperIdScopeSpec, 15218 const DeclarationNameInfo &MapperId, 15219 QualType Type, 15220 Expr *UnresolvedMapper) { 15221 if (MapperIdScopeSpec.isInvalid()) 15222 return ExprError(); 15223 // Get the actual type for the array type. 15224 if (Type->isArrayType()) { 15225 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15226 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15227 } 15228 // Find all user-defined mappers with the given MapperId. 15229 SmallVector<UnresolvedSet<8>, 4> Lookups; 15230 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15231 Lookup.suppressDiagnostics(); 15232 if (S) { 15233 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15234 NamedDecl *D = Lookup.getRepresentativeDecl(); 15235 while (S && !S->isDeclScope(D)) 15236 S = S->getParent(); 15237 if (S) 15238 S = S->getParent(); 15239 Lookups.emplace_back(); 15240 Lookups.back().append(Lookup.begin(), Lookup.end()); 15241 Lookup.clear(); 15242 } 15243 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15244 // Extract the user-defined mappers with the given MapperId. 15245 Lookups.push_back(UnresolvedSet<8>()); 15246 for (NamedDecl *D : ULE->decls()) { 15247 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15248 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15249 Lookups.back().addDecl(DMD); 15250 } 15251 } 15252 // Defer the lookup for dependent types. The results will be passed through 15253 // UnresolvedMapper on instantiation. 15254 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15255 Type->isInstantiationDependentType() || 15256 Type->containsUnexpandedParameterPack() || 15257 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15258 return !D->isInvalidDecl() && 15259 (D->getType()->isDependentType() || 15260 D->getType()->isInstantiationDependentType() || 15261 D->getType()->containsUnexpandedParameterPack()); 15262 })) { 15263 UnresolvedSet<8> URS; 15264 for (const UnresolvedSet<8> &Set : Lookups) { 15265 if (Set.empty()) 15266 continue; 15267 URS.append(Set.begin(), Set.end()); 15268 } 15269 return UnresolvedLookupExpr::Create( 15270 SemaRef.Context, /*NamingClass=*/nullptr, 15271 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15272 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15273 } 15274 SourceLocation Loc = MapperId.getLoc(); 15275 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15276 // The type must be of struct, union or class type in C and C++ 15277 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15278 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15279 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15280 return ExprError(); 15281 } 15282 // Perform argument dependent lookup. 15283 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15284 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15285 // Return the first user-defined mapper with the desired type. 15286 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15287 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15288 if (!D->isInvalidDecl() && 15289 SemaRef.Context.hasSameType(D->getType(), Type)) 15290 return D; 15291 return nullptr; 15292 })) 15293 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15294 // Find the first user-defined mapper with a type derived from the desired 15295 // type. 15296 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15297 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15298 if (!D->isInvalidDecl() && 15299 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15300 !Type.isMoreQualifiedThan(D->getType())) 15301 return D; 15302 return nullptr; 15303 })) { 15304 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15305 /*DetectVirtual=*/false); 15306 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15307 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15308 VD->getType().getUnqualifiedType()))) { 15309 if (SemaRef.CheckBaseClassAccess( 15310 Loc, VD->getType(), Type, Paths.front(), 15311 /*DiagID=*/0) != Sema::AR_inaccessible) { 15312 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15313 } 15314 } 15315 } 15316 } 15317 // Report error if a mapper is specified, but cannot be found. 15318 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15319 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15320 << Type << MapperId.getName(); 15321 return ExprError(); 15322 } 15323 return ExprEmpty(); 15324 } 15325 15326 namespace { 15327 // Utility struct that gathers all the related lists associated with a mappable 15328 // expression. 15329 struct MappableVarListInfo { 15330 // The list of expressions. 15331 ArrayRef<Expr *> VarList; 15332 // The list of processed expressions. 15333 SmallVector<Expr *, 16> ProcessedVarList; 15334 // The mappble components for each expression. 15335 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15336 // The base declaration of the variable. 15337 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15338 // The reference to the user-defined mapper associated with every expression. 15339 SmallVector<Expr *, 16> UDMapperList; 15340 15341 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15342 // We have a list of components and base declarations for each entry in the 15343 // variable list. 15344 VarComponents.reserve(VarList.size()); 15345 VarBaseDeclarations.reserve(VarList.size()); 15346 } 15347 }; 15348 } 15349 15350 // Check the validity of the provided variable list for the provided clause kind 15351 // \a CKind. In the check process the valid expressions, mappable expression 15352 // components, variables, and user-defined mappers are extracted and used to 15353 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15354 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15355 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15356 static void checkMappableExpressionList( 15357 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15358 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15359 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15360 ArrayRef<Expr *> UnresolvedMappers, 15361 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15362 bool IsMapTypeImplicit = false) { 15363 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15364 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15365 "Unexpected clause kind with mappable expressions!"); 15366 15367 // If the identifier of user-defined mapper is not specified, it is "default". 15368 // We do not change the actual name in this clause to distinguish whether a 15369 // mapper is specified explicitly, i.e., it is not explicitly specified when 15370 // MapperId.getName() is empty. 15371 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15372 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15373 MapperId.setName(DeclNames.getIdentifier( 15374 &SemaRef.getASTContext().Idents.get("default"))); 15375 } 15376 15377 // Iterators to find the current unresolved mapper expression. 15378 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15379 bool UpdateUMIt = false; 15380 Expr *UnresolvedMapper = nullptr; 15381 15382 // Keep track of the mappable components and base declarations in this clause. 15383 // Each entry in the list is going to have a list of components associated. We 15384 // record each set of the components so that we can build the clause later on. 15385 // In the end we should have the same amount of declarations and component 15386 // lists. 15387 15388 for (Expr *RE : MVLI.VarList) { 15389 assert(RE && "Null expr in omp to/from/map clause"); 15390 SourceLocation ELoc = RE->getExprLoc(); 15391 15392 // Find the current unresolved mapper expression. 15393 if (UpdateUMIt && UMIt != UMEnd) { 15394 UMIt++; 15395 assert( 15396 UMIt != UMEnd && 15397 "Expect the size of UnresolvedMappers to match with that of VarList"); 15398 } 15399 UpdateUMIt = true; 15400 if (UMIt != UMEnd) 15401 UnresolvedMapper = *UMIt; 15402 15403 const Expr *VE = RE->IgnoreParenLValueCasts(); 15404 15405 if (VE->isValueDependent() || VE->isTypeDependent() || 15406 VE->isInstantiationDependent() || 15407 VE->containsUnexpandedParameterPack()) { 15408 // Try to find the associated user-defined mapper. 15409 ExprResult ER = buildUserDefinedMapperRef( 15410 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15411 VE->getType().getCanonicalType(), UnresolvedMapper); 15412 if (ER.isInvalid()) 15413 continue; 15414 MVLI.UDMapperList.push_back(ER.get()); 15415 // We can only analyze this information once the missing information is 15416 // resolved. 15417 MVLI.ProcessedVarList.push_back(RE); 15418 continue; 15419 } 15420 15421 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15422 15423 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15424 SemaRef.Diag(ELoc, 15425 diag::err_omp_expected_named_var_member_or_array_expression) 15426 << RE->getSourceRange(); 15427 continue; 15428 } 15429 15430 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15431 ValueDecl *CurDeclaration = nullptr; 15432 15433 // Obtain the array or member expression bases if required. Also, fill the 15434 // components array with all the components identified in the process. 15435 const Expr *BE = checkMapClauseExpressionBase( 15436 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15437 if (!BE) 15438 continue; 15439 15440 assert(!CurComponents.empty() && 15441 "Invalid mappable expression information."); 15442 15443 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15444 // Add store "this" pointer to class in DSAStackTy for future checking 15445 DSAS->addMappedClassesQualTypes(TE->getType()); 15446 // Try to find the associated user-defined mapper. 15447 ExprResult ER = buildUserDefinedMapperRef( 15448 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15449 VE->getType().getCanonicalType(), UnresolvedMapper); 15450 if (ER.isInvalid()) 15451 continue; 15452 MVLI.UDMapperList.push_back(ER.get()); 15453 // Skip restriction checking for variable or field declarations 15454 MVLI.ProcessedVarList.push_back(RE); 15455 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15456 MVLI.VarComponents.back().append(CurComponents.begin(), 15457 CurComponents.end()); 15458 MVLI.VarBaseDeclarations.push_back(nullptr); 15459 continue; 15460 } 15461 15462 // For the following checks, we rely on the base declaration which is 15463 // expected to be associated with the last component. The declaration is 15464 // expected to be a variable or a field (if 'this' is being mapped). 15465 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15466 assert(CurDeclaration && "Null decl on map clause."); 15467 assert( 15468 CurDeclaration->isCanonicalDecl() && 15469 "Expecting components to have associated only canonical declarations."); 15470 15471 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15472 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15473 15474 assert((VD || FD) && "Only variables or fields are expected here!"); 15475 (void)FD; 15476 15477 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15478 // threadprivate variables cannot appear in a map clause. 15479 // OpenMP 4.5 [2.10.5, target update Construct] 15480 // threadprivate variables cannot appear in a from clause. 15481 if (VD && DSAS->isThreadPrivate(VD)) { 15482 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15483 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15484 << getOpenMPClauseName(CKind); 15485 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15486 continue; 15487 } 15488 15489 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15490 // A list item cannot appear in both a map clause and a data-sharing 15491 // attribute clause on the same construct. 15492 15493 // Check conflicts with other map clause expressions. We check the conflicts 15494 // with the current construct separately from the enclosing data 15495 // environment, because the restrictions are different. We only have to 15496 // check conflicts across regions for the map clauses. 15497 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15498 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15499 break; 15500 if (CKind == OMPC_map && 15501 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15502 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15503 break; 15504 15505 // OpenMP 4.5 [2.10.5, target update Construct] 15506 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15507 // If the type of a list item is a reference to a type T then the type will 15508 // be considered to be T for all purposes of this clause. 15509 auto I = llvm::find_if( 15510 CurComponents, 15511 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15512 return MC.getAssociatedDeclaration(); 15513 }); 15514 assert(I != CurComponents.end() && "Null decl on map clause."); 15515 QualType Type = 15516 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15517 15518 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15519 // A list item in a to or from clause must have a mappable type. 15520 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15521 // A list item must have a mappable type. 15522 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15523 DSAS, Type)) 15524 continue; 15525 15526 if (CKind == OMPC_map) { 15527 // target enter data 15528 // OpenMP [2.10.2, Restrictions, p. 99] 15529 // A map-type must be specified in all map clauses and must be either 15530 // to or alloc. 15531 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15532 if (DKind == OMPD_target_enter_data && 15533 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15534 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15535 << (IsMapTypeImplicit ? 1 : 0) 15536 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15537 << getOpenMPDirectiveName(DKind); 15538 continue; 15539 } 15540 15541 // target exit_data 15542 // OpenMP [2.10.3, Restrictions, p. 102] 15543 // A map-type must be specified in all map clauses and must be either 15544 // from, release, or delete. 15545 if (DKind == OMPD_target_exit_data && 15546 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15547 MapType == OMPC_MAP_delete)) { 15548 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15549 << (IsMapTypeImplicit ? 1 : 0) 15550 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15551 << getOpenMPDirectiveName(DKind); 15552 continue; 15553 } 15554 15555 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15556 // A list item cannot appear in both a map clause and a data-sharing 15557 // attribute clause on the same construct 15558 // 15559 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15560 // A list item cannot appear in both a map clause and a data-sharing 15561 // attribute clause on the same construct unless the construct is a 15562 // combined construct. 15563 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15564 isOpenMPTargetExecutionDirective(DKind)) || 15565 DKind == OMPD_target)) { 15566 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15567 if (isOpenMPPrivate(DVar.CKind)) { 15568 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15569 << getOpenMPClauseName(DVar.CKind) 15570 << getOpenMPClauseName(OMPC_map) 15571 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15572 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15573 continue; 15574 } 15575 } 15576 } 15577 15578 // Try to find the associated user-defined mapper. 15579 ExprResult ER = buildUserDefinedMapperRef( 15580 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15581 Type.getCanonicalType(), UnresolvedMapper); 15582 if (ER.isInvalid()) 15583 continue; 15584 MVLI.UDMapperList.push_back(ER.get()); 15585 15586 // Save the current expression. 15587 MVLI.ProcessedVarList.push_back(RE); 15588 15589 // Store the components in the stack so that they can be used to check 15590 // against other clauses later on. 15591 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15592 /*WhereFoundClauseKind=*/OMPC_map); 15593 15594 // Save the components and declaration to create the clause. For purposes of 15595 // the clause creation, any component list that has has base 'this' uses 15596 // null as base declaration. 15597 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15598 MVLI.VarComponents.back().append(CurComponents.begin(), 15599 CurComponents.end()); 15600 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15601 : CurDeclaration); 15602 } 15603 } 15604 15605 OMPClause *Sema::ActOnOpenMPMapClause( 15606 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15607 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15608 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15609 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15610 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15611 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15612 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15613 OMPC_MAP_MODIFIER_unknown, 15614 OMPC_MAP_MODIFIER_unknown}; 15615 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15616 15617 // Process map-type-modifiers, flag errors for duplicate modifiers. 15618 unsigned Count = 0; 15619 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15620 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15621 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15622 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15623 continue; 15624 } 15625 assert(Count < OMPMapClause::NumberOfModifiers && 15626 "Modifiers exceed the allowed number of map type modifiers"); 15627 Modifiers[Count] = MapTypeModifiers[I]; 15628 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15629 ++Count; 15630 } 15631 15632 MappableVarListInfo MVLI(VarList); 15633 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15634 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15635 MapType, IsMapTypeImplicit); 15636 15637 // We need to produce a map clause even if we don't have variables so that 15638 // other diagnostics related with non-existing map clauses are accurate. 15639 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15640 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15641 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15642 MapperIdScopeSpec.getWithLocInContext(Context), 15643 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15644 } 15645 15646 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15647 TypeResult ParsedType) { 15648 assert(ParsedType.isUsable()); 15649 15650 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15651 if (ReductionType.isNull()) 15652 return QualType(); 15653 15654 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15655 // A type name in a declare reduction directive cannot be a function type, an 15656 // array type, a reference type, or a type qualified with const, volatile or 15657 // restrict. 15658 if (ReductionType.hasQualifiers()) { 15659 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15660 return QualType(); 15661 } 15662 15663 if (ReductionType->isFunctionType()) { 15664 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15665 return QualType(); 15666 } 15667 if (ReductionType->isReferenceType()) { 15668 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15669 return QualType(); 15670 } 15671 if (ReductionType->isArrayType()) { 15672 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15673 return QualType(); 15674 } 15675 return ReductionType; 15676 } 15677 15678 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15679 Scope *S, DeclContext *DC, DeclarationName Name, 15680 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15681 AccessSpecifier AS, Decl *PrevDeclInScope) { 15682 SmallVector<Decl *, 8> Decls; 15683 Decls.reserve(ReductionTypes.size()); 15684 15685 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15686 forRedeclarationInCurContext()); 15687 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15688 // A reduction-identifier may not be re-declared in the current scope for the 15689 // same type or for a type that is compatible according to the base language 15690 // rules. 15691 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15692 OMPDeclareReductionDecl *PrevDRD = nullptr; 15693 bool InCompoundScope = true; 15694 if (S != nullptr) { 15695 // Find previous declaration with the same name not referenced in other 15696 // declarations. 15697 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15698 InCompoundScope = 15699 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15700 LookupName(Lookup, S); 15701 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15702 /*AllowInlineNamespace=*/false); 15703 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15704 LookupResult::Filter Filter = Lookup.makeFilter(); 15705 while (Filter.hasNext()) { 15706 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15707 if (InCompoundScope) { 15708 auto I = UsedAsPrevious.find(PrevDecl); 15709 if (I == UsedAsPrevious.end()) 15710 UsedAsPrevious[PrevDecl] = false; 15711 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15712 UsedAsPrevious[D] = true; 15713 } 15714 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15715 PrevDecl->getLocation(); 15716 } 15717 Filter.done(); 15718 if (InCompoundScope) { 15719 for (const auto &PrevData : UsedAsPrevious) { 15720 if (!PrevData.second) { 15721 PrevDRD = PrevData.first; 15722 break; 15723 } 15724 } 15725 } 15726 } else if (PrevDeclInScope != nullptr) { 15727 auto *PrevDRDInScope = PrevDRD = 15728 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15729 do { 15730 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15731 PrevDRDInScope->getLocation(); 15732 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15733 } while (PrevDRDInScope != nullptr); 15734 } 15735 for (const auto &TyData : ReductionTypes) { 15736 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15737 bool Invalid = false; 15738 if (I != PreviousRedeclTypes.end()) { 15739 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15740 << TyData.first; 15741 Diag(I->second, diag::note_previous_definition); 15742 Invalid = true; 15743 } 15744 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15745 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15746 Name, TyData.first, PrevDRD); 15747 DC->addDecl(DRD); 15748 DRD->setAccess(AS); 15749 Decls.push_back(DRD); 15750 if (Invalid) 15751 DRD->setInvalidDecl(); 15752 else 15753 PrevDRD = DRD; 15754 } 15755 15756 return DeclGroupPtrTy::make( 15757 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15758 } 15759 15760 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15761 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15762 15763 // Enter new function scope. 15764 PushFunctionScope(); 15765 setFunctionHasBranchProtectedScope(); 15766 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15767 15768 if (S != nullptr) 15769 PushDeclContext(S, DRD); 15770 else 15771 CurContext = DRD; 15772 15773 PushExpressionEvaluationContext( 15774 ExpressionEvaluationContext::PotentiallyEvaluated); 15775 15776 QualType ReductionType = DRD->getType(); 15777 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15778 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15779 // uses semantics of argument handles by value, but it should be passed by 15780 // reference. C lang does not support references, so pass all parameters as 15781 // pointers. 15782 // Create 'T omp_in;' variable. 15783 VarDecl *OmpInParm = 15784 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15785 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15786 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15787 // uses semantics of argument handles by value, but it should be passed by 15788 // reference. C lang does not support references, so pass all parameters as 15789 // pointers. 15790 // Create 'T omp_out;' variable. 15791 VarDecl *OmpOutParm = 15792 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15793 if (S != nullptr) { 15794 PushOnScopeChains(OmpInParm, S); 15795 PushOnScopeChains(OmpOutParm, S); 15796 } else { 15797 DRD->addDecl(OmpInParm); 15798 DRD->addDecl(OmpOutParm); 15799 } 15800 Expr *InE = 15801 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15802 Expr *OutE = 15803 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15804 DRD->setCombinerData(InE, OutE); 15805 } 15806 15807 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15808 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15809 DiscardCleanupsInEvaluationContext(); 15810 PopExpressionEvaluationContext(); 15811 15812 PopDeclContext(); 15813 PopFunctionScopeInfo(); 15814 15815 if (Combiner != nullptr) 15816 DRD->setCombiner(Combiner); 15817 else 15818 DRD->setInvalidDecl(); 15819 } 15820 15821 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15822 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15823 15824 // Enter new function scope. 15825 PushFunctionScope(); 15826 setFunctionHasBranchProtectedScope(); 15827 15828 if (S != nullptr) 15829 PushDeclContext(S, DRD); 15830 else 15831 CurContext = DRD; 15832 15833 PushExpressionEvaluationContext( 15834 ExpressionEvaluationContext::PotentiallyEvaluated); 15835 15836 QualType ReductionType = DRD->getType(); 15837 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15838 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15839 // uses semantics of argument handles by value, but it should be passed by 15840 // reference. C lang does not support references, so pass all parameters as 15841 // pointers. 15842 // Create 'T omp_priv;' variable. 15843 VarDecl *OmpPrivParm = 15844 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15845 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15846 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15847 // uses semantics of argument handles by value, but it should be passed by 15848 // reference. C lang does not support references, so pass all parameters as 15849 // pointers. 15850 // Create 'T omp_orig;' variable. 15851 VarDecl *OmpOrigParm = 15852 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15853 if (S != nullptr) { 15854 PushOnScopeChains(OmpPrivParm, S); 15855 PushOnScopeChains(OmpOrigParm, S); 15856 } else { 15857 DRD->addDecl(OmpPrivParm); 15858 DRD->addDecl(OmpOrigParm); 15859 } 15860 Expr *OrigE = 15861 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15862 Expr *PrivE = 15863 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15864 DRD->setInitializerData(OrigE, PrivE); 15865 return OmpPrivParm; 15866 } 15867 15868 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15869 VarDecl *OmpPrivParm) { 15870 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15871 DiscardCleanupsInEvaluationContext(); 15872 PopExpressionEvaluationContext(); 15873 15874 PopDeclContext(); 15875 PopFunctionScopeInfo(); 15876 15877 if (Initializer != nullptr) { 15878 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15879 } else if (OmpPrivParm->hasInit()) { 15880 DRD->setInitializer(OmpPrivParm->getInit(), 15881 OmpPrivParm->isDirectInit() 15882 ? OMPDeclareReductionDecl::DirectInit 15883 : OMPDeclareReductionDecl::CopyInit); 15884 } else { 15885 DRD->setInvalidDecl(); 15886 } 15887 } 15888 15889 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15890 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15891 for (Decl *D : DeclReductions.get()) { 15892 if (IsValid) { 15893 if (S) 15894 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15895 /*AddToContext=*/false); 15896 } else { 15897 D->setInvalidDecl(); 15898 } 15899 } 15900 return DeclReductions; 15901 } 15902 15903 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15904 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15905 QualType T = TInfo->getType(); 15906 if (D.isInvalidType()) 15907 return true; 15908 15909 if (getLangOpts().CPlusPlus) { 15910 // Check that there are no default arguments (C++ only). 15911 CheckExtraCXXDefaultArguments(D); 15912 } 15913 15914 return CreateParsedType(T, TInfo); 15915 } 15916 15917 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15918 TypeResult ParsedType) { 15919 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15920 15921 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15922 assert(!MapperType.isNull() && "Expect valid mapper type"); 15923 15924 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15925 // The type must be of struct, union or class type in C and C++ 15926 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15927 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15928 return QualType(); 15929 } 15930 return MapperType; 15931 } 15932 15933 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15934 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15935 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15936 Decl *PrevDeclInScope) { 15937 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15938 forRedeclarationInCurContext()); 15939 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15940 // A mapper-identifier may not be redeclared in the current scope for the 15941 // same type or for a type that is compatible according to the base language 15942 // rules. 15943 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15944 OMPDeclareMapperDecl *PrevDMD = nullptr; 15945 bool InCompoundScope = true; 15946 if (S != nullptr) { 15947 // Find previous declaration with the same name not referenced in other 15948 // declarations. 15949 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15950 InCompoundScope = 15951 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15952 LookupName(Lookup, S); 15953 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15954 /*AllowInlineNamespace=*/false); 15955 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15956 LookupResult::Filter Filter = Lookup.makeFilter(); 15957 while (Filter.hasNext()) { 15958 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15959 if (InCompoundScope) { 15960 auto I = UsedAsPrevious.find(PrevDecl); 15961 if (I == UsedAsPrevious.end()) 15962 UsedAsPrevious[PrevDecl] = false; 15963 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15964 UsedAsPrevious[D] = true; 15965 } 15966 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15967 PrevDecl->getLocation(); 15968 } 15969 Filter.done(); 15970 if (InCompoundScope) { 15971 for (const auto &PrevData : UsedAsPrevious) { 15972 if (!PrevData.second) { 15973 PrevDMD = PrevData.first; 15974 break; 15975 } 15976 } 15977 } 15978 } else if (PrevDeclInScope) { 15979 auto *PrevDMDInScope = PrevDMD = 15980 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15981 do { 15982 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15983 PrevDMDInScope->getLocation(); 15984 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15985 } while (PrevDMDInScope != nullptr); 15986 } 15987 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15988 bool Invalid = false; 15989 if (I != PreviousRedeclTypes.end()) { 15990 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15991 << MapperType << Name; 15992 Diag(I->second, diag::note_previous_definition); 15993 Invalid = true; 15994 } 15995 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15996 MapperType, VN, PrevDMD); 15997 DC->addDecl(DMD); 15998 DMD->setAccess(AS); 15999 if (Invalid) 16000 DMD->setInvalidDecl(); 16001 16002 // Enter new function scope. 16003 PushFunctionScope(); 16004 setFunctionHasBranchProtectedScope(); 16005 16006 CurContext = DMD; 16007 16008 return DMD; 16009 } 16010 16011 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16012 Scope *S, 16013 QualType MapperType, 16014 SourceLocation StartLoc, 16015 DeclarationName VN) { 16016 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16017 if (S) 16018 PushOnScopeChains(VD, S); 16019 else 16020 DMD->addDecl(VD); 16021 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16022 DMD->setMapperVarRef(MapperVarRefExpr); 16023 } 16024 16025 Sema::DeclGroupPtrTy 16026 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16027 ArrayRef<OMPClause *> ClauseList) { 16028 PopDeclContext(); 16029 PopFunctionScopeInfo(); 16030 16031 if (D) { 16032 if (S) 16033 PushOnScopeChains(D, S, /*AddToContext=*/false); 16034 D->CreateClauses(Context, ClauseList); 16035 } 16036 16037 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16038 } 16039 16040 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16041 SourceLocation StartLoc, 16042 SourceLocation LParenLoc, 16043 SourceLocation EndLoc) { 16044 Expr *ValExpr = NumTeams; 16045 Stmt *HelperValStmt = nullptr; 16046 16047 // OpenMP [teams Constrcut, Restrictions] 16048 // The num_teams expression must evaluate to a positive integer value. 16049 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16050 /*StrictlyPositive=*/true)) 16051 return nullptr; 16052 16053 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16054 OpenMPDirectiveKind CaptureRegion = 16055 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 16056 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16057 ValExpr = MakeFullExpr(ValExpr).get(); 16058 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16059 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16060 HelperValStmt = buildPreInits(Context, Captures); 16061 } 16062 16063 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16064 StartLoc, LParenLoc, EndLoc); 16065 } 16066 16067 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16068 SourceLocation StartLoc, 16069 SourceLocation LParenLoc, 16070 SourceLocation EndLoc) { 16071 Expr *ValExpr = ThreadLimit; 16072 Stmt *HelperValStmt = nullptr; 16073 16074 // OpenMP [teams Constrcut, Restrictions] 16075 // The thread_limit expression must evaluate to a positive integer value. 16076 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16077 /*StrictlyPositive=*/true)) 16078 return nullptr; 16079 16080 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16081 OpenMPDirectiveKind CaptureRegion = 16082 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 16083 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16084 ValExpr = MakeFullExpr(ValExpr).get(); 16085 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16086 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16087 HelperValStmt = buildPreInits(Context, Captures); 16088 } 16089 16090 return new (Context) OMPThreadLimitClause( 16091 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16092 } 16093 16094 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16095 SourceLocation StartLoc, 16096 SourceLocation LParenLoc, 16097 SourceLocation EndLoc) { 16098 Expr *ValExpr = Priority; 16099 Stmt *HelperValStmt = nullptr; 16100 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16101 16102 // OpenMP [2.9.1, task Constrcut] 16103 // The priority-value is a non-negative numerical scalar expression. 16104 if (!isNonNegativeIntegerValue( 16105 ValExpr, *this, OMPC_priority, 16106 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16107 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16108 return nullptr; 16109 16110 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16111 StartLoc, LParenLoc, EndLoc); 16112 } 16113 16114 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16115 SourceLocation StartLoc, 16116 SourceLocation LParenLoc, 16117 SourceLocation EndLoc) { 16118 Expr *ValExpr = Grainsize; 16119 Stmt *HelperValStmt = nullptr; 16120 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16121 16122 // OpenMP [2.9.2, taskloop Constrcut] 16123 // The parameter of the grainsize clause must be a positive integer 16124 // expression. 16125 if (!isNonNegativeIntegerValue( 16126 ValExpr, *this, OMPC_grainsize, 16127 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16128 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16129 return nullptr; 16130 16131 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16132 StartLoc, LParenLoc, EndLoc); 16133 } 16134 16135 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16136 SourceLocation StartLoc, 16137 SourceLocation LParenLoc, 16138 SourceLocation EndLoc) { 16139 Expr *ValExpr = NumTasks; 16140 Stmt *HelperValStmt = nullptr; 16141 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16142 16143 // OpenMP [2.9.2, taskloop Constrcut] 16144 // The parameter of the num_tasks clause must be a positive integer 16145 // expression. 16146 if (!isNonNegativeIntegerValue( 16147 ValExpr, *this, OMPC_num_tasks, 16148 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16149 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16150 return nullptr; 16151 16152 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16153 StartLoc, LParenLoc, EndLoc); 16154 } 16155 16156 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16157 SourceLocation LParenLoc, 16158 SourceLocation EndLoc) { 16159 // OpenMP [2.13.2, critical construct, Description] 16160 // ... where hint-expression is an integer constant expression that evaluates 16161 // to a valid lock hint. 16162 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16163 if (HintExpr.isInvalid()) 16164 return nullptr; 16165 return new (Context) 16166 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16167 } 16168 16169 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16170 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16171 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16172 SourceLocation EndLoc) { 16173 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16174 std::string Values; 16175 Values += "'"; 16176 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16177 Values += "'"; 16178 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16179 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16180 return nullptr; 16181 } 16182 Expr *ValExpr = ChunkSize; 16183 Stmt *HelperValStmt = nullptr; 16184 if (ChunkSize) { 16185 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16186 !ChunkSize->isInstantiationDependent() && 16187 !ChunkSize->containsUnexpandedParameterPack()) { 16188 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16189 ExprResult Val = 16190 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16191 if (Val.isInvalid()) 16192 return nullptr; 16193 16194 ValExpr = Val.get(); 16195 16196 // OpenMP [2.7.1, Restrictions] 16197 // chunk_size must be a loop invariant integer expression with a positive 16198 // value. 16199 llvm::APSInt Result; 16200 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16201 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16202 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16203 << "dist_schedule" << ChunkSize->getSourceRange(); 16204 return nullptr; 16205 } 16206 } else if (getOpenMPCaptureRegionForClause( 16207 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 16208 OMPD_unknown && 16209 !CurContext->isDependentContext()) { 16210 ValExpr = MakeFullExpr(ValExpr).get(); 16211 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16212 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16213 HelperValStmt = buildPreInits(Context, Captures); 16214 } 16215 } 16216 } 16217 16218 return new (Context) 16219 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16220 Kind, ValExpr, HelperValStmt); 16221 } 16222 16223 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16224 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16225 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16226 SourceLocation KindLoc, SourceLocation EndLoc) { 16227 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 16228 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 16229 std::string Value; 16230 SourceLocation Loc; 16231 Value += "'"; 16232 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16233 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16234 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16235 Loc = MLoc; 16236 } else { 16237 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16238 OMPC_DEFAULTMAP_scalar); 16239 Loc = KindLoc; 16240 } 16241 Value += "'"; 16242 Diag(Loc, diag::err_omp_unexpected_clause_value) 16243 << Value << getOpenMPClauseName(OMPC_defaultmap); 16244 return nullptr; 16245 } 16246 DSAStack->setDefaultDMAToFromScalar(StartLoc); 16247 16248 return new (Context) 16249 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16250 } 16251 16252 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16253 DeclContext *CurLexicalContext = getCurLexicalContext(); 16254 if (!CurLexicalContext->isFileContext() && 16255 !CurLexicalContext->isExternCContext() && 16256 !CurLexicalContext->isExternCXXContext() && 16257 !isa<CXXRecordDecl>(CurLexicalContext) && 16258 !isa<ClassTemplateDecl>(CurLexicalContext) && 16259 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16260 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16261 Diag(Loc, diag::err_omp_region_not_file_context); 16262 return false; 16263 } 16264 ++DeclareTargetNestingLevel; 16265 return true; 16266 } 16267 16268 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16269 assert(DeclareTargetNestingLevel > 0 && 16270 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16271 --DeclareTargetNestingLevel; 16272 } 16273 16274 NamedDecl * 16275 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16276 const DeclarationNameInfo &Id, 16277 NamedDeclSetType &SameDirectiveDecls) { 16278 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16279 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16280 16281 if (Lookup.isAmbiguous()) 16282 return nullptr; 16283 Lookup.suppressDiagnostics(); 16284 16285 if (!Lookup.isSingleResult()) { 16286 VarOrFuncDeclFilterCCC CCC(*this); 16287 if (TypoCorrection Corrected = 16288 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16289 CTK_ErrorRecovery)) { 16290 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16291 << Id.getName()); 16292 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16293 return nullptr; 16294 } 16295 16296 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16297 return nullptr; 16298 } 16299 16300 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16301 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16302 !isa<FunctionTemplateDecl>(ND)) { 16303 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16304 return nullptr; 16305 } 16306 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16307 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16308 return ND; 16309 } 16310 16311 void Sema::ActOnOpenMPDeclareTargetName( 16312 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16313 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16314 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16315 isa<FunctionTemplateDecl>(ND)) && 16316 "Expected variable, function or function template."); 16317 16318 // Diagnose marking after use as it may lead to incorrect diagnosis and 16319 // codegen. 16320 if (LangOpts.OpenMP >= 50 && 16321 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16322 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16323 16324 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16325 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16326 if (DevTy.hasValue() && *DevTy != DT) { 16327 Diag(Loc, diag::err_omp_device_type_mismatch) 16328 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16329 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16330 return; 16331 } 16332 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16333 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16334 if (!Res) { 16335 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16336 SourceRange(Loc, Loc)); 16337 ND->addAttr(A); 16338 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16339 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16340 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16341 } else if (*Res != MT) { 16342 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16343 } 16344 } 16345 16346 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16347 Sema &SemaRef, Decl *D) { 16348 if (!D || !isa<VarDecl>(D)) 16349 return; 16350 auto *VD = cast<VarDecl>(D); 16351 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16352 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16353 if (SemaRef.LangOpts.OpenMP >= 50 && 16354 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16355 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16356 VD->hasGlobalStorage()) { 16357 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16358 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16359 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16360 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16361 // If a lambda declaration and definition appears between a 16362 // declare target directive and the matching end declare target 16363 // directive, all variables that are captured by the lambda 16364 // expression must also appear in a to clause. 16365 SemaRef.Diag(VD->getLocation(), 16366 diag::err_omp_lambda_capture_in_declare_target_not_to); 16367 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16368 << VD << 0 << SR; 16369 return; 16370 } 16371 } 16372 if (MapTy.hasValue()) 16373 return; 16374 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16375 SemaRef.Diag(SL, diag::note_used_here) << SR; 16376 } 16377 16378 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16379 Sema &SemaRef, DSAStackTy *Stack, 16380 ValueDecl *VD) { 16381 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16382 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16383 /*FullCheck=*/false); 16384 } 16385 16386 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16387 SourceLocation IdLoc) { 16388 if (!D || D->isInvalidDecl()) 16389 return; 16390 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16391 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16392 if (auto *VD = dyn_cast<VarDecl>(D)) { 16393 // Only global variables can be marked as declare target. 16394 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16395 !VD->isStaticDataMember()) 16396 return; 16397 // 2.10.6: threadprivate variable cannot appear in a declare target 16398 // directive. 16399 if (DSAStack->isThreadPrivate(VD)) { 16400 Diag(SL, diag::err_omp_threadprivate_in_target); 16401 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16402 return; 16403 } 16404 } 16405 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16406 D = FTD->getTemplatedDecl(); 16407 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16408 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16409 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16410 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16411 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16412 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16413 return; 16414 } 16415 // Mark the function as must be emitted for the device. 16416 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16417 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16418 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16419 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16420 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16421 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16422 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16423 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16424 } 16425 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16426 // Problem if any with var declared with incomplete type will be reported 16427 // as normal, so no need to check it here. 16428 if ((E || !VD->getType()->isIncompleteType()) && 16429 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16430 return; 16431 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16432 // Checking declaration inside declare target region. 16433 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16434 isa<FunctionTemplateDecl>(D)) { 16435 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16436 Context, OMPDeclareTargetDeclAttr::MT_To, 16437 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16438 D->addAttr(A); 16439 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16440 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16441 } 16442 return; 16443 } 16444 } 16445 if (!E) 16446 return; 16447 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16448 } 16449 16450 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16451 CXXScopeSpec &MapperIdScopeSpec, 16452 DeclarationNameInfo &MapperId, 16453 const OMPVarListLocTy &Locs, 16454 ArrayRef<Expr *> UnresolvedMappers) { 16455 MappableVarListInfo MVLI(VarList); 16456 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16457 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16458 if (MVLI.ProcessedVarList.empty()) 16459 return nullptr; 16460 16461 return OMPToClause::Create( 16462 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16463 MVLI.VarComponents, MVLI.UDMapperList, 16464 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16465 } 16466 16467 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16468 CXXScopeSpec &MapperIdScopeSpec, 16469 DeclarationNameInfo &MapperId, 16470 const OMPVarListLocTy &Locs, 16471 ArrayRef<Expr *> UnresolvedMappers) { 16472 MappableVarListInfo MVLI(VarList); 16473 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16474 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16475 if (MVLI.ProcessedVarList.empty()) 16476 return nullptr; 16477 16478 return OMPFromClause::Create( 16479 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16480 MVLI.VarComponents, MVLI.UDMapperList, 16481 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16482 } 16483 16484 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16485 const OMPVarListLocTy &Locs) { 16486 MappableVarListInfo MVLI(VarList); 16487 SmallVector<Expr *, 8> PrivateCopies; 16488 SmallVector<Expr *, 8> Inits; 16489 16490 for (Expr *RefExpr : VarList) { 16491 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16492 SourceLocation ELoc; 16493 SourceRange ERange; 16494 Expr *SimpleRefExpr = RefExpr; 16495 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16496 if (Res.second) { 16497 // It will be analyzed later. 16498 MVLI.ProcessedVarList.push_back(RefExpr); 16499 PrivateCopies.push_back(nullptr); 16500 Inits.push_back(nullptr); 16501 } 16502 ValueDecl *D = Res.first; 16503 if (!D) 16504 continue; 16505 16506 QualType Type = D->getType(); 16507 Type = Type.getNonReferenceType().getUnqualifiedType(); 16508 16509 auto *VD = dyn_cast<VarDecl>(D); 16510 16511 // Item should be a pointer or reference to pointer. 16512 if (!Type->isPointerType()) { 16513 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16514 << 0 << RefExpr->getSourceRange(); 16515 continue; 16516 } 16517 16518 // Build the private variable and the expression that refers to it. 16519 auto VDPrivate = 16520 buildVarDecl(*this, ELoc, Type, D->getName(), 16521 D->hasAttrs() ? &D->getAttrs() : nullptr, 16522 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16523 if (VDPrivate->isInvalidDecl()) 16524 continue; 16525 16526 CurContext->addDecl(VDPrivate); 16527 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16528 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16529 16530 // Add temporary variable to initialize the private copy of the pointer. 16531 VarDecl *VDInit = 16532 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16533 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16534 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16535 AddInitializerToDecl(VDPrivate, 16536 DefaultLvalueConversion(VDInitRefExpr).get(), 16537 /*DirectInit=*/false); 16538 16539 // If required, build a capture to implement the privatization initialized 16540 // with the current list item value. 16541 DeclRefExpr *Ref = nullptr; 16542 if (!VD) 16543 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16544 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16545 PrivateCopies.push_back(VDPrivateRefExpr); 16546 Inits.push_back(VDInitRefExpr); 16547 16548 // We need to add a data sharing attribute for this variable to make sure it 16549 // is correctly captured. A variable that shows up in a use_device_ptr has 16550 // similar properties of a first private variable. 16551 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16552 16553 // Create a mappable component for the list item. List items in this clause 16554 // only need a component. 16555 MVLI.VarBaseDeclarations.push_back(D); 16556 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16557 MVLI.VarComponents.back().push_back( 16558 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16559 } 16560 16561 if (MVLI.ProcessedVarList.empty()) 16562 return nullptr; 16563 16564 return OMPUseDevicePtrClause::Create( 16565 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16566 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16567 } 16568 16569 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16570 const OMPVarListLocTy &Locs) { 16571 MappableVarListInfo MVLI(VarList); 16572 for (Expr *RefExpr : VarList) { 16573 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16574 SourceLocation ELoc; 16575 SourceRange ERange; 16576 Expr *SimpleRefExpr = RefExpr; 16577 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16578 if (Res.second) { 16579 // It will be analyzed later. 16580 MVLI.ProcessedVarList.push_back(RefExpr); 16581 } 16582 ValueDecl *D = Res.first; 16583 if (!D) 16584 continue; 16585 16586 QualType Type = D->getType(); 16587 // item should be a pointer or array or reference to pointer or array 16588 if (!Type.getNonReferenceType()->isPointerType() && 16589 !Type.getNonReferenceType()->isArrayType()) { 16590 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16591 << 0 << RefExpr->getSourceRange(); 16592 continue; 16593 } 16594 16595 // Check if the declaration in the clause does not show up in any data 16596 // sharing attribute. 16597 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16598 if (isOpenMPPrivate(DVar.CKind)) { 16599 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16600 << getOpenMPClauseName(DVar.CKind) 16601 << getOpenMPClauseName(OMPC_is_device_ptr) 16602 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16603 reportOriginalDsa(*this, DSAStack, D, DVar); 16604 continue; 16605 } 16606 16607 const Expr *ConflictExpr; 16608 if (DSAStack->checkMappableExprComponentListsForDecl( 16609 D, /*CurrentRegionOnly=*/true, 16610 [&ConflictExpr]( 16611 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16612 OpenMPClauseKind) -> bool { 16613 ConflictExpr = R.front().getAssociatedExpression(); 16614 return true; 16615 })) { 16616 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16617 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16618 << ConflictExpr->getSourceRange(); 16619 continue; 16620 } 16621 16622 // Store the components in the stack so that they can be used to check 16623 // against other clauses later on. 16624 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16625 DSAStack->addMappableExpressionComponents( 16626 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16627 16628 // Record the expression we've just processed. 16629 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16630 16631 // Create a mappable component for the list item. List items in this clause 16632 // only need a component. We use a null declaration to signal fields in 16633 // 'this'. 16634 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16635 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16636 "Unexpected device pointer expression!"); 16637 MVLI.VarBaseDeclarations.push_back( 16638 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16639 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16640 MVLI.VarComponents.back().push_back(MC); 16641 } 16642 16643 if (MVLI.ProcessedVarList.empty()) 16644 return nullptr; 16645 16646 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16647 MVLI.VarBaseDeclarations, 16648 MVLI.VarComponents); 16649 } 16650 16651 OMPClause *Sema::ActOnOpenMPAllocateClause( 16652 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16653 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16654 if (Allocator) { 16655 // OpenMP [2.11.4 allocate Clause, Description] 16656 // allocator is an expression of omp_allocator_handle_t type. 16657 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16658 return nullptr; 16659 16660 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16661 if (AllocatorRes.isInvalid()) 16662 return nullptr; 16663 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16664 DSAStack->getOMPAllocatorHandleT(), 16665 Sema::AA_Initializing, 16666 /*AllowExplicit=*/true); 16667 if (AllocatorRes.isInvalid()) 16668 return nullptr; 16669 Allocator = AllocatorRes.get(); 16670 } else { 16671 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16672 // allocate clauses that appear on a target construct or on constructs in a 16673 // target region must specify an allocator expression unless a requires 16674 // directive with the dynamic_allocators clause is present in the same 16675 // compilation unit. 16676 if (LangOpts.OpenMPIsDevice && 16677 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16678 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16679 } 16680 // Analyze and build list of variables. 16681 SmallVector<Expr *, 8> Vars; 16682 for (Expr *RefExpr : VarList) { 16683 assert(RefExpr && "NULL expr in OpenMP private clause."); 16684 SourceLocation ELoc; 16685 SourceRange ERange; 16686 Expr *SimpleRefExpr = RefExpr; 16687 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16688 if (Res.second) { 16689 // It will be analyzed later. 16690 Vars.push_back(RefExpr); 16691 } 16692 ValueDecl *D = Res.first; 16693 if (!D) 16694 continue; 16695 16696 auto *VD = dyn_cast<VarDecl>(D); 16697 DeclRefExpr *Ref = nullptr; 16698 if (!VD && !CurContext->isDependentContext()) 16699 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16700 Vars.push_back((VD || CurContext->isDependentContext()) 16701 ? RefExpr->IgnoreParens() 16702 : Ref); 16703 } 16704 16705 if (Vars.empty()) 16706 return nullptr; 16707 16708 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16709 ColonLoc, EndLoc, Vars); 16710 } 16711