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 // If we want to determine whether the variable should be captured from the 1898 // perspective of the current capturing scope, and we've already left all the 1899 // capturing scopes of the top directive on the stack, check from the 1900 // perspective of its parent directive (if any) instead. 1901 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1902 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1903 1904 // If we are attempting to capture a global variable in a directive with 1905 // 'target' we return true so that this global is also mapped to the device. 1906 // 1907 auto *VD = dyn_cast<VarDecl>(D); 1908 if (VD && !VD->hasLocalStorage() && 1909 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1910 if (isInOpenMPDeclareTargetContext()) { 1911 // Try to mark variable as declare target if it is used in capturing 1912 // regions. 1913 if (LangOpts.OpenMP <= 45 && 1914 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1915 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1916 return nullptr; 1917 } else if (isInOpenMPTargetExecutionDirective()) { 1918 // If the declaration is enclosed in a 'declare target' directive, 1919 // then it should not be captured. 1920 // 1921 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1922 return nullptr; 1923 return VD; 1924 } 1925 } 1926 1927 if (CheckScopeInfo) { 1928 bool OpenMPFound = false; 1929 for (unsigned I = StopAt + 1; I > 0; --I) { 1930 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1931 if(!isa<CapturingScopeInfo>(FSI)) 1932 return nullptr; 1933 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1934 if (RSI->CapRegionKind == CR_OpenMP) { 1935 OpenMPFound = true; 1936 break; 1937 } 1938 } 1939 if (!OpenMPFound) 1940 return nullptr; 1941 } 1942 1943 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1944 (!DSAStack->isClauseParsingMode() || 1945 DSAStack->getParentDirective() != OMPD_unknown)) { 1946 auto &&Info = DSAStack->isLoopControlVariable(D); 1947 if (Info.first || 1948 (VD && VD->hasLocalStorage() && 1949 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1950 (VD && DSAStack->isForceVarCapturing())) 1951 return VD ? VD : Info.second; 1952 DSAStackTy::DSAVarData DVarPrivate = 1953 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1954 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1955 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1956 // Threadprivate variables must not be captured. 1957 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1958 return nullptr; 1959 // The variable is not private or it is the variable in the directive with 1960 // default(none) clause and not used in any clause. 1961 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1962 [](OpenMPDirectiveKind) { return true; }, 1963 DSAStack->isClauseParsingMode()); 1964 if (DVarPrivate.CKind != OMPC_unknown || 1965 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1966 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1967 } 1968 return nullptr; 1969 } 1970 1971 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1972 unsigned Level) const { 1973 SmallVector<OpenMPDirectiveKind, 4> Regions; 1974 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1975 FunctionScopesIndex -= Regions.size(); 1976 } 1977 1978 void Sema::startOpenMPLoop() { 1979 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1980 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1981 DSAStack->loopInit(); 1982 } 1983 1984 void Sema::startOpenMPCXXRangeFor() { 1985 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1986 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1987 DSAStack->resetPossibleLoopCounter(); 1988 DSAStack->loopStart(); 1989 } 1990 } 1991 1992 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1993 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1994 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1995 if (DSAStack->getAssociatedLoops() > 0 && 1996 !DSAStack->isLoopStarted()) { 1997 DSAStack->resetPossibleLoopCounter(D); 1998 DSAStack->loopStart(); 1999 return true; 2000 } 2001 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2002 DSAStack->isLoopControlVariable(D).first) && 2003 !DSAStack->hasExplicitDSA( 2004 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2005 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2006 return true; 2007 } 2008 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2009 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2010 DSAStack->isForceVarCapturing() && 2011 !DSAStack->hasExplicitDSA( 2012 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2013 return true; 2014 } 2015 return DSAStack->hasExplicitDSA( 2016 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2017 (DSAStack->isClauseParsingMode() && 2018 DSAStack->getClauseParsingMode() == OMPC_private) || 2019 // Consider taskgroup reduction descriptor variable a private to avoid 2020 // possible capture in the region. 2021 (DSAStack->hasExplicitDirective( 2022 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2023 Level) && 2024 DSAStack->isTaskgroupReductionRef(D, Level)); 2025 } 2026 2027 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2028 unsigned Level) { 2029 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2030 D = getCanonicalDecl(D); 2031 OpenMPClauseKind OMPC = OMPC_unknown; 2032 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2033 const unsigned NewLevel = I - 1; 2034 if (DSAStack->hasExplicitDSA(D, 2035 [&OMPC](const OpenMPClauseKind K) { 2036 if (isOpenMPPrivate(K)) { 2037 OMPC = K; 2038 return true; 2039 } 2040 return false; 2041 }, 2042 NewLevel)) 2043 break; 2044 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2045 D, NewLevel, 2046 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2047 OpenMPClauseKind) { return true; })) { 2048 OMPC = OMPC_map; 2049 break; 2050 } 2051 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2052 NewLevel)) { 2053 OMPC = OMPC_map; 2054 if (D->getType()->isScalarType() && 2055 DSAStack->getDefaultDMAAtLevel(NewLevel) != 2056 DefaultMapAttributes::DMA_tofrom_scalar) 2057 OMPC = OMPC_firstprivate; 2058 break; 2059 } 2060 } 2061 if (OMPC != OMPC_unknown) 2062 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2063 } 2064 2065 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2066 unsigned Level) const { 2067 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2068 // Return true if the current level is no longer enclosed in a target region. 2069 2070 const auto *VD = dyn_cast<VarDecl>(D); 2071 return VD && !VD->hasLocalStorage() && 2072 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2073 Level); 2074 } 2075 2076 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2077 2078 void Sema::finalizeOpenMPDelayedAnalysis() { 2079 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2080 // Diagnose implicit declare target functions and their callees. 2081 for (const auto &CallerCallees : DeviceCallGraph) { 2082 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2083 OMPDeclareTargetDeclAttr::getDeviceType( 2084 CallerCallees.getFirst()->getMostRecentDecl()); 2085 // Ignore host functions during device analyzis. 2086 if (LangOpts.OpenMPIsDevice && DevTy && 2087 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2088 continue; 2089 // Ignore nohost functions during host analyzis. 2090 if (!LangOpts.OpenMPIsDevice && DevTy && 2091 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2092 continue; 2093 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2094 &Callee : CallerCallees.getSecond()) { 2095 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2096 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2097 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2098 if (LangOpts.OpenMPIsDevice && DevTy && 2099 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2100 // Diagnose host function called during device codegen. 2101 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2102 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2103 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2104 << HostDevTy << 0; 2105 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2106 diag::note_omp_marked_device_type_here) 2107 << HostDevTy; 2108 continue; 2109 } 2110 if (!LangOpts.OpenMPIsDevice && DevTy && 2111 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2112 // Diagnose nohost function called during host codegen. 2113 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2114 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2115 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2116 << NoHostDevTy << 1; 2117 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2118 diag::note_omp_marked_device_type_here) 2119 << NoHostDevTy; 2120 continue; 2121 } 2122 } 2123 } 2124 } 2125 2126 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2127 const DeclarationNameInfo &DirName, 2128 Scope *CurScope, SourceLocation Loc) { 2129 DSAStack->push(DKind, DirName, CurScope, Loc); 2130 PushExpressionEvaluationContext( 2131 ExpressionEvaluationContext::PotentiallyEvaluated); 2132 } 2133 2134 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2135 DSAStack->setClauseParsingMode(K); 2136 } 2137 2138 void Sema::EndOpenMPClause() { 2139 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2140 } 2141 2142 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2143 ArrayRef<OMPClause *> Clauses); 2144 2145 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2146 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2147 // A variable of class type (or array thereof) that appears in a lastprivate 2148 // clause requires an accessible, unambiguous default constructor for the 2149 // class type, unless the list item is also specified in a firstprivate 2150 // clause. 2151 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2152 for (OMPClause *C : D->clauses()) { 2153 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2154 SmallVector<Expr *, 8> PrivateCopies; 2155 for (Expr *DE : Clause->varlists()) { 2156 if (DE->isValueDependent() || DE->isTypeDependent()) { 2157 PrivateCopies.push_back(nullptr); 2158 continue; 2159 } 2160 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2161 auto *VD = cast<VarDecl>(DRE->getDecl()); 2162 QualType Type = VD->getType().getNonReferenceType(); 2163 const DSAStackTy::DSAVarData DVar = 2164 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2165 if (DVar.CKind == OMPC_lastprivate) { 2166 // Generate helper private variable and initialize it with the 2167 // default value. The address of the original variable is replaced 2168 // by the address of the new private variable in CodeGen. This new 2169 // variable is not added to IdResolver, so the code in the OpenMP 2170 // region uses original variable for proper diagnostics. 2171 VarDecl *VDPrivate = buildVarDecl( 2172 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2173 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2174 ActOnUninitializedDecl(VDPrivate); 2175 if (VDPrivate->isInvalidDecl()) { 2176 PrivateCopies.push_back(nullptr); 2177 continue; 2178 } 2179 PrivateCopies.push_back(buildDeclRefExpr( 2180 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2181 } else { 2182 // The variable is also a firstprivate, so initialization sequence 2183 // for private copy is generated already. 2184 PrivateCopies.push_back(nullptr); 2185 } 2186 } 2187 Clause->setPrivateCopies(PrivateCopies); 2188 } 2189 } 2190 // Check allocate clauses. 2191 if (!CurContext->isDependentContext()) 2192 checkAllocateClauses(*this, DSAStack, D->clauses()); 2193 } 2194 2195 DSAStack->pop(); 2196 DiscardCleanupsInEvaluationContext(); 2197 PopExpressionEvaluationContext(); 2198 } 2199 2200 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2201 Expr *NumIterations, Sema &SemaRef, 2202 Scope *S, DSAStackTy *Stack); 2203 2204 namespace { 2205 2206 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2207 private: 2208 Sema &SemaRef; 2209 2210 public: 2211 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2212 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2213 NamedDecl *ND = Candidate.getCorrectionDecl(); 2214 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2215 return VD->hasGlobalStorage() && 2216 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2217 SemaRef.getCurScope()); 2218 } 2219 return false; 2220 } 2221 2222 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2223 return std::make_unique<VarDeclFilterCCC>(*this); 2224 } 2225 2226 }; 2227 2228 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2229 private: 2230 Sema &SemaRef; 2231 2232 public: 2233 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2234 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2235 NamedDecl *ND = Candidate.getCorrectionDecl(); 2236 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2237 isa<FunctionDecl>(ND))) { 2238 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2239 SemaRef.getCurScope()); 2240 } 2241 return false; 2242 } 2243 2244 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2245 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2246 } 2247 }; 2248 2249 } // namespace 2250 2251 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2252 CXXScopeSpec &ScopeSpec, 2253 const DeclarationNameInfo &Id, 2254 OpenMPDirectiveKind Kind) { 2255 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2256 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2257 2258 if (Lookup.isAmbiguous()) 2259 return ExprError(); 2260 2261 VarDecl *VD; 2262 if (!Lookup.isSingleResult()) { 2263 VarDeclFilterCCC CCC(*this); 2264 if (TypoCorrection Corrected = 2265 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2266 CTK_ErrorRecovery)) { 2267 diagnoseTypo(Corrected, 2268 PDiag(Lookup.empty() 2269 ? diag::err_undeclared_var_use_suggest 2270 : diag::err_omp_expected_var_arg_suggest) 2271 << Id.getName()); 2272 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2273 } else { 2274 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2275 : diag::err_omp_expected_var_arg) 2276 << Id.getName(); 2277 return ExprError(); 2278 } 2279 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2280 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2281 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2282 return ExprError(); 2283 } 2284 Lookup.suppressDiagnostics(); 2285 2286 // OpenMP [2.9.2, Syntax, C/C++] 2287 // Variables must be file-scope, namespace-scope, or static block-scope. 2288 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2289 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2290 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2291 bool IsDecl = 2292 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2293 Diag(VD->getLocation(), 2294 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2295 << VD; 2296 return ExprError(); 2297 } 2298 2299 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2300 NamedDecl *ND = CanonicalVD; 2301 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2302 // A threadprivate directive for file-scope variables must appear outside 2303 // any definition or declaration. 2304 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2305 !getCurLexicalContext()->isTranslationUnit()) { 2306 Diag(Id.getLoc(), diag::err_omp_var_scope) 2307 << getOpenMPDirectiveName(Kind) << VD; 2308 bool IsDecl = 2309 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2310 Diag(VD->getLocation(), 2311 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2312 << VD; 2313 return ExprError(); 2314 } 2315 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2316 // A threadprivate directive for static class member variables must appear 2317 // in the class definition, in the same scope in which the member 2318 // variables are declared. 2319 if (CanonicalVD->isStaticDataMember() && 2320 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2321 Diag(Id.getLoc(), diag::err_omp_var_scope) 2322 << getOpenMPDirectiveName(Kind) << VD; 2323 bool IsDecl = 2324 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2325 Diag(VD->getLocation(), 2326 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2327 << VD; 2328 return ExprError(); 2329 } 2330 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2331 // A threadprivate directive for namespace-scope variables must appear 2332 // outside any definition or declaration other than the namespace 2333 // definition itself. 2334 if (CanonicalVD->getDeclContext()->isNamespace() && 2335 (!getCurLexicalContext()->isFileContext() || 2336 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2337 Diag(Id.getLoc(), diag::err_omp_var_scope) 2338 << getOpenMPDirectiveName(Kind) << VD; 2339 bool IsDecl = 2340 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2341 Diag(VD->getLocation(), 2342 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2343 << VD; 2344 return ExprError(); 2345 } 2346 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2347 // A threadprivate directive for static block-scope variables must appear 2348 // in the scope of the variable and not in a nested scope. 2349 if (CanonicalVD->isLocalVarDecl() && CurScope && 2350 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2351 Diag(Id.getLoc(), diag::err_omp_var_scope) 2352 << getOpenMPDirectiveName(Kind) << VD; 2353 bool IsDecl = 2354 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2355 Diag(VD->getLocation(), 2356 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2357 << VD; 2358 return ExprError(); 2359 } 2360 2361 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2362 // A threadprivate directive must lexically precede all references to any 2363 // of the variables in its list. 2364 if (Kind == OMPD_threadprivate && VD->isUsed() && 2365 !DSAStack->isThreadPrivate(VD)) { 2366 Diag(Id.getLoc(), diag::err_omp_var_used) 2367 << getOpenMPDirectiveName(Kind) << VD; 2368 return ExprError(); 2369 } 2370 2371 QualType ExprType = VD->getType().getNonReferenceType(); 2372 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2373 SourceLocation(), VD, 2374 /*RefersToEnclosingVariableOrCapture=*/false, 2375 Id.getLoc(), ExprType, VK_LValue); 2376 } 2377 2378 Sema::DeclGroupPtrTy 2379 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2380 ArrayRef<Expr *> VarList) { 2381 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2382 CurContext->addDecl(D); 2383 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2384 } 2385 return nullptr; 2386 } 2387 2388 namespace { 2389 class LocalVarRefChecker final 2390 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2391 Sema &SemaRef; 2392 2393 public: 2394 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2395 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2396 if (VD->hasLocalStorage()) { 2397 SemaRef.Diag(E->getBeginLoc(), 2398 diag::err_omp_local_var_in_threadprivate_init) 2399 << E->getSourceRange(); 2400 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2401 << VD << VD->getSourceRange(); 2402 return true; 2403 } 2404 } 2405 return false; 2406 } 2407 bool VisitStmt(const Stmt *S) { 2408 for (const Stmt *Child : S->children()) { 2409 if (Child && Visit(Child)) 2410 return true; 2411 } 2412 return false; 2413 } 2414 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2415 }; 2416 } // namespace 2417 2418 OMPThreadPrivateDecl * 2419 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2420 SmallVector<Expr *, 8> Vars; 2421 for (Expr *RefExpr : VarList) { 2422 auto *DE = cast<DeclRefExpr>(RefExpr); 2423 auto *VD = cast<VarDecl>(DE->getDecl()); 2424 SourceLocation ILoc = DE->getExprLoc(); 2425 2426 // Mark variable as used. 2427 VD->setReferenced(); 2428 VD->markUsed(Context); 2429 2430 QualType QType = VD->getType(); 2431 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2432 // It will be analyzed later. 2433 Vars.push_back(DE); 2434 continue; 2435 } 2436 2437 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2438 // A threadprivate variable must not have an incomplete type. 2439 if (RequireCompleteType(ILoc, VD->getType(), 2440 diag::err_omp_threadprivate_incomplete_type)) { 2441 continue; 2442 } 2443 2444 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2445 // A threadprivate variable must not have a reference type. 2446 if (VD->getType()->isReferenceType()) { 2447 Diag(ILoc, diag::err_omp_ref_type_arg) 2448 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2449 bool IsDecl = 2450 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2451 Diag(VD->getLocation(), 2452 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2453 << VD; 2454 continue; 2455 } 2456 2457 // Check if this is a TLS variable. If TLS is not being supported, produce 2458 // the corresponding diagnostic. 2459 if ((VD->getTLSKind() != VarDecl::TLS_None && 2460 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2461 getLangOpts().OpenMPUseTLS && 2462 getASTContext().getTargetInfo().isTLSSupported())) || 2463 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2464 !VD->isLocalVarDecl())) { 2465 Diag(ILoc, diag::err_omp_var_thread_local) 2466 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2467 bool IsDecl = 2468 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2469 Diag(VD->getLocation(), 2470 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2471 << VD; 2472 continue; 2473 } 2474 2475 // Check if initial value of threadprivate variable reference variable with 2476 // local storage (it is not supported by runtime). 2477 if (const Expr *Init = VD->getAnyInitializer()) { 2478 LocalVarRefChecker Checker(*this); 2479 if (Checker.Visit(Init)) 2480 continue; 2481 } 2482 2483 Vars.push_back(RefExpr); 2484 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2485 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2486 Context, SourceRange(Loc, Loc))); 2487 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2488 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2489 } 2490 OMPThreadPrivateDecl *D = nullptr; 2491 if (!Vars.empty()) { 2492 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2493 Vars); 2494 D->setAccess(AS_public); 2495 } 2496 return D; 2497 } 2498 2499 static OMPAllocateDeclAttr::AllocatorTypeTy 2500 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2501 if (!Allocator) 2502 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2503 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2504 Allocator->isInstantiationDependent() || 2505 Allocator->containsUnexpandedParameterPack()) 2506 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2507 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2508 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2509 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2510 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2511 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2512 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2513 llvm::FoldingSetNodeID AEId, DAEId; 2514 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2515 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2516 if (AEId == DAEId) { 2517 AllocatorKindRes = AllocatorKind; 2518 break; 2519 } 2520 } 2521 return AllocatorKindRes; 2522 } 2523 2524 static bool checkPreviousOMPAllocateAttribute( 2525 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2526 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2527 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2528 return false; 2529 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2530 Expr *PrevAllocator = A->getAllocator(); 2531 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2532 getAllocatorKind(S, Stack, PrevAllocator); 2533 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2534 if (AllocatorsMatch && 2535 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2536 Allocator && PrevAllocator) { 2537 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2538 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2539 llvm::FoldingSetNodeID AEId, PAEId; 2540 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2541 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2542 AllocatorsMatch = AEId == PAEId; 2543 } 2544 if (!AllocatorsMatch) { 2545 SmallString<256> AllocatorBuffer; 2546 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2547 if (Allocator) 2548 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2549 SmallString<256> PrevAllocatorBuffer; 2550 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2551 if (PrevAllocator) 2552 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2553 S.getPrintingPolicy()); 2554 2555 SourceLocation AllocatorLoc = 2556 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2557 SourceRange AllocatorRange = 2558 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2559 SourceLocation PrevAllocatorLoc = 2560 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2561 SourceRange PrevAllocatorRange = 2562 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2563 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2564 << (Allocator ? 1 : 0) << AllocatorStream.str() 2565 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2566 << AllocatorRange; 2567 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2568 << PrevAllocatorRange; 2569 return true; 2570 } 2571 return false; 2572 } 2573 2574 static void 2575 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2576 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2577 Expr *Allocator, SourceRange SR) { 2578 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2579 return; 2580 if (Allocator && 2581 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2582 Allocator->isInstantiationDependent() || 2583 Allocator->containsUnexpandedParameterPack())) 2584 return; 2585 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2586 Allocator, SR); 2587 VD->addAttr(A); 2588 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2589 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2590 } 2591 2592 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2593 SourceLocation Loc, ArrayRef<Expr *> VarList, 2594 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2595 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2596 Expr *Allocator = nullptr; 2597 if (Clauses.empty()) { 2598 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2599 // allocate directives that appear in a target region must specify an 2600 // allocator clause unless a requires directive with the dynamic_allocators 2601 // clause is present in the same compilation unit. 2602 if (LangOpts.OpenMPIsDevice && 2603 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2604 targetDiag(Loc, diag::err_expected_allocator_clause); 2605 } else { 2606 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2607 } 2608 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2609 getAllocatorKind(*this, DSAStack, Allocator); 2610 SmallVector<Expr *, 8> Vars; 2611 for (Expr *RefExpr : VarList) { 2612 auto *DE = cast<DeclRefExpr>(RefExpr); 2613 auto *VD = cast<VarDecl>(DE->getDecl()); 2614 2615 // Check if this is a TLS variable or global register. 2616 if (VD->getTLSKind() != VarDecl::TLS_None || 2617 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2618 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2619 !VD->isLocalVarDecl())) 2620 continue; 2621 2622 // If the used several times in the allocate directive, the same allocator 2623 // must be used. 2624 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2625 AllocatorKind, Allocator)) 2626 continue; 2627 2628 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2629 // If a list item has a static storage type, the allocator expression in the 2630 // allocator clause must be a constant expression that evaluates to one of 2631 // the predefined memory allocator values. 2632 if (Allocator && VD->hasGlobalStorage()) { 2633 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2634 Diag(Allocator->getExprLoc(), 2635 diag::err_omp_expected_predefined_allocator) 2636 << Allocator->getSourceRange(); 2637 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2638 VarDecl::DeclarationOnly; 2639 Diag(VD->getLocation(), 2640 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2641 << VD; 2642 continue; 2643 } 2644 } 2645 2646 Vars.push_back(RefExpr); 2647 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2648 DE->getSourceRange()); 2649 } 2650 if (Vars.empty()) 2651 return nullptr; 2652 if (!Owner) 2653 Owner = getCurLexicalContext(); 2654 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2655 D->setAccess(AS_public); 2656 Owner->addDecl(D); 2657 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2658 } 2659 2660 Sema::DeclGroupPtrTy 2661 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2662 ArrayRef<OMPClause *> ClauseList) { 2663 OMPRequiresDecl *D = nullptr; 2664 if (!CurContext->isFileContext()) { 2665 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2666 } else { 2667 D = CheckOMPRequiresDecl(Loc, ClauseList); 2668 if (D) { 2669 CurContext->addDecl(D); 2670 DSAStack->addRequiresDecl(D); 2671 } 2672 } 2673 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2674 } 2675 2676 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2677 ArrayRef<OMPClause *> ClauseList) { 2678 /// For target specific clauses, the requires directive cannot be 2679 /// specified after the handling of any of the target regions in the 2680 /// current compilation unit. 2681 ArrayRef<SourceLocation> TargetLocations = 2682 DSAStack->getEncounteredTargetLocs(); 2683 if (!TargetLocations.empty()) { 2684 for (const OMPClause *CNew : ClauseList) { 2685 // Check if any of the requires clauses affect target regions. 2686 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2687 isa<OMPUnifiedAddressClause>(CNew) || 2688 isa<OMPReverseOffloadClause>(CNew) || 2689 isa<OMPDynamicAllocatorsClause>(CNew)) { 2690 Diag(Loc, diag::err_omp_target_before_requires) 2691 << getOpenMPClauseName(CNew->getClauseKind()); 2692 for (SourceLocation TargetLoc : TargetLocations) { 2693 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2694 } 2695 } 2696 } 2697 } 2698 2699 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2700 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2701 ClauseList); 2702 return nullptr; 2703 } 2704 2705 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2706 const ValueDecl *D, 2707 const DSAStackTy::DSAVarData &DVar, 2708 bool IsLoopIterVar = false) { 2709 if (DVar.RefExpr) { 2710 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2711 << getOpenMPClauseName(DVar.CKind); 2712 return; 2713 } 2714 enum { 2715 PDSA_StaticMemberShared, 2716 PDSA_StaticLocalVarShared, 2717 PDSA_LoopIterVarPrivate, 2718 PDSA_LoopIterVarLinear, 2719 PDSA_LoopIterVarLastprivate, 2720 PDSA_ConstVarShared, 2721 PDSA_GlobalVarShared, 2722 PDSA_TaskVarFirstprivate, 2723 PDSA_LocalVarPrivate, 2724 PDSA_Implicit 2725 } Reason = PDSA_Implicit; 2726 bool ReportHint = false; 2727 auto ReportLoc = D->getLocation(); 2728 auto *VD = dyn_cast<VarDecl>(D); 2729 if (IsLoopIterVar) { 2730 if (DVar.CKind == OMPC_private) 2731 Reason = PDSA_LoopIterVarPrivate; 2732 else if (DVar.CKind == OMPC_lastprivate) 2733 Reason = PDSA_LoopIterVarLastprivate; 2734 else 2735 Reason = PDSA_LoopIterVarLinear; 2736 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2737 DVar.CKind == OMPC_firstprivate) { 2738 Reason = PDSA_TaskVarFirstprivate; 2739 ReportLoc = DVar.ImplicitDSALoc; 2740 } else if (VD && VD->isStaticLocal()) 2741 Reason = PDSA_StaticLocalVarShared; 2742 else if (VD && VD->isStaticDataMember()) 2743 Reason = PDSA_StaticMemberShared; 2744 else if (VD && VD->isFileVarDecl()) 2745 Reason = PDSA_GlobalVarShared; 2746 else if (D->getType().isConstant(SemaRef.getASTContext())) 2747 Reason = PDSA_ConstVarShared; 2748 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2749 ReportHint = true; 2750 Reason = PDSA_LocalVarPrivate; 2751 } 2752 if (Reason != PDSA_Implicit) { 2753 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2754 << Reason << ReportHint 2755 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2756 } else if (DVar.ImplicitDSALoc.isValid()) { 2757 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2758 << getOpenMPClauseName(DVar.CKind); 2759 } 2760 } 2761 2762 namespace { 2763 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2764 DSAStackTy *Stack; 2765 Sema &SemaRef; 2766 bool ErrorFound = false; 2767 CapturedStmt *CS = nullptr; 2768 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2769 llvm::SmallVector<Expr *, 4> ImplicitMap; 2770 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2771 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2772 2773 void VisitSubCaptures(OMPExecutableDirective *S) { 2774 // Check implicitly captured variables. 2775 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2776 return; 2777 visitSubCaptures(S->getInnermostCapturedStmt()); 2778 } 2779 2780 public: 2781 void VisitDeclRefExpr(DeclRefExpr *E) { 2782 if (E->isTypeDependent() || E->isValueDependent() || 2783 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2784 return; 2785 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2786 // Check the datasharing rules for the expressions in the clauses. 2787 if (!CS) { 2788 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2789 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2790 Visit(CED->getInit()); 2791 return; 2792 } 2793 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2794 // Do not analyze internal variables and do not enclose them into 2795 // implicit clauses. 2796 return; 2797 VD = VD->getCanonicalDecl(); 2798 // Skip internally declared variables. 2799 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2800 return; 2801 2802 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2803 // Check if the variable has explicit DSA set and stop analysis if it so. 2804 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2805 return; 2806 2807 // Skip internally declared static variables. 2808 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2809 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2810 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2811 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2812 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2813 return; 2814 2815 SourceLocation ELoc = E->getExprLoc(); 2816 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2817 // The default(none) clause requires that each variable that is referenced 2818 // in the construct, and does not have a predetermined data-sharing 2819 // attribute, must have its data-sharing attribute explicitly determined 2820 // by being listed in a data-sharing attribute clause. 2821 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2822 isImplicitOrExplicitTaskingRegion(DKind) && 2823 VarsWithInheritedDSA.count(VD) == 0) { 2824 VarsWithInheritedDSA[VD] = E; 2825 return; 2826 } 2827 2828 if (isOpenMPTargetExecutionDirective(DKind) && 2829 !Stack->isLoopControlVariable(VD).first) { 2830 if (!Stack->checkMappableExprComponentListsForDecl( 2831 VD, /*CurrentRegionOnly=*/true, 2832 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2833 StackComponents, 2834 OpenMPClauseKind) { 2835 // Variable is used if it has been marked as an array, array 2836 // section or the variable iself. 2837 return StackComponents.size() == 1 || 2838 std::all_of( 2839 std::next(StackComponents.rbegin()), 2840 StackComponents.rend(), 2841 [](const OMPClauseMappableExprCommon:: 2842 MappableComponent &MC) { 2843 return MC.getAssociatedDeclaration() == 2844 nullptr && 2845 (isa<OMPArraySectionExpr>( 2846 MC.getAssociatedExpression()) || 2847 isa<ArraySubscriptExpr>( 2848 MC.getAssociatedExpression())); 2849 }); 2850 })) { 2851 bool IsFirstprivate = false; 2852 // By default lambdas are captured as firstprivates. 2853 if (const auto *RD = 2854 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2855 IsFirstprivate = RD->isLambda(); 2856 IsFirstprivate = 2857 IsFirstprivate || 2858 (VD->getType().getNonReferenceType()->isScalarType() && 2859 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2860 if (IsFirstprivate) 2861 ImplicitFirstprivate.emplace_back(E); 2862 else 2863 ImplicitMap.emplace_back(E); 2864 return; 2865 } 2866 } 2867 2868 // OpenMP [2.9.3.6, Restrictions, p.2] 2869 // A list item that appears in a reduction clause of the innermost 2870 // enclosing worksharing or parallel construct may not be accessed in an 2871 // explicit task. 2872 DVar = Stack->hasInnermostDSA( 2873 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2874 [](OpenMPDirectiveKind K) { 2875 return isOpenMPParallelDirective(K) || 2876 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2877 }, 2878 /*FromParent=*/true); 2879 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2880 ErrorFound = true; 2881 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2882 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2883 return; 2884 } 2885 2886 // Define implicit data-sharing attributes for task. 2887 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2888 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2889 !Stack->isLoopControlVariable(VD).first) { 2890 ImplicitFirstprivate.push_back(E); 2891 return; 2892 } 2893 2894 // Store implicitly used globals with declare target link for parent 2895 // target. 2896 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2897 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2898 Stack->addToParentTargetRegionLinkGlobals(E); 2899 return; 2900 } 2901 } 2902 } 2903 void VisitMemberExpr(MemberExpr *E) { 2904 if (E->isTypeDependent() || E->isValueDependent() || 2905 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2906 return; 2907 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2908 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2909 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2910 if (!FD) 2911 return; 2912 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2913 // Check if the variable has explicit DSA set and stop analysis if it 2914 // so. 2915 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2916 return; 2917 2918 if (isOpenMPTargetExecutionDirective(DKind) && 2919 !Stack->isLoopControlVariable(FD).first && 2920 !Stack->checkMappableExprComponentListsForDecl( 2921 FD, /*CurrentRegionOnly=*/true, 2922 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2923 StackComponents, 2924 OpenMPClauseKind) { 2925 return isa<CXXThisExpr>( 2926 cast<MemberExpr>( 2927 StackComponents.back().getAssociatedExpression()) 2928 ->getBase() 2929 ->IgnoreParens()); 2930 })) { 2931 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2932 // A bit-field cannot appear in a map clause. 2933 // 2934 if (FD->isBitField()) 2935 return; 2936 2937 // Check to see if the member expression is referencing a class that 2938 // has already been explicitly mapped 2939 if (Stack->isClassPreviouslyMapped(TE->getType())) 2940 return; 2941 2942 ImplicitMap.emplace_back(E); 2943 return; 2944 } 2945 2946 SourceLocation ELoc = E->getExprLoc(); 2947 // OpenMP [2.9.3.6, Restrictions, p.2] 2948 // A list item that appears in a reduction clause of the innermost 2949 // enclosing worksharing or parallel construct may not be accessed in 2950 // an explicit task. 2951 DVar = Stack->hasInnermostDSA( 2952 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2953 [](OpenMPDirectiveKind K) { 2954 return isOpenMPParallelDirective(K) || 2955 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2956 }, 2957 /*FromParent=*/true); 2958 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2959 ErrorFound = true; 2960 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2961 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2962 return; 2963 } 2964 2965 // Define implicit data-sharing attributes for task. 2966 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2967 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2968 !Stack->isLoopControlVariable(FD).first) { 2969 // Check if there is a captured expression for the current field in the 2970 // region. Do not mark it as firstprivate unless there is no captured 2971 // expression. 2972 // TODO: try to make it firstprivate. 2973 if (DVar.CKind != OMPC_unknown) 2974 ImplicitFirstprivate.push_back(E); 2975 } 2976 return; 2977 } 2978 if (isOpenMPTargetExecutionDirective(DKind)) { 2979 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2980 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2981 /*NoDiagnose=*/true)) 2982 return; 2983 const auto *VD = cast<ValueDecl>( 2984 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2985 if (!Stack->checkMappableExprComponentListsForDecl( 2986 VD, /*CurrentRegionOnly=*/true, 2987 [&CurComponents]( 2988 OMPClauseMappableExprCommon::MappableExprComponentListRef 2989 StackComponents, 2990 OpenMPClauseKind) { 2991 auto CCI = CurComponents.rbegin(); 2992 auto CCE = CurComponents.rend(); 2993 for (const auto &SC : llvm::reverse(StackComponents)) { 2994 // Do both expressions have the same kind? 2995 if (CCI->getAssociatedExpression()->getStmtClass() != 2996 SC.getAssociatedExpression()->getStmtClass()) 2997 if (!(isa<OMPArraySectionExpr>( 2998 SC.getAssociatedExpression()) && 2999 isa<ArraySubscriptExpr>( 3000 CCI->getAssociatedExpression()))) 3001 return false; 3002 3003 const Decl *CCD = CCI->getAssociatedDeclaration(); 3004 const Decl *SCD = SC.getAssociatedDeclaration(); 3005 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3006 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3007 if (SCD != CCD) 3008 return false; 3009 std::advance(CCI, 1); 3010 if (CCI == CCE) 3011 break; 3012 } 3013 return true; 3014 })) { 3015 Visit(E->getBase()); 3016 } 3017 } else { 3018 Visit(E->getBase()); 3019 } 3020 } 3021 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3022 for (OMPClause *C : S->clauses()) { 3023 // Skip analysis of arguments of implicitly defined firstprivate clause 3024 // for task|target directives. 3025 // Skip analysis of arguments of implicitly defined map clause for target 3026 // directives. 3027 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3028 C->isImplicit())) { 3029 for (Stmt *CC : C->children()) { 3030 if (CC) 3031 Visit(CC); 3032 } 3033 } 3034 } 3035 // Check implicitly captured variables. 3036 VisitSubCaptures(S); 3037 } 3038 void VisitStmt(Stmt *S) { 3039 for (Stmt *C : S->children()) { 3040 if (C) { 3041 // Check implicitly captured variables in the task-based directives to 3042 // check if they must be firstprivatized. 3043 Visit(C); 3044 } 3045 } 3046 } 3047 3048 void visitSubCaptures(CapturedStmt *S) { 3049 for (const CapturedStmt::Capture &Cap : S->captures()) { 3050 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3051 continue; 3052 VarDecl *VD = Cap.getCapturedVar(); 3053 // Do not try to map the variable if it or its sub-component was mapped 3054 // already. 3055 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3056 Stack->checkMappableExprComponentListsForDecl( 3057 VD, /*CurrentRegionOnly=*/true, 3058 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3059 OpenMPClauseKind) { return true; })) 3060 continue; 3061 DeclRefExpr *DRE = buildDeclRefExpr( 3062 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3063 Cap.getLocation(), /*RefersToCapture=*/true); 3064 Visit(DRE); 3065 } 3066 } 3067 bool isErrorFound() const { return ErrorFound; } 3068 ArrayRef<Expr *> getImplicitFirstprivate() const { 3069 return ImplicitFirstprivate; 3070 } 3071 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 3072 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3073 return VarsWithInheritedDSA; 3074 } 3075 3076 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3077 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3078 // Process declare target link variables for the target directives. 3079 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3080 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3081 Visit(E); 3082 } 3083 } 3084 }; 3085 } // namespace 3086 3087 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3088 switch (DKind) { 3089 case OMPD_parallel: 3090 case OMPD_parallel_for: 3091 case OMPD_parallel_for_simd: 3092 case OMPD_parallel_sections: 3093 case OMPD_teams: 3094 case OMPD_teams_distribute: 3095 case OMPD_teams_distribute_simd: { 3096 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3097 QualType KmpInt32PtrTy = 3098 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3099 Sema::CapturedParamNameType Params[] = { 3100 std::make_pair(".global_tid.", KmpInt32PtrTy), 3101 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3102 std::make_pair(StringRef(), QualType()) // __context with shared vars 3103 }; 3104 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3105 Params); 3106 break; 3107 } 3108 case OMPD_target_teams: 3109 case OMPD_target_parallel: 3110 case OMPD_target_parallel_for: 3111 case OMPD_target_parallel_for_simd: 3112 case OMPD_target_teams_distribute: 3113 case OMPD_target_teams_distribute_simd: { 3114 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3115 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3116 QualType KmpInt32PtrTy = 3117 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3118 QualType Args[] = {VoidPtrTy}; 3119 FunctionProtoType::ExtProtoInfo EPI; 3120 EPI.Variadic = true; 3121 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3122 Sema::CapturedParamNameType Params[] = { 3123 std::make_pair(".global_tid.", KmpInt32Ty), 3124 std::make_pair(".part_id.", KmpInt32PtrTy), 3125 std::make_pair(".privates.", VoidPtrTy), 3126 std::make_pair( 3127 ".copy_fn.", 3128 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3129 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3130 std::make_pair(StringRef(), QualType()) // __context with shared vars 3131 }; 3132 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3133 Params, /*OpenMPCaptureLevel=*/0); 3134 // Mark this captured region as inlined, because we don't use outlined 3135 // function directly. 3136 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3137 AlwaysInlineAttr::CreateImplicit( 3138 Context, {}, AttributeCommonInfo::AS_Keyword, 3139 AlwaysInlineAttr::Keyword_forceinline)); 3140 Sema::CapturedParamNameType ParamsTarget[] = { 3141 std::make_pair(StringRef(), QualType()) // __context with shared vars 3142 }; 3143 // Start a captured region for 'target' with no implicit parameters. 3144 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3145 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3146 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3147 std::make_pair(".global_tid.", KmpInt32PtrTy), 3148 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3149 std::make_pair(StringRef(), QualType()) // __context with shared vars 3150 }; 3151 // Start a captured region for 'teams' or 'parallel'. Both regions have 3152 // the same implicit parameters. 3153 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3154 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3155 break; 3156 } 3157 case OMPD_target: 3158 case OMPD_target_simd: { 3159 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3160 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3161 QualType KmpInt32PtrTy = 3162 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3163 QualType Args[] = {VoidPtrTy}; 3164 FunctionProtoType::ExtProtoInfo EPI; 3165 EPI.Variadic = true; 3166 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3167 Sema::CapturedParamNameType Params[] = { 3168 std::make_pair(".global_tid.", KmpInt32Ty), 3169 std::make_pair(".part_id.", KmpInt32PtrTy), 3170 std::make_pair(".privates.", VoidPtrTy), 3171 std::make_pair( 3172 ".copy_fn.", 3173 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3174 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3175 std::make_pair(StringRef(), QualType()) // __context with shared vars 3176 }; 3177 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3178 Params, /*OpenMPCaptureLevel=*/0); 3179 // Mark this captured region as inlined, because we don't use outlined 3180 // function directly. 3181 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3182 AlwaysInlineAttr::CreateImplicit( 3183 Context, {}, AttributeCommonInfo::AS_Keyword, 3184 AlwaysInlineAttr::Keyword_forceinline)); 3185 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3186 std::make_pair(StringRef(), QualType()), 3187 /*OpenMPCaptureLevel=*/1); 3188 break; 3189 } 3190 case OMPD_simd: 3191 case OMPD_for: 3192 case OMPD_for_simd: 3193 case OMPD_sections: 3194 case OMPD_section: 3195 case OMPD_single: 3196 case OMPD_master: 3197 case OMPD_critical: 3198 case OMPD_taskgroup: 3199 case OMPD_distribute: 3200 case OMPD_distribute_simd: 3201 case OMPD_ordered: 3202 case OMPD_atomic: 3203 case OMPD_target_data: { 3204 Sema::CapturedParamNameType Params[] = { 3205 std::make_pair(StringRef(), QualType()) // __context with shared vars 3206 }; 3207 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3208 Params); 3209 break; 3210 } 3211 case OMPD_task: { 3212 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3213 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3214 QualType KmpInt32PtrTy = 3215 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3216 QualType Args[] = {VoidPtrTy}; 3217 FunctionProtoType::ExtProtoInfo EPI; 3218 EPI.Variadic = true; 3219 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3220 Sema::CapturedParamNameType Params[] = { 3221 std::make_pair(".global_tid.", KmpInt32Ty), 3222 std::make_pair(".part_id.", KmpInt32PtrTy), 3223 std::make_pair(".privates.", VoidPtrTy), 3224 std::make_pair( 3225 ".copy_fn.", 3226 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3227 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3228 std::make_pair(StringRef(), QualType()) // __context with shared vars 3229 }; 3230 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3231 Params); 3232 // Mark this captured region as inlined, because we don't use outlined 3233 // function directly. 3234 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3235 AlwaysInlineAttr::CreateImplicit( 3236 Context, {}, AttributeCommonInfo::AS_Keyword, 3237 AlwaysInlineAttr::Keyword_forceinline)); 3238 break; 3239 } 3240 case OMPD_taskloop: 3241 case OMPD_taskloop_simd: 3242 case OMPD_master_taskloop: { 3243 QualType KmpInt32Ty = 3244 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3245 .withConst(); 3246 QualType KmpUInt64Ty = 3247 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3248 .withConst(); 3249 QualType KmpInt64Ty = 3250 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3251 .withConst(); 3252 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3253 QualType KmpInt32PtrTy = 3254 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3255 QualType Args[] = {VoidPtrTy}; 3256 FunctionProtoType::ExtProtoInfo EPI; 3257 EPI.Variadic = true; 3258 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3259 Sema::CapturedParamNameType Params[] = { 3260 std::make_pair(".global_tid.", KmpInt32Ty), 3261 std::make_pair(".part_id.", KmpInt32PtrTy), 3262 std::make_pair(".privates.", VoidPtrTy), 3263 std::make_pair( 3264 ".copy_fn.", 3265 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3266 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3267 std::make_pair(".lb.", KmpUInt64Ty), 3268 std::make_pair(".ub.", KmpUInt64Ty), 3269 std::make_pair(".st.", KmpInt64Ty), 3270 std::make_pair(".liter.", KmpInt32Ty), 3271 std::make_pair(".reductions.", VoidPtrTy), 3272 std::make_pair(StringRef(), QualType()) // __context with shared vars 3273 }; 3274 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3275 Params); 3276 // Mark this captured region as inlined, because we don't use outlined 3277 // function directly. 3278 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3279 AlwaysInlineAttr::CreateImplicit( 3280 Context, {}, AttributeCommonInfo::AS_Keyword, 3281 AlwaysInlineAttr::Keyword_forceinline)); 3282 break; 3283 } 3284 case OMPD_parallel_master_taskloop: { 3285 QualType KmpInt32Ty = 3286 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3287 .withConst(); 3288 QualType KmpUInt64Ty = 3289 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3290 .withConst(); 3291 QualType KmpInt64Ty = 3292 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3293 .withConst(); 3294 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3295 QualType KmpInt32PtrTy = 3296 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3297 Sema::CapturedParamNameType ParamsParallel[] = { 3298 std::make_pair(".global_tid.", KmpInt32PtrTy), 3299 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3300 std::make_pair(StringRef(), QualType()) // __context with shared vars 3301 }; 3302 // Start a captured region for 'parallel'. 3303 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3304 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3305 QualType Args[] = {VoidPtrTy}; 3306 FunctionProtoType::ExtProtoInfo EPI; 3307 EPI.Variadic = true; 3308 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3309 Sema::CapturedParamNameType Params[] = { 3310 std::make_pair(".global_tid.", KmpInt32Ty), 3311 std::make_pair(".part_id.", KmpInt32PtrTy), 3312 std::make_pair(".privates.", VoidPtrTy), 3313 std::make_pair( 3314 ".copy_fn.", 3315 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3316 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3317 std::make_pair(".lb.", KmpUInt64Ty), 3318 std::make_pair(".ub.", KmpUInt64Ty), 3319 std::make_pair(".st.", KmpInt64Ty), 3320 std::make_pair(".liter.", KmpInt32Ty), 3321 std::make_pair(".reductions.", VoidPtrTy), 3322 std::make_pair(StringRef(), QualType()) // __context with shared vars 3323 }; 3324 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3325 Params, /*OpenMPCaptureLevel=*/2); 3326 // Mark this captured region as inlined, because we don't use outlined 3327 // function directly. 3328 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3329 AlwaysInlineAttr::CreateImplicit( 3330 Context, {}, AttributeCommonInfo::AS_Keyword, 3331 AlwaysInlineAttr::Keyword_forceinline)); 3332 break; 3333 } 3334 case OMPD_distribute_parallel_for_simd: 3335 case OMPD_distribute_parallel_for: { 3336 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3337 QualType KmpInt32PtrTy = 3338 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3339 Sema::CapturedParamNameType Params[] = { 3340 std::make_pair(".global_tid.", KmpInt32PtrTy), 3341 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3342 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3343 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3344 std::make_pair(StringRef(), QualType()) // __context with shared vars 3345 }; 3346 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3347 Params); 3348 break; 3349 } 3350 case OMPD_target_teams_distribute_parallel_for: 3351 case OMPD_target_teams_distribute_parallel_for_simd: { 3352 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3353 QualType KmpInt32PtrTy = 3354 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3355 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3356 3357 QualType Args[] = {VoidPtrTy}; 3358 FunctionProtoType::ExtProtoInfo EPI; 3359 EPI.Variadic = true; 3360 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3361 Sema::CapturedParamNameType Params[] = { 3362 std::make_pair(".global_tid.", KmpInt32Ty), 3363 std::make_pair(".part_id.", KmpInt32PtrTy), 3364 std::make_pair(".privates.", VoidPtrTy), 3365 std::make_pair( 3366 ".copy_fn.", 3367 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3368 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3369 std::make_pair(StringRef(), QualType()) // __context with shared vars 3370 }; 3371 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3372 Params, /*OpenMPCaptureLevel=*/0); 3373 // Mark this captured region as inlined, because we don't use outlined 3374 // function directly. 3375 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3376 AlwaysInlineAttr::CreateImplicit( 3377 Context, {}, AttributeCommonInfo::AS_Keyword, 3378 AlwaysInlineAttr::Keyword_forceinline)); 3379 Sema::CapturedParamNameType ParamsTarget[] = { 3380 std::make_pair(StringRef(), QualType()) // __context with shared vars 3381 }; 3382 // Start a captured region for 'target' with no implicit parameters. 3383 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3384 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3385 3386 Sema::CapturedParamNameType ParamsTeams[] = { 3387 std::make_pair(".global_tid.", KmpInt32PtrTy), 3388 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3389 std::make_pair(StringRef(), QualType()) // __context with shared vars 3390 }; 3391 // Start a captured region for 'target' with no implicit parameters. 3392 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3393 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3394 3395 Sema::CapturedParamNameType ParamsParallel[] = { 3396 std::make_pair(".global_tid.", KmpInt32PtrTy), 3397 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3398 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3399 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3400 std::make_pair(StringRef(), QualType()) // __context with shared vars 3401 }; 3402 // Start a captured region for 'teams' or 'parallel'. Both regions have 3403 // the same implicit parameters. 3404 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3405 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3406 break; 3407 } 3408 3409 case OMPD_teams_distribute_parallel_for: 3410 case OMPD_teams_distribute_parallel_for_simd: { 3411 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3412 QualType KmpInt32PtrTy = 3413 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3414 3415 Sema::CapturedParamNameType ParamsTeams[] = { 3416 std::make_pair(".global_tid.", KmpInt32PtrTy), 3417 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3418 std::make_pair(StringRef(), QualType()) // __context with shared vars 3419 }; 3420 // Start a captured region for 'target' with no implicit parameters. 3421 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3422 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3423 3424 Sema::CapturedParamNameType ParamsParallel[] = { 3425 std::make_pair(".global_tid.", KmpInt32PtrTy), 3426 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3427 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3428 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3429 std::make_pair(StringRef(), QualType()) // __context with shared vars 3430 }; 3431 // Start a captured region for 'teams' or 'parallel'. Both regions have 3432 // the same implicit parameters. 3433 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3434 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3435 break; 3436 } 3437 case OMPD_target_update: 3438 case OMPD_target_enter_data: 3439 case OMPD_target_exit_data: { 3440 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3441 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3442 QualType KmpInt32PtrTy = 3443 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3444 QualType Args[] = {VoidPtrTy}; 3445 FunctionProtoType::ExtProtoInfo EPI; 3446 EPI.Variadic = true; 3447 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3448 Sema::CapturedParamNameType Params[] = { 3449 std::make_pair(".global_tid.", KmpInt32Ty), 3450 std::make_pair(".part_id.", KmpInt32PtrTy), 3451 std::make_pair(".privates.", VoidPtrTy), 3452 std::make_pair( 3453 ".copy_fn.", 3454 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3455 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3456 std::make_pair(StringRef(), QualType()) // __context with shared vars 3457 }; 3458 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3459 Params); 3460 // Mark this captured region as inlined, because we don't use outlined 3461 // function directly. 3462 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3463 AlwaysInlineAttr::CreateImplicit( 3464 Context, {}, AttributeCommonInfo::AS_Keyword, 3465 AlwaysInlineAttr::Keyword_forceinline)); 3466 break; 3467 } 3468 case OMPD_threadprivate: 3469 case OMPD_allocate: 3470 case OMPD_taskyield: 3471 case OMPD_barrier: 3472 case OMPD_taskwait: 3473 case OMPD_cancellation_point: 3474 case OMPD_cancel: 3475 case OMPD_flush: 3476 case OMPD_declare_reduction: 3477 case OMPD_declare_mapper: 3478 case OMPD_declare_simd: 3479 case OMPD_declare_target: 3480 case OMPD_end_declare_target: 3481 case OMPD_requires: 3482 case OMPD_declare_variant: 3483 llvm_unreachable("OpenMP Directive is not allowed"); 3484 case OMPD_unknown: 3485 llvm_unreachable("Unknown OpenMP directive"); 3486 } 3487 } 3488 3489 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3490 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3491 } 3492 3493 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3494 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3495 getOpenMPCaptureRegions(CaptureRegions, DKind); 3496 return CaptureRegions.size(); 3497 } 3498 3499 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3500 Expr *CaptureExpr, bool WithInit, 3501 bool AsExpression) { 3502 assert(CaptureExpr); 3503 ASTContext &C = S.getASTContext(); 3504 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3505 QualType Ty = Init->getType(); 3506 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3507 if (S.getLangOpts().CPlusPlus) { 3508 Ty = C.getLValueReferenceType(Ty); 3509 } else { 3510 Ty = C.getPointerType(Ty); 3511 ExprResult Res = 3512 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3513 if (!Res.isUsable()) 3514 return nullptr; 3515 Init = Res.get(); 3516 } 3517 WithInit = true; 3518 } 3519 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3520 CaptureExpr->getBeginLoc()); 3521 if (!WithInit) 3522 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3523 S.CurContext->addHiddenDecl(CED); 3524 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3525 return CED; 3526 } 3527 3528 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3529 bool WithInit) { 3530 OMPCapturedExprDecl *CD; 3531 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3532 CD = cast<OMPCapturedExprDecl>(VD); 3533 else 3534 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3535 /*AsExpression=*/false); 3536 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3537 CaptureExpr->getExprLoc()); 3538 } 3539 3540 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3541 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3542 if (!Ref) { 3543 OMPCapturedExprDecl *CD = buildCaptureDecl( 3544 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3545 /*WithInit=*/true, /*AsExpression=*/true); 3546 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3547 CaptureExpr->getExprLoc()); 3548 } 3549 ExprResult Res = Ref; 3550 if (!S.getLangOpts().CPlusPlus && 3551 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3552 Ref->getType()->isPointerType()) { 3553 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3554 if (!Res.isUsable()) 3555 return ExprError(); 3556 } 3557 return S.DefaultLvalueConversion(Res.get()); 3558 } 3559 3560 namespace { 3561 // OpenMP directives parsed in this section are represented as a 3562 // CapturedStatement with an associated statement. If a syntax error 3563 // is detected during the parsing of the associated statement, the 3564 // compiler must abort processing and close the CapturedStatement. 3565 // 3566 // Combined directives such as 'target parallel' have more than one 3567 // nested CapturedStatements. This RAII ensures that we unwind out 3568 // of all the nested CapturedStatements when an error is found. 3569 class CaptureRegionUnwinderRAII { 3570 private: 3571 Sema &S; 3572 bool &ErrorFound; 3573 OpenMPDirectiveKind DKind = OMPD_unknown; 3574 3575 public: 3576 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3577 OpenMPDirectiveKind DKind) 3578 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3579 ~CaptureRegionUnwinderRAII() { 3580 if (ErrorFound) { 3581 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3582 while (--ThisCaptureLevel >= 0) 3583 S.ActOnCapturedRegionError(); 3584 } 3585 } 3586 }; 3587 } // namespace 3588 3589 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3590 // Capture variables captured by reference in lambdas for target-based 3591 // directives. 3592 if (!CurContext->isDependentContext() && 3593 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3594 isOpenMPTargetDataManagementDirective( 3595 DSAStack->getCurrentDirective()))) { 3596 QualType Type = V->getType(); 3597 if (const auto *RD = Type.getCanonicalType() 3598 .getNonReferenceType() 3599 ->getAsCXXRecordDecl()) { 3600 bool SavedForceCaptureByReferenceInTargetExecutable = 3601 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3602 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3603 /*V=*/true); 3604 if (RD->isLambda()) { 3605 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3606 FieldDecl *ThisCapture; 3607 RD->getCaptureFields(Captures, ThisCapture); 3608 for (const LambdaCapture &LC : RD->captures()) { 3609 if (LC.getCaptureKind() == LCK_ByRef) { 3610 VarDecl *VD = LC.getCapturedVar(); 3611 DeclContext *VDC = VD->getDeclContext(); 3612 if (!VDC->Encloses(CurContext)) 3613 continue; 3614 MarkVariableReferenced(LC.getLocation(), VD); 3615 } else if (LC.getCaptureKind() == LCK_This) { 3616 QualType ThisTy = getCurrentThisType(); 3617 if (!ThisTy.isNull() && 3618 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3619 CheckCXXThisCapture(LC.getLocation()); 3620 } 3621 } 3622 } 3623 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3624 SavedForceCaptureByReferenceInTargetExecutable); 3625 } 3626 } 3627 } 3628 3629 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3630 ArrayRef<OMPClause *> Clauses) { 3631 bool ErrorFound = false; 3632 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3633 *this, ErrorFound, DSAStack->getCurrentDirective()); 3634 if (!S.isUsable()) { 3635 ErrorFound = true; 3636 return StmtError(); 3637 } 3638 3639 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3640 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3641 OMPOrderedClause *OC = nullptr; 3642 OMPScheduleClause *SC = nullptr; 3643 SmallVector<const OMPLinearClause *, 4> LCs; 3644 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3645 // This is required for proper codegen. 3646 for (OMPClause *Clause : Clauses) { 3647 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3648 Clause->getClauseKind() == OMPC_in_reduction) { 3649 // Capture taskgroup task_reduction descriptors inside the tasking regions 3650 // with the corresponding in_reduction items. 3651 auto *IRC = cast<OMPInReductionClause>(Clause); 3652 for (Expr *E : IRC->taskgroup_descriptors()) 3653 if (E) 3654 MarkDeclarationsReferencedInExpr(E); 3655 } 3656 if (isOpenMPPrivate(Clause->getClauseKind()) || 3657 Clause->getClauseKind() == OMPC_copyprivate || 3658 (getLangOpts().OpenMPUseTLS && 3659 getASTContext().getTargetInfo().isTLSSupported() && 3660 Clause->getClauseKind() == OMPC_copyin)) { 3661 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3662 // Mark all variables in private list clauses as used in inner region. 3663 for (Stmt *VarRef : Clause->children()) { 3664 if (auto *E = cast_or_null<Expr>(VarRef)) { 3665 MarkDeclarationsReferencedInExpr(E); 3666 } 3667 } 3668 DSAStack->setForceVarCapturing(/*V=*/false); 3669 } else if (CaptureRegions.size() > 1 || 3670 CaptureRegions.back() != OMPD_unknown) { 3671 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3672 PICs.push_back(C); 3673 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3674 if (Expr *E = C->getPostUpdateExpr()) 3675 MarkDeclarationsReferencedInExpr(E); 3676 } 3677 } 3678 if (Clause->getClauseKind() == OMPC_schedule) 3679 SC = cast<OMPScheduleClause>(Clause); 3680 else if (Clause->getClauseKind() == OMPC_ordered) 3681 OC = cast<OMPOrderedClause>(Clause); 3682 else if (Clause->getClauseKind() == OMPC_linear) 3683 LCs.push_back(cast<OMPLinearClause>(Clause)); 3684 } 3685 // OpenMP, 2.7.1 Loop Construct, Restrictions 3686 // The nonmonotonic modifier cannot be specified if an ordered clause is 3687 // specified. 3688 if (SC && 3689 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3690 SC->getSecondScheduleModifier() == 3691 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3692 OC) { 3693 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3694 ? SC->getFirstScheduleModifierLoc() 3695 : SC->getSecondScheduleModifierLoc(), 3696 diag::err_omp_schedule_nonmonotonic_ordered) 3697 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3698 ErrorFound = true; 3699 } 3700 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3701 for (const OMPLinearClause *C : LCs) { 3702 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3703 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3704 } 3705 ErrorFound = true; 3706 } 3707 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3708 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3709 OC->getNumForLoops()) { 3710 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3711 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3712 ErrorFound = true; 3713 } 3714 if (ErrorFound) { 3715 return StmtError(); 3716 } 3717 StmtResult SR = S; 3718 unsigned CompletedRegions = 0; 3719 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3720 // Mark all variables in private list clauses as used in inner region. 3721 // Required for proper codegen of combined directives. 3722 // TODO: add processing for other clauses. 3723 if (ThisCaptureRegion != OMPD_unknown) { 3724 for (const clang::OMPClauseWithPreInit *C : PICs) { 3725 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3726 // Find the particular capture region for the clause if the 3727 // directive is a combined one with multiple capture regions. 3728 // If the directive is not a combined one, the capture region 3729 // associated with the clause is OMPD_unknown and is generated 3730 // only once. 3731 if (CaptureRegion == ThisCaptureRegion || 3732 CaptureRegion == OMPD_unknown) { 3733 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3734 for (Decl *D : DS->decls()) 3735 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3736 } 3737 } 3738 } 3739 } 3740 if (++CompletedRegions == CaptureRegions.size()) 3741 DSAStack->setBodyComplete(); 3742 SR = ActOnCapturedRegionEnd(SR.get()); 3743 } 3744 return SR; 3745 } 3746 3747 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3748 OpenMPDirectiveKind CancelRegion, 3749 SourceLocation StartLoc) { 3750 // CancelRegion is only needed for cancel and cancellation_point. 3751 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3752 return false; 3753 3754 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3755 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3756 return false; 3757 3758 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3759 << getOpenMPDirectiveName(CancelRegion); 3760 return true; 3761 } 3762 3763 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3764 OpenMPDirectiveKind CurrentRegion, 3765 const DeclarationNameInfo &CurrentName, 3766 OpenMPDirectiveKind CancelRegion, 3767 SourceLocation StartLoc) { 3768 if (Stack->getCurScope()) { 3769 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3770 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3771 bool NestingProhibited = false; 3772 bool CloseNesting = true; 3773 bool OrphanSeen = false; 3774 enum { 3775 NoRecommend, 3776 ShouldBeInParallelRegion, 3777 ShouldBeInOrderedRegion, 3778 ShouldBeInTargetRegion, 3779 ShouldBeInTeamsRegion 3780 } Recommend = NoRecommend; 3781 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3782 // OpenMP [2.16, Nesting of Regions] 3783 // OpenMP constructs may not be nested inside a simd region. 3784 // OpenMP [2.8.1,simd Construct, Restrictions] 3785 // An ordered construct with the simd clause is the only OpenMP 3786 // construct that can appear in the simd region. 3787 // Allowing a SIMD construct nested in another SIMD construct is an 3788 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3789 // message. 3790 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3791 ? diag::err_omp_prohibited_region_simd 3792 : diag::warn_omp_nesting_simd); 3793 return CurrentRegion != OMPD_simd; 3794 } 3795 if (ParentRegion == OMPD_atomic) { 3796 // OpenMP [2.16, Nesting of Regions] 3797 // OpenMP constructs may not be nested inside an atomic region. 3798 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3799 return true; 3800 } 3801 if (CurrentRegion == OMPD_section) { 3802 // OpenMP [2.7.2, sections Construct, Restrictions] 3803 // Orphaned section directives are prohibited. That is, the section 3804 // directives must appear within the sections construct and must not be 3805 // encountered elsewhere in the sections region. 3806 if (ParentRegion != OMPD_sections && 3807 ParentRegion != OMPD_parallel_sections) { 3808 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3809 << (ParentRegion != OMPD_unknown) 3810 << getOpenMPDirectiveName(ParentRegion); 3811 return true; 3812 } 3813 return false; 3814 } 3815 // Allow some constructs (except teams and cancellation constructs) to be 3816 // orphaned (they could be used in functions, called from OpenMP regions 3817 // with the required preconditions). 3818 if (ParentRegion == OMPD_unknown && 3819 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3820 CurrentRegion != OMPD_cancellation_point && 3821 CurrentRegion != OMPD_cancel) 3822 return false; 3823 if (CurrentRegion == OMPD_cancellation_point || 3824 CurrentRegion == OMPD_cancel) { 3825 // OpenMP [2.16, Nesting of Regions] 3826 // A cancellation point construct for which construct-type-clause is 3827 // taskgroup must be nested inside a task construct. A cancellation 3828 // point construct for which construct-type-clause is not taskgroup must 3829 // be closely nested inside an OpenMP construct that matches the type 3830 // specified in construct-type-clause. 3831 // A cancel construct for which construct-type-clause is taskgroup must be 3832 // nested inside a task construct. A cancel construct for which 3833 // construct-type-clause is not taskgroup must be closely nested inside an 3834 // OpenMP construct that matches the type specified in 3835 // construct-type-clause. 3836 NestingProhibited = 3837 !((CancelRegion == OMPD_parallel && 3838 (ParentRegion == OMPD_parallel || 3839 ParentRegion == OMPD_target_parallel)) || 3840 (CancelRegion == OMPD_for && 3841 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3842 ParentRegion == OMPD_target_parallel_for || 3843 ParentRegion == OMPD_distribute_parallel_for || 3844 ParentRegion == OMPD_teams_distribute_parallel_for || 3845 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3846 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3847 (CancelRegion == OMPD_sections && 3848 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3849 ParentRegion == OMPD_parallel_sections))); 3850 OrphanSeen = ParentRegion == OMPD_unknown; 3851 } else if (CurrentRegion == OMPD_master) { 3852 // OpenMP [2.16, Nesting of Regions] 3853 // A master region may not be closely nested inside a worksharing, 3854 // atomic, or explicit task region. 3855 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3856 isOpenMPTaskingDirective(ParentRegion); 3857 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3858 // OpenMP [2.16, Nesting of Regions] 3859 // A critical region may not be nested (closely or otherwise) inside a 3860 // critical region with the same name. Note that this restriction is not 3861 // sufficient to prevent deadlock. 3862 SourceLocation PreviousCriticalLoc; 3863 bool DeadLock = Stack->hasDirective( 3864 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3865 const DeclarationNameInfo &DNI, 3866 SourceLocation Loc) { 3867 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3868 PreviousCriticalLoc = Loc; 3869 return true; 3870 } 3871 return false; 3872 }, 3873 false /* skip top directive */); 3874 if (DeadLock) { 3875 SemaRef.Diag(StartLoc, 3876 diag::err_omp_prohibited_region_critical_same_name) 3877 << CurrentName.getName(); 3878 if (PreviousCriticalLoc.isValid()) 3879 SemaRef.Diag(PreviousCriticalLoc, 3880 diag::note_omp_previous_critical_region); 3881 return true; 3882 } 3883 } else if (CurrentRegion == OMPD_barrier) { 3884 // OpenMP [2.16, Nesting of Regions] 3885 // A barrier region may not be closely nested inside a worksharing, 3886 // explicit task, critical, ordered, atomic, or master region. 3887 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3888 isOpenMPTaskingDirective(ParentRegion) || 3889 ParentRegion == OMPD_master || 3890 ParentRegion == OMPD_critical || 3891 ParentRegion == OMPD_ordered; 3892 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3893 !isOpenMPParallelDirective(CurrentRegion) && 3894 !isOpenMPTeamsDirective(CurrentRegion)) { 3895 // OpenMP [2.16, Nesting of Regions] 3896 // A worksharing region may not be closely nested inside a worksharing, 3897 // explicit task, critical, ordered, atomic, or master region. 3898 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3899 isOpenMPTaskingDirective(ParentRegion) || 3900 ParentRegion == OMPD_master || 3901 ParentRegion == OMPD_critical || 3902 ParentRegion == OMPD_ordered; 3903 Recommend = ShouldBeInParallelRegion; 3904 } else if (CurrentRegion == OMPD_ordered) { 3905 // OpenMP [2.16, Nesting of Regions] 3906 // An ordered region may not be closely nested inside a critical, 3907 // atomic, or explicit task region. 3908 // An ordered region must be closely nested inside a loop region (or 3909 // parallel loop region) with an ordered clause. 3910 // OpenMP [2.8.1,simd Construct, Restrictions] 3911 // An ordered construct with the simd clause is the only OpenMP construct 3912 // that can appear in the simd region. 3913 NestingProhibited = ParentRegion == OMPD_critical || 3914 isOpenMPTaskingDirective(ParentRegion) || 3915 !(isOpenMPSimdDirective(ParentRegion) || 3916 Stack->isParentOrderedRegion()); 3917 Recommend = ShouldBeInOrderedRegion; 3918 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3919 // OpenMP [2.16, Nesting of Regions] 3920 // If specified, a teams construct must be contained within a target 3921 // construct. 3922 NestingProhibited = 3923 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 3924 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 3925 ParentRegion != OMPD_target); 3926 OrphanSeen = ParentRegion == OMPD_unknown; 3927 Recommend = ShouldBeInTargetRegion; 3928 } 3929 if (!NestingProhibited && 3930 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3931 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3932 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3933 // OpenMP [2.16, Nesting of Regions] 3934 // distribute, parallel, parallel sections, parallel workshare, and the 3935 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3936 // constructs that can be closely nested in the teams region. 3937 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3938 !isOpenMPDistributeDirective(CurrentRegion); 3939 Recommend = ShouldBeInParallelRegion; 3940 } 3941 if (!NestingProhibited && 3942 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3943 // OpenMP 4.5 [2.17 Nesting of Regions] 3944 // The region associated with the distribute construct must be strictly 3945 // nested inside a teams region 3946 NestingProhibited = 3947 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3948 Recommend = ShouldBeInTeamsRegion; 3949 } 3950 if (!NestingProhibited && 3951 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3952 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3953 // OpenMP 4.5 [2.17 Nesting of Regions] 3954 // If a target, target update, target data, target enter data, or 3955 // target exit data construct is encountered during execution of a 3956 // target region, the behavior is unspecified. 3957 NestingProhibited = Stack->hasDirective( 3958 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3959 SourceLocation) { 3960 if (isOpenMPTargetExecutionDirective(K)) { 3961 OffendingRegion = K; 3962 return true; 3963 } 3964 return false; 3965 }, 3966 false /* don't skip top directive */); 3967 CloseNesting = false; 3968 } 3969 if (NestingProhibited) { 3970 if (OrphanSeen) { 3971 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3972 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3973 } else { 3974 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3975 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3976 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3977 } 3978 return true; 3979 } 3980 } 3981 return false; 3982 } 3983 3984 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3985 ArrayRef<OMPClause *> Clauses, 3986 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3987 bool ErrorFound = false; 3988 unsigned NamedModifiersNumber = 0; 3989 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3990 OMPD_unknown + 1); 3991 SmallVector<SourceLocation, 4> NameModifierLoc; 3992 for (const OMPClause *C : Clauses) { 3993 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3994 // At most one if clause without a directive-name-modifier can appear on 3995 // the directive. 3996 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3997 if (FoundNameModifiers[CurNM]) { 3998 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3999 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4000 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4001 ErrorFound = true; 4002 } else if (CurNM != OMPD_unknown) { 4003 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4004 ++NamedModifiersNumber; 4005 } 4006 FoundNameModifiers[CurNM] = IC; 4007 if (CurNM == OMPD_unknown) 4008 continue; 4009 // Check if the specified name modifier is allowed for the current 4010 // directive. 4011 // At most one if clause with the particular directive-name-modifier can 4012 // appear on the directive. 4013 bool MatchFound = false; 4014 for (auto NM : AllowedNameModifiers) { 4015 if (CurNM == NM) { 4016 MatchFound = true; 4017 break; 4018 } 4019 } 4020 if (!MatchFound) { 4021 S.Diag(IC->getNameModifierLoc(), 4022 diag::err_omp_wrong_if_directive_name_modifier) 4023 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4024 ErrorFound = true; 4025 } 4026 } 4027 } 4028 // If any if clause on the directive includes a directive-name-modifier then 4029 // all if clauses on the directive must include a directive-name-modifier. 4030 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4031 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4032 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4033 diag::err_omp_no_more_if_clause); 4034 } else { 4035 std::string Values; 4036 std::string Sep(", "); 4037 unsigned AllowedCnt = 0; 4038 unsigned TotalAllowedNum = 4039 AllowedNameModifiers.size() - NamedModifiersNumber; 4040 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4041 ++Cnt) { 4042 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4043 if (!FoundNameModifiers[NM]) { 4044 Values += "'"; 4045 Values += getOpenMPDirectiveName(NM); 4046 Values += "'"; 4047 if (AllowedCnt + 2 == TotalAllowedNum) 4048 Values += " or "; 4049 else if (AllowedCnt + 1 != TotalAllowedNum) 4050 Values += Sep; 4051 ++AllowedCnt; 4052 } 4053 } 4054 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4055 diag::err_omp_unnamed_if_clause) 4056 << (TotalAllowedNum > 1) << Values; 4057 } 4058 for (SourceLocation Loc : NameModifierLoc) { 4059 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4060 } 4061 ErrorFound = true; 4062 } 4063 return ErrorFound; 4064 } 4065 4066 static std::pair<ValueDecl *, bool> 4067 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4068 SourceRange &ERange, bool AllowArraySection = false) { 4069 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4070 RefExpr->containsUnexpandedParameterPack()) 4071 return std::make_pair(nullptr, true); 4072 4073 // OpenMP [3.1, C/C++] 4074 // A list item is a variable name. 4075 // OpenMP [2.9.3.3, Restrictions, p.1] 4076 // A variable that is part of another variable (as an array or 4077 // structure element) cannot appear in a private clause. 4078 RefExpr = RefExpr->IgnoreParens(); 4079 enum { 4080 NoArrayExpr = -1, 4081 ArraySubscript = 0, 4082 OMPArraySection = 1 4083 } IsArrayExpr = NoArrayExpr; 4084 if (AllowArraySection) { 4085 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4086 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4087 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4088 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4089 RefExpr = Base; 4090 IsArrayExpr = ArraySubscript; 4091 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4092 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4093 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4094 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4095 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4096 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4097 RefExpr = Base; 4098 IsArrayExpr = OMPArraySection; 4099 } 4100 } 4101 ELoc = RefExpr->getExprLoc(); 4102 ERange = RefExpr->getSourceRange(); 4103 RefExpr = RefExpr->IgnoreParenImpCasts(); 4104 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4105 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4106 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4107 (S.getCurrentThisType().isNull() || !ME || 4108 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4109 !isa<FieldDecl>(ME->getMemberDecl()))) { 4110 if (IsArrayExpr != NoArrayExpr) { 4111 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4112 << ERange; 4113 } else { 4114 S.Diag(ELoc, 4115 AllowArraySection 4116 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4117 : diag::err_omp_expected_var_name_member_expr) 4118 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4119 } 4120 return std::make_pair(nullptr, false); 4121 } 4122 return std::make_pair( 4123 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4124 } 4125 4126 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4127 ArrayRef<OMPClause *> Clauses) { 4128 assert(!S.CurContext->isDependentContext() && 4129 "Expected non-dependent context."); 4130 auto AllocateRange = 4131 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4132 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4133 DeclToCopy; 4134 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4135 return isOpenMPPrivate(C->getClauseKind()); 4136 }); 4137 for (OMPClause *Cl : PrivateRange) { 4138 MutableArrayRef<Expr *>::iterator I, It, Et; 4139 if (Cl->getClauseKind() == OMPC_private) { 4140 auto *PC = cast<OMPPrivateClause>(Cl); 4141 I = PC->private_copies().begin(); 4142 It = PC->varlist_begin(); 4143 Et = PC->varlist_end(); 4144 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4145 auto *PC = cast<OMPFirstprivateClause>(Cl); 4146 I = PC->private_copies().begin(); 4147 It = PC->varlist_begin(); 4148 Et = PC->varlist_end(); 4149 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4150 auto *PC = cast<OMPLastprivateClause>(Cl); 4151 I = PC->private_copies().begin(); 4152 It = PC->varlist_begin(); 4153 Et = PC->varlist_end(); 4154 } else if (Cl->getClauseKind() == OMPC_linear) { 4155 auto *PC = cast<OMPLinearClause>(Cl); 4156 I = PC->privates().begin(); 4157 It = PC->varlist_begin(); 4158 Et = PC->varlist_end(); 4159 } else if (Cl->getClauseKind() == OMPC_reduction) { 4160 auto *PC = cast<OMPReductionClause>(Cl); 4161 I = PC->privates().begin(); 4162 It = PC->varlist_begin(); 4163 Et = PC->varlist_end(); 4164 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4165 auto *PC = cast<OMPTaskReductionClause>(Cl); 4166 I = PC->privates().begin(); 4167 It = PC->varlist_begin(); 4168 Et = PC->varlist_end(); 4169 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4170 auto *PC = cast<OMPInReductionClause>(Cl); 4171 I = PC->privates().begin(); 4172 It = PC->varlist_begin(); 4173 Et = PC->varlist_end(); 4174 } else { 4175 llvm_unreachable("Expected private clause."); 4176 } 4177 for (Expr *E : llvm::make_range(It, Et)) { 4178 if (!*I) { 4179 ++I; 4180 continue; 4181 } 4182 SourceLocation ELoc; 4183 SourceRange ERange; 4184 Expr *SimpleRefExpr = E; 4185 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4186 /*AllowArraySection=*/true); 4187 DeclToCopy.try_emplace(Res.first, 4188 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4189 ++I; 4190 } 4191 } 4192 for (OMPClause *C : AllocateRange) { 4193 auto *AC = cast<OMPAllocateClause>(C); 4194 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4195 getAllocatorKind(S, Stack, AC->getAllocator()); 4196 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4197 // For task, taskloop or target directives, allocation requests to memory 4198 // allocators with the trait access set to thread result in unspecified 4199 // behavior. 4200 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4201 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4202 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4203 S.Diag(AC->getAllocator()->getExprLoc(), 4204 diag::warn_omp_allocate_thread_on_task_target_directive) 4205 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4206 } 4207 for (Expr *E : AC->varlists()) { 4208 SourceLocation ELoc; 4209 SourceRange ERange; 4210 Expr *SimpleRefExpr = E; 4211 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4212 ValueDecl *VD = Res.first; 4213 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4214 if (!isOpenMPPrivate(Data.CKind)) { 4215 S.Diag(E->getExprLoc(), 4216 diag::err_omp_expected_private_copy_for_allocate); 4217 continue; 4218 } 4219 VarDecl *PrivateVD = DeclToCopy[VD]; 4220 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4221 AllocatorKind, AC->getAllocator())) 4222 continue; 4223 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4224 E->getSourceRange()); 4225 } 4226 } 4227 } 4228 4229 StmtResult Sema::ActOnOpenMPExecutableDirective( 4230 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4231 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4232 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4233 StmtResult Res = StmtError(); 4234 // First check CancelRegion which is then used in checkNestingOfRegions. 4235 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4236 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4237 StartLoc)) 4238 return StmtError(); 4239 4240 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4241 VarsWithInheritedDSAType VarsWithInheritedDSA; 4242 bool ErrorFound = false; 4243 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4244 if (AStmt && !CurContext->isDependentContext()) { 4245 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4246 4247 // Check default data sharing attributes for referenced variables. 4248 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4249 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4250 Stmt *S = AStmt; 4251 while (--ThisCaptureLevel >= 0) 4252 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4253 DSAChecker.Visit(S); 4254 if (!isOpenMPTargetDataManagementDirective(Kind) && 4255 !isOpenMPTaskingDirective(Kind)) { 4256 // Visit subcaptures to generate implicit clauses for captured vars. 4257 auto *CS = cast<CapturedStmt>(AStmt); 4258 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4259 getOpenMPCaptureRegions(CaptureRegions, Kind); 4260 // Ignore outer tasking regions for target directives. 4261 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4262 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4263 DSAChecker.visitSubCaptures(CS); 4264 } 4265 if (DSAChecker.isErrorFound()) 4266 return StmtError(); 4267 // Generate list of implicitly defined firstprivate variables. 4268 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4269 4270 SmallVector<Expr *, 4> ImplicitFirstprivates( 4271 DSAChecker.getImplicitFirstprivate().begin(), 4272 DSAChecker.getImplicitFirstprivate().end()); 4273 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4274 DSAChecker.getImplicitMap().end()); 4275 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4276 for (OMPClause *C : Clauses) { 4277 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4278 for (Expr *E : IRC->taskgroup_descriptors()) 4279 if (E) 4280 ImplicitFirstprivates.emplace_back(E); 4281 } 4282 } 4283 if (!ImplicitFirstprivates.empty()) { 4284 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4285 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4286 SourceLocation())) { 4287 ClausesWithImplicit.push_back(Implicit); 4288 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4289 ImplicitFirstprivates.size(); 4290 } else { 4291 ErrorFound = true; 4292 } 4293 } 4294 if (!ImplicitMaps.empty()) { 4295 CXXScopeSpec MapperIdScopeSpec; 4296 DeclarationNameInfo MapperId; 4297 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4298 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4299 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4300 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4301 ClausesWithImplicit.emplace_back(Implicit); 4302 ErrorFound |= 4303 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4304 } else { 4305 ErrorFound = true; 4306 } 4307 } 4308 } 4309 4310 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4311 switch (Kind) { 4312 case OMPD_parallel: 4313 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4314 EndLoc); 4315 AllowedNameModifiers.push_back(OMPD_parallel); 4316 break; 4317 case OMPD_simd: 4318 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4319 VarsWithInheritedDSA); 4320 break; 4321 case OMPD_for: 4322 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4323 VarsWithInheritedDSA); 4324 break; 4325 case OMPD_for_simd: 4326 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4327 EndLoc, VarsWithInheritedDSA); 4328 break; 4329 case OMPD_sections: 4330 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4331 EndLoc); 4332 break; 4333 case OMPD_section: 4334 assert(ClausesWithImplicit.empty() && 4335 "No clauses are allowed for 'omp section' directive"); 4336 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4337 break; 4338 case OMPD_single: 4339 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4340 EndLoc); 4341 break; 4342 case OMPD_master: 4343 assert(ClausesWithImplicit.empty() && 4344 "No clauses are allowed for 'omp master' directive"); 4345 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4346 break; 4347 case OMPD_critical: 4348 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4349 StartLoc, EndLoc); 4350 break; 4351 case OMPD_parallel_for: 4352 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4353 EndLoc, VarsWithInheritedDSA); 4354 AllowedNameModifiers.push_back(OMPD_parallel); 4355 break; 4356 case OMPD_parallel_for_simd: 4357 Res = ActOnOpenMPParallelForSimdDirective( 4358 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4359 AllowedNameModifiers.push_back(OMPD_parallel); 4360 break; 4361 case OMPD_parallel_sections: 4362 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4363 StartLoc, EndLoc); 4364 AllowedNameModifiers.push_back(OMPD_parallel); 4365 break; 4366 case OMPD_task: 4367 Res = 4368 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4369 AllowedNameModifiers.push_back(OMPD_task); 4370 break; 4371 case OMPD_taskyield: 4372 assert(ClausesWithImplicit.empty() && 4373 "No clauses are allowed for 'omp taskyield' directive"); 4374 assert(AStmt == nullptr && 4375 "No associated statement allowed for 'omp taskyield' directive"); 4376 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4377 break; 4378 case OMPD_barrier: 4379 assert(ClausesWithImplicit.empty() && 4380 "No clauses are allowed for 'omp barrier' directive"); 4381 assert(AStmt == nullptr && 4382 "No associated statement allowed for 'omp barrier' directive"); 4383 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4384 break; 4385 case OMPD_taskwait: 4386 assert(ClausesWithImplicit.empty() && 4387 "No clauses are allowed for 'omp taskwait' directive"); 4388 assert(AStmt == nullptr && 4389 "No associated statement allowed for 'omp taskwait' directive"); 4390 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4391 break; 4392 case OMPD_taskgroup: 4393 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4394 EndLoc); 4395 break; 4396 case OMPD_flush: 4397 assert(AStmt == nullptr && 4398 "No associated statement allowed for 'omp flush' directive"); 4399 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4400 break; 4401 case OMPD_ordered: 4402 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4403 EndLoc); 4404 break; 4405 case OMPD_atomic: 4406 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4407 EndLoc); 4408 break; 4409 case OMPD_teams: 4410 Res = 4411 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4412 break; 4413 case OMPD_target: 4414 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4415 EndLoc); 4416 AllowedNameModifiers.push_back(OMPD_target); 4417 break; 4418 case OMPD_target_parallel: 4419 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4420 StartLoc, EndLoc); 4421 AllowedNameModifiers.push_back(OMPD_target); 4422 AllowedNameModifiers.push_back(OMPD_parallel); 4423 break; 4424 case OMPD_target_parallel_for: 4425 Res = ActOnOpenMPTargetParallelForDirective( 4426 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4427 AllowedNameModifiers.push_back(OMPD_target); 4428 AllowedNameModifiers.push_back(OMPD_parallel); 4429 break; 4430 case OMPD_cancellation_point: 4431 assert(ClausesWithImplicit.empty() && 4432 "No clauses are allowed for 'omp cancellation point' directive"); 4433 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4434 "cancellation point' directive"); 4435 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4436 break; 4437 case OMPD_cancel: 4438 assert(AStmt == nullptr && 4439 "No associated statement allowed for 'omp cancel' directive"); 4440 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4441 CancelRegion); 4442 AllowedNameModifiers.push_back(OMPD_cancel); 4443 break; 4444 case OMPD_target_data: 4445 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4446 EndLoc); 4447 AllowedNameModifiers.push_back(OMPD_target_data); 4448 break; 4449 case OMPD_target_enter_data: 4450 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4451 EndLoc, AStmt); 4452 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4453 break; 4454 case OMPD_target_exit_data: 4455 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4456 EndLoc, AStmt); 4457 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4458 break; 4459 case OMPD_taskloop: 4460 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4461 EndLoc, VarsWithInheritedDSA); 4462 AllowedNameModifiers.push_back(OMPD_taskloop); 4463 break; 4464 case OMPD_taskloop_simd: 4465 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4466 EndLoc, VarsWithInheritedDSA); 4467 AllowedNameModifiers.push_back(OMPD_taskloop); 4468 break; 4469 case OMPD_master_taskloop: 4470 Res = ActOnOpenMPMasterTaskLoopDirective( 4471 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4472 AllowedNameModifiers.push_back(OMPD_taskloop); 4473 break; 4474 case OMPD_parallel_master_taskloop: 4475 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4476 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4477 AllowedNameModifiers.push_back(OMPD_taskloop); 4478 AllowedNameModifiers.push_back(OMPD_parallel); 4479 break; 4480 case OMPD_distribute: 4481 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4482 EndLoc, VarsWithInheritedDSA); 4483 break; 4484 case OMPD_target_update: 4485 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4486 EndLoc, AStmt); 4487 AllowedNameModifiers.push_back(OMPD_target_update); 4488 break; 4489 case OMPD_distribute_parallel_for: 4490 Res = ActOnOpenMPDistributeParallelForDirective( 4491 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4492 AllowedNameModifiers.push_back(OMPD_parallel); 4493 break; 4494 case OMPD_distribute_parallel_for_simd: 4495 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4496 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4497 AllowedNameModifiers.push_back(OMPD_parallel); 4498 break; 4499 case OMPD_distribute_simd: 4500 Res = ActOnOpenMPDistributeSimdDirective( 4501 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4502 break; 4503 case OMPD_target_parallel_for_simd: 4504 Res = ActOnOpenMPTargetParallelForSimdDirective( 4505 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4506 AllowedNameModifiers.push_back(OMPD_target); 4507 AllowedNameModifiers.push_back(OMPD_parallel); 4508 break; 4509 case OMPD_target_simd: 4510 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4511 EndLoc, VarsWithInheritedDSA); 4512 AllowedNameModifiers.push_back(OMPD_target); 4513 break; 4514 case OMPD_teams_distribute: 4515 Res = ActOnOpenMPTeamsDistributeDirective( 4516 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4517 break; 4518 case OMPD_teams_distribute_simd: 4519 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4520 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4521 break; 4522 case OMPD_teams_distribute_parallel_for_simd: 4523 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4524 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4525 AllowedNameModifiers.push_back(OMPD_parallel); 4526 break; 4527 case OMPD_teams_distribute_parallel_for: 4528 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4529 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4530 AllowedNameModifiers.push_back(OMPD_parallel); 4531 break; 4532 case OMPD_target_teams: 4533 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4534 EndLoc); 4535 AllowedNameModifiers.push_back(OMPD_target); 4536 break; 4537 case OMPD_target_teams_distribute: 4538 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4539 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4540 AllowedNameModifiers.push_back(OMPD_target); 4541 break; 4542 case OMPD_target_teams_distribute_parallel_for: 4543 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4544 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4545 AllowedNameModifiers.push_back(OMPD_target); 4546 AllowedNameModifiers.push_back(OMPD_parallel); 4547 break; 4548 case OMPD_target_teams_distribute_parallel_for_simd: 4549 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4550 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4551 AllowedNameModifiers.push_back(OMPD_target); 4552 AllowedNameModifiers.push_back(OMPD_parallel); 4553 break; 4554 case OMPD_target_teams_distribute_simd: 4555 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4556 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4557 AllowedNameModifiers.push_back(OMPD_target); 4558 break; 4559 case OMPD_declare_target: 4560 case OMPD_end_declare_target: 4561 case OMPD_threadprivate: 4562 case OMPD_allocate: 4563 case OMPD_declare_reduction: 4564 case OMPD_declare_mapper: 4565 case OMPD_declare_simd: 4566 case OMPD_requires: 4567 case OMPD_declare_variant: 4568 llvm_unreachable("OpenMP Directive is not allowed"); 4569 case OMPD_unknown: 4570 llvm_unreachable("Unknown OpenMP directive"); 4571 } 4572 4573 ErrorFound = Res.isInvalid() || ErrorFound; 4574 4575 // Check variables in the clauses if default(none) was specified. 4576 if (DSAStack->getDefaultDSA() == DSA_none) { 4577 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4578 for (OMPClause *C : Clauses) { 4579 switch (C->getClauseKind()) { 4580 case OMPC_num_threads: 4581 case OMPC_dist_schedule: 4582 // Do not analyse if no parent teams directive. 4583 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4584 break; 4585 continue; 4586 case OMPC_if: 4587 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4588 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4589 break; 4590 continue; 4591 case OMPC_schedule: 4592 break; 4593 case OMPC_grainsize: 4594 // Do not analyze if no parent parallel directive. 4595 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective())) 4596 break; 4597 continue; 4598 case OMPC_num_tasks: 4599 // Do not analyze if no parent parallel directive. 4600 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective())) 4601 break; 4602 continue; 4603 case OMPC_final: 4604 // Do not analyze if no parent parallel directive. 4605 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective())) 4606 break; 4607 continue; 4608 case OMPC_ordered: 4609 case OMPC_device: 4610 case OMPC_num_teams: 4611 case OMPC_thread_limit: 4612 case OMPC_priority: 4613 case OMPC_hint: 4614 case OMPC_collapse: 4615 case OMPC_safelen: 4616 case OMPC_simdlen: 4617 case OMPC_default: 4618 case OMPC_proc_bind: 4619 case OMPC_private: 4620 case OMPC_firstprivate: 4621 case OMPC_lastprivate: 4622 case OMPC_shared: 4623 case OMPC_reduction: 4624 case OMPC_task_reduction: 4625 case OMPC_in_reduction: 4626 case OMPC_linear: 4627 case OMPC_aligned: 4628 case OMPC_copyin: 4629 case OMPC_copyprivate: 4630 case OMPC_nowait: 4631 case OMPC_untied: 4632 case OMPC_mergeable: 4633 case OMPC_allocate: 4634 case OMPC_read: 4635 case OMPC_write: 4636 case OMPC_update: 4637 case OMPC_capture: 4638 case OMPC_seq_cst: 4639 case OMPC_depend: 4640 case OMPC_threads: 4641 case OMPC_simd: 4642 case OMPC_map: 4643 case OMPC_nogroup: 4644 case OMPC_defaultmap: 4645 case OMPC_to: 4646 case OMPC_from: 4647 case OMPC_use_device_ptr: 4648 case OMPC_is_device_ptr: 4649 continue; 4650 case OMPC_allocator: 4651 case OMPC_flush: 4652 case OMPC_threadprivate: 4653 case OMPC_uniform: 4654 case OMPC_unknown: 4655 case OMPC_unified_address: 4656 case OMPC_unified_shared_memory: 4657 case OMPC_reverse_offload: 4658 case OMPC_dynamic_allocators: 4659 case OMPC_atomic_default_mem_order: 4660 case OMPC_device_type: 4661 case OMPC_match: 4662 llvm_unreachable("Unexpected clause"); 4663 } 4664 for (Stmt *CC : C->children()) { 4665 if (CC) 4666 DSAChecker.Visit(CC); 4667 } 4668 } 4669 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4670 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4671 } 4672 for (const auto &P : VarsWithInheritedDSA) { 4673 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4674 continue; 4675 ErrorFound = true; 4676 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4677 << P.first << P.second->getSourceRange(); 4678 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4679 } 4680 4681 if (!AllowedNameModifiers.empty()) 4682 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4683 ErrorFound; 4684 4685 if (ErrorFound) 4686 return StmtError(); 4687 4688 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4689 Res.getAs<OMPExecutableDirective>() 4690 ->getStructuredBlock() 4691 ->setIsOMPStructuredBlock(true); 4692 } 4693 4694 if (!CurContext->isDependentContext() && 4695 isOpenMPTargetExecutionDirective(Kind) && 4696 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4697 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4698 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4699 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4700 // Register target to DSA Stack. 4701 DSAStack->addTargetDirLocation(StartLoc); 4702 } 4703 4704 return Res; 4705 } 4706 4707 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4708 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4709 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4710 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4711 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4712 assert(Aligneds.size() == Alignments.size()); 4713 assert(Linears.size() == LinModifiers.size()); 4714 assert(Linears.size() == Steps.size()); 4715 if (!DG || DG.get().isNull()) 4716 return DeclGroupPtrTy(); 4717 4718 const int SimdId = 0; 4719 if (!DG.get().isSingleDecl()) { 4720 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4721 << SimdId; 4722 return DG; 4723 } 4724 Decl *ADecl = DG.get().getSingleDecl(); 4725 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4726 ADecl = FTD->getTemplatedDecl(); 4727 4728 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4729 if (!FD) { 4730 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4731 return DeclGroupPtrTy(); 4732 } 4733 4734 // OpenMP [2.8.2, declare simd construct, Description] 4735 // The parameter of the simdlen clause must be a constant positive integer 4736 // expression. 4737 ExprResult SL; 4738 if (Simdlen) 4739 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4740 // OpenMP [2.8.2, declare simd construct, Description] 4741 // The special this pointer can be used as if was one of the arguments to the 4742 // function in any of the linear, aligned, or uniform clauses. 4743 // The uniform clause declares one or more arguments to have an invariant 4744 // value for all concurrent invocations of the function in the execution of a 4745 // single SIMD loop. 4746 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4747 const Expr *UniformedLinearThis = nullptr; 4748 for (const Expr *E : Uniforms) { 4749 E = E->IgnoreParenImpCasts(); 4750 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4751 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4752 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4753 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4754 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4755 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4756 continue; 4757 } 4758 if (isa<CXXThisExpr>(E)) { 4759 UniformedLinearThis = E; 4760 continue; 4761 } 4762 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4763 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4764 } 4765 // OpenMP [2.8.2, declare simd construct, Description] 4766 // The aligned clause declares that the object to which each list item points 4767 // is aligned to the number of bytes expressed in the optional parameter of 4768 // the aligned clause. 4769 // The special this pointer can be used as if was one of the arguments to the 4770 // function in any of the linear, aligned, or uniform clauses. 4771 // The type of list items appearing in the aligned clause must be array, 4772 // pointer, reference to array, or reference to pointer. 4773 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4774 const Expr *AlignedThis = nullptr; 4775 for (const Expr *E : Aligneds) { 4776 E = E->IgnoreParenImpCasts(); 4777 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4778 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4779 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4780 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4781 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4782 ->getCanonicalDecl() == CanonPVD) { 4783 // OpenMP [2.8.1, simd construct, Restrictions] 4784 // A list-item cannot appear in more than one aligned clause. 4785 if (AlignedArgs.count(CanonPVD) > 0) { 4786 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4787 << 1 << E->getSourceRange(); 4788 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4789 diag::note_omp_explicit_dsa) 4790 << getOpenMPClauseName(OMPC_aligned); 4791 continue; 4792 } 4793 AlignedArgs[CanonPVD] = E; 4794 QualType QTy = PVD->getType() 4795 .getNonReferenceType() 4796 .getUnqualifiedType() 4797 .getCanonicalType(); 4798 const Type *Ty = QTy.getTypePtrOrNull(); 4799 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4800 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4801 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4802 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4803 } 4804 continue; 4805 } 4806 } 4807 if (isa<CXXThisExpr>(E)) { 4808 if (AlignedThis) { 4809 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4810 << 2 << E->getSourceRange(); 4811 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4812 << getOpenMPClauseName(OMPC_aligned); 4813 } 4814 AlignedThis = E; 4815 continue; 4816 } 4817 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4818 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4819 } 4820 // The optional parameter of the aligned clause, alignment, must be a constant 4821 // positive integer expression. If no optional parameter is specified, 4822 // implementation-defined default alignments for SIMD instructions on the 4823 // target platforms are assumed. 4824 SmallVector<const Expr *, 4> NewAligns; 4825 for (Expr *E : Alignments) { 4826 ExprResult Align; 4827 if (E) 4828 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4829 NewAligns.push_back(Align.get()); 4830 } 4831 // OpenMP [2.8.2, declare simd construct, Description] 4832 // The linear clause declares one or more list items to be private to a SIMD 4833 // lane and to have a linear relationship with respect to the iteration space 4834 // of a loop. 4835 // The special this pointer can be used as if was one of the arguments to the 4836 // function in any of the linear, aligned, or uniform clauses. 4837 // When a linear-step expression is specified in a linear clause it must be 4838 // either a constant integer expression or an integer-typed parameter that is 4839 // specified in a uniform clause on the directive. 4840 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4841 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4842 auto MI = LinModifiers.begin(); 4843 for (const Expr *E : Linears) { 4844 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4845 ++MI; 4846 E = E->IgnoreParenImpCasts(); 4847 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4848 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4849 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4850 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4851 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4852 ->getCanonicalDecl() == CanonPVD) { 4853 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4854 // A list-item cannot appear in more than one linear clause. 4855 if (LinearArgs.count(CanonPVD) > 0) { 4856 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4857 << getOpenMPClauseName(OMPC_linear) 4858 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4859 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4860 diag::note_omp_explicit_dsa) 4861 << getOpenMPClauseName(OMPC_linear); 4862 continue; 4863 } 4864 // Each argument can appear in at most one uniform or linear clause. 4865 if (UniformedArgs.count(CanonPVD) > 0) { 4866 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4867 << getOpenMPClauseName(OMPC_linear) 4868 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4869 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4870 diag::note_omp_explicit_dsa) 4871 << getOpenMPClauseName(OMPC_uniform); 4872 continue; 4873 } 4874 LinearArgs[CanonPVD] = E; 4875 if (E->isValueDependent() || E->isTypeDependent() || 4876 E->isInstantiationDependent() || 4877 E->containsUnexpandedParameterPack()) 4878 continue; 4879 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4880 PVD->getOriginalType()); 4881 continue; 4882 } 4883 } 4884 if (isa<CXXThisExpr>(E)) { 4885 if (UniformedLinearThis) { 4886 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4887 << getOpenMPClauseName(OMPC_linear) 4888 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4889 << E->getSourceRange(); 4890 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4891 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4892 : OMPC_linear); 4893 continue; 4894 } 4895 UniformedLinearThis = E; 4896 if (E->isValueDependent() || E->isTypeDependent() || 4897 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4898 continue; 4899 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4900 E->getType()); 4901 continue; 4902 } 4903 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4904 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4905 } 4906 Expr *Step = nullptr; 4907 Expr *NewStep = nullptr; 4908 SmallVector<Expr *, 4> NewSteps; 4909 for (Expr *E : Steps) { 4910 // Skip the same step expression, it was checked already. 4911 if (Step == E || !E) { 4912 NewSteps.push_back(E ? NewStep : nullptr); 4913 continue; 4914 } 4915 Step = E; 4916 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4917 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4918 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4919 if (UniformedArgs.count(CanonPVD) == 0) { 4920 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4921 << Step->getSourceRange(); 4922 } else if (E->isValueDependent() || E->isTypeDependent() || 4923 E->isInstantiationDependent() || 4924 E->containsUnexpandedParameterPack() || 4925 CanonPVD->getType()->hasIntegerRepresentation()) { 4926 NewSteps.push_back(Step); 4927 } else { 4928 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4929 << Step->getSourceRange(); 4930 } 4931 continue; 4932 } 4933 NewStep = Step; 4934 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4935 !Step->isInstantiationDependent() && 4936 !Step->containsUnexpandedParameterPack()) { 4937 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4938 .get(); 4939 if (NewStep) 4940 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4941 } 4942 NewSteps.push_back(NewStep); 4943 } 4944 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4945 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4946 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4947 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4948 const_cast<Expr **>(Linears.data()), Linears.size(), 4949 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4950 NewSteps.data(), NewSteps.size(), SR); 4951 ADecl->addAttr(NewAttr); 4952 return DG; 4953 } 4954 4955 Optional<std::pair<FunctionDecl *, Expr *>> 4956 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 4957 Expr *VariantRef, SourceRange SR) { 4958 if (!DG || DG.get().isNull()) 4959 return None; 4960 4961 const int VariantId = 1; 4962 // Must be applied only to single decl. 4963 if (!DG.get().isSingleDecl()) { 4964 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4965 << VariantId << SR; 4966 return None; 4967 } 4968 Decl *ADecl = DG.get().getSingleDecl(); 4969 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4970 ADecl = FTD->getTemplatedDecl(); 4971 4972 // Decl must be a function. 4973 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4974 if (!FD) { 4975 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 4976 << VariantId << SR; 4977 return None; 4978 } 4979 4980 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 4981 return FD->hasAttrs() && 4982 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 4983 FD->hasAttr<TargetAttr>()); 4984 }; 4985 // OpenMP is not compatible with CPU-specific attributes. 4986 if (HasMultiVersionAttributes(FD)) { 4987 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 4988 << SR; 4989 return None; 4990 } 4991 4992 // Allow #pragma omp declare variant only if the function is not used. 4993 if (FD->isUsed(false)) 4994 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 4995 << FD->getLocation(); 4996 4997 // Check if the function was emitted already. 4998 const FunctionDecl *Definition; 4999 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5000 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5001 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5002 << FD->getLocation(); 5003 5004 // The VariantRef must point to function. 5005 if (!VariantRef) { 5006 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5007 return None; 5008 } 5009 5010 // Do not check templates, wait until instantiation. 5011 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5012 VariantRef->containsUnexpandedParameterPack() || 5013 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5014 return std::make_pair(FD, VariantRef); 5015 5016 // Convert VariantRef expression to the type of the original function to 5017 // resolve possible conflicts. 5018 ExprResult VariantRefCast; 5019 if (LangOpts.CPlusPlus) { 5020 QualType FnPtrType; 5021 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5022 if (Method && !Method->isStatic()) { 5023 const Type *ClassType = 5024 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5025 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5026 ExprResult ER; 5027 { 5028 // Build adrr_of unary op to correctly handle type checks for member 5029 // functions. 5030 Sema::TentativeAnalysisScope Trap(*this); 5031 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5032 VariantRef); 5033 } 5034 if (!ER.isUsable()) { 5035 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5036 << VariantId << VariantRef->getSourceRange(); 5037 return None; 5038 } 5039 VariantRef = ER.get(); 5040 } else { 5041 FnPtrType = Context.getPointerType(FD->getType()); 5042 } 5043 ImplicitConversionSequence ICS = 5044 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5045 /*SuppressUserConversions=*/false, 5046 /*AllowExplicit=*/false, 5047 /*InOverloadResolution=*/false, 5048 /*CStyle=*/false, 5049 /*AllowObjCWritebackConversion=*/false); 5050 if (ICS.isFailure()) { 5051 Diag(VariantRef->getExprLoc(), 5052 diag::err_omp_declare_variant_incompat_types) 5053 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 5054 return None; 5055 } 5056 VariantRefCast = PerformImplicitConversion( 5057 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5058 if (!VariantRefCast.isUsable()) 5059 return None; 5060 // Drop previously built artificial addr_of unary op for member functions. 5061 if (Method && !Method->isStatic()) { 5062 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5063 if (auto *UO = dyn_cast<UnaryOperator>( 5064 PossibleAddrOfVariantRef->IgnoreImplicit())) 5065 VariantRefCast = UO->getSubExpr(); 5066 } 5067 } else { 5068 VariantRefCast = VariantRef; 5069 } 5070 5071 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5072 if (!ER.isUsable() || 5073 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5074 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5075 << VariantId << VariantRef->getSourceRange(); 5076 return None; 5077 } 5078 5079 // The VariantRef must point to function. 5080 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5081 if (!DRE) { 5082 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5083 << VariantId << VariantRef->getSourceRange(); 5084 return None; 5085 } 5086 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5087 if (!NewFD) { 5088 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5089 << VariantId << VariantRef->getSourceRange(); 5090 return None; 5091 } 5092 5093 // Check if variant function is not marked with declare variant directive. 5094 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5095 Diag(VariantRef->getExprLoc(), 5096 diag::warn_omp_declare_variant_marked_as_declare_variant) 5097 << VariantRef->getSourceRange(); 5098 SourceRange SR = 5099 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5100 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5101 return None; 5102 } 5103 5104 enum DoesntSupport { 5105 VirtFuncs = 1, 5106 Constructors = 3, 5107 Destructors = 4, 5108 DeletedFuncs = 5, 5109 DefaultedFuncs = 6, 5110 ConstexprFuncs = 7, 5111 ConstevalFuncs = 8, 5112 }; 5113 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5114 if (CXXFD->isVirtual()) { 5115 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5116 << VirtFuncs; 5117 return None; 5118 } 5119 5120 if (isa<CXXConstructorDecl>(FD)) { 5121 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5122 << Constructors; 5123 return None; 5124 } 5125 5126 if (isa<CXXDestructorDecl>(FD)) { 5127 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5128 << Destructors; 5129 return None; 5130 } 5131 } 5132 5133 if (FD->isDeleted()) { 5134 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5135 << DeletedFuncs; 5136 return None; 5137 } 5138 5139 if (FD->isDefaulted()) { 5140 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5141 << DefaultedFuncs; 5142 return None; 5143 } 5144 5145 if (FD->isConstexpr()) { 5146 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5147 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5148 return None; 5149 } 5150 5151 // Check general compatibility. 5152 if (areMultiversionVariantFunctionsCompatible( 5153 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5154 PartialDiagnosticAt( 5155 SR.getBegin(), 5156 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5157 PartialDiagnosticAt( 5158 VariantRef->getExprLoc(), 5159 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5160 PartialDiagnosticAt(VariantRef->getExprLoc(), 5161 PDiag(diag::err_omp_declare_variant_diff) 5162 << FD->getLocation()), 5163 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5164 /*CLinkageMayDiffer=*/true)) 5165 return None; 5166 return std::make_pair(FD, cast<Expr>(DRE)); 5167 } 5168 5169 void Sema::ActOnOpenMPDeclareVariantDirective( 5170 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5171 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { 5172 if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || 5173 Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) 5174 return; 5175 Expr *Score = nullptr; 5176 OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown; 5177 if (Data.CtxScore.isUsable()) { 5178 ST = OMPDeclareVariantAttr::ScoreSpecified; 5179 Score = Data.CtxScore.get(); 5180 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5181 !Score->isInstantiationDependent() && 5182 !Score->containsUnexpandedParameterPack()) { 5183 llvm::APSInt Result; 5184 ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result); 5185 if (ICE.isInvalid()) 5186 return; 5187 } 5188 } 5189 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5190 Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, 5191 Data.ImplVendors.begin(), Data.ImplVendors.size(), SR); 5192 FD->addAttr(NewAttr); 5193 } 5194 5195 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5196 FunctionDecl *Func, 5197 bool MightBeOdrUse) { 5198 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5199 5200 if (!Func->isDependentContext() && Func->hasAttrs()) { 5201 for (OMPDeclareVariantAttr *A : 5202 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5203 // TODO: add checks for active OpenMP context where possible. 5204 Expr *VariantRef = A->getVariantFuncRef(); 5205 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5206 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5207 if (!F->isDefined() && F->isTemplateInstantiation()) 5208 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5209 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5210 } 5211 } 5212 } 5213 5214 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5215 Stmt *AStmt, 5216 SourceLocation StartLoc, 5217 SourceLocation EndLoc) { 5218 if (!AStmt) 5219 return StmtError(); 5220 5221 auto *CS = cast<CapturedStmt>(AStmt); 5222 // 1.2.2 OpenMP Language Terminology 5223 // Structured block - An executable statement with a single entry at the 5224 // top and a single exit at the bottom. 5225 // The point of exit cannot be a branch out of the structured block. 5226 // longjmp() and throw() must not violate the entry/exit criteria. 5227 CS->getCapturedDecl()->setNothrow(); 5228 5229 setFunctionHasBranchProtectedScope(); 5230 5231 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5232 DSAStack->isCancelRegion()); 5233 } 5234 5235 namespace { 5236 /// Iteration space of a single for loop. 5237 struct LoopIterationSpace final { 5238 /// True if the condition operator is the strict compare operator (<, > or 5239 /// !=). 5240 bool IsStrictCompare = false; 5241 /// Condition of the loop. 5242 Expr *PreCond = nullptr; 5243 /// This expression calculates the number of iterations in the loop. 5244 /// It is always possible to calculate it before starting the loop. 5245 Expr *NumIterations = nullptr; 5246 /// The loop counter variable. 5247 Expr *CounterVar = nullptr; 5248 /// Private loop counter variable. 5249 Expr *PrivateCounterVar = nullptr; 5250 /// This is initializer for the initial value of #CounterVar. 5251 Expr *CounterInit = nullptr; 5252 /// This is step for the #CounterVar used to generate its update: 5253 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5254 Expr *CounterStep = nullptr; 5255 /// Should step be subtracted? 5256 bool Subtract = false; 5257 /// Source range of the loop init. 5258 SourceRange InitSrcRange; 5259 /// Source range of the loop condition. 5260 SourceRange CondSrcRange; 5261 /// Source range of the loop increment. 5262 SourceRange IncSrcRange; 5263 /// Minimum value that can have the loop control variable. Used to support 5264 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5265 /// since only such variables can be used in non-loop invariant expressions. 5266 Expr *MinValue = nullptr; 5267 /// Maximum value that can have the loop control variable. Used to support 5268 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5269 /// since only such variables can be used in non-loop invariant expressions. 5270 Expr *MaxValue = nullptr; 5271 /// true, if the lower bound depends on the outer loop control var. 5272 bool IsNonRectangularLB = false; 5273 /// true, if the upper bound depends on the outer loop control var. 5274 bool IsNonRectangularUB = false; 5275 /// Index of the loop this loop depends on and forms non-rectangular loop 5276 /// nest. 5277 unsigned LoopDependentIdx = 0; 5278 /// Final condition for the non-rectangular loop nest support. It is used to 5279 /// check that the number of iterations for this particular counter must be 5280 /// finished. 5281 Expr *FinalCondition = nullptr; 5282 }; 5283 5284 /// Helper class for checking canonical form of the OpenMP loops and 5285 /// extracting iteration space of each loop in the loop nest, that will be used 5286 /// for IR generation. 5287 class OpenMPIterationSpaceChecker { 5288 /// Reference to Sema. 5289 Sema &SemaRef; 5290 /// Data-sharing stack. 5291 DSAStackTy &Stack; 5292 /// A location for diagnostics (when there is no some better location). 5293 SourceLocation DefaultLoc; 5294 /// A location for diagnostics (when increment is not compatible). 5295 SourceLocation ConditionLoc; 5296 /// A source location for referring to loop init later. 5297 SourceRange InitSrcRange; 5298 /// A source location for referring to condition later. 5299 SourceRange ConditionSrcRange; 5300 /// A source location for referring to increment later. 5301 SourceRange IncrementSrcRange; 5302 /// Loop variable. 5303 ValueDecl *LCDecl = nullptr; 5304 /// Reference to loop variable. 5305 Expr *LCRef = nullptr; 5306 /// Lower bound (initializer for the var). 5307 Expr *LB = nullptr; 5308 /// Upper bound. 5309 Expr *UB = nullptr; 5310 /// Loop step (increment). 5311 Expr *Step = nullptr; 5312 /// This flag is true when condition is one of: 5313 /// Var < UB 5314 /// Var <= UB 5315 /// UB > Var 5316 /// UB >= Var 5317 /// This will have no value when the condition is != 5318 llvm::Optional<bool> TestIsLessOp; 5319 /// This flag is true when condition is strict ( < or > ). 5320 bool TestIsStrictOp = false; 5321 /// This flag is true when step is subtracted on each iteration. 5322 bool SubtractStep = false; 5323 /// The outer loop counter this loop depends on (if any). 5324 const ValueDecl *DepDecl = nullptr; 5325 /// Contains number of loop (starts from 1) on which loop counter init 5326 /// expression of this loop depends on. 5327 Optional<unsigned> InitDependOnLC; 5328 /// Contains number of loop (starts from 1) on which loop counter condition 5329 /// expression of this loop depends on. 5330 Optional<unsigned> CondDependOnLC; 5331 /// Checks if the provide statement depends on the loop counter. 5332 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5333 /// Original condition required for checking of the exit condition for 5334 /// non-rectangular loop. 5335 Expr *Condition = nullptr; 5336 5337 public: 5338 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5339 SourceLocation DefaultLoc) 5340 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5341 ConditionLoc(DefaultLoc) {} 5342 /// Check init-expr for canonical loop form and save loop counter 5343 /// variable - #Var and its initialization value - #LB. 5344 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5345 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5346 /// for less/greater and for strict/non-strict comparison. 5347 bool checkAndSetCond(Expr *S); 5348 /// Check incr-expr for canonical loop form and return true if it 5349 /// does not conform, otherwise save loop step (#Step). 5350 bool checkAndSetInc(Expr *S); 5351 /// Return the loop counter variable. 5352 ValueDecl *getLoopDecl() const { return LCDecl; } 5353 /// Return the reference expression to loop counter variable. 5354 Expr *getLoopDeclRefExpr() const { return LCRef; } 5355 /// Source range of the loop init. 5356 SourceRange getInitSrcRange() const { return InitSrcRange; } 5357 /// Source range of the loop condition. 5358 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5359 /// Source range of the loop increment. 5360 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5361 /// True if the step should be subtracted. 5362 bool shouldSubtractStep() const { return SubtractStep; } 5363 /// True, if the compare operator is strict (<, > or !=). 5364 bool isStrictTestOp() const { return TestIsStrictOp; } 5365 /// Build the expression to calculate the number of iterations. 5366 Expr *buildNumIterations( 5367 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5368 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5369 /// Build the precondition expression for the loops. 5370 Expr * 5371 buildPreCond(Scope *S, Expr *Cond, 5372 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5373 /// Build reference expression to the counter be used for codegen. 5374 DeclRefExpr * 5375 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5376 DSAStackTy &DSA) const; 5377 /// Build reference expression to the private counter be used for 5378 /// codegen. 5379 Expr *buildPrivateCounterVar() const; 5380 /// Build initialization of the counter be used for codegen. 5381 Expr *buildCounterInit() const; 5382 /// Build step of the counter be used for codegen. 5383 Expr *buildCounterStep() const; 5384 /// Build loop data with counter value for depend clauses in ordered 5385 /// directives. 5386 Expr * 5387 buildOrderedLoopData(Scope *S, Expr *Counter, 5388 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5389 SourceLocation Loc, Expr *Inc = nullptr, 5390 OverloadedOperatorKind OOK = OO_Amp); 5391 /// Builds the minimum value for the loop counter. 5392 std::pair<Expr *, Expr *> buildMinMaxValues( 5393 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5394 /// Builds final condition for the non-rectangular loops. 5395 Expr *buildFinalCondition(Scope *S) const; 5396 /// Return true if any expression is dependent. 5397 bool dependent() const; 5398 /// Returns true if the initializer forms non-rectangular loop. 5399 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5400 /// Returns true if the condition forms non-rectangular loop. 5401 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5402 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5403 unsigned getLoopDependentIdx() const { 5404 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5405 } 5406 5407 private: 5408 /// Check the right-hand side of an assignment in the increment 5409 /// expression. 5410 bool checkAndSetIncRHS(Expr *RHS); 5411 /// Helper to set loop counter variable and its initializer. 5412 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5413 bool EmitDiags); 5414 /// Helper to set upper bound. 5415 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5416 SourceRange SR, SourceLocation SL); 5417 /// Helper to set loop increment. 5418 bool setStep(Expr *NewStep, bool Subtract); 5419 }; 5420 5421 bool OpenMPIterationSpaceChecker::dependent() const { 5422 if (!LCDecl) { 5423 assert(!LB && !UB && !Step); 5424 return false; 5425 } 5426 return LCDecl->getType()->isDependentType() || 5427 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5428 (Step && Step->isValueDependent()); 5429 } 5430 5431 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5432 Expr *NewLCRefExpr, 5433 Expr *NewLB, bool EmitDiags) { 5434 // State consistency checking to ensure correct usage. 5435 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5436 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5437 if (!NewLCDecl || !NewLB) 5438 return true; 5439 LCDecl = getCanonicalDecl(NewLCDecl); 5440 LCRef = NewLCRefExpr; 5441 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5442 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5443 if ((Ctor->isCopyOrMoveConstructor() || 5444 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5445 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5446 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5447 LB = NewLB; 5448 if (EmitDiags) 5449 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5450 return false; 5451 } 5452 5453 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5454 llvm::Optional<bool> LessOp, 5455 bool StrictOp, SourceRange SR, 5456 SourceLocation SL) { 5457 // State consistency checking to ensure correct usage. 5458 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5459 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5460 if (!NewUB) 5461 return true; 5462 UB = NewUB; 5463 if (LessOp) 5464 TestIsLessOp = LessOp; 5465 TestIsStrictOp = StrictOp; 5466 ConditionSrcRange = SR; 5467 ConditionLoc = SL; 5468 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5469 return false; 5470 } 5471 5472 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5473 // State consistency checking to ensure correct usage. 5474 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5475 if (!NewStep) 5476 return true; 5477 if (!NewStep->isValueDependent()) { 5478 // Check that the step is integer expression. 5479 SourceLocation StepLoc = NewStep->getBeginLoc(); 5480 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5481 StepLoc, getExprAsWritten(NewStep)); 5482 if (Val.isInvalid()) 5483 return true; 5484 NewStep = Val.get(); 5485 5486 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5487 // If test-expr is of form var relational-op b and relational-op is < or 5488 // <= then incr-expr must cause var to increase on each iteration of the 5489 // loop. If test-expr is of form var relational-op b and relational-op is 5490 // > or >= then incr-expr must cause var to decrease on each iteration of 5491 // the loop. 5492 // If test-expr is of form b relational-op var and relational-op is < or 5493 // <= then incr-expr must cause var to decrease on each iteration of the 5494 // loop. If test-expr is of form b relational-op var and relational-op is 5495 // > or >= then incr-expr must cause var to increase on each iteration of 5496 // the loop. 5497 llvm::APSInt Result; 5498 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5499 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5500 bool IsConstNeg = 5501 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5502 bool IsConstPos = 5503 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5504 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5505 5506 // != with increment is treated as <; != with decrement is treated as > 5507 if (!TestIsLessOp.hasValue()) 5508 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5509 if (UB && (IsConstZero || 5510 (TestIsLessOp.getValue() ? 5511 (IsConstNeg || (IsUnsigned && Subtract)) : 5512 (IsConstPos || (IsUnsigned && !Subtract))))) { 5513 SemaRef.Diag(NewStep->getExprLoc(), 5514 diag::err_omp_loop_incr_not_compatible) 5515 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5516 SemaRef.Diag(ConditionLoc, 5517 diag::note_omp_loop_cond_requres_compatible_incr) 5518 << TestIsLessOp.getValue() << ConditionSrcRange; 5519 return true; 5520 } 5521 if (TestIsLessOp.getValue() == Subtract) { 5522 NewStep = 5523 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5524 .get(); 5525 Subtract = !Subtract; 5526 } 5527 } 5528 5529 Step = NewStep; 5530 SubtractStep = Subtract; 5531 return false; 5532 } 5533 5534 namespace { 5535 /// Checker for the non-rectangular loops. Checks if the initializer or 5536 /// condition expression references loop counter variable. 5537 class LoopCounterRefChecker final 5538 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5539 Sema &SemaRef; 5540 DSAStackTy &Stack; 5541 const ValueDecl *CurLCDecl = nullptr; 5542 const ValueDecl *DepDecl = nullptr; 5543 const ValueDecl *PrevDepDecl = nullptr; 5544 bool IsInitializer = true; 5545 unsigned BaseLoopId = 0; 5546 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5547 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5548 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5549 << (IsInitializer ? 0 : 1); 5550 return false; 5551 } 5552 const auto &&Data = Stack.isLoopControlVariable(VD); 5553 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5554 // The type of the loop iterator on which we depend may not have a random 5555 // access iterator type. 5556 if (Data.first && VD->getType()->isRecordType()) { 5557 SmallString<128> Name; 5558 llvm::raw_svector_ostream OS(Name); 5559 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5560 /*Qualified=*/true); 5561 SemaRef.Diag(E->getExprLoc(), 5562 diag::err_omp_wrong_dependency_iterator_type) 5563 << OS.str(); 5564 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5565 return false; 5566 } 5567 if (Data.first && 5568 (DepDecl || (PrevDepDecl && 5569 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5570 if (!DepDecl && PrevDepDecl) 5571 DepDecl = PrevDepDecl; 5572 SmallString<128> Name; 5573 llvm::raw_svector_ostream OS(Name); 5574 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5575 /*Qualified=*/true); 5576 SemaRef.Diag(E->getExprLoc(), 5577 diag::err_omp_invariant_or_linear_dependency) 5578 << OS.str(); 5579 return false; 5580 } 5581 if (Data.first) { 5582 DepDecl = VD; 5583 BaseLoopId = Data.first; 5584 } 5585 return Data.first; 5586 } 5587 5588 public: 5589 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5590 const ValueDecl *VD = E->getDecl(); 5591 if (isa<VarDecl>(VD)) 5592 return checkDecl(E, VD); 5593 return false; 5594 } 5595 bool VisitMemberExpr(const MemberExpr *E) { 5596 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5597 const ValueDecl *VD = E->getMemberDecl(); 5598 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5599 return checkDecl(E, VD); 5600 } 5601 return false; 5602 } 5603 bool VisitStmt(const Stmt *S) { 5604 bool Res = false; 5605 for (const Stmt *Child : S->children()) 5606 Res = (Child && Visit(Child)) || Res; 5607 return Res; 5608 } 5609 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5610 const ValueDecl *CurLCDecl, bool IsInitializer, 5611 const ValueDecl *PrevDepDecl = nullptr) 5612 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5613 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5614 unsigned getBaseLoopId() const { 5615 assert(CurLCDecl && "Expected loop dependency."); 5616 return BaseLoopId; 5617 } 5618 const ValueDecl *getDepDecl() const { 5619 assert(CurLCDecl && "Expected loop dependency."); 5620 return DepDecl; 5621 } 5622 }; 5623 } // namespace 5624 5625 Optional<unsigned> 5626 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5627 bool IsInitializer) { 5628 // Check for the non-rectangular loops. 5629 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5630 DepDecl); 5631 if (LoopStmtChecker.Visit(S)) { 5632 DepDecl = LoopStmtChecker.getDepDecl(); 5633 return LoopStmtChecker.getBaseLoopId(); 5634 } 5635 return llvm::None; 5636 } 5637 5638 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5639 // Check init-expr for canonical loop form and save loop counter 5640 // variable - #Var and its initialization value - #LB. 5641 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5642 // var = lb 5643 // integer-type var = lb 5644 // random-access-iterator-type var = lb 5645 // pointer-type var = lb 5646 // 5647 if (!S) { 5648 if (EmitDiags) { 5649 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5650 } 5651 return true; 5652 } 5653 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5654 if (!ExprTemp->cleanupsHaveSideEffects()) 5655 S = ExprTemp->getSubExpr(); 5656 5657 InitSrcRange = S->getSourceRange(); 5658 if (Expr *E = dyn_cast<Expr>(S)) 5659 S = E->IgnoreParens(); 5660 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5661 if (BO->getOpcode() == BO_Assign) { 5662 Expr *LHS = BO->getLHS()->IgnoreParens(); 5663 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5664 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5665 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5666 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5667 EmitDiags); 5668 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5669 } 5670 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5671 if (ME->isArrow() && 5672 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5673 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5674 EmitDiags); 5675 } 5676 } 5677 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5678 if (DS->isSingleDecl()) { 5679 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5680 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5681 // Accept non-canonical init form here but emit ext. warning. 5682 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5683 SemaRef.Diag(S->getBeginLoc(), 5684 diag::ext_omp_loop_not_canonical_init) 5685 << S->getSourceRange(); 5686 return setLCDeclAndLB( 5687 Var, 5688 buildDeclRefExpr(SemaRef, Var, 5689 Var->getType().getNonReferenceType(), 5690 DS->getBeginLoc()), 5691 Var->getInit(), EmitDiags); 5692 } 5693 } 5694 } 5695 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5696 if (CE->getOperator() == OO_Equal) { 5697 Expr *LHS = CE->getArg(0); 5698 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5699 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5700 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5701 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5702 EmitDiags); 5703 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5704 } 5705 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5706 if (ME->isArrow() && 5707 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5708 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5709 EmitDiags); 5710 } 5711 } 5712 } 5713 5714 if (dependent() || SemaRef.CurContext->isDependentContext()) 5715 return false; 5716 if (EmitDiags) { 5717 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5718 << S->getSourceRange(); 5719 } 5720 return true; 5721 } 5722 5723 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5724 /// variable (which may be the loop variable) if possible. 5725 static const ValueDecl *getInitLCDecl(const Expr *E) { 5726 if (!E) 5727 return nullptr; 5728 E = getExprAsWritten(E); 5729 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5730 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5731 if ((Ctor->isCopyOrMoveConstructor() || 5732 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5733 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5734 E = CE->getArg(0)->IgnoreParenImpCasts(); 5735 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5736 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5737 return getCanonicalDecl(VD); 5738 } 5739 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5740 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5741 return getCanonicalDecl(ME->getMemberDecl()); 5742 return nullptr; 5743 } 5744 5745 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5746 // Check test-expr for canonical form, save upper-bound UB, flags for 5747 // less/greater and for strict/non-strict comparison. 5748 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5749 // var relational-op b 5750 // b relational-op var 5751 // 5752 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5753 if (!S) { 5754 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5755 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5756 return true; 5757 } 5758 Condition = S; 5759 S = getExprAsWritten(S); 5760 SourceLocation CondLoc = S->getBeginLoc(); 5761 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5762 if (BO->isRelationalOp()) { 5763 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5764 return setUB(BO->getRHS(), 5765 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5766 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5767 BO->getSourceRange(), BO->getOperatorLoc()); 5768 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5769 return setUB(BO->getLHS(), 5770 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5771 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5772 BO->getSourceRange(), BO->getOperatorLoc()); 5773 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5774 return setUB( 5775 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5776 /*LessOp=*/llvm::None, 5777 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5778 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5779 if (CE->getNumArgs() == 2) { 5780 auto Op = CE->getOperator(); 5781 switch (Op) { 5782 case OO_Greater: 5783 case OO_GreaterEqual: 5784 case OO_Less: 5785 case OO_LessEqual: 5786 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5787 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5788 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5789 CE->getOperatorLoc()); 5790 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5791 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5792 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5793 CE->getOperatorLoc()); 5794 break; 5795 case OO_ExclaimEqual: 5796 if (IneqCondIsCanonical) 5797 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5798 : CE->getArg(0), 5799 /*LessOp=*/llvm::None, 5800 /*StrictOp=*/true, CE->getSourceRange(), 5801 CE->getOperatorLoc()); 5802 break; 5803 default: 5804 break; 5805 } 5806 } 5807 } 5808 if (dependent() || SemaRef.CurContext->isDependentContext()) 5809 return false; 5810 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5811 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5812 return true; 5813 } 5814 5815 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5816 // RHS of canonical loop form increment can be: 5817 // var + incr 5818 // incr + var 5819 // var - incr 5820 // 5821 RHS = RHS->IgnoreParenImpCasts(); 5822 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5823 if (BO->isAdditiveOp()) { 5824 bool IsAdd = BO->getOpcode() == BO_Add; 5825 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5826 return setStep(BO->getRHS(), !IsAdd); 5827 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5828 return setStep(BO->getLHS(), /*Subtract=*/false); 5829 } 5830 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5831 bool IsAdd = CE->getOperator() == OO_Plus; 5832 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5833 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5834 return setStep(CE->getArg(1), !IsAdd); 5835 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5836 return setStep(CE->getArg(0), /*Subtract=*/false); 5837 } 5838 } 5839 if (dependent() || SemaRef.CurContext->isDependentContext()) 5840 return false; 5841 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5842 << RHS->getSourceRange() << LCDecl; 5843 return true; 5844 } 5845 5846 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5847 // Check incr-expr for canonical loop form and return true if it 5848 // does not conform. 5849 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5850 // ++var 5851 // var++ 5852 // --var 5853 // var-- 5854 // var += incr 5855 // var -= incr 5856 // var = var + incr 5857 // var = incr + var 5858 // var = var - incr 5859 // 5860 if (!S) { 5861 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5862 return true; 5863 } 5864 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5865 if (!ExprTemp->cleanupsHaveSideEffects()) 5866 S = ExprTemp->getSubExpr(); 5867 5868 IncrementSrcRange = S->getSourceRange(); 5869 S = S->IgnoreParens(); 5870 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5871 if (UO->isIncrementDecrementOp() && 5872 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5873 return setStep(SemaRef 5874 .ActOnIntegerConstant(UO->getBeginLoc(), 5875 (UO->isDecrementOp() ? -1 : 1)) 5876 .get(), 5877 /*Subtract=*/false); 5878 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5879 switch (BO->getOpcode()) { 5880 case BO_AddAssign: 5881 case BO_SubAssign: 5882 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5883 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5884 break; 5885 case BO_Assign: 5886 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5887 return checkAndSetIncRHS(BO->getRHS()); 5888 break; 5889 default: 5890 break; 5891 } 5892 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5893 switch (CE->getOperator()) { 5894 case OO_PlusPlus: 5895 case OO_MinusMinus: 5896 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5897 return setStep(SemaRef 5898 .ActOnIntegerConstant( 5899 CE->getBeginLoc(), 5900 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5901 .get(), 5902 /*Subtract=*/false); 5903 break; 5904 case OO_PlusEqual: 5905 case OO_MinusEqual: 5906 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5907 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5908 break; 5909 case OO_Equal: 5910 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5911 return checkAndSetIncRHS(CE->getArg(1)); 5912 break; 5913 default: 5914 break; 5915 } 5916 } 5917 if (dependent() || SemaRef.CurContext->isDependentContext()) 5918 return false; 5919 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5920 << S->getSourceRange() << LCDecl; 5921 return true; 5922 } 5923 5924 static ExprResult 5925 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5926 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5927 if (SemaRef.CurContext->isDependentContext()) 5928 return ExprResult(Capture); 5929 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5930 return SemaRef.PerformImplicitConversion( 5931 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5932 /*AllowExplicit=*/true); 5933 auto I = Captures.find(Capture); 5934 if (I != Captures.end()) 5935 return buildCapture(SemaRef, Capture, I->second); 5936 DeclRefExpr *Ref = nullptr; 5937 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5938 Captures[Capture] = Ref; 5939 return Res; 5940 } 5941 5942 /// Build the expression to calculate the number of iterations. 5943 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5944 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5945 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5946 ExprResult Diff; 5947 QualType VarType = LCDecl->getType().getNonReferenceType(); 5948 if (VarType->isIntegerType() || VarType->isPointerType() || 5949 SemaRef.getLangOpts().CPlusPlus) { 5950 Expr *LBVal = LB; 5951 Expr *UBVal = UB; 5952 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5953 // max(LB(MinVal), LB(MaxVal)) 5954 if (InitDependOnLC) { 5955 const LoopIterationSpace &IS = 5956 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5957 InitDependOnLC.getValueOr( 5958 CondDependOnLC.getValueOr(0))]; 5959 if (!IS.MinValue || !IS.MaxValue) 5960 return nullptr; 5961 // OuterVar = Min 5962 ExprResult MinValue = 5963 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5964 if (!MinValue.isUsable()) 5965 return nullptr; 5966 5967 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5968 IS.CounterVar, MinValue.get()); 5969 if (!LBMinVal.isUsable()) 5970 return nullptr; 5971 // OuterVar = Min, LBVal 5972 LBMinVal = 5973 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5974 if (!LBMinVal.isUsable()) 5975 return nullptr; 5976 // (OuterVar = Min, LBVal) 5977 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5978 if (!LBMinVal.isUsable()) 5979 return nullptr; 5980 5981 // OuterVar = Max 5982 ExprResult MaxValue = 5983 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5984 if (!MaxValue.isUsable()) 5985 return nullptr; 5986 5987 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5988 IS.CounterVar, MaxValue.get()); 5989 if (!LBMaxVal.isUsable()) 5990 return nullptr; 5991 // OuterVar = Max, LBVal 5992 LBMaxVal = 5993 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5994 if (!LBMaxVal.isUsable()) 5995 return nullptr; 5996 // (OuterVar = Max, LBVal) 5997 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5998 if (!LBMaxVal.isUsable()) 5999 return nullptr; 6000 6001 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6002 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6003 if (!LBMin || !LBMax) 6004 return nullptr; 6005 // LB(MinVal) < LB(MaxVal) 6006 ExprResult MinLessMaxRes = 6007 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6008 if (!MinLessMaxRes.isUsable()) 6009 return nullptr; 6010 Expr *MinLessMax = 6011 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6012 if (!MinLessMax) 6013 return nullptr; 6014 if (TestIsLessOp.getValue()) { 6015 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6016 // LB(MaxVal)) 6017 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6018 MinLessMax, LBMin, LBMax); 6019 if (!MinLB.isUsable()) 6020 return nullptr; 6021 LBVal = MinLB.get(); 6022 } else { 6023 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6024 // LB(MaxVal)) 6025 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6026 MinLessMax, LBMax, LBMin); 6027 if (!MaxLB.isUsable()) 6028 return nullptr; 6029 LBVal = MaxLB.get(); 6030 } 6031 } 6032 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6033 // min(UB(MinVal), UB(MaxVal)) 6034 if (CondDependOnLC) { 6035 const LoopIterationSpace &IS = 6036 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6037 InitDependOnLC.getValueOr( 6038 CondDependOnLC.getValueOr(0))]; 6039 if (!IS.MinValue || !IS.MaxValue) 6040 return nullptr; 6041 // OuterVar = Min 6042 ExprResult MinValue = 6043 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6044 if (!MinValue.isUsable()) 6045 return nullptr; 6046 6047 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6048 IS.CounterVar, MinValue.get()); 6049 if (!UBMinVal.isUsable()) 6050 return nullptr; 6051 // OuterVar = Min, UBVal 6052 UBMinVal = 6053 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6054 if (!UBMinVal.isUsable()) 6055 return nullptr; 6056 // (OuterVar = Min, UBVal) 6057 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6058 if (!UBMinVal.isUsable()) 6059 return nullptr; 6060 6061 // OuterVar = Max 6062 ExprResult MaxValue = 6063 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6064 if (!MaxValue.isUsable()) 6065 return nullptr; 6066 6067 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6068 IS.CounterVar, MaxValue.get()); 6069 if (!UBMaxVal.isUsable()) 6070 return nullptr; 6071 // OuterVar = Max, UBVal 6072 UBMaxVal = 6073 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6074 if (!UBMaxVal.isUsable()) 6075 return nullptr; 6076 // (OuterVar = Max, UBVal) 6077 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6078 if (!UBMaxVal.isUsable()) 6079 return nullptr; 6080 6081 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6082 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6083 if (!UBMin || !UBMax) 6084 return nullptr; 6085 // UB(MinVal) > UB(MaxVal) 6086 ExprResult MinGreaterMaxRes = 6087 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6088 if (!MinGreaterMaxRes.isUsable()) 6089 return nullptr; 6090 Expr *MinGreaterMax = 6091 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6092 if (!MinGreaterMax) 6093 return nullptr; 6094 if (TestIsLessOp.getValue()) { 6095 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6096 // UB(MaxVal)) 6097 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6098 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6099 if (!MaxUB.isUsable()) 6100 return nullptr; 6101 UBVal = MaxUB.get(); 6102 } else { 6103 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6104 // UB(MaxVal)) 6105 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6106 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6107 if (!MinUB.isUsable()) 6108 return nullptr; 6109 UBVal = MinUB.get(); 6110 } 6111 } 6112 // Upper - Lower 6113 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6114 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6115 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6116 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6117 if (!Upper || !Lower) 6118 return nullptr; 6119 6120 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6121 6122 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6123 // BuildBinOp already emitted error, this one is to point user to upper 6124 // and lower bound, and to tell what is passed to 'operator-'. 6125 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6126 << Upper->getSourceRange() << Lower->getSourceRange(); 6127 return nullptr; 6128 } 6129 } 6130 6131 if (!Diff.isUsable()) 6132 return nullptr; 6133 6134 // Upper - Lower [- 1] 6135 if (TestIsStrictOp) 6136 Diff = SemaRef.BuildBinOp( 6137 S, DefaultLoc, BO_Sub, Diff.get(), 6138 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6139 if (!Diff.isUsable()) 6140 return nullptr; 6141 6142 // Upper - Lower [- 1] + Step 6143 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6144 if (!NewStep.isUsable()) 6145 return nullptr; 6146 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6147 if (!Diff.isUsable()) 6148 return nullptr; 6149 6150 // Parentheses (for dumping/debugging purposes only). 6151 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6152 if (!Diff.isUsable()) 6153 return nullptr; 6154 6155 // (Upper - Lower [- 1] + Step) / Step 6156 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6157 if (!Diff.isUsable()) 6158 return nullptr; 6159 6160 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6161 QualType Type = Diff.get()->getType(); 6162 ASTContext &C = SemaRef.Context; 6163 bool UseVarType = VarType->hasIntegerRepresentation() && 6164 C.getTypeSize(Type) > C.getTypeSize(VarType); 6165 if (!Type->isIntegerType() || UseVarType) { 6166 unsigned NewSize = 6167 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6168 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6169 : Type->hasSignedIntegerRepresentation(); 6170 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6171 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6172 Diff = SemaRef.PerformImplicitConversion( 6173 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6174 if (!Diff.isUsable()) 6175 return nullptr; 6176 } 6177 } 6178 if (LimitedType) { 6179 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6180 if (NewSize != C.getTypeSize(Type)) { 6181 if (NewSize < C.getTypeSize(Type)) { 6182 assert(NewSize == 64 && "incorrect loop var size"); 6183 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6184 << InitSrcRange << ConditionSrcRange; 6185 } 6186 QualType NewType = C.getIntTypeForBitwidth( 6187 NewSize, Type->hasSignedIntegerRepresentation() || 6188 C.getTypeSize(Type) < NewSize); 6189 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6190 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6191 Sema::AA_Converting, true); 6192 if (!Diff.isUsable()) 6193 return nullptr; 6194 } 6195 } 6196 } 6197 6198 return Diff.get(); 6199 } 6200 6201 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6202 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6203 // Do not build for iterators, they cannot be used in non-rectangular loop 6204 // nests. 6205 if (LCDecl->getType()->isRecordType()) 6206 return std::make_pair(nullptr, nullptr); 6207 // If we subtract, the min is in the condition, otherwise the min is in the 6208 // init value. 6209 Expr *MinExpr = nullptr; 6210 Expr *MaxExpr = nullptr; 6211 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6212 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6213 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6214 : CondDependOnLC.hasValue(); 6215 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6216 : InitDependOnLC.hasValue(); 6217 Expr *Lower = 6218 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6219 Expr *Upper = 6220 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6221 if (!Upper || !Lower) 6222 return std::make_pair(nullptr, nullptr); 6223 6224 if (TestIsLessOp.getValue()) 6225 MinExpr = Lower; 6226 else 6227 MaxExpr = Upper; 6228 6229 // Build minimum/maximum value based on number of iterations. 6230 ExprResult Diff; 6231 QualType VarType = LCDecl->getType().getNonReferenceType(); 6232 6233 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6234 if (!Diff.isUsable()) 6235 return std::make_pair(nullptr, nullptr); 6236 6237 // Upper - Lower [- 1] 6238 if (TestIsStrictOp) 6239 Diff = SemaRef.BuildBinOp( 6240 S, DefaultLoc, BO_Sub, Diff.get(), 6241 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6242 if (!Diff.isUsable()) 6243 return std::make_pair(nullptr, nullptr); 6244 6245 // Upper - Lower [- 1] + Step 6246 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6247 if (!NewStep.isUsable()) 6248 return std::make_pair(nullptr, nullptr); 6249 6250 // Parentheses (for dumping/debugging purposes only). 6251 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6252 if (!Diff.isUsable()) 6253 return std::make_pair(nullptr, nullptr); 6254 6255 // (Upper - Lower [- 1]) / Step 6256 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6257 if (!Diff.isUsable()) 6258 return std::make_pair(nullptr, nullptr); 6259 6260 // ((Upper - Lower [- 1]) / Step) * Step 6261 // Parentheses (for dumping/debugging purposes only). 6262 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6263 if (!Diff.isUsable()) 6264 return std::make_pair(nullptr, nullptr); 6265 6266 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6267 if (!Diff.isUsable()) 6268 return std::make_pair(nullptr, nullptr); 6269 6270 // Convert to the original type or ptrdiff_t, if original type is pointer. 6271 if (!VarType->isAnyPointerType() && 6272 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6273 Diff = SemaRef.PerformImplicitConversion( 6274 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6275 } else if (VarType->isAnyPointerType() && 6276 !SemaRef.Context.hasSameType( 6277 Diff.get()->getType(), 6278 SemaRef.Context.getUnsignedPointerDiffType())) { 6279 Diff = SemaRef.PerformImplicitConversion( 6280 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6281 Sema::AA_Converting, /*AllowExplicit=*/true); 6282 } 6283 if (!Diff.isUsable()) 6284 return std::make_pair(nullptr, nullptr); 6285 6286 // Parentheses (for dumping/debugging purposes only). 6287 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6288 if (!Diff.isUsable()) 6289 return std::make_pair(nullptr, nullptr); 6290 6291 if (TestIsLessOp.getValue()) { 6292 // MinExpr = Lower; 6293 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6294 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6295 if (!Diff.isUsable()) 6296 return std::make_pair(nullptr, nullptr); 6297 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6298 if (!Diff.isUsable()) 6299 return std::make_pair(nullptr, nullptr); 6300 MaxExpr = Diff.get(); 6301 } else { 6302 // MaxExpr = Upper; 6303 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6304 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6305 if (!Diff.isUsable()) 6306 return std::make_pair(nullptr, nullptr); 6307 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6308 if (!Diff.isUsable()) 6309 return std::make_pair(nullptr, nullptr); 6310 MinExpr = Diff.get(); 6311 } 6312 6313 return std::make_pair(MinExpr, MaxExpr); 6314 } 6315 6316 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6317 if (InitDependOnLC || CondDependOnLC) 6318 return Condition; 6319 return nullptr; 6320 } 6321 6322 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6323 Scope *S, Expr *Cond, 6324 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6325 // Do not build a precondition when the condition/initialization is dependent 6326 // to prevent pessimistic early loop exit. 6327 // TODO: this can be improved by calculating min/max values but not sure that 6328 // it will be very effective. 6329 if (CondDependOnLC || InitDependOnLC) 6330 return SemaRef.PerformImplicitConversion( 6331 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6332 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6333 /*AllowExplicit=*/true).get(); 6334 6335 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6336 Sema::TentativeAnalysisScope Trap(SemaRef); 6337 6338 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6339 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6340 if (!NewLB.isUsable() || !NewUB.isUsable()) 6341 return nullptr; 6342 6343 ExprResult CondExpr = 6344 SemaRef.BuildBinOp(S, DefaultLoc, 6345 TestIsLessOp.getValue() ? 6346 (TestIsStrictOp ? BO_LT : BO_LE) : 6347 (TestIsStrictOp ? BO_GT : BO_GE), 6348 NewLB.get(), NewUB.get()); 6349 if (CondExpr.isUsable()) { 6350 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6351 SemaRef.Context.BoolTy)) 6352 CondExpr = SemaRef.PerformImplicitConversion( 6353 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6354 /*AllowExplicit=*/true); 6355 } 6356 6357 // Otherwise use original loop condition and evaluate it in runtime. 6358 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6359 } 6360 6361 /// Build reference expression to the counter be used for codegen. 6362 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6363 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6364 DSAStackTy &DSA) const { 6365 auto *VD = dyn_cast<VarDecl>(LCDecl); 6366 if (!VD) { 6367 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6368 DeclRefExpr *Ref = buildDeclRefExpr( 6369 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6370 const DSAStackTy::DSAVarData Data = 6371 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6372 // If the loop control decl is explicitly marked as private, do not mark it 6373 // as captured again. 6374 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6375 Captures.insert(std::make_pair(LCRef, Ref)); 6376 return Ref; 6377 } 6378 return cast<DeclRefExpr>(LCRef); 6379 } 6380 6381 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6382 if (LCDecl && !LCDecl->isInvalidDecl()) { 6383 QualType Type = LCDecl->getType().getNonReferenceType(); 6384 VarDecl *PrivateVar = buildVarDecl( 6385 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6386 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6387 isa<VarDecl>(LCDecl) 6388 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6389 : nullptr); 6390 if (PrivateVar->isInvalidDecl()) 6391 return nullptr; 6392 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6393 } 6394 return nullptr; 6395 } 6396 6397 /// Build initialization of the counter to be used for codegen. 6398 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6399 6400 /// Build step of the counter be used for codegen. 6401 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6402 6403 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6404 Scope *S, Expr *Counter, 6405 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6406 Expr *Inc, OverloadedOperatorKind OOK) { 6407 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6408 if (!Cnt) 6409 return nullptr; 6410 if (Inc) { 6411 assert((OOK == OO_Plus || OOK == OO_Minus) && 6412 "Expected only + or - operations for depend clauses."); 6413 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6414 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6415 if (!Cnt) 6416 return nullptr; 6417 } 6418 ExprResult Diff; 6419 QualType VarType = LCDecl->getType().getNonReferenceType(); 6420 if (VarType->isIntegerType() || VarType->isPointerType() || 6421 SemaRef.getLangOpts().CPlusPlus) { 6422 // Upper - Lower 6423 Expr *Upper = TestIsLessOp.getValue() 6424 ? Cnt 6425 : tryBuildCapture(SemaRef, UB, Captures).get(); 6426 Expr *Lower = TestIsLessOp.getValue() 6427 ? tryBuildCapture(SemaRef, LB, Captures).get() 6428 : Cnt; 6429 if (!Upper || !Lower) 6430 return nullptr; 6431 6432 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6433 6434 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6435 // BuildBinOp already emitted error, this one is to point user to upper 6436 // and lower bound, and to tell what is passed to 'operator-'. 6437 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6438 << Upper->getSourceRange() << Lower->getSourceRange(); 6439 return nullptr; 6440 } 6441 } 6442 6443 if (!Diff.isUsable()) 6444 return nullptr; 6445 6446 // Parentheses (for dumping/debugging purposes only). 6447 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6448 if (!Diff.isUsable()) 6449 return nullptr; 6450 6451 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6452 if (!NewStep.isUsable()) 6453 return nullptr; 6454 // (Upper - Lower) / Step 6455 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6456 if (!Diff.isUsable()) 6457 return nullptr; 6458 6459 return Diff.get(); 6460 } 6461 } // namespace 6462 6463 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6464 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6465 assert(Init && "Expected loop in canonical form."); 6466 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6467 if (AssociatedLoops > 0 && 6468 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6469 DSAStack->loopStart(); 6470 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6471 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6472 if (ValueDecl *D = ISC.getLoopDecl()) { 6473 auto *VD = dyn_cast<VarDecl>(D); 6474 DeclRefExpr *PrivateRef = nullptr; 6475 if (!VD) { 6476 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6477 VD = Private; 6478 } else { 6479 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6480 /*WithInit=*/false); 6481 VD = cast<VarDecl>(PrivateRef->getDecl()); 6482 } 6483 } 6484 DSAStack->addLoopControlVariable(D, VD); 6485 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6486 if (LD != D->getCanonicalDecl()) { 6487 DSAStack->resetPossibleLoopCounter(); 6488 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6489 MarkDeclarationsReferencedInExpr( 6490 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6491 Var->getType().getNonLValueExprType(Context), 6492 ForLoc, /*RefersToCapture=*/true)); 6493 } 6494 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6495 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6496 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6497 // associated for-loop of a simd construct with just one associated 6498 // for-loop may be listed in a linear clause with a constant-linear-step 6499 // that is the increment of the associated for-loop. The loop iteration 6500 // variable(s) in the associated for-loop(s) of a for or parallel for 6501 // construct may be listed in a private or lastprivate clause. 6502 DSAStackTy::DSAVarData DVar = 6503 DSAStack->getTopDSA(D, /*FromParent=*/false); 6504 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6505 // is declared in the loop and it is predetermined as a private. 6506 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6507 OpenMPClauseKind PredeterminedCKind = 6508 isOpenMPSimdDirective(DKind) 6509 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6510 : OMPC_private; 6511 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6512 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6513 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6514 DVar.CKind != OMPC_private))) || 6515 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6516 DKind == OMPD_master_taskloop || 6517 DKind == OMPD_parallel_master_taskloop || 6518 isOpenMPDistributeDirective(DKind)) && 6519 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6520 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6521 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6522 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6523 << getOpenMPClauseName(DVar.CKind) 6524 << getOpenMPDirectiveName(DKind) 6525 << getOpenMPClauseName(PredeterminedCKind); 6526 if (DVar.RefExpr == nullptr) 6527 DVar.CKind = PredeterminedCKind; 6528 reportOriginalDsa(*this, DSAStack, D, DVar, 6529 /*IsLoopIterVar=*/true); 6530 } else if (LoopDeclRefExpr) { 6531 // Make the loop iteration variable private (for worksharing 6532 // constructs), linear (for simd directives with the only one 6533 // associated loop) or lastprivate (for simd directives with several 6534 // collapsed or ordered loops). 6535 if (DVar.CKind == OMPC_unknown) 6536 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6537 PrivateRef); 6538 } 6539 } 6540 } 6541 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6542 } 6543 } 6544 6545 /// Called on a for stmt to check and extract its iteration space 6546 /// for further processing (such as collapsing). 6547 static bool checkOpenMPIterationSpace( 6548 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6549 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6550 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6551 Expr *OrderedLoopCountExpr, 6552 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6553 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6554 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6555 // OpenMP [2.9.1, Canonical Loop Form] 6556 // for (init-expr; test-expr; incr-expr) structured-block 6557 // for (range-decl: range-expr) structured-block 6558 auto *For = dyn_cast_or_null<ForStmt>(S); 6559 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6560 // Ranged for is supported only in OpenMP 5.0. 6561 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6562 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6563 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6564 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6565 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6566 if (TotalNestedLoopCount > 1) { 6567 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6568 SemaRef.Diag(DSA.getConstructLoc(), 6569 diag::note_omp_collapse_ordered_expr) 6570 << 2 << CollapseLoopCountExpr->getSourceRange() 6571 << OrderedLoopCountExpr->getSourceRange(); 6572 else if (CollapseLoopCountExpr) 6573 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6574 diag::note_omp_collapse_ordered_expr) 6575 << 0 << CollapseLoopCountExpr->getSourceRange(); 6576 else 6577 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6578 diag::note_omp_collapse_ordered_expr) 6579 << 1 << OrderedLoopCountExpr->getSourceRange(); 6580 } 6581 return true; 6582 } 6583 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6584 "No loop body."); 6585 6586 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6587 For ? For->getForLoc() : CXXFor->getForLoc()); 6588 6589 // Check init. 6590 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6591 if (ISC.checkAndSetInit(Init)) 6592 return true; 6593 6594 bool HasErrors = false; 6595 6596 // Check loop variable's type. 6597 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6598 // OpenMP [2.6, Canonical Loop Form] 6599 // Var is one of the following: 6600 // A variable of signed or unsigned integer type. 6601 // For C++, a variable of a random access iterator type. 6602 // For C, a variable of a pointer type. 6603 QualType VarType = LCDecl->getType().getNonReferenceType(); 6604 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6605 !VarType->isPointerType() && 6606 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6607 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6608 << SemaRef.getLangOpts().CPlusPlus; 6609 HasErrors = true; 6610 } 6611 6612 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6613 // a Construct 6614 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6615 // parallel for construct is (are) private. 6616 // The loop iteration variable in the associated for-loop of a simd 6617 // construct with just one associated for-loop is linear with a 6618 // constant-linear-step that is the increment of the associated for-loop. 6619 // Exclude loop var from the list of variables with implicitly defined data 6620 // sharing attributes. 6621 VarsWithImplicitDSA.erase(LCDecl); 6622 6623 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6624 6625 // Check test-expr. 6626 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6627 6628 // Check incr-expr. 6629 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6630 } 6631 6632 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6633 return HasErrors; 6634 6635 // Build the loop's iteration space representation. 6636 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6637 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6638 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6639 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6640 (isOpenMPWorksharingDirective(DKind) || 6641 isOpenMPTaskLoopDirective(DKind) || 6642 isOpenMPDistributeDirective(DKind)), 6643 Captures); 6644 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6645 ISC.buildCounterVar(Captures, DSA); 6646 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6647 ISC.buildPrivateCounterVar(); 6648 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6649 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6650 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6651 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6652 ISC.getConditionSrcRange(); 6653 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6654 ISC.getIncrementSrcRange(); 6655 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6656 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6657 ISC.isStrictTestOp(); 6658 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6659 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6660 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6661 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6662 ISC.buildFinalCondition(DSA.getCurScope()); 6663 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6664 ISC.doesInitDependOnLC(); 6665 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6666 ISC.doesCondDependOnLC(); 6667 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6668 ISC.getLoopDependentIdx(); 6669 6670 HasErrors |= 6671 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6672 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6673 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6674 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6675 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6676 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6677 if (!HasErrors && DSA.isOrderedRegion()) { 6678 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6679 if (CurrentNestedLoopCount < 6680 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6681 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6682 CurrentNestedLoopCount, 6683 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6684 DSA.getOrderedRegionParam().second->setLoopCounter( 6685 CurrentNestedLoopCount, 6686 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6687 } 6688 } 6689 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6690 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6691 // Erroneous case - clause has some problems. 6692 continue; 6693 } 6694 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6695 Pair.second.size() <= CurrentNestedLoopCount) { 6696 // Erroneous case - clause has some problems. 6697 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6698 continue; 6699 } 6700 Expr *CntValue; 6701 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6702 CntValue = ISC.buildOrderedLoopData( 6703 DSA.getCurScope(), 6704 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6705 Pair.first->getDependencyLoc()); 6706 else 6707 CntValue = ISC.buildOrderedLoopData( 6708 DSA.getCurScope(), 6709 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6710 Pair.first->getDependencyLoc(), 6711 Pair.second[CurrentNestedLoopCount].first, 6712 Pair.second[CurrentNestedLoopCount].second); 6713 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6714 } 6715 } 6716 6717 return HasErrors; 6718 } 6719 6720 /// Build 'VarRef = Start. 6721 static ExprResult 6722 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6723 ExprResult Start, bool IsNonRectangularLB, 6724 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6725 // Build 'VarRef = Start. 6726 ExprResult NewStart = IsNonRectangularLB 6727 ? Start.get() 6728 : tryBuildCapture(SemaRef, Start.get(), Captures); 6729 if (!NewStart.isUsable()) 6730 return ExprError(); 6731 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6732 VarRef.get()->getType())) { 6733 NewStart = SemaRef.PerformImplicitConversion( 6734 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6735 /*AllowExplicit=*/true); 6736 if (!NewStart.isUsable()) 6737 return ExprError(); 6738 } 6739 6740 ExprResult Init = 6741 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6742 return Init; 6743 } 6744 6745 /// Build 'VarRef = Start + Iter * Step'. 6746 static ExprResult buildCounterUpdate( 6747 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6748 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6749 bool IsNonRectangularLB, 6750 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6751 // Add parentheses (for debugging purposes only). 6752 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6753 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6754 !Step.isUsable()) 6755 return ExprError(); 6756 6757 ExprResult NewStep = Step; 6758 if (Captures) 6759 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6760 if (NewStep.isInvalid()) 6761 return ExprError(); 6762 ExprResult Update = 6763 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6764 if (!Update.isUsable()) 6765 return ExprError(); 6766 6767 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6768 // 'VarRef = Start (+|-) Iter * Step'. 6769 if (!Start.isUsable()) 6770 return ExprError(); 6771 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6772 if (!NewStart.isUsable()) 6773 return ExprError(); 6774 if (Captures && !IsNonRectangularLB) 6775 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6776 if (NewStart.isInvalid()) 6777 return ExprError(); 6778 6779 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6780 ExprResult SavedUpdate = Update; 6781 ExprResult UpdateVal; 6782 if (VarRef.get()->getType()->isOverloadableType() || 6783 NewStart.get()->getType()->isOverloadableType() || 6784 Update.get()->getType()->isOverloadableType()) { 6785 Sema::TentativeAnalysisScope Trap(SemaRef); 6786 6787 Update = 6788 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6789 if (Update.isUsable()) { 6790 UpdateVal = 6791 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6792 VarRef.get(), SavedUpdate.get()); 6793 if (UpdateVal.isUsable()) { 6794 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6795 UpdateVal.get()); 6796 } 6797 } 6798 } 6799 6800 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6801 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6802 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6803 NewStart.get(), SavedUpdate.get()); 6804 if (!Update.isUsable()) 6805 return ExprError(); 6806 6807 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6808 VarRef.get()->getType())) { 6809 Update = SemaRef.PerformImplicitConversion( 6810 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6811 if (!Update.isUsable()) 6812 return ExprError(); 6813 } 6814 6815 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6816 } 6817 return Update; 6818 } 6819 6820 /// Convert integer expression \a E to make it have at least \a Bits 6821 /// bits. 6822 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6823 if (E == nullptr) 6824 return ExprError(); 6825 ASTContext &C = SemaRef.Context; 6826 QualType OldType = E->getType(); 6827 unsigned HasBits = C.getTypeSize(OldType); 6828 if (HasBits >= Bits) 6829 return ExprResult(E); 6830 // OK to convert to signed, because new type has more bits than old. 6831 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6832 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6833 true); 6834 } 6835 6836 /// Check if the given expression \a E is a constant integer that fits 6837 /// into \a Bits bits. 6838 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6839 if (E == nullptr) 6840 return false; 6841 llvm::APSInt Result; 6842 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6843 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6844 return false; 6845 } 6846 6847 /// Build preinits statement for the given declarations. 6848 static Stmt *buildPreInits(ASTContext &Context, 6849 MutableArrayRef<Decl *> PreInits) { 6850 if (!PreInits.empty()) { 6851 return new (Context) DeclStmt( 6852 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6853 SourceLocation(), SourceLocation()); 6854 } 6855 return nullptr; 6856 } 6857 6858 /// Build preinits statement for the given declarations. 6859 static Stmt * 6860 buildPreInits(ASTContext &Context, 6861 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6862 if (!Captures.empty()) { 6863 SmallVector<Decl *, 16> PreInits; 6864 for (const auto &Pair : Captures) 6865 PreInits.push_back(Pair.second->getDecl()); 6866 return buildPreInits(Context, PreInits); 6867 } 6868 return nullptr; 6869 } 6870 6871 /// Build postupdate expression for the given list of postupdates expressions. 6872 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6873 Expr *PostUpdate = nullptr; 6874 if (!PostUpdates.empty()) { 6875 for (Expr *E : PostUpdates) { 6876 Expr *ConvE = S.BuildCStyleCastExpr( 6877 E->getExprLoc(), 6878 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6879 E->getExprLoc(), E) 6880 .get(); 6881 PostUpdate = PostUpdate 6882 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6883 PostUpdate, ConvE) 6884 .get() 6885 : ConvE; 6886 } 6887 } 6888 return PostUpdate; 6889 } 6890 6891 /// Called on a for stmt to check itself and nested loops (if any). 6892 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6893 /// number of collapsed loops otherwise. 6894 static unsigned 6895 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6896 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6897 DSAStackTy &DSA, 6898 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6899 OMPLoopDirective::HelperExprs &Built) { 6900 unsigned NestedLoopCount = 1; 6901 if (CollapseLoopCountExpr) { 6902 // Found 'collapse' clause - calculate collapse number. 6903 Expr::EvalResult Result; 6904 if (!CollapseLoopCountExpr->isValueDependent() && 6905 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6906 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6907 } else { 6908 Built.clear(/*Size=*/1); 6909 return 1; 6910 } 6911 } 6912 unsigned OrderedLoopCount = 1; 6913 if (OrderedLoopCountExpr) { 6914 // Found 'ordered' clause - calculate collapse number. 6915 Expr::EvalResult EVResult; 6916 if (!OrderedLoopCountExpr->isValueDependent() && 6917 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6918 SemaRef.getASTContext())) { 6919 llvm::APSInt Result = EVResult.Val.getInt(); 6920 if (Result.getLimitedValue() < NestedLoopCount) { 6921 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6922 diag::err_omp_wrong_ordered_loop_count) 6923 << OrderedLoopCountExpr->getSourceRange(); 6924 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6925 diag::note_collapse_loop_count) 6926 << CollapseLoopCountExpr->getSourceRange(); 6927 } 6928 OrderedLoopCount = Result.getLimitedValue(); 6929 } else { 6930 Built.clear(/*Size=*/1); 6931 return 1; 6932 } 6933 } 6934 // This is helper routine for loop directives (e.g., 'for', 'simd', 6935 // 'for simd', etc.). 6936 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6937 SmallVector<LoopIterationSpace, 4> IterSpaces( 6938 std::max(OrderedLoopCount, NestedLoopCount)); 6939 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6940 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6941 if (checkOpenMPIterationSpace( 6942 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6943 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6944 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6945 return 0; 6946 // Move on to the next nested for loop, or to the loop body. 6947 // OpenMP [2.8.1, simd construct, Restrictions] 6948 // All loops associated with the construct must be perfectly nested; that 6949 // is, there must be no intervening code nor any OpenMP directive between 6950 // any two loops. 6951 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6952 CurStmt = For->getBody(); 6953 } else { 6954 assert(isa<CXXForRangeStmt>(CurStmt) && 6955 "Expected canonical for or range-based for loops."); 6956 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6957 } 6958 CurStmt = CurStmt->IgnoreContainers(); 6959 } 6960 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6961 if (checkOpenMPIterationSpace( 6962 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6963 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6964 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6965 return 0; 6966 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6967 // Handle initialization of captured loop iterator variables. 6968 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6969 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6970 Captures[DRE] = DRE; 6971 } 6972 } 6973 // Move on to the next nested for loop, or to the loop body. 6974 // OpenMP [2.8.1, simd construct, Restrictions] 6975 // All loops associated with the construct must be perfectly nested; that 6976 // is, there must be no intervening code nor any OpenMP directive between 6977 // any two loops. 6978 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6979 CurStmt = For->getBody(); 6980 } else { 6981 assert(isa<CXXForRangeStmt>(CurStmt) && 6982 "Expected canonical for or range-based for loops."); 6983 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6984 } 6985 CurStmt = CurStmt->IgnoreContainers(); 6986 } 6987 6988 Built.clear(/* size */ NestedLoopCount); 6989 6990 if (SemaRef.CurContext->isDependentContext()) 6991 return NestedLoopCount; 6992 6993 // An example of what is generated for the following code: 6994 // 6995 // #pragma omp simd collapse(2) ordered(2) 6996 // for (i = 0; i < NI; ++i) 6997 // for (k = 0; k < NK; ++k) 6998 // for (j = J0; j < NJ; j+=2) { 6999 // <loop body> 7000 // } 7001 // 7002 // We generate the code below. 7003 // Note: the loop body may be outlined in CodeGen. 7004 // Note: some counters may be C++ classes, operator- is used to find number of 7005 // iterations and operator+= to calculate counter value. 7006 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7007 // or i64 is currently supported). 7008 // 7009 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7010 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7011 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7012 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7013 // // similar updates for vars in clauses (e.g. 'linear') 7014 // <loop body (using local i and j)> 7015 // } 7016 // i = NI; // assign final values of counters 7017 // j = NJ; 7018 // 7019 7020 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7021 // the iteration counts of the collapsed for loops. 7022 // Precondition tests if there is at least one iteration (all conditions are 7023 // true). 7024 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7025 Expr *N0 = IterSpaces[0].NumIterations; 7026 ExprResult LastIteration32 = 7027 widenIterationCount(/*Bits=*/32, 7028 SemaRef 7029 .PerformImplicitConversion( 7030 N0->IgnoreImpCasts(), N0->getType(), 7031 Sema::AA_Converting, /*AllowExplicit=*/true) 7032 .get(), 7033 SemaRef); 7034 ExprResult LastIteration64 = widenIterationCount( 7035 /*Bits=*/64, 7036 SemaRef 7037 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7038 Sema::AA_Converting, 7039 /*AllowExplicit=*/true) 7040 .get(), 7041 SemaRef); 7042 7043 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7044 return NestedLoopCount; 7045 7046 ASTContext &C = SemaRef.Context; 7047 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7048 7049 Scope *CurScope = DSA.getCurScope(); 7050 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7051 if (PreCond.isUsable()) { 7052 PreCond = 7053 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7054 PreCond.get(), IterSpaces[Cnt].PreCond); 7055 } 7056 Expr *N = IterSpaces[Cnt].NumIterations; 7057 SourceLocation Loc = N->getExprLoc(); 7058 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7059 if (LastIteration32.isUsable()) 7060 LastIteration32 = SemaRef.BuildBinOp( 7061 CurScope, Loc, BO_Mul, LastIteration32.get(), 7062 SemaRef 7063 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7064 Sema::AA_Converting, 7065 /*AllowExplicit=*/true) 7066 .get()); 7067 if (LastIteration64.isUsable()) 7068 LastIteration64 = SemaRef.BuildBinOp( 7069 CurScope, Loc, BO_Mul, LastIteration64.get(), 7070 SemaRef 7071 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7072 Sema::AA_Converting, 7073 /*AllowExplicit=*/true) 7074 .get()); 7075 } 7076 7077 // Choose either the 32-bit or 64-bit version. 7078 ExprResult LastIteration = LastIteration64; 7079 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7080 (LastIteration32.isUsable() && 7081 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7082 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7083 fitsInto( 7084 /*Bits=*/32, 7085 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7086 LastIteration64.get(), SemaRef)))) 7087 LastIteration = LastIteration32; 7088 QualType VType = LastIteration.get()->getType(); 7089 QualType RealVType = VType; 7090 QualType StrideVType = VType; 7091 if (isOpenMPTaskLoopDirective(DKind)) { 7092 VType = 7093 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7094 StrideVType = 7095 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7096 } 7097 7098 if (!LastIteration.isUsable()) 7099 return 0; 7100 7101 // Save the number of iterations. 7102 ExprResult NumIterations = LastIteration; 7103 { 7104 LastIteration = SemaRef.BuildBinOp( 7105 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7106 LastIteration.get(), 7107 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7108 if (!LastIteration.isUsable()) 7109 return 0; 7110 } 7111 7112 // Calculate the last iteration number beforehand instead of doing this on 7113 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7114 llvm::APSInt Result; 7115 bool IsConstant = 7116 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7117 ExprResult CalcLastIteration; 7118 if (!IsConstant) { 7119 ExprResult SaveRef = 7120 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7121 LastIteration = SaveRef; 7122 7123 // Prepare SaveRef + 1. 7124 NumIterations = SemaRef.BuildBinOp( 7125 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7126 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7127 if (!NumIterations.isUsable()) 7128 return 0; 7129 } 7130 7131 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7132 7133 // Build variables passed into runtime, necessary for worksharing directives. 7134 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7135 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7136 isOpenMPDistributeDirective(DKind)) { 7137 // Lower bound variable, initialized with zero. 7138 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7139 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7140 SemaRef.AddInitializerToDecl(LBDecl, 7141 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7142 /*DirectInit*/ false); 7143 7144 // Upper bound variable, initialized with last iteration number. 7145 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7146 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7147 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7148 /*DirectInit*/ false); 7149 7150 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7151 // This will be used to implement clause 'lastprivate'. 7152 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7153 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7154 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7155 SemaRef.AddInitializerToDecl(ILDecl, 7156 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7157 /*DirectInit*/ false); 7158 7159 // Stride variable returned by runtime (we initialize it to 1 by default). 7160 VarDecl *STDecl = 7161 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7162 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7163 SemaRef.AddInitializerToDecl(STDecl, 7164 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7165 /*DirectInit*/ false); 7166 7167 // Build expression: UB = min(UB, LastIteration) 7168 // It is necessary for CodeGen of directives with static scheduling. 7169 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7170 UB.get(), LastIteration.get()); 7171 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7172 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7173 LastIteration.get(), UB.get()); 7174 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7175 CondOp.get()); 7176 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7177 7178 // If we have a combined directive that combines 'distribute', 'for' or 7179 // 'simd' we need to be able to access the bounds of the schedule of the 7180 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7181 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7182 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7183 // Lower bound variable, initialized with zero. 7184 VarDecl *CombLBDecl = 7185 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7186 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7187 SemaRef.AddInitializerToDecl( 7188 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7189 /*DirectInit*/ false); 7190 7191 // Upper bound variable, initialized with last iteration number. 7192 VarDecl *CombUBDecl = 7193 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7194 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7195 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7196 /*DirectInit*/ false); 7197 7198 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7199 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7200 ExprResult CombCondOp = 7201 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7202 LastIteration.get(), CombUB.get()); 7203 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7204 CombCondOp.get()); 7205 CombEUB = 7206 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7207 7208 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7209 // We expect to have at least 2 more parameters than the 'parallel' 7210 // directive does - the lower and upper bounds of the previous schedule. 7211 assert(CD->getNumParams() >= 4 && 7212 "Unexpected number of parameters in loop combined directive"); 7213 7214 // Set the proper type for the bounds given what we learned from the 7215 // enclosed loops. 7216 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7217 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7218 7219 // Previous lower and upper bounds are obtained from the region 7220 // parameters. 7221 PrevLB = 7222 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7223 PrevUB = 7224 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7225 } 7226 } 7227 7228 // Build the iteration variable and its initialization before loop. 7229 ExprResult IV; 7230 ExprResult Init, CombInit; 7231 { 7232 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7233 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7234 Expr *RHS = 7235 (isOpenMPWorksharingDirective(DKind) || 7236 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7237 ? LB.get() 7238 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7239 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7240 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7241 7242 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7243 Expr *CombRHS = 7244 (isOpenMPWorksharingDirective(DKind) || 7245 isOpenMPTaskLoopDirective(DKind) || 7246 isOpenMPDistributeDirective(DKind)) 7247 ? CombLB.get() 7248 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7249 CombInit = 7250 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7251 CombInit = 7252 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7253 } 7254 } 7255 7256 bool UseStrictCompare = 7257 RealVType->hasUnsignedIntegerRepresentation() && 7258 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7259 return LIS.IsStrictCompare; 7260 }); 7261 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7262 // unsigned IV)) for worksharing loops. 7263 SourceLocation CondLoc = AStmt->getBeginLoc(); 7264 Expr *BoundUB = UB.get(); 7265 if (UseStrictCompare) { 7266 BoundUB = 7267 SemaRef 7268 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7269 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7270 .get(); 7271 BoundUB = 7272 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7273 } 7274 ExprResult Cond = 7275 (isOpenMPWorksharingDirective(DKind) || 7276 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7277 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7278 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7279 BoundUB) 7280 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7281 NumIterations.get()); 7282 ExprResult CombDistCond; 7283 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7284 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7285 NumIterations.get()); 7286 } 7287 7288 ExprResult CombCond; 7289 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7290 Expr *BoundCombUB = CombUB.get(); 7291 if (UseStrictCompare) { 7292 BoundCombUB = 7293 SemaRef 7294 .BuildBinOp( 7295 CurScope, CondLoc, BO_Add, BoundCombUB, 7296 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7297 .get(); 7298 BoundCombUB = 7299 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7300 .get(); 7301 } 7302 CombCond = 7303 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7304 IV.get(), BoundCombUB); 7305 } 7306 // Loop increment (IV = IV + 1) 7307 SourceLocation IncLoc = AStmt->getBeginLoc(); 7308 ExprResult Inc = 7309 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7310 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7311 if (!Inc.isUsable()) 7312 return 0; 7313 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7314 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7315 if (!Inc.isUsable()) 7316 return 0; 7317 7318 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7319 // Used for directives with static scheduling. 7320 // In combined construct, add combined version that use CombLB and CombUB 7321 // base variables for the update 7322 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7323 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7324 isOpenMPDistributeDirective(DKind)) { 7325 // LB + ST 7326 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7327 if (!NextLB.isUsable()) 7328 return 0; 7329 // LB = LB + ST 7330 NextLB = 7331 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7332 NextLB = 7333 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7334 if (!NextLB.isUsable()) 7335 return 0; 7336 // UB + ST 7337 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7338 if (!NextUB.isUsable()) 7339 return 0; 7340 // UB = UB + ST 7341 NextUB = 7342 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7343 NextUB = 7344 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7345 if (!NextUB.isUsable()) 7346 return 0; 7347 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7348 CombNextLB = 7349 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7350 if (!NextLB.isUsable()) 7351 return 0; 7352 // LB = LB + ST 7353 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7354 CombNextLB.get()); 7355 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7356 /*DiscardedValue*/ false); 7357 if (!CombNextLB.isUsable()) 7358 return 0; 7359 // UB + ST 7360 CombNextUB = 7361 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7362 if (!CombNextUB.isUsable()) 7363 return 0; 7364 // UB = UB + ST 7365 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7366 CombNextUB.get()); 7367 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7368 /*DiscardedValue*/ false); 7369 if (!CombNextUB.isUsable()) 7370 return 0; 7371 } 7372 } 7373 7374 // Create increment expression for distribute loop when combined in a same 7375 // directive with for as IV = IV + ST; ensure upper bound expression based 7376 // on PrevUB instead of NumIterations - used to implement 'for' when found 7377 // in combination with 'distribute', like in 'distribute parallel for' 7378 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7379 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7380 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7381 DistCond = SemaRef.BuildBinOp( 7382 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7383 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7384 7385 DistInc = 7386 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7387 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7388 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7389 DistInc.get()); 7390 DistInc = 7391 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7392 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7393 7394 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7395 // construct 7396 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7397 ExprResult IsUBGreater = 7398 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7399 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7400 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7401 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7402 CondOp.get()); 7403 PrevEUB = 7404 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7405 7406 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7407 // parallel for is in combination with a distribute directive with 7408 // schedule(static, 1) 7409 Expr *BoundPrevUB = PrevUB.get(); 7410 if (UseStrictCompare) { 7411 BoundPrevUB = 7412 SemaRef 7413 .BuildBinOp( 7414 CurScope, CondLoc, BO_Add, BoundPrevUB, 7415 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7416 .get(); 7417 BoundPrevUB = 7418 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7419 .get(); 7420 } 7421 ParForInDistCond = 7422 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7423 IV.get(), BoundPrevUB); 7424 } 7425 7426 // Build updates and final values of the loop counters. 7427 bool HasErrors = false; 7428 Built.Counters.resize(NestedLoopCount); 7429 Built.Inits.resize(NestedLoopCount); 7430 Built.Updates.resize(NestedLoopCount); 7431 Built.Finals.resize(NestedLoopCount); 7432 Built.DependentCounters.resize(NestedLoopCount); 7433 Built.DependentInits.resize(NestedLoopCount); 7434 Built.FinalsConditions.resize(NestedLoopCount); 7435 { 7436 // We implement the following algorithm for obtaining the 7437 // original loop iteration variable values based on the 7438 // value of the collapsed loop iteration variable IV. 7439 // 7440 // Let n+1 be the number of collapsed loops in the nest. 7441 // Iteration variables (I0, I1, .... In) 7442 // Iteration counts (N0, N1, ... Nn) 7443 // 7444 // Acc = IV; 7445 // 7446 // To compute Ik for loop k, 0 <= k <= n, generate: 7447 // Prod = N(k+1) * N(k+2) * ... * Nn; 7448 // Ik = Acc / Prod; 7449 // Acc -= Ik * Prod; 7450 // 7451 ExprResult Acc = IV; 7452 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7453 LoopIterationSpace &IS = IterSpaces[Cnt]; 7454 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7455 ExprResult Iter; 7456 7457 // Compute prod 7458 ExprResult Prod = 7459 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7460 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7461 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7462 IterSpaces[K].NumIterations); 7463 7464 // Iter = Acc / Prod 7465 // If there is at least one more inner loop to avoid 7466 // multiplication by 1. 7467 if (Cnt + 1 < NestedLoopCount) 7468 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7469 Acc.get(), Prod.get()); 7470 else 7471 Iter = Acc; 7472 if (!Iter.isUsable()) { 7473 HasErrors = true; 7474 break; 7475 } 7476 7477 // Update Acc: 7478 // Acc -= Iter * Prod 7479 // Check if there is at least one more inner loop to avoid 7480 // multiplication by 1. 7481 if (Cnt + 1 < NestedLoopCount) 7482 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7483 Iter.get(), Prod.get()); 7484 else 7485 Prod = Iter; 7486 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7487 Acc.get(), Prod.get()); 7488 7489 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7490 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7491 DeclRefExpr *CounterVar = buildDeclRefExpr( 7492 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7493 /*RefersToCapture=*/true); 7494 ExprResult Init = 7495 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7496 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7497 if (!Init.isUsable()) { 7498 HasErrors = true; 7499 break; 7500 } 7501 ExprResult Update = buildCounterUpdate( 7502 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7503 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7504 if (!Update.isUsable()) { 7505 HasErrors = true; 7506 break; 7507 } 7508 7509 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7510 ExprResult Final = 7511 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7512 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7513 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7514 if (!Final.isUsable()) { 7515 HasErrors = true; 7516 break; 7517 } 7518 7519 if (!Update.isUsable() || !Final.isUsable()) { 7520 HasErrors = true; 7521 break; 7522 } 7523 // Save results 7524 Built.Counters[Cnt] = IS.CounterVar; 7525 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7526 Built.Inits[Cnt] = Init.get(); 7527 Built.Updates[Cnt] = Update.get(); 7528 Built.Finals[Cnt] = Final.get(); 7529 Built.DependentCounters[Cnt] = nullptr; 7530 Built.DependentInits[Cnt] = nullptr; 7531 Built.FinalsConditions[Cnt] = nullptr; 7532 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7533 Built.DependentCounters[Cnt] = 7534 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7535 Built.DependentInits[Cnt] = 7536 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7537 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7538 } 7539 } 7540 } 7541 7542 if (HasErrors) 7543 return 0; 7544 7545 // Save results 7546 Built.IterationVarRef = IV.get(); 7547 Built.LastIteration = LastIteration.get(); 7548 Built.NumIterations = NumIterations.get(); 7549 Built.CalcLastIteration = SemaRef 7550 .ActOnFinishFullExpr(CalcLastIteration.get(), 7551 /*DiscardedValue=*/false) 7552 .get(); 7553 Built.PreCond = PreCond.get(); 7554 Built.PreInits = buildPreInits(C, Captures); 7555 Built.Cond = Cond.get(); 7556 Built.Init = Init.get(); 7557 Built.Inc = Inc.get(); 7558 Built.LB = LB.get(); 7559 Built.UB = UB.get(); 7560 Built.IL = IL.get(); 7561 Built.ST = ST.get(); 7562 Built.EUB = EUB.get(); 7563 Built.NLB = NextLB.get(); 7564 Built.NUB = NextUB.get(); 7565 Built.PrevLB = PrevLB.get(); 7566 Built.PrevUB = PrevUB.get(); 7567 Built.DistInc = DistInc.get(); 7568 Built.PrevEUB = PrevEUB.get(); 7569 Built.DistCombinedFields.LB = CombLB.get(); 7570 Built.DistCombinedFields.UB = CombUB.get(); 7571 Built.DistCombinedFields.EUB = CombEUB.get(); 7572 Built.DistCombinedFields.Init = CombInit.get(); 7573 Built.DistCombinedFields.Cond = CombCond.get(); 7574 Built.DistCombinedFields.NLB = CombNextLB.get(); 7575 Built.DistCombinedFields.NUB = CombNextUB.get(); 7576 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7577 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7578 7579 return NestedLoopCount; 7580 } 7581 7582 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7583 auto CollapseClauses = 7584 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7585 if (CollapseClauses.begin() != CollapseClauses.end()) 7586 return (*CollapseClauses.begin())->getNumForLoops(); 7587 return nullptr; 7588 } 7589 7590 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7591 auto OrderedClauses = 7592 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7593 if (OrderedClauses.begin() != OrderedClauses.end()) 7594 return (*OrderedClauses.begin())->getNumForLoops(); 7595 return nullptr; 7596 } 7597 7598 static bool checkSimdlenSafelenSpecified(Sema &S, 7599 const ArrayRef<OMPClause *> Clauses) { 7600 const OMPSafelenClause *Safelen = nullptr; 7601 const OMPSimdlenClause *Simdlen = nullptr; 7602 7603 for (const OMPClause *Clause : Clauses) { 7604 if (Clause->getClauseKind() == OMPC_safelen) 7605 Safelen = cast<OMPSafelenClause>(Clause); 7606 else if (Clause->getClauseKind() == OMPC_simdlen) 7607 Simdlen = cast<OMPSimdlenClause>(Clause); 7608 if (Safelen && Simdlen) 7609 break; 7610 } 7611 7612 if (Simdlen && Safelen) { 7613 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7614 const Expr *SafelenLength = Safelen->getSafelen(); 7615 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7616 SimdlenLength->isInstantiationDependent() || 7617 SimdlenLength->containsUnexpandedParameterPack()) 7618 return false; 7619 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7620 SafelenLength->isInstantiationDependent() || 7621 SafelenLength->containsUnexpandedParameterPack()) 7622 return false; 7623 Expr::EvalResult SimdlenResult, SafelenResult; 7624 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7625 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7626 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7627 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7628 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7629 // If both simdlen and safelen clauses are specified, the value of the 7630 // simdlen parameter must be less than or equal to the value of the safelen 7631 // parameter. 7632 if (SimdlenRes > SafelenRes) { 7633 S.Diag(SimdlenLength->getExprLoc(), 7634 diag::err_omp_wrong_simdlen_safelen_values) 7635 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7636 return true; 7637 } 7638 } 7639 return false; 7640 } 7641 7642 StmtResult 7643 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7644 SourceLocation StartLoc, SourceLocation EndLoc, 7645 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7646 if (!AStmt) 7647 return StmtError(); 7648 7649 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7650 OMPLoopDirective::HelperExprs B; 7651 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7652 // define the nested loops number. 7653 unsigned NestedLoopCount = checkOpenMPLoop( 7654 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7655 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7656 if (NestedLoopCount == 0) 7657 return StmtError(); 7658 7659 assert((CurContext->isDependentContext() || B.builtAll()) && 7660 "omp simd loop exprs were not built"); 7661 7662 if (!CurContext->isDependentContext()) { 7663 // Finalize the clauses that need pre-built expressions for CodeGen. 7664 for (OMPClause *C : Clauses) { 7665 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7666 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7667 B.NumIterations, *this, CurScope, 7668 DSAStack)) 7669 return StmtError(); 7670 } 7671 } 7672 7673 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7674 return StmtError(); 7675 7676 setFunctionHasBranchProtectedScope(); 7677 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7678 Clauses, AStmt, B); 7679 } 7680 7681 StmtResult 7682 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7683 SourceLocation StartLoc, SourceLocation EndLoc, 7684 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7685 if (!AStmt) 7686 return StmtError(); 7687 7688 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7689 OMPLoopDirective::HelperExprs B; 7690 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7691 // define the nested loops number. 7692 unsigned NestedLoopCount = checkOpenMPLoop( 7693 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7694 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7695 if (NestedLoopCount == 0) 7696 return StmtError(); 7697 7698 assert((CurContext->isDependentContext() || B.builtAll()) && 7699 "omp for loop exprs were not built"); 7700 7701 if (!CurContext->isDependentContext()) { 7702 // Finalize the clauses that need pre-built expressions for CodeGen. 7703 for (OMPClause *C : Clauses) { 7704 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7705 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7706 B.NumIterations, *this, CurScope, 7707 DSAStack)) 7708 return StmtError(); 7709 } 7710 } 7711 7712 setFunctionHasBranchProtectedScope(); 7713 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7714 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7715 } 7716 7717 StmtResult Sema::ActOnOpenMPForSimdDirective( 7718 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7719 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7720 if (!AStmt) 7721 return StmtError(); 7722 7723 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7724 OMPLoopDirective::HelperExprs B; 7725 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7726 // define the nested loops number. 7727 unsigned NestedLoopCount = 7728 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7729 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7730 VarsWithImplicitDSA, B); 7731 if (NestedLoopCount == 0) 7732 return StmtError(); 7733 7734 assert((CurContext->isDependentContext() || B.builtAll()) && 7735 "omp for simd loop exprs were not built"); 7736 7737 if (!CurContext->isDependentContext()) { 7738 // Finalize the clauses that need pre-built expressions for CodeGen. 7739 for (OMPClause *C : Clauses) { 7740 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7741 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7742 B.NumIterations, *this, CurScope, 7743 DSAStack)) 7744 return StmtError(); 7745 } 7746 } 7747 7748 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7749 return StmtError(); 7750 7751 setFunctionHasBranchProtectedScope(); 7752 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7753 Clauses, AStmt, B); 7754 } 7755 7756 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7757 Stmt *AStmt, 7758 SourceLocation StartLoc, 7759 SourceLocation EndLoc) { 7760 if (!AStmt) 7761 return StmtError(); 7762 7763 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7764 auto BaseStmt = AStmt; 7765 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7766 BaseStmt = CS->getCapturedStmt(); 7767 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7768 auto S = C->children(); 7769 if (S.begin() == S.end()) 7770 return StmtError(); 7771 // All associated statements must be '#pragma omp section' except for 7772 // the first one. 7773 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7774 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7775 if (SectionStmt) 7776 Diag(SectionStmt->getBeginLoc(), 7777 diag::err_omp_sections_substmt_not_section); 7778 return StmtError(); 7779 } 7780 cast<OMPSectionDirective>(SectionStmt) 7781 ->setHasCancel(DSAStack->isCancelRegion()); 7782 } 7783 } else { 7784 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7785 return StmtError(); 7786 } 7787 7788 setFunctionHasBranchProtectedScope(); 7789 7790 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7791 DSAStack->isCancelRegion()); 7792 } 7793 7794 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7795 SourceLocation StartLoc, 7796 SourceLocation EndLoc) { 7797 if (!AStmt) 7798 return StmtError(); 7799 7800 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7801 7802 setFunctionHasBranchProtectedScope(); 7803 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7804 7805 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7806 DSAStack->isCancelRegion()); 7807 } 7808 7809 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7810 Stmt *AStmt, 7811 SourceLocation StartLoc, 7812 SourceLocation EndLoc) { 7813 if (!AStmt) 7814 return StmtError(); 7815 7816 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7817 7818 setFunctionHasBranchProtectedScope(); 7819 7820 // OpenMP [2.7.3, single Construct, Restrictions] 7821 // The copyprivate clause must not be used with the nowait clause. 7822 const OMPClause *Nowait = nullptr; 7823 const OMPClause *Copyprivate = nullptr; 7824 for (const OMPClause *Clause : Clauses) { 7825 if (Clause->getClauseKind() == OMPC_nowait) 7826 Nowait = Clause; 7827 else if (Clause->getClauseKind() == OMPC_copyprivate) 7828 Copyprivate = Clause; 7829 if (Copyprivate && Nowait) { 7830 Diag(Copyprivate->getBeginLoc(), 7831 diag::err_omp_single_copyprivate_with_nowait); 7832 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7833 return StmtError(); 7834 } 7835 } 7836 7837 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7838 } 7839 7840 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7841 SourceLocation StartLoc, 7842 SourceLocation EndLoc) { 7843 if (!AStmt) 7844 return StmtError(); 7845 7846 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7847 7848 setFunctionHasBranchProtectedScope(); 7849 7850 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7851 } 7852 7853 StmtResult Sema::ActOnOpenMPCriticalDirective( 7854 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7855 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7856 if (!AStmt) 7857 return StmtError(); 7858 7859 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7860 7861 bool ErrorFound = false; 7862 llvm::APSInt Hint; 7863 SourceLocation HintLoc; 7864 bool DependentHint = false; 7865 for (const OMPClause *C : Clauses) { 7866 if (C->getClauseKind() == OMPC_hint) { 7867 if (!DirName.getName()) { 7868 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7869 ErrorFound = true; 7870 } 7871 Expr *E = cast<OMPHintClause>(C)->getHint(); 7872 if (E->isTypeDependent() || E->isValueDependent() || 7873 E->isInstantiationDependent()) { 7874 DependentHint = true; 7875 } else { 7876 Hint = E->EvaluateKnownConstInt(Context); 7877 HintLoc = C->getBeginLoc(); 7878 } 7879 } 7880 } 7881 if (ErrorFound) 7882 return StmtError(); 7883 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7884 if (Pair.first && DirName.getName() && !DependentHint) { 7885 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7886 Diag(StartLoc, diag::err_omp_critical_with_hint); 7887 if (HintLoc.isValid()) 7888 Diag(HintLoc, diag::note_omp_critical_hint_here) 7889 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7890 else 7891 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7892 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7893 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7894 << 1 7895 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7896 /*Radix=*/10, /*Signed=*/false); 7897 } else { 7898 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7899 } 7900 } 7901 } 7902 7903 setFunctionHasBranchProtectedScope(); 7904 7905 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7906 Clauses, AStmt); 7907 if (!Pair.first && DirName.getName() && !DependentHint) 7908 DSAStack->addCriticalWithHint(Dir, Hint); 7909 return Dir; 7910 } 7911 7912 StmtResult Sema::ActOnOpenMPParallelForDirective( 7913 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7914 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7915 if (!AStmt) 7916 return StmtError(); 7917 7918 auto *CS = cast<CapturedStmt>(AStmt); 7919 // 1.2.2 OpenMP Language Terminology 7920 // Structured block - An executable statement with a single entry at the 7921 // top and a single exit at the bottom. 7922 // The point of exit cannot be a branch out of the structured block. 7923 // longjmp() and throw() must not violate the entry/exit criteria. 7924 CS->getCapturedDecl()->setNothrow(); 7925 7926 OMPLoopDirective::HelperExprs B; 7927 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7928 // define the nested loops number. 7929 unsigned NestedLoopCount = 7930 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7931 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7932 VarsWithImplicitDSA, B); 7933 if (NestedLoopCount == 0) 7934 return StmtError(); 7935 7936 assert((CurContext->isDependentContext() || B.builtAll()) && 7937 "omp parallel for loop exprs were not built"); 7938 7939 if (!CurContext->isDependentContext()) { 7940 // Finalize the clauses that need pre-built expressions for CodeGen. 7941 for (OMPClause *C : Clauses) { 7942 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7943 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7944 B.NumIterations, *this, CurScope, 7945 DSAStack)) 7946 return StmtError(); 7947 } 7948 } 7949 7950 setFunctionHasBranchProtectedScope(); 7951 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7952 NestedLoopCount, Clauses, AStmt, B, 7953 DSAStack->isCancelRegion()); 7954 } 7955 7956 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7957 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7958 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7959 if (!AStmt) 7960 return StmtError(); 7961 7962 auto *CS = cast<CapturedStmt>(AStmt); 7963 // 1.2.2 OpenMP Language Terminology 7964 // Structured block - An executable statement with a single entry at the 7965 // top and a single exit at the bottom. 7966 // The point of exit cannot be a branch out of the structured block. 7967 // longjmp() and throw() must not violate the entry/exit criteria. 7968 CS->getCapturedDecl()->setNothrow(); 7969 7970 OMPLoopDirective::HelperExprs B; 7971 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7972 // define the nested loops number. 7973 unsigned NestedLoopCount = 7974 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7975 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7976 VarsWithImplicitDSA, B); 7977 if (NestedLoopCount == 0) 7978 return StmtError(); 7979 7980 if (!CurContext->isDependentContext()) { 7981 // Finalize the clauses that need pre-built expressions for CodeGen. 7982 for (OMPClause *C : Clauses) { 7983 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7984 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7985 B.NumIterations, *this, CurScope, 7986 DSAStack)) 7987 return StmtError(); 7988 } 7989 } 7990 7991 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7992 return StmtError(); 7993 7994 setFunctionHasBranchProtectedScope(); 7995 return OMPParallelForSimdDirective::Create( 7996 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7997 } 7998 7999 StmtResult 8000 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8001 Stmt *AStmt, SourceLocation StartLoc, 8002 SourceLocation EndLoc) { 8003 if (!AStmt) 8004 return StmtError(); 8005 8006 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8007 auto BaseStmt = AStmt; 8008 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8009 BaseStmt = CS->getCapturedStmt(); 8010 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8011 auto S = C->children(); 8012 if (S.begin() == S.end()) 8013 return StmtError(); 8014 // All associated statements must be '#pragma omp section' except for 8015 // the first one. 8016 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8017 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8018 if (SectionStmt) 8019 Diag(SectionStmt->getBeginLoc(), 8020 diag::err_omp_parallel_sections_substmt_not_section); 8021 return StmtError(); 8022 } 8023 cast<OMPSectionDirective>(SectionStmt) 8024 ->setHasCancel(DSAStack->isCancelRegion()); 8025 } 8026 } else { 8027 Diag(AStmt->getBeginLoc(), 8028 diag::err_omp_parallel_sections_not_compound_stmt); 8029 return StmtError(); 8030 } 8031 8032 setFunctionHasBranchProtectedScope(); 8033 8034 return OMPParallelSectionsDirective::Create( 8035 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8036 } 8037 8038 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8039 Stmt *AStmt, SourceLocation StartLoc, 8040 SourceLocation EndLoc) { 8041 if (!AStmt) 8042 return StmtError(); 8043 8044 auto *CS = cast<CapturedStmt>(AStmt); 8045 // 1.2.2 OpenMP Language Terminology 8046 // Structured block - An executable statement with a single entry at the 8047 // top and a single exit at the bottom. 8048 // The point of exit cannot be a branch out of the structured block. 8049 // longjmp() and throw() must not violate the entry/exit criteria. 8050 CS->getCapturedDecl()->setNothrow(); 8051 8052 setFunctionHasBranchProtectedScope(); 8053 8054 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8055 DSAStack->isCancelRegion()); 8056 } 8057 8058 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8059 SourceLocation EndLoc) { 8060 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8061 } 8062 8063 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8064 SourceLocation EndLoc) { 8065 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8066 } 8067 8068 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8069 SourceLocation EndLoc) { 8070 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8071 } 8072 8073 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8074 Stmt *AStmt, 8075 SourceLocation StartLoc, 8076 SourceLocation EndLoc) { 8077 if (!AStmt) 8078 return StmtError(); 8079 8080 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8081 8082 setFunctionHasBranchProtectedScope(); 8083 8084 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8085 AStmt, 8086 DSAStack->getTaskgroupReductionRef()); 8087 } 8088 8089 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8090 SourceLocation StartLoc, 8091 SourceLocation EndLoc) { 8092 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8093 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8094 } 8095 8096 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8097 Stmt *AStmt, 8098 SourceLocation StartLoc, 8099 SourceLocation EndLoc) { 8100 const OMPClause *DependFound = nullptr; 8101 const OMPClause *DependSourceClause = nullptr; 8102 const OMPClause *DependSinkClause = nullptr; 8103 bool ErrorFound = false; 8104 const OMPThreadsClause *TC = nullptr; 8105 const OMPSIMDClause *SC = nullptr; 8106 for (const OMPClause *C : Clauses) { 8107 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8108 DependFound = C; 8109 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8110 if (DependSourceClause) { 8111 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8112 << getOpenMPDirectiveName(OMPD_ordered) 8113 << getOpenMPClauseName(OMPC_depend) << 2; 8114 ErrorFound = true; 8115 } else { 8116 DependSourceClause = C; 8117 } 8118 if (DependSinkClause) { 8119 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8120 << 0; 8121 ErrorFound = true; 8122 } 8123 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8124 if (DependSourceClause) { 8125 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8126 << 1; 8127 ErrorFound = true; 8128 } 8129 DependSinkClause = C; 8130 } 8131 } else if (C->getClauseKind() == OMPC_threads) { 8132 TC = cast<OMPThreadsClause>(C); 8133 } else if (C->getClauseKind() == OMPC_simd) { 8134 SC = cast<OMPSIMDClause>(C); 8135 } 8136 } 8137 if (!ErrorFound && !SC && 8138 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8139 // OpenMP [2.8.1,simd Construct, Restrictions] 8140 // An ordered construct with the simd clause is the only OpenMP construct 8141 // that can appear in the simd region. 8142 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 8143 ErrorFound = true; 8144 } else if (DependFound && (TC || SC)) { 8145 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8146 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8147 ErrorFound = true; 8148 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8149 Diag(DependFound->getBeginLoc(), 8150 diag::err_omp_ordered_directive_without_param); 8151 ErrorFound = true; 8152 } else if (TC || Clauses.empty()) { 8153 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8154 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8155 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8156 << (TC != nullptr); 8157 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8158 ErrorFound = true; 8159 } 8160 } 8161 if ((!AStmt && !DependFound) || ErrorFound) 8162 return StmtError(); 8163 8164 if (AStmt) { 8165 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8166 8167 setFunctionHasBranchProtectedScope(); 8168 } 8169 8170 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8171 } 8172 8173 namespace { 8174 /// Helper class for checking expression in 'omp atomic [update]' 8175 /// construct. 8176 class OpenMPAtomicUpdateChecker { 8177 /// Error results for atomic update expressions. 8178 enum ExprAnalysisErrorCode { 8179 /// A statement is not an expression statement. 8180 NotAnExpression, 8181 /// Expression is not builtin binary or unary operation. 8182 NotABinaryOrUnaryExpression, 8183 /// Unary operation is not post-/pre- increment/decrement operation. 8184 NotAnUnaryIncDecExpression, 8185 /// An expression is not of scalar type. 8186 NotAScalarType, 8187 /// A binary operation is not an assignment operation. 8188 NotAnAssignmentOp, 8189 /// RHS part of the binary operation is not a binary expression. 8190 NotABinaryExpression, 8191 /// RHS part is not additive/multiplicative/shift/biwise binary 8192 /// expression. 8193 NotABinaryOperator, 8194 /// RHS binary operation does not have reference to the updated LHS 8195 /// part. 8196 NotAnUpdateExpression, 8197 /// No errors is found. 8198 NoError 8199 }; 8200 /// Reference to Sema. 8201 Sema &SemaRef; 8202 /// A location for note diagnostics (when error is found). 8203 SourceLocation NoteLoc; 8204 /// 'x' lvalue part of the source atomic expression. 8205 Expr *X; 8206 /// 'expr' rvalue part of the source atomic expression. 8207 Expr *E; 8208 /// Helper expression of the form 8209 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8210 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8211 Expr *UpdateExpr; 8212 /// Is 'x' a LHS in a RHS part of full update expression. It is 8213 /// important for non-associative operations. 8214 bool IsXLHSInRHSPart; 8215 BinaryOperatorKind Op; 8216 SourceLocation OpLoc; 8217 /// true if the source expression is a postfix unary operation, false 8218 /// if it is a prefix unary operation. 8219 bool IsPostfixUpdate; 8220 8221 public: 8222 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8223 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8224 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8225 /// Check specified statement that it is suitable for 'atomic update' 8226 /// constructs and extract 'x', 'expr' and Operation from the original 8227 /// expression. If DiagId and NoteId == 0, then only check is performed 8228 /// without error notification. 8229 /// \param DiagId Diagnostic which should be emitted if error is found. 8230 /// \param NoteId Diagnostic note for the main error message. 8231 /// \return true if statement is not an update expression, false otherwise. 8232 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8233 /// Return the 'x' lvalue part of the source atomic expression. 8234 Expr *getX() const { return X; } 8235 /// Return the 'expr' rvalue part of the source atomic expression. 8236 Expr *getExpr() const { return E; } 8237 /// Return the update expression used in calculation of the updated 8238 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8239 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8240 Expr *getUpdateExpr() const { return UpdateExpr; } 8241 /// Return true if 'x' is LHS in RHS part of full update expression, 8242 /// false otherwise. 8243 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8244 8245 /// true if the source expression is a postfix unary operation, false 8246 /// if it is a prefix unary operation. 8247 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8248 8249 private: 8250 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8251 unsigned NoteId = 0); 8252 }; 8253 } // namespace 8254 8255 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8256 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8257 ExprAnalysisErrorCode ErrorFound = NoError; 8258 SourceLocation ErrorLoc, NoteLoc; 8259 SourceRange ErrorRange, NoteRange; 8260 // Allowed constructs are: 8261 // x = x binop expr; 8262 // x = expr binop x; 8263 if (AtomicBinOp->getOpcode() == BO_Assign) { 8264 X = AtomicBinOp->getLHS(); 8265 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8266 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8267 if (AtomicInnerBinOp->isMultiplicativeOp() || 8268 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8269 AtomicInnerBinOp->isBitwiseOp()) { 8270 Op = AtomicInnerBinOp->getOpcode(); 8271 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8272 Expr *LHS = AtomicInnerBinOp->getLHS(); 8273 Expr *RHS = AtomicInnerBinOp->getRHS(); 8274 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8275 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8276 /*Canonical=*/true); 8277 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8278 /*Canonical=*/true); 8279 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8280 /*Canonical=*/true); 8281 if (XId == LHSId) { 8282 E = RHS; 8283 IsXLHSInRHSPart = true; 8284 } else if (XId == RHSId) { 8285 E = LHS; 8286 IsXLHSInRHSPart = false; 8287 } else { 8288 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8289 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8290 NoteLoc = X->getExprLoc(); 8291 NoteRange = X->getSourceRange(); 8292 ErrorFound = NotAnUpdateExpression; 8293 } 8294 } else { 8295 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8296 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8297 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8298 NoteRange = SourceRange(NoteLoc, NoteLoc); 8299 ErrorFound = NotABinaryOperator; 8300 } 8301 } else { 8302 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8303 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8304 ErrorFound = NotABinaryExpression; 8305 } 8306 } else { 8307 ErrorLoc = AtomicBinOp->getExprLoc(); 8308 ErrorRange = AtomicBinOp->getSourceRange(); 8309 NoteLoc = AtomicBinOp->getOperatorLoc(); 8310 NoteRange = SourceRange(NoteLoc, NoteLoc); 8311 ErrorFound = NotAnAssignmentOp; 8312 } 8313 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8314 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8315 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8316 return true; 8317 } 8318 if (SemaRef.CurContext->isDependentContext()) 8319 E = X = UpdateExpr = nullptr; 8320 return ErrorFound != NoError; 8321 } 8322 8323 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8324 unsigned NoteId) { 8325 ExprAnalysisErrorCode ErrorFound = NoError; 8326 SourceLocation ErrorLoc, NoteLoc; 8327 SourceRange ErrorRange, NoteRange; 8328 // Allowed constructs are: 8329 // x++; 8330 // x--; 8331 // ++x; 8332 // --x; 8333 // x binop= expr; 8334 // x = x binop expr; 8335 // x = expr binop x; 8336 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8337 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8338 if (AtomicBody->getType()->isScalarType() || 8339 AtomicBody->isInstantiationDependent()) { 8340 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8341 AtomicBody->IgnoreParenImpCasts())) { 8342 // Check for Compound Assignment Operation 8343 Op = BinaryOperator::getOpForCompoundAssignment( 8344 AtomicCompAssignOp->getOpcode()); 8345 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8346 E = AtomicCompAssignOp->getRHS(); 8347 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8348 IsXLHSInRHSPart = true; 8349 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8350 AtomicBody->IgnoreParenImpCasts())) { 8351 // Check for Binary Operation 8352 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8353 return true; 8354 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8355 AtomicBody->IgnoreParenImpCasts())) { 8356 // Check for Unary Operation 8357 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8358 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8359 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8360 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8361 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8362 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8363 IsXLHSInRHSPart = true; 8364 } else { 8365 ErrorFound = NotAnUnaryIncDecExpression; 8366 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8367 ErrorRange = AtomicUnaryOp->getSourceRange(); 8368 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8369 NoteRange = SourceRange(NoteLoc, NoteLoc); 8370 } 8371 } else if (!AtomicBody->isInstantiationDependent()) { 8372 ErrorFound = NotABinaryOrUnaryExpression; 8373 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8374 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8375 } 8376 } else { 8377 ErrorFound = NotAScalarType; 8378 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8379 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8380 } 8381 } else { 8382 ErrorFound = NotAnExpression; 8383 NoteLoc = ErrorLoc = S->getBeginLoc(); 8384 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8385 } 8386 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8387 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8388 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8389 return true; 8390 } 8391 if (SemaRef.CurContext->isDependentContext()) 8392 E = X = UpdateExpr = nullptr; 8393 if (ErrorFound == NoError && E && X) { 8394 // Build an update expression of form 'OpaqueValueExpr(x) binop 8395 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8396 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8397 auto *OVEX = new (SemaRef.getASTContext()) 8398 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8399 auto *OVEExpr = new (SemaRef.getASTContext()) 8400 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8401 ExprResult Update = 8402 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8403 IsXLHSInRHSPart ? OVEExpr : OVEX); 8404 if (Update.isInvalid()) 8405 return true; 8406 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8407 Sema::AA_Casting); 8408 if (Update.isInvalid()) 8409 return true; 8410 UpdateExpr = Update.get(); 8411 } 8412 return ErrorFound != NoError; 8413 } 8414 8415 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8416 Stmt *AStmt, 8417 SourceLocation StartLoc, 8418 SourceLocation EndLoc) { 8419 if (!AStmt) 8420 return StmtError(); 8421 8422 auto *CS = cast<CapturedStmt>(AStmt); 8423 // 1.2.2 OpenMP Language Terminology 8424 // Structured block - An executable statement with a single entry at the 8425 // top and a single exit at the bottom. 8426 // The point of exit cannot be a branch out of the structured block. 8427 // longjmp() and throw() must not violate the entry/exit criteria. 8428 OpenMPClauseKind AtomicKind = OMPC_unknown; 8429 SourceLocation AtomicKindLoc; 8430 for (const OMPClause *C : Clauses) { 8431 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8432 C->getClauseKind() == OMPC_update || 8433 C->getClauseKind() == OMPC_capture) { 8434 if (AtomicKind != OMPC_unknown) { 8435 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8436 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8437 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8438 << getOpenMPClauseName(AtomicKind); 8439 } else { 8440 AtomicKind = C->getClauseKind(); 8441 AtomicKindLoc = C->getBeginLoc(); 8442 } 8443 } 8444 } 8445 8446 Stmt *Body = CS->getCapturedStmt(); 8447 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8448 Body = EWC->getSubExpr(); 8449 8450 Expr *X = nullptr; 8451 Expr *V = nullptr; 8452 Expr *E = nullptr; 8453 Expr *UE = nullptr; 8454 bool IsXLHSInRHSPart = false; 8455 bool IsPostfixUpdate = false; 8456 // OpenMP [2.12.6, atomic Construct] 8457 // In the next expressions: 8458 // * x and v (as applicable) are both l-value expressions with scalar type. 8459 // * During the execution of an atomic region, multiple syntactic 8460 // occurrences of x must designate the same storage location. 8461 // * Neither of v and expr (as applicable) may access the storage location 8462 // designated by x. 8463 // * Neither of x and expr (as applicable) may access the storage location 8464 // designated by v. 8465 // * expr is an expression with scalar type. 8466 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8467 // * binop, binop=, ++, and -- are not overloaded operators. 8468 // * The expression x binop expr must be numerically equivalent to x binop 8469 // (expr). This requirement is satisfied if the operators in expr have 8470 // precedence greater than binop, or by using parentheses around expr or 8471 // subexpressions of expr. 8472 // * The expression expr binop x must be numerically equivalent to (expr) 8473 // binop x. This requirement is satisfied if the operators in expr have 8474 // precedence equal to or greater than binop, or by using parentheses around 8475 // expr or subexpressions of expr. 8476 // * For forms that allow multiple occurrences of x, the number of times 8477 // that x is evaluated is unspecified. 8478 if (AtomicKind == OMPC_read) { 8479 enum { 8480 NotAnExpression, 8481 NotAnAssignmentOp, 8482 NotAScalarType, 8483 NotAnLValue, 8484 NoError 8485 } ErrorFound = NoError; 8486 SourceLocation ErrorLoc, NoteLoc; 8487 SourceRange ErrorRange, NoteRange; 8488 // If clause is read: 8489 // v = x; 8490 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8491 const auto *AtomicBinOp = 8492 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8493 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8494 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8495 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8496 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8497 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8498 if (!X->isLValue() || !V->isLValue()) { 8499 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8500 ErrorFound = NotAnLValue; 8501 ErrorLoc = AtomicBinOp->getExprLoc(); 8502 ErrorRange = AtomicBinOp->getSourceRange(); 8503 NoteLoc = NotLValueExpr->getExprLoc(); 8504 NoteRange = NotLValueExpr->getSourceRange(); 8505 } 8506 } else if (!X->isInstantiationDependent() || 8507 !V->isInstantiationDependent()) { 8508 const Expr *NotScalarExpr = 8509 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8510 ? V 8511 : X; 8512 ErrorFound = NotAScalarType; 8513 ErrorLoc = AtomicBinOp->getExprLoc(); 8514 ErrorRange = AtomicBinOp->getSourceRange(); 8515 NoteLoc = NotScalarExpr->getExprLoc(); 8516 NoteRange = NotScalarExpr->getSourceRange(); 8517 } 8518 } else if (!AtomicBody->isInstantiationDependent()) { 8519 ErrorFound = NotAnAssignmentOp; 8520 ErrorLoc = AtomicBody->getExprLoc(); 8521 ErrorRange = AtomicBody->getSourceRange(); 8522 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8523 : AtomicBody->getExprLoc(); 8524 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8525 : AtomicBody->getSourceRange(); 8526 } 8527 } else { 8528 ErrorFound = NotAnExpression; 8529 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8530 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8531 } 8532 if (ErrorFound != NoError) { 8533 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8534 << ErrorRange; 8535 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8536 << NoteRange; 8537 return StmtError(); 8538 } 8539 if (CurContext->isDependentContext()) 8540 V = X = nullptr; 8541 } else if (AtomicKind == OMPC_write) { 8542 enum { 8543 NotAnExpression, 8544 NotAnAssignmentOp, 8545 NotAScalarType, 8546 NotAnLValue, 8547 NoError 8548 } ErrorFound = NoError; 8549 SourceLocation ErrorLoc, NoteLoc; 8550 SourceRange ErrorRange, NoteRange; 8551 // If clause is write: 8552 // x = expr; 8553 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8554 const auto *AtomicBinOp = 8555 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8556 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8557 X = AtomicBinOp->getLHS(); 8558 E = AtomicBinOp->getRHS(); 8559 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8560 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8561 if (!X->isLValue()) { 8562 ErrorFound = NotAnLValue; 8563 ErrorLoc = AtomicBinOp->getExprLoc(); 8564 ErrorRange = AtomicBinOp->getSourceRange(); 8565 NoteLoc = X->getExprLoc(); 8566 NoteRange = X->getSourceRange(); 8567 } 8568 } else if (!X->isInstantiationDependent() || 8569 !E->isInstantiationDependent()) { 8570 const Expr *NotScalarExpr = 8571 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8572 ? E 8573 : X; 8574 ErrorFound = NotAScalarType; 8575 ErrorLoc = AtomicBinOp->getExprLoc(); 8576 ErrorRange = AtomicBinOp->getSourceRange(); 8577 NoteLoc = NotScalarExpr->getExprLoc(); 8578 NoteRange = NotScalarExpr->getSourceRange(); 8579 } 8580 } else if (!AtomicBody->isInstantiationDependent()) { 8581 ErrorFound = NotAnAssignmentOp; 8582 ErrorLoc = AtomicBody->getExprLoc(); 8583 ErrorRange = AtomicBody->getSourceRange(); 8584 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8585 : AtomicBody->getExprLoc(); 8586 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8587 : AtomicBody->getSourceRange(); 8588 } 8589 } else { 8590 ErrorFound = NotAnExpression; 8591 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8592 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8593 } 8594 if (ErrorFound != NoError) { 8595 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8596 << ErrorRange; 8597 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8598 << NoteRange; 8599 return StmtError(); 8600 } 8601 if (CurContext->isDependentContext()) 8602 E = X = nullptr; 8603 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8604 // If clause is update: 8605 // x++; 8606 // x--; 8607 // ++x; 8608 // --x; 8609 // x binop= expr; 8610 // x = x binop expr; 8611 // x = expr binop x; 8612 OpenMPAtomicUpdateChecker Checker(*this); 8613 if (Checker.checkStatement( 8614 Body, (AtomicKind == OMPC_update) 8615 ? diag::err_omp_atomic_update_not_expression_statement 8616 : diag::err_omp_atomic_not_expression_statement, 8617 diag::note_omp_atomic_update)) 8618 return StmtError(); 8619 if (!CurContext->isDependentContext()) { 8620 E = Checker.getExpr(); 8621 X = Checker.getX(); 8622 UE = Checker.getUpdateExpr(); 8623 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8624 } 8625 } else if (AtomicKind == OMPC_capture) { 8626 enum { 8627 NotAnAssignmentOp, 8628 NotACompoundStatement, 8629 NotTwoSubstatements, 8630 NotASpecificExpression, 8631 NoError 8632 } ErrorFound = NoError; 8633 SourceLocation ErrorLoc, NoteLoc; 8634 SourceRange ErrorRange, NoteRange; 8635 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8636 // If clause is a capture: 8637 // v = x++; 8638 // v = x--; 8639 // v = ++x; 8640 // v = --x; 8641 // v = x binop= expr; 8642 // v = x = x binop expr; 8643 // v = x = expr binop x; 8644 const auto *AtomicBinOp = 8645 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8646 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8647 V = AtomicBinOp->getLHS(); 8648 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8649 OpenMPAtomicUpdateChecker Checker(*this); 8650 if (Checker.checkStatement( 8651 Body, diag::err_omp_atomic_capture_not_expression_statement, 8652 diag::note_omp_atomic_update)) 8653 return StmtError(); 8654 E = Checker.getExpr(); 8655 X = Checker.getX(); 8656 UE = Checker.getUpdateExpr(); 8657 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8658 IsPostfixUpdate = Checker.isPostfixUpdate(); 8659 } else if (!AtomicBody->isInstantiationDependent()) { 8660 ErrorLoc = AtomicBody->getExprLoc(); 8661 ErrorRange = AtomicBody->getSourceRange(); 8662 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8663 : AtomicBody->getExprLoc(); 8664 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8665 : AtomicBody->getSourceRange(); 8666 ErrorFound = NotAnAssignmentOp; 8667 } 8668 if (ErrorFound != NoError) { 8669 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8670 << ErrorRange; 8671 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8672 return StmtError(); 8673 } 8674 if (CurContext->isDependentContext()) 8675 UE = V = E = X = nullptr; 8676 } else { 8677 // If clause is a capture: 8678 // { v = x; x = expr; } 8679 // { v = x; x++; } 8680 // { v = x; x--; } 8681 // { v = x; ++x; } 8682 // { v = x; --x; } 8683 // { v = x; x binop= expr; } 8684 // { v = x; x = x binop expr; } 8685 // { v = x; x = expr binop x; } 8686 // { x++; v = x; } 8687 // { x--; v = x; } 8688 // { ++x; v = x; } 8689 // { --x; v = x; } 8690 // { x binop= expr; v = x; } 8691 // { x = x binop expr; v = x; } 8692 // { x = expr binop x; v = x; } 8693 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8694 // Check that this is { expr1; expr2; } 8695 if (CS->size() == 2) { 8696 Stmt *First = CS->body_front(); 8697 Stmt *Second = CS->body_back(); 8698 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8699 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8700 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8701 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8702 // Need to find what subexpression is 'v' and what is 'x'. 8703 OpenMPAtomicUpdateChecker Checker(*this); 8704 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8705 BinaryOperator *BinOp = nullptr; 8706 if (IsUpdateExprFound) { 8707 BinOp = dyn_cast<BinaryOperator>(First); 8708 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8709 } 8710 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8711 // { v = x; x++; } 8712 // { v = x; x--; } 8713 // { v = x; ++x; } 8714 // { v = x; --x; } 8715 // { v = x; x binop= expr; } 8716 // { v = x; x = x binop expr; } 8717 // { v = x; x = expr binop x; } 8718 // Check that the first expression has form v = x. 8719 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8720 llvm::FoldingSetNodeID XId, PossibleXId; 8721 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8722 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8723 IsUpdateExprFound = XId == PossibleXId; 8724 if (IsUpdateExprFound) { 8725 V = BinOp->getLHS(); 8726 X = Checker.getX(); 8727 E = Checker.getExpr(); 8728 UE = Checker.getUpdateExpr(); 8729 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8730 IsPostfixUpdate = true; 8731 } 8732 } 8733 if (!IsUpdateExprFound) { 8734 IsUpdateExprFound = !Checker.checkStatement(First); 8735 BinOp = nullptr; 8736 if (IsUpdateExprFound) { 8737 BinOp = dyn_cast<BinaryOperator>(Second); 8738 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8739 } 8740 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8741 // { x++; v = x; } 8742 // { x--; v = x; } 8743 // { ++x; v = x; } 8744 // { --x; v = x; } 8745 // { x binop= expr; v = x; } 8746 // { x = x binop expr; v = x; } 8747 // { x = expr binop x; v = x; } 8748 // Check that the second expression has form v = x. 8749 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8750 llvm::FoldingSetNodeID XId, PossibleXId; 8751 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8752 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8753 IsUpdateExprFound = XId == PossibleXId; 8754 if (IsUpdateExprFound) { 8755 V = BinOp->getLHS(); 8756 X = Checker.getX(); 8757 E = Checker.getExpr(); 8758 UE = Checker.getUpdateExpr(); 8759 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8760 IsPostfixUpdate = false; 8761 } 8762 } 8763 } 8764 if (!IsUpdateExprFound) { 8765 // { v = x; x = expr; } 8766 auto *FirstExpr = dyn_cast<Expr>(First); 8767 auto *SecondExpr = dyn_cast<Expr>(Second); 8768 if (!FirstExpr || !SecondExpr || 8769 !(FirstExpr->isInstantiationDependent() || 8770 SecondExpr->isInstantiationDependent())) { 8771 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8772 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8773 ErrorFound = NotAnAssignmentOp; 8774 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8775 : First->getBeginLoc(); 8776 NoteRange = ErrorRange = FirstBinOp 8777 ? FirstBinOp->getSourceRange() 8778 : SourceRange(ErrorLoc, ErrorLoc); 8779 } else { 8780 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8781 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8782 ErrorFound = NotAnAssignmentOp; 8783 NoteLoc = ErrorLoc = SecondBinOp 8784 ? SecondBinOp->getOperatorLoc() 8785 : Second->getBeginLoc(); 8786 NoteRange = ErrorRange = 8787 SecondBinOp ? SecondBinOp->getSourceRange() 8788 : SourceRange(ErrorLoc, ErrorLoc); 8789 } else { 8790 Expr *PossibleXRHSInFirst = 8791 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8792 Expr *PossibleXLHSInSecond = 8793 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8794 llvm::FoldingSetNodeID X1Id, X2Id; 8795 PossibleXRHSInFirst->Profile(X1Id, Context, 8796 /*Canonical=*/true); 8797 PossibleXLHSInSecond->Profile(X2Id, Context, 8798 /*Canonical=*/true); 8799 IsUpdateExprFound = X1Id == X2Id; 8800 if (IsUpdateExprFound) { 8801 V = FirstBinOp->getLHS(); 8802 X = SecondBinOp->getLHS(); 8803 E = SecondBinOp->getRHS(); 8804 UE = nullptr; 8805 IsXLHSInRHSPart = false; 8806 IsPostfixUpdate = true; 8807 } else { 8808 ErrorFound = NotASpecificExpression; 8809 ErrorLoc = FirstBinOp->getExprLoc(); 8810 ErrorRange = FirstBinOp->getSourceRange(); 8811 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8812 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8813 } 8814 } 8815 } 8816 } 8817 } 8818 } else { 8819 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8820 NoteRange = ErrorRange = 8821 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8822 ErrorFound = NotTwoSubstatements; 8823 } 8824 } else { 8825 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8826 NoteRange = ErrorRange = 8827 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8828 ErrorFound = NotACompoundStatement; 8829 } 8830 if (ErrorFound != NoError) { 8831 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8832 << ErrorRange; 8833 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8834 return StmtError(); 8835 } 8836 if (CurContext->isDependentContext()) 8837 UE = V = E = X = nullptr; 8838 } 8839 } 8840 8841 setFunctionHasBranchProtectedScope(); 8842 8843 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8844 X, V, E, UE, IsXLHSInRHSPart, 8845 IsPostfixUpdate); 8846 } 8847 8848 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8849 Stmt *AStmt, 8850 SourceLocation StartLoc, 8851 SourceLocation EndLoc) { 8852 if (!AStmt) 8853 return StmtError(); 8854 8855 auto *CS = cast<CapturedStmt>(AStmt); 8856 // 1.2.2 OpenMP Language Terminology 8857 // Structured block - An executable statement with a single entry at the 8858 // top and a single exit at the bottom. 8859 // The point of exit cannot be a branch out of the structured block. 8860 // longjmp() and throw() must not violate the entry/exit criteria. 8861 CS->getCapturedDecl()->setNothrow(); 8862 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8863 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8864 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8865 // 1.2.2 OpenMP Language Terminology 8866 // Structured block - An executable statement with a single entry at the 8867 // top and a single exit at the bottom. 8868 // The point of exit cannot be a branch out of the structured block. 8869 // longjmp() and throw() must not violate the entry/exit criteria. 8870 CS->getCapturedDecl()->setNothrow(); 8871 } 8872 8873 // OpenMP [2.16, Nesting of Regions] 8874 // If specified, a teams construct must be contained within a target 8875 // construct. That target construct must contain no statements or directives 8876 // outside of the teams construct. 8877 if (DSAStack->hasInnerTeamsRegion()) { 8878 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8879 bool OMPTeamsFound = true; 8880 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8881 auto I = CS->body_begin(); 8882 while (I != CS->body_end()) { 8883 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8884 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8885 OMPTeamsFound) { 8886 8887 OMPTeamsFound = false; 8888 break; 8889 } 8890 ++I; 8891 } 8892 assert(I != CS->body_end() && "Not found statement"); 8893 S = *I; 8894 } else { 8895 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8896 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8897 } 8898 if (!OMPTeamsFound) { 8899 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8900 Diag(DSAStack->getInnerTeamsRegionLoc(), 8901 diag::note_omp_nested_teams_construct_here); 8902 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8903 << isa<OMPExecutableDirective>(S); 8904 return StmtError(); 8905 } 8906 } 8907 8908 setFunctionHasBranchProtectedScope(); 8909 8910 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8911 } 8912 8913 StmtResult 8914 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8915 Stmt *AStmt, SourceLocation StartLoc, 8916 SourceLocation EndLoc) { 8917 if (!AStmt) 8918 return StmtError(); 8919 8920 auto *CS = cast<CapturedStmt>(AStmt); 8921 // 1.2.2 OpenMP Language Terminology 8922 // Structured block - An executable statement with a single entry at the 8923 // top and a single exit at the bottom. 8924 // The point of exit cannot be a branch out of the structured block. 8925 // longjmp() and throw() must not violate the entry/exit criteria. 8926 CS->getCapturedDecl()->setNothrow(); 8927 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8928 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8929 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8930 // 1.2.2 OpenMP Language Terminology 8931 // Structured block - An executable statement with a single entry at the 8932 // top and a single exit at the bottom. 8933 // The point of exit cannot be a branch out of the structured block. 8934 // longjmp() and throw() must not violate the entry/exit criteria. 8935 CS->getCapturedDecl()->setNothrow(); 8936 } 8937 8938 setFunctionHasBranchProtectedScope(); 8939 8940 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8941 AStmt); 8942 } 8943 8944 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8945 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8946 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8947 if (!AStmt) 8948 return StmtError(); 8949 8950 auto *CS = cast<CapturedStmt>(AStmt); 8951 // 1.2.2 OpenMP Language Terminology 8952 // Structured block - An executable statement with a single entry at the 8953 // top and a single exit at the bottom. 8954 // The point of exit cannot be a branch out of the structured block. 8955 // longjmp() and throw() must not violate the entry/exit criteria. 8956 CS->getCapturedDecl()->setNothrow(); 8957 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8958 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8959 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8960 // 1.2.2 OpenMP Language Terminology 8961 // Structured block - An executable statement with a single entry at the 8962 // top and a single exit at the bottom. 8963 // The point of exit cannot be a branch out of the structured block. 8964 // longjmp() and throw() must not violate the entry/exit criteria. 8965 CS->getCapturedDecl()->setNothrow(); 8966 } 8967 8968 OMPLoopDirective::HelperExprs B; 8969 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8970 // define the nested loops number. 8971 unsigned NestedLoopCount = 8972 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8973 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8974 VarsWithImplicitDSA, B); 8975 if (NestedLoopCount == 0) 8976 return StmtError(); 8977 8978 assert((CurContext->isDependentContext() || B.builtAll()) && 8979 "omp target parallel for loop exprs were not built"); 8980 8981 if (!CurContext->isDependentContext()) { 8982 // Finalize the clauses that need pre-built expressions for CodeGen. 8983 for (OMPClause *C : Clauses) { 8984 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8985 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8986 B.NumIterations, *this, CurScope, 8987 DSAStack)) 8988 return StmtError(); 8989 } 8990 } 8991 8992 setFunctionHasBranchProtectedScope(); 8993 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8994 NestedLoopCount, Clauses, AStmt, 8995 B, DSAStack->isCancelRegion()); 8996 } 8997 8998 /// Check for existence of a map clause in the list of clauses. 8999 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9000 const OpenMPClauseKind K) { 9001 return llvm::any_of( 9002 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9003 } 9004 9005 template <typename... Params> 9006 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9007 const Params... ClauseTypes) { 9008 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9009 } 9010 9011 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9012 Stmt *AStmt, 9013 SourceLocation StartLoc, 9014 SourceLocation EndLoc) { 9015 if (!AStmt) 9016 return StmtError(); 9017 9018 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9019 9020 // OpenMP [2.10.1, Restrictions, p. 97] 9021 // At least one map clause must appear on the directive. 9022 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9023 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9024 << "'map' or 'use_device_ptr'" 9025 << getOpenMPDirectiveName(OMPD_target_data); 9026 return StmtError(); 9027 } 9028 9029 setFunctionHasBranchProtectedScope(); 9030 9031 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9032 AStmt); 9033 } 9034 9035 StmtResult 9036 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9037 SourceLocation StartLoc, 9038 SourceLocation EndLoc, Stmt *AStmt) { 9039 if (!AStmt) 9040 return StmtError(); 9041 9042 auto *CS = cast<CapturedStmt>(AStmt); 9043 // 1.2.2 OpenMP Language Terminology 9044 // Structured block - An executable statement with a single entry at the 9045 // top and a single exit at the bottom. 9046 // The point of exit cannot be a branch out of the structured block. 9047 // longjmp() and throw() must not violate the entry/exit criteria. 9048 CS->getCapturedDecl()->setNothrow(); 9049 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9050 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9051 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9052 // 1.2.2 OpenMP Language Terminology 9053 // Structured block - An executable statement with a single entry at the 9054 // top and a single exit at the bottom. 9055 // The point of exit cannot be a branch out of the structured block. 9056 // longjmp() and throw() must not violate the entry/exit criteria. 9057 CS->getCapturedDecl()->setNothrow(); 9058 } 9059 9060 // OpenMP [2.10.2, Restrictions, p. 99] 9061 // At least one map clause must appear on the directive. 9062 if (!hasClauses(Clauses, OMPC_map)) { 9063 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9064 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9065 return StmtError(); 9066 } 9067 9068 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9069 AStmt); 9070 } 9071 9072 StmtResult 9073 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9074 SourceLocation StartLoc, 9075 SourceLocation EndLoc, Stmt *AStmt) { 9076 if (!AStmt) 9077 return StmtError(); 9078 9079 auto *CS = cast<CapturedStmt>(AStmt); 9080 // 1.2.2 OpenMP Language Terminology 9081 // Structured block - An executable statement with a single entry at the 9082 // top and a single exit at the bottom. 9083 // The point of exit cannot be a branch out of the structured block. 9084 // longjmp() and throw() must not violate the entry/exit criteria. 9085 CS->getCapturedDecl()->setNothrow(); 9086 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9087 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9088 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9089 // 1.2.2 OpenMP Language Terminology 9090 // Structured block - An executable statement with a single entry at the 9091 // top and a single exit at the bottom. 9092 // The point of exit cannot be a branch out of the structured block. 9093 // longjmp() and throw() must not violate the entry/exit criteria. 9094 CS->getCapturedDecl()->setNothrow(); 9095 } 9096 9097 // OpenMP [2.10.3, Restrictions, p. 102] 9098 // At least one map clause must appear on the directive. 9099 if (!hasClauses(Clauses, OMPC_map)) { 9100 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9101 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9102 return StmtError(); 9103 } 9104 9105 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9106 AStmt); 9107 } 9108 9109 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9110 SourceLocation StartLoc, 9111 SourceLocation EndLoc, 9112 Stmt *AStmt) { 9113 if (!AStmt) 9114 return StmtError(); 9115 9116 auto *CS = cast<CapturedStmt>(AStmt); 9117 // 1.2.2 OpenMP Language Terminology 9118 // Structured block - An executable statement with a single entry at the 9119 // top and a single exit at the bottom. 9120 // The point of exit cannot be a branch out of the structured block. 9121 // longjmp() and throw() must not violate the entry/exit criteria. 9122 CS->getCapturedDecl()->setNothrow(); 9123 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9124 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9125 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9126 // 1.2.2 OpenMP Language Terminology 9127 // Structured block - An executable statement with a single entry at the 9128 // top and a single exit at the bottom. 9129 // The point of exit cannot be a branch out of the structured block. 9130 // longjmp() and throw() must not violate the entry/exit criteria. 9131 CS->getCapturedDecl()->setNothrow(); 9132 } 9133 9134 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9135 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9136 return StmtError(); 9137 } 9138 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9139 AStmt); 9140 } 9141 9142 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9143 Stmt *AStmt, SourceLocation StartLoc, 9144 SourceLocation EndLoc) { 9145 if (!AStmt) 9146 return StmtError(); 9147 9148 auto *CS = cast<CapturedStmt>(AStmt); 9149 // 1.2.2 OpenMP Language Terminology 9150 // Structured block - An executable statement with a single entry at the 9151 // top and a single exit at the bottom. 9152 // The point of exit cannot be a branch out of the structured block. 9153 // longjmp() and throw() must not violate the entry/exit criteria. 9154 CS->getCapturedDecl()->setNothrow(); 9155 9156 setFunctionHasBranchProtectedScope(); 9157 9158 DSAStack->setParentTeamsRegionLoc(StartLoc); 9159 9160 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9161 } 9162 9163 StmtResult 9164 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9165 SourceLocation EndLoc, 9166 OpenMPDirectiveKind CancelRegion) { 9167 if (DSAStack->isParentNowaitRegion()) { 9168 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9169 return StmtError(); 9170 } 9171 if (DSAStack->isParentOrderedRegion()) { 9172 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9173 return StmtError(); 9174 } 9175 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9176 CancelRegion); 9177 } 9178 9179 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9180 SourceLocation StartLoc, 9181 SourceLocation EndLoc, 9182 OpenMPDirectiveKind CancelRegion) { 9183 if (DSAStack->isParentNowaitRegion()) { 9184 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9185 return StmtError(); 9186 } 9187 if (DSAStack->isParentOrderedRegion()) { 9188 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9189 return StmtError(); 9190 } 9191 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9192 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9193 CancelRegion); 9194 } 9195 9196 static bool checkGrainsizeNumTasksClauses(Sema &S, 9197 ArrayRef<OMPClause *> Clauses) { 9198 const OMPClause *PrevClause = nullptr; 9199 bool ErrorFound = false; 9200 for (const OMPClause *C : Clauses) { 9201 if (C->getClauseKind() == OMPC_grainsize || 9202 C->getClauseKind() == OMPC_num_tasks) { 9203 if (!PrevClause) 9204 PrevClause = C; 9205 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9206 S.Diag(C->getBeginLoc(), 9207 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9208 << getOpenMPClauseName(C->getClauseKind()) 9209 << getOpenMPClauseName(PrevClause->getClauseKind()); 9210 S.Diag(PrevClause->getBeginLoc(), 9211 diag::note_omp_previous_grainsize_num_tasks) 9212 << getOpenMPClauseName(PrevClause->getClauseKind()); 9213 ErrorFound = true; 9214 } 9215 } 9216 } 9217 return ErrorFound; 9218 } 9219 9220 static bool checkReductionClauseWithNogroup(Sema &S, 9221 ArrayRef<OMPClause *> Clauses) { 9222 const OMPClause *ReductionClause = nullptr; 9223 const OMPClause *NogroupClause = nullptr; 9224 for (const OMPClause *C : Clauses) { 9225 if (C->getClauseKind() == OMPC_reduction) { 9226 ReductionClause = C; 9227 if (NogroupClause) 9228 break; 9229 continue; 9230 } 9231 if (C->getClauseKind() == OMPC_nogroup) { 9232 NogroupClause = C; 9233 if (ReductionClause) 9234 break; 9235 continue; 9236 } 9237 } 9238 if (ReductionClause && NogroupClause) { 9239 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9240 << SourceRange(NogroupClause->getBeginLoc(), 9241 NogroupClause->getEndLoc()); 9242 return true; 9243 } 9244 return false; 9245 } 9246 9247 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9248 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9249 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9250 if (!AStmt) 9251 return StmtError(); 9252 9253 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9254 OMPLoopDirective::HelperExprs B; 9255 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9256 // define the nested loops number. 9257 unsigned NestedLoopCount = 9258 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9259 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9260 VarsWithImplicitDSA, B); 9261 if (NestedLoopCount == 0) 9262 return StmtError(); 9263 9264 assert((CurContext->isDependentContext() || B.builtAll()) && 9265 "omp for loop exprs were not built"); 9266 9267 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9268 // The grainsize clause and num_tasks clause are mutually exclusive and may 9269 // not appear on the same taskloop directive. 9270 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9271 return StmtError(); 9272 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9273 // If a reduction clause is present on the taskloop directive, the nogroup 9274 // clause must not be specified. 9275 if (checkReductionClauseWithNogroup(*this, Clauses)) 9276 return StmtError(); 9277 9278 setFunctionHasBranchProtectedScope(); 9279 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9280 NestedLoopCount, Clauses, AStmt, B); 9281 } 9282 9283 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9284 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9285 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9286 if (!AStmt) 9287 return StmtError(); 9288 9289 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9290 OMPLoopDirective::HelperExprs B; 9291 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9292 // define the nested loops number. 9293 unsigned NestedLoopCount = 9294 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9295 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9296 VarsWithImplicitDSA, B); 9297 if (NestedLoopCount == 0) 9298 return StmtError(); 9299 9300 assert((CurContext->isDependentContext() || B.builtAll()) && 9301 "omp for loop exprs were not built"); 9302 9303 if (!CurContext->isDependentContext()) { 9304 // Finalize the clauses that need pre-built expressions for CodeGen. 9305 for (OMPClause *C : Clauses) { 9306 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9307 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9308 B.NumIterations, *this, CurScope, 9309 DSAStack)) 9310 return StmtError(); 9311 } 9312 } 9313 9314 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9315 // The grainsize clause and num_tasks clause are mutually exclusive and may 9316 // not appear on the same taskloop directive. 9317 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9318 return StmtError(); 9319 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9320 // If a reduction clause is present on the taskloop directive, the nogroup 9321 // clause must not be specified. 9322 if (checkReductionClauseWithNogroup(*this, Clauses)) 9323 return StmtError(); 9324 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9325 return StmtError(); 9326 9327 setFunctionHasBranchProtectedScope(); 9328 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9329 NestedLoopCount, Clauses, AStmt, B); 9330 } 9331 9332 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9333 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9334 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9335 if (!AStmt) 9336 return StmtError(); 9337 9338 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9339 OMPLoopDirective::HelperExprs B; 9340 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9341 // define the nested loops number. 9342 unsigned NestedLoopCount = 9343 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9344 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9345 VarsWithImplicitDSA, B); 9346 if (NestedLoopCount == 0) 9347 return StmtError(); 9348 9349 assert((CurContext->isDependentContext() || B.builtAll()) && 9350 "omp for loop exprs were not built"); 9351 9352 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9353 // The grainsize clause and num_tasks clause are mutually exclusive and may 9354 // not appear on the same taskloop directive. 9355 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9356 return StmtError(); 9357 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9358 // If a reduction clause is present on the taskloop directive, the nogroup 9359 // clause must not be specified. 9360 if (checkReductionClauseWithNogroup(*this, Clauses)) 9361 return StmtError(); 9362 9363 setFunctionHasBranchProtectedScope(); 9364 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9365 NestedLoopCount, Clauses, AStmt, B); 9366 } 9367 9368 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9369 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9370 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9371 if (!AStmt) 9372 return StmtError(); 9373 9374 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9375 auto *CS = cast<CapturedStmt>(AStmt); 9376 // 1.2.2 OpenMP Language Terminology 9377 // Structured block - An executable statement with a single entry at the 9378 // top and a single exit at the bottom. 9379 // The point of exit cannot be a branch out of the structured block. 9380 // longjmp() and throw() must not violate the entry/exit criteria. 9381 CS->getCapturedDecl()->setNothrow(); 9382 for (int ThisCaptureLevel = 9383 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9384 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9385 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9386 // 1.2.2 OpenMP Language Terminology 9387 // Structured block - An executable statement with a single entry at the 9388 // top and a single exit at the bottom. 9389 // The point of exit cannot be a branch out of the structured block. 9390 // longjmp() and throw() must not violate the entry/exit criteria. 9391 CS->getCapturedDecl()->setNothrow(); 9392 } 9393 9394 OMPLoopDirective::HelperExprs B; 9395 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9396 // define the nested loops number. 9397 unsigned NestedLoopCount = checkOpenMPLoop( 9398 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9399 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9400 VarsWithImplicitDSA, B); 9401 if (NestedLoopCount == 0) 9402 return StmtError(); 9403 9404 assert((CurContext->isDependentContext() || B.builtAll()) && 9405 "omp for loop exprs were not built"); 9406 9407 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9408 // The grainsize clause and num_tasks clause are mutually exclusive and may 9409 // not appear on the same taskloop directive. 9410 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9411 return StmtError(); 9412 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9413 // If a reduction clause is present on the taskloop directive, the nogroup 9414 // clause must not be specified. 9415 if (checkReductionClauseWithNogroup(*this, Clauses)) 9416 return StmtError(); 9417 9418 setFunctionHasBranchProtectedScope(); 9419 return OMPParallelMasterTaskLoopDirective::Create( 9420 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9421 } 9422 9423 StmtResult Sema::ActOnOpenMPDistributeDirective( 9424 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9425 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9426 if (!AStmt) 9427 return StmtError(); 9428 9429 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9430 OMPLoopDirective::HelperExprs B; 9431 // In presence of clause 'collapse' with number of loops, it will 9432 // define the nested loops number. 9433 unsigned NestedLoopCount = 9434 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9435 nullptr /*ordered not a clause on distribute*/, AStmt, 9436 *this, *DSAStack, VarsWithImplicitDSA, B); 9437 if (NestedLoopCount == 0) 9438 return StmtError(); 9439 9440 assert((CurContext->isDependentContext() || B.builtAll()) && 9441 "omp for loop exprs were not built"); 9442 9443 setFunctionHasBranchProtectedScope(); 9444 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9445 NestedLoopCount, Clauses, AStmt, B); 9446 } 9447 9448 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9449 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9450 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9451 if (!AStmt) 9452 return StmtError(); 9453 9454 auto *CS = cast<CapturedStmt>(AStmt); 9455 // 1.2.2 OpenMP Language Terminology 9456 // Structured block - An executable statement with a single entry at the 9457 // top and a single exit at the bottom. 9458 // The point of exit cannot be a branch out of the structured block. 9459 // longjmp() and throw() must not violate the entry/exit criteria. 9460 CS->getCapturedDecl()->setNothrow(); 9461 for (int ThisCaptureLevel = 9462 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9463 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9464 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9465 // 1.2.2 OpenMP Language Terminology 9466 // Structured block - An executable statement with a single entry at the 9467 // top and a single exit at the bottom. 9468 // The point of exit cannot be a branch out of the structured block. 9469 // longjmp() and throw() must not violate the entry/exit criteria. 9470 CS->getCapturedDecl()->setNothrow(); 9471 } 9472 9473 OMPLoopDirective::HelperExprs B; 9474 // In presence of clause 'collapse' with number of loops, it will 9475 // define the nested loops number. 9476 unsigned NestedLoopCount = checkOpenMPLoop( 9477 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9478 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9479 VarsWithImplicitDSA, B); 9480 if (NestedLoopCount == 0) 9481 return StmtError(); 9482 9483 assert((CurContext->isDependentContext() || B.builtAll()) && 9484 "omp for loop exprs were not built"); 9485 9486 setFunctionHasBranchProtectedScope(); 9487 return OMPDistributeParallelForDirective::Create( 9488 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9489 DSAStack->isCancelRegion()); 9490 } 9491 9492 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9493 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9494 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9495 if (!AStmt) 9496 return StmtError(); 9497 9498 auto *CS = cast<CapturedStmt>(AStmt); 9499 // 1.2.2 OpenMP Language Terminology 9500 // Structured block - An executable statement with a single entry at the 9501 // top and a single exit at the bottom. 9502 // The point of exit cannot be a branch out of the structured block. 9503 // longjmp() and throw() must not violate the entry/exit criteria. 9504 CS->getCapturedDecl()->setNothrow(); 9505 for (int ThisCaptureLevel = 9506 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9507 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9508 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9509 // 1.2.2 OpenMP Language Terminology 9510 // Structured block - An executable statement with a single entry at the 9511 // top and a single exit at the bottom. 9512 // The point of exit cannot be a branch out of the structured block. 9513 // longjmp() and throw() must not violate the entry/exit criteria. 9514 CS->getCapturedDecl()->setNothrow(); 9515 } 9516 9517 OMPLoopDirective::HelperExprs B; 9518 // In presence of clause 'collapse' with number of loops, it will 9519 // define the nested loops number. 9520 unsigned NestedLoopCount = checkOpenMPLoop( 9521 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9522 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9523 VarsWithImplicitDSA, B); 9524 if (NestedLoopCount == 0) 9525 return StmtError(); 9526 9527 assert((CurContext->isDependentContext() || B.builtAll()) && 9528 "omp for loop exprs were not built"); 9529 9530 if (!CurContext->isDependentContext()) { 9531 // Finalize the clauses that need pre-built expressions for CodeGen. 9532 for (OMPClause *C : Clauses) { 9533 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9534 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9535 B.NumIterations, *this, CurScope, 9536 DSAStack)) 9537 return StmtError(); 9538 } 9539 } 9540 9541 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9542 return StmtError(); 9543 9544 setFunctionHasBranchProtectedScope(); 9545 return OMPDistributeParallelForSimdDirective::Create( 9546 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9547 } 9548 9549 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9550 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9551 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9552 if (!AStmt) 9553 return StmtError(); 9554 9555 auto *CS = cast<CapturedStmt>(AStmt); 9556 // 1.2.2 OpenMP Language Terminology 9557 // Structured block - An executable statement with a single entry at the 9558 // top and a single exit at the bottom. 9559 // The point of exit cannot be a branch out of the structured block. 9560 // longjmp() and throw() must not violate the entry/exit criteria. 9561 CS->getCapturedDecl()->setNothrow(); 9562 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9563 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9564 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9565 // 1.2.2 OpenMP Language Terminology 9566 // Structured block - An executable statement with a single entry at the 9567 // top and a single exit at the bottom. 9568 // The point of exit cannot be a branch out of the structured block. 9569 // longjmp() and throw() must not violate the entry/exit criteria. 9570 CS->getCapturedDecl()->setNothrow(); 9571 } 9572 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_simd, getCollapseNumberExpr(Clauses), 9578 nullptr /*ordered not a clause on distribute*/, CS, *this, 9579 *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 if (!CurContext->isDependentContext()) { 9587 // Finalize the clauses that need pre-built expressions for CodeGen. 9588 for (OMPClause *C : Clauses) { 9589 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9590 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9591 B.NumIterations, *this, CurScope, 9592 DSAStack)) 9593 return StmtError(); 9594 } 9595 } 9596 9597 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9598 return StmtError(); 9599 9600 setFunctionHasBranchProtectedScope(); 9601 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9602 NestedLoopCount, Clauses, AStmt, B); 9603 } 9604 9605 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9606 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9607 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9608 if (!AStmt) 9609 return StmtError(); 9610 9611 auto *CS = cast<CapturedStmt>(AStmt); 9612 // 1.2.2 OpenMP Language Terminology 9613 // Structured block - An executable statement with a single entry at the 9614 // top and a single exit at the bottom. 9615 // The point of exit cannot be a branch out of the structured block. 9616 // longjmp() and throw() must not violate the entry/exit criteria. 9617 CS->getCapturedDecl()->setNothrow(); 9618 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9619 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9620 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9621 // 1.2.2 OpenMP Language Terminology 9622 // Structured block - An executable statement with a single entry at the 9623 // top and a single exit at the bottom. 9624 // The point of exit cannot be a branch out of the structured block. 9625 // longjmp() and throw() must not violate the entry/exit criteria. 9626 CS->getCapturedDecl()->setNothrow(); 9627 } 9628 9629 OMPLoopDirective::HelperExprs B; 9630 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9631 // define the nested loops number. 9632 unsigned NestedLoopCount = checkOpenMPLoop( 9633 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9634 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9635 VarsWithImplicitDSA, B); 9636 if (NestedLoopCount == 0) 9637 return StmtError(); 9638 9639 assert((CurContext->isDependentContext() || B.builtAll()) && 9640 "omp target parallel for simd loop exprs were not built"); 9641 9642 if (!CurContext->isDependentContext()) { 9643 // Finalize the clauses that need pre-built expressions for CodeGen. 9644 for (OMPClause *C : Clauses) { 9645 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9646 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9647 B.NumIterations, *this, CurScope, 9648 DSAStack)) 9649 return StmtError(); 9650 } 9651 } 9652 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9653 return StmtError(); 9654 9655 setFunctionHasBranchProtectedScope(); 9656 return OMPTargetParallelForSimdDirective::Create( 9657 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9658 } 9659 9660 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9661 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9662 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9663 if (!AStmt) 9664 return StmtError(); 9665 9666 auto *CS = cast<CapturedStmt>(AStmt); 9667 // 1.2.2 OpenMP Language Terminology 9668 // Structured block - An executable statement with a single entry at the 9669 // top and a single exit at the bottom. 9670 // The point of exit cannot be a branch out of the structured block. 9671 // longjmp() and throw() must not violate the entry/exit criteria. 9672 CS->getCapturedDecl()->setNothrow(); 9673 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9674 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9675 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9676 // 1.2.2 OpenMP Language Terminology 9677 // Structured block - An executable statement with a single entry at the 9678 // top and a single exit at the bottom. 9679 // The point of exit cannot be a branch out of the structured block. 9680 // longjmp() and throw() must not violate the entry/exit criteria. 9681 CS->getCapturedDecl()->setNothrow(); 9682 } 9683 9684 OMPLoopDirective::HelperExprs B; 9685 // In presence of clause 'collapse' with number of loops, it will define the 9686 // nested loops number. 9687 unsigned NestedLoopCount = 9688 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9689 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9690 VarsWithImplicitDSA, B); 9691 if (NestedLoopCount == 0) 9692 return StmtError(); 9693 9694 assert((CurContext->isDependentContext() || B.builtAll()) && 9695 "omp target simd loop exprs were not built"); 9696 9697 if (!CurContext->isDependentContext()) { 9698 // Finalize the clauses that need pre-built expressions for CodeGen. 9699 for (OMPClause *C : Clauses) { 9700 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9701 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9702 B.NumIterations, *this, CurScope, 9703 DSAStack)) 9704 return StmtError(); 9705 } 9706 } 9707 9708 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9709 return StmtError(); 9710 9711 setFunctionHasBranchProtectedScope(); 9712 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9713 NestedLoopCount, Clauses, AStmt, B); 9714 } 9715 9716 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9717 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9718 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9719 if (!AStmt) 9720 return StmtError(); 9721 9722 auto *CS = cast<CapturedStmt>(AStmt); 9723 // 1.2.2 OpenMP Language Terminology 9724 // Structured block - An executable statement with a single entry at the 9725 // top and a single exit at the bottom. 9726 // The point of exit cannot be a branch out of the structured block. 9727 // longjmp() and throw() must not violate the entry/exit criteria. 9728 CS->getCapturedDecl()->setNothrow(); 9729 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9730 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9731 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9732 // 1.2.2 OpenMP Language Terminology 9733 // Structured block - An executable statement with a single entry at the 9734 // top and a single exit at the bottom. 9735 // The point of exit cannot be a branch out of the structured block. 9736 // longjmp() and throw() must not violate the entry/exit criteria. 9737 CS->getCapturedDecl()->setNothrow(); 9738 } 9739 9740 OMPLoopDirective::HelperExprs B; 9741 // In presence of clause 'collapse' with number of loops, it will 9742 // define the nested loops number. 9743 unsigned NestedLoopCount = 9744 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9745 nullptr /*ordered not a clause on distribute*/, CS, *this, 9746 *DSAStack, VarsWithImplicitDSA, B); 9747 if (NestedLoopCount == 0) 9748 return StmtError(); 9749 9750 assert((CurContext->isDependentContext() || B.builtAll()) && 9751 "omp teams distribute loop exprs were not built"); 9752 9753 setFunctionHasBranchProtectedScope(); 9754 9755 DSAStack->setParentTeamsRegionLoc(StartLoc); 9756 9757 return OMPTeamsDistributeDirective::Create( 9758 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9759 } 9760 9761 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9762 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9763 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9764 if (!AStmt) 9765 return StmtError(); 9766 9767 auto *CS = cast<CapturedStmt>(AStmt); 9768 // 1.2.2 OpenMP Language Terminology 9769 // Structured block - An executable statement with a single entry at the 9770 // top and a single exit at the bottom. 9771 // The point of exit cannot be a branch out of the structured block. 9772 // longjmp() and throw() must not violate the entry/exit criteria. 9773 CS->getCapturedDecl()->setNothrow(); 9774 for (int ThisCaptureLevel = 9775 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9776 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9777 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9778 // 1.2.2 OpenMP Language Terminology 9779 // Structured block - An executable statement with a single entry at the 9780 // top and a single exit at the bottom. 9781 // The point of exit cannot be a branch out of the structured block. 9782 // longjmp() and throw() must not violate the entry/exit criteria. 9783 CS->getCapturedDecl()->setNothrow(); 9784 } 9785 9786 9787 OMPLoopDirective::HelperExprs B; 9788 // In presence of clause 'collapse' with number of loops, it will 9789 // define the nested loops number. 9790 unsigned NestedLoopCount = checkOpenMPLoop( 9791 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9792 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9793 VarsWithImplicitDSA, B); 9794 9795 if (NestedLoopCount == 0) 9796 return StmtError(); 9797 9798 assert((CurContext->isDependentContext() || B.builtAll()) && 9799 "omp teams distribute simd loop exprs were not built"); 9800 9801 if (!CurContext->isDependentContext()) { 9802 // Finalize the clauses that need pre-built expressions for CodeGen. 9803 for (OMPClause *C : Clauses) { 9804 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9805 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9806 B.NumIterations, *this, CurScope, 9807 DSAStack)) 9808 return StmtError(); 9809 } 9810 } 9811 9812 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9813 return StmtError(); 9814 9815 setFunctionHasBranchProtectedScope(); 9816 9817 DSAStack->setParentTeamsRegionLoc(StartLoc); 9818 9819 return OMPTeamsDistributeSimdDirective::Create( 9820 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9821 } 9822 9823 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9824 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9825 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9826 if (!AStmt) 9827 return StmtError(); 9828 9829 auto *CS = cast<CapturedStmt>(AStmt); 9830 // 1.2.2 OpenMP Language Terminology 9831 // Structured block - An executable statement with a single entry at the 9832 // top and a single exit at the bottom. 9833 // The point of exit cannot be a branch out of the structured block. 9834 // longjmp() and throw() must not violate the entry/exit criteria. 9835 CS->getCapturedDecl()->setNothrow(); 9836 9837 for (int ThisCaptureLevel = 9838 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9839 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9840 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9841 // 1.2.2 OpenMP Language Terminology 9842 // Structured block - An executable statement with a single entry at the 9843 // top and a single exit at the bottom. 9844 // The point of exit cannot be a branch out of the structured block. 9845 // longjmp() and throw() must not violate the entry/exit criteria. 9846 CS->getCapturedDecl()->setNothrow(); 9847 } 9848 9849 OMPLoopDirective::HelperExprs B; 9850 // In presence of clause 'collapse' with number of loops, it will 9851 // define the nested loops number. 9852 unsigned NestedLoopCount = checkOpenMPLoop( 9853 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9854 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9855 VarsWithImplicitDSA, B); 9856 9857 if (NestedLoopCount == 0) 9858 return StmtError(); 9859 9860 assert((CurContext->isDependentContext() || B.builtAll()) && 9861 "omp for loop exprs were not built"); 9862 9863 if (!CurContext->isDependentContext()) { 9864 // Finalize the clauses that need pre-built expressions for CodeGen. 9865 for (OMPClause *C : Clauses) { 9866 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9867 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9868 B.NumIterations, *this, CurScope, 9869 DSAStack)) 9870 return StmtError(); 9871 } 9872 } 9873 9874 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9875 return StmtError(); 9876 9877 setFunctionHasBranchProtectedScope(); 9878 9879 DSAStack->setParentTeamsRegionLoc(StartLoc); 9880 9881 return OMPTeamsDistributeParallelForSimdDirective::Create( 9882 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9883 } 9884 9885 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9886 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9887 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9888 if (!AStmt) 9889 return StmtError(); 9890 9891 auto *CS = cast<CapturedStmt>(AStmt); 9892 // 1.2.2 OpenMP Language Terminology 9893 // Structured block - An executable statement with a single entry at the 9894 // top and a single exit at the bottom. 9895 // The point of exit cannot be a branch out of the structured block. 9896 // longjmp() and throw() must not violate the entry/exit criteria. 9897 CS->getCapturedDecl()->setNothrow(); 9898 9899 for (int ThisCaptureLevel = 9900 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9901 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9902 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9903 // 1.2.2 OpenMP Language Terminology 9904 // Structured block - An executable statement with a single entry at the 9905 // top and a single exit at the bottom. 9906 // The point of exit cannot be a branch out of the structured block. 9907 // longjmp() and throw() must not violate the entry/exit criteria. 9908 CS->getCapturedDecl()->setNothrow(); 9909 } 9910 9911 OMPLoopDirective::HelperExprs B; 9912 // In presence of clause 'collapse' with number of loops, it will 9913 // define the nested loops number. 9914 unsigned NestedLoopCount = checkOpenMPLoop( 9915 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9916 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9917 VarsWithImplicitDSA, B); 9918 9919 if (NestedLoopCount == 0) 9920 return StmtError(); 9921 9922 assert((CurContext->isDependentContext() || B.builtAll()) && 9923 "omp for loop exprs were not built"); 9924 9925 setFunctionHasBranchProtectedScope(); 9926 9927 DSAStack->setParentTeamsRegionLoc(StartLoc); 9928 9929 return OMPTeamsDistributeParallelForDirective::Create( 9930 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9931 DSAStack->isCancelRegion()); 9932 } 9933 9934 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9935 Stmt *AStmt, 9936 SourceLocation StartLoc, 9937 SourceLocation EndLoc) { 9938 if (!AStmt) 9939 return StmtError(); 9940 9941 auto *CS = cast<CapturedStmt>(AStmt); 9942 // 1.2.2 OpenMP Language Terminology 9943 // Structured block - An executable statement with a single entry at the 9944 // top and a single exit at the bottom. 9945 // The point of exit cannot be a branch out of the structured block. 9946 // longjmp() and throw() must not violate the entry/exit criteria. 9947 CS->getCapturedDecl()->setNothrow(); 9948 9949 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9950 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9951 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9952 // 1.2.2 OpenMP Language Terminology 9953 // Structured block - An executable statement with a single entry at the 9954 // top and a single exit at the bottom. 9955 // The point of exit cannot be a branch out of the structured block. 9956 // longjmp() and throw() must not violate the entry/exit criteria. 9957 CS->getCapturedDecl()->setNothrow(); 9958 } 9959 setFunctionHasBranchProtectedScope(); 9960 9961 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9962 AStmt); 9963 } 9964 9965 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9966 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9967 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9968 if (!AStmt) 9969 return StmtError(); 9970 9971 auto *CS = cast<CapturedStmt>(AStmt); 9972 // 1.2.2 OpenMP Language Terminology 9973 // Structured block - An executable statement with a single entry at the 9974 // top and a single exit at the bottom. 9975 // The point of exit cannot be a branch out of the structured block. 9976 // longjmp() and throw() must not violate the entry/exit criteria. 9977 CS->getCapturedDecl()->setNothrow(); 9978 for (int ThisCaptureLevel = 9979 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9980 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9981 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9982 // 1.2.2 OpenMP Language Terminology 9983 // Structured block - An executable statement with a single entry at the 9984 // top and a single exit at the bottom. 9985 // The point of exit cannot be a branch out of the structured block. 9986 // longjmp() and throw() must not violate the entry/exit criteria. 9987 CS->getCapturedDecl()->setNothrow(); 9988 } 9989 9990 OMPLoopDirective::HelperExprs B; 9991 // In presence of clause 'collapse' with number of loops, it will 9992 // define the nested loops number. 9993 unsigned NestedLoopCount = checkOpenMPLoop( 9994 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9995 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9996 VarsWithImplicitDSA, B); 9997 if (NestedLoopCount == 0) 9998 return StmtError(); 9999 10000 assert((CurContext->isDependentContext() || B.builtAll()) && 10001 "omp target teams distribute loop exprs were not built"); 10002 10003 setFunctionHasBranchProtectedScope(); 10004 return OMPTargetTeamsDistributeDirective::Create( 10005 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10006 } 10007 10008 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10009 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10010 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10011 if (!AStmt) 10012 return StmtError(); 10013 10014 auto *CS = cast<CapturedStmt>(AStmt); 10015 // 1.2.2 OpenMP Language Terminology 10016 // Structured block - An executable statement with a single entry at the 10017 // top and a single exit at the bottom. 10018 // The point of exit cannot be a branch out of the structured block. 10019 // longjmp() and throw() must not violate the entry/exit criteria. 10020 CS->getCapturedDecl()->setNothrow(); 10021 for (int ThisCaptureLevel = 10022 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10023 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10024 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10025 // 1.2.2 OpenMP Language Terminology 10026 // Structured block - An executable statement with a single entry at the 10027 // top and a single exit at the bottom. 10028 // The point of exit cannot be a branch out of the structured block. 10029 // longjmp() and throw() must not violate the entry/exit criteria. 10030 CS->getCapturedDecl()->setNothrow(); 10031 } 10032 10033 OMPLoopDirective::HelperExprs B; 10034 // In presence of clause 'collapse' with number of loops, it will 10035 // define the nested loops number. 10036 unsigned NestedLoopCount = checkOpenMPLoop( 10037 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10038 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10039 VarsWithImplicitDSA, B); 10040 if (NestedLoopCount == 0) 10041 return StmtError(); 10042 10043 assert((CurContext->isDependentContext() || B.builtAll()) && 10044 "omp target teams distribute parallel for loop exprs were not built"); 10045 10046 if (!CurContext->isDependentContext()) { 10047 // Finalize the clauses that need pre-built expressions for CodeGen. 10048 for (OMPClause *C : Clauses) { 10049 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10050 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10051 B.NumIterations, *this, CurScope, 10052 DSAStack)) 10053 return StmtError(); 10054 } 10055 } 10056 10057 setFunctionHasBranchProtectedScope(); 10058 return OMPTargetTeamsDistributeParallelForDirective::Create( 10059 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10060 DSAStack->isCancelRegion()); 10061 } 10062 10063 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10064 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10065 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10066 if (!AStmt) 10067 return StmtError(); 10068 10069 auto *CS = cast<CapturedStmt>(AStmt); 10070 // 1.2.2 OpenMP Language Terminology 10071 // Structured block - An executable statement with a single entry at the 10072 // top and a single exit at the bottom. 10073 // The point of exit cannot be a branch out of the structured block. 10074 // longjmp() and throw() must not violate the entry/exit criteria. 10075 CS->getCapturedDecl()->setNothrow(); 10076 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10077 OMPD_target_teams_distribute_parallel_for_simd); 10078 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10079 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10080 // 1.2.2 OpenMP Language Terminology 10081 // Structured block - An executable statement with a single entry at the 10082 // top and a single exit at the bottom. 10083 // The point of exit cannot be a branch out of the structured block. 10084 // longjmp() and throw() must not violate the entry/exit criteria. 10085 CS->getCapturedDecl()->setNothrow(); 10086 } 10087 10088 OMPLoopDirective::HelperExprs B; 10089 // In presence of clause 'collapse' with number of loops, it will 10090 // define the nested loops number. 10091 unsigned NestedLoopCount = 10092 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10093 getCollapseNumberExpr(Clauses), 10094 nullptr /*ordered not a clause on distribute*/, CS, *this, 10095 *DSAStack, VarsWithImplicitDSA, B); 10096 if (NestedLoopCount == 0) 10097 return StmtError(); 10098 10099 assert((CurContext->isDependentContext() || B.builtAll()) && 10100 "omp target teams distribute parallel for simd loop exprs were not " 10101 "built"); 10102 10103 if (!CurContext->isDependentContext()) { 10104 // Finalize the clauses that need pre-built expressions for CodeGen. 10105 for (OMPClause *C : Clauses) { 10106 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10107 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10108 B.NumIterations, *this, CurScope, 10109 DSAStack)) 10110 return StmtError(); 10111 } 10112 } 10113 10114 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10115 return StmtError(); 10116 10117 setFunctionHasBranchProtectedScope(); 10118 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10119 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10120 } 10121 10122 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10123 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10124 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10125 if (!AStmt) 10126 return StmtError(); 10127 10128 auto *CS = cast<CapturedStmt>(AStmt); 10129 // 1.2.2 OpenMP Language Terminology 10130 // Structured block - An executable statement with a single entry at the 10131 // top and a single exit at the bottom. 10132 // The point of exit cannot be a branch out of the structured block. 10133 // longjmp() and throw() must not violate the entry/exit criteria. 10134 CS->getCapturedDecl()->setNothrow(); 10135 for (int ThisCaptureLevel = 10136 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10137 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10138 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10139 // 1.2.2 OpenMP Language Terminology 10140 // Structured block - An executable statement with a single entry at the 10141 // top and a single exit at the bottom. 10142 // The point of exit cannot be a branch out of the structured block. 10143 // longjmp() and throw() must not violate the entry/exit criteria. 10144 CS->getCapturedDecl()->setNothrow(); 10145 } 10146 10147 OMPLoopDirective::HelperExprs B; 10148 // In presence of clause 'collapse' with number of loops, it will 10149 // define the nested loops number. 10150 unsigned NestedLoopCount = checkOpenMPLoop( 10151 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10152 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10153 VarsWithImplicitDSA, B); 10154 if (NestedLoopCount == 0) 10155 return StmtError(); 10156 10157 assert((CurContext->isDependentContext() || B.builtAll()) && 10158 "omp target teams distribute simd loop exprs were not built"); 10159 10160 if (!CurContext->isDependentContext()) { 10161 // Finalize the clauses that need pre-built expressions for CodeGen. 10162 for (OMPClause *C : Clauses) { 10163 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10164 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10165 B.NumIterations, *this, CurScope, 10166 DSAStack)) 10167 return StmtError(); 10168 } 10169 } 10170 10171 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10172 return StmtError(); 10173 10174 setFunctionHasBranchProtectedScope(); 10175 return OMPTargetTeamsDistributeSimdDirective::Create( 10176 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10177 } 10178 10179 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10180 SourceLocation StartLoc, 10181 SourceLocation LParenLoc, 10182 SourceLocation EndLoc) { 10183 OMPClause *Res = nullptr; 10184 switch (Kind) { 10185 case OMPC_final: 10186 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10187 break; 10188 case OMPC_num_threads: 10189 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10190 break; 10191 case OMPC_safelen: 10192 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10193 break; 10194 case OMPC_simdlen: 10195 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10196 break; 10197 case OMPC_allocator: 10198 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10199 break; 10200 case OMPC_collapse: 10201 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10202 break; 10203 case OMPC_ordered: 10204 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10205 break; 10206 case OMPC_device: 10207 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10208 break; 10209 case OMPC_num_teams: 10210 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10211 break; 10212 case OMPC_thread_limit: 10213 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10214 break; 10215 case OMPC_priority: 10216 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10217 break; 10218 case OMPC_grainsize: 10219 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10220 break; 10221 case OMPC_num_tasks: 10222 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10223 break; 10224 case OMPC_hint: 10225 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10226 break; 10227 case OMPC_if: 10228 case OMPC_default: 10229 case OMPC_proc_bind: 10230 case OMPC_schedule: 10231 case OMPC_private: 10232 case OMPC_firstprivate: 10233 case OMPC_lastprivate: 10234 case OMPC_shared: 10235 case OMPC_reduction: 10236 case OMPC_task_reduction: 10237 case OMPC_in_reduction: 10238 case OMPC_linear: 10239 case OMPC_aligned: 10240 case OMPC_copyin: 10241 case OMPC_copyprivate: 10242 case OMPC_nowait: 10243 case OMPC_untied: 10244 case OMPC_mergeable: 10245 case OMPC_threadprivate: 10246 case OMPC_allocate: 10247 case OMPC_flush: 10248 case OMPC_read: 10249 case OMPC_write: 10250 case OMPC_update: 10251 case OMPC_capture: 10252 case OMPC_seq_cst: 10253 case OMPC_depend: 10254 case OMPC_threads: 10255 case OMPC_simd: 10256 case OMPC_map: 10257 case OMPC_nogroup: 10258 case OMPC_dist_schedule: 10259 case OMPC_defaultmap: 10260 case OMPC_unknown: 10261 case OMPC_uniform: 10262 case OMPC_to: 10263 case OMPC_from: 10264 case OMPC_use_device_ptr: 10265 case OMPC_is_device_ptr: 10266 case OMPC_unified_address: 10267 case OMPC_unified_shared_memory: 10268 case OMPC_reverse_offload: 10269 case OMPC_dynamic_allocators: 10270 case OMPC_atomic_default_mem_order: 10271 case OMPC_device_type: 10272 case OMPC_match: 10273 llvm_unreachable("Clause is not allowed."); 10274 } 10275 return Res; 10276 } 10277 10278 // An OpenMP directive such as 'target parallel' has two captured regions: 10279 // for the 'target' and 'parallel' respectively. This function returns 10280 // the region in which to capture expressions associated with a clause. 10281 // A return value of OMPD_unknown signifies that the expression should not 10282 // be captured. 10283 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10284 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10285 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10286 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10287 switch (CKind) { 10288 case OMPC_if: 10289 switch (DKind) { 10290 case OMPD_target_parallel: 10291 case OMPD_target_parallel_for: 10292 case OMPD_target_parallel_for_simd: 10293 // If this clause applies to the nested 'parallel' region, capture within 10294 // the 'target' region, otherwise do not capture. 10295 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10296 CaptureRegion = OMPD_target; 10297 break; 10298 case OMPD_target_teams_distribute_parallel_for: 10299 case OMPD_target_teams_distribute_parallel_for_simd: 10300 // If this clause applies to the nested 'parallel' region, capture within 10301 // the 'teams' region, otherwise do not capture. 10302 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10303 CaptureRegion = OMPD_teams; 10304 break; 10305 case OMPD_teams_distribute_parallel_for: 10306 case OMPD_teams_distribute_parallel_for_simd: 10307 CaptureRegion = OMPD_teams; 10308 break; 10309 case OMPD_target_update: 10310 case OMPD_target_enter_data: 10311 case OMPD_target_exit_data: 10312 CaptureRegion = OMPD_task; 10313 break; 10314 case OMPD_parallel_master_taskloop: 10315 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10316 CaptureRegion = OMPD_parallel; 10317 break; 10318 case OMPD_cancel: 10319 case OMPD_parallel: 10320 case OMPD_parallel_sections: 10321 case OMPD_parallel_for: 10322 case OMPD_parallel_for_simd: 10323 case OMPD_target: 10324 case OMPD_target_simd: 10325 case OMPD_target_teams: 10326 case OMPD_target_teams_distribute: 10327 case OMPD_target_teams_distribute_simd: 10328 case OMPD_distribute_parallel_for: 10329 case OMPD_distribute_parallel_for_simd: 10330 case OMPD_task: 10331 case OMPD_taskloop: 10332 case OMPD_taskloop_simd: 10333 case OMPD_master_taskloop: 10334 case OMPD_target_data: 10335 // Do not capture if-clause expressions. 10336 break; 10337 case OMPD_threadprivate: 10338 case OMPD_allocate: 10339 case OMPD_taskyield: 10340 case OMPD_barrier: 10341 case OMPD_taskwait: 10342 case OMPD_cancellation_point: 10343 case OMPD_flush: 10344 case OMPD_declare_reduction: 10345 case OMPD_declare_mapper: 10346 case OMPD_declare_simd: 10347 case OMPD_declare_variant: 10348 case OMPD_declare_target: 10349 case OMPD_end_declare_target: 10350 case OMPD_teams: 10351 case OMPD_simd: 10352 case OMPD_for: 10353 case OMPD_for_simd: 10354 case OMPD_sections: 10355 case OMPD_section: 10356 case OMPD_single: 10357 case OMPD_master: 10358 case OMPD_critical: 10359 case OMPD_taskgroup: 10360 case OMPD_distribute: 10361 case OMPD_ordered: 10362 case OMPD_atomic: 10363 case OMPD_distribute_simd: 10364 case OMPD_teams_distribute: 10365 case OMPD_teams_distribute_simd: 10366 case OMPD_requires: 10367 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10368 case OMPD_unknown: 10369 llvm_unreachable("Unknown OpenMP directive"); 10370 } 10371 break; 10372 case OMPC_num_threads: 10373 switch (DKind) { 10374 case OMPD_target_parallel: 10375 case OMPD_target_parallel_for: 10376 case OMPD_target_parallel_for_simd: 10377 CaptureRegion = OMPD_target; 10378 break; 10379 case OMPD_teams_distribute_parallel_for: 10380 case OMPD_teams_distribute_parallel_for_simd: 10381 case OMPD_target_teams_distribute_parallel_for: 10382 case OMPD_target_teams_distribute_parallel_for_simd: 10383 CaptureRegion = OMPD_teams; 10384 break; 10385 case OMPD_parallel: 10386 case OMPD_parallel_sections: 10387 case OMPD_parallel_for: 10388 case OMPD_parallel_for_simd: 10389 case OMPD_distribute_parallel_for: 10390 case OMPD_distribute_parallel_for_simd: 10391 case OMPD_parallel_master_taskloop: 10392 // Do not capture num_threads-clause expressions. 10393 break; 10394 case OMPD_target_data: 10395 case OMPD_target_enter_data: 10396 case OMPD_target_exit_data: 10397 case OMPD_target_update: 10398 case OMPD_target: 10399 case OMPD_target_simd: 10400 case OMPD_target_teams: 10401 case OMPD_target_teams_distribute: 10402 case OMPD_target_teams_distribute_simd: 10403 case OMPD_cancel: 10404 case OMPD_task: 10405 case OMPD_taskloop: 10406 case OMPD_taskloop_simd: 10407 case OMPD_master_taskloop: 10408 case OMPD_threadprivate: 10409 case OMPD_allocate: 10410 case OMPD_taskyield: 10411 case OMPD_barrier: 10412 case OMPD_taskwait: 10413 case OMPD_cancellation_point: 10414 case OMPD_flush: 10415 case OMPD_declare_reduction: 10416 case OMPD_declare_mapper: 10417 case OMPD_declare_simd: 10418 case OMPD_declare_variant: 10419 case OMPD_declare_target: 10420 case OMPD_end_declare_target: 10421 case OMPD_teams: 10422 case OMPD_simd: 10423 case OMPD_for: 10424 case OMPD_for_simd: 10425 case OMPD_sections: 10426 case OMPD_section: 10427 case OMPD_single: 10428 case OMPD_master: 10429 case OMPD_critical: 10430 case OMPD_taskgroup: 10431 case OMPD_distribute: 10432 case OMPD_ordered: 10433 case OMPD_atomic: 10434 case OMPD_distribute_simd: 10435 case OMPD_teams_distribute: 10436 case OMPD_teams_distribute_simd: 10437 case OMPD_requires: 10438 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10439 case OMPD_unknown: 10440 llvm_unreachable("Unknown OpenMP directive"); 10441 } 10442 break; 10443 case OMPC_num_teams: 10444 switch (DKind) { 10445 case OMPD_target_teams: 10446 case OMPD_target_teams_distribute: 10447 case OMPD_target_teams_distribute_simd: 10448 case OMPD_target_teams_distribute_parallel_for: 10449 case OMPD_target_teams_distribute_parallel_for_simd: 10450 CaptureRegion = OMPD_target; 10451 break; 10452 case OMPD_teams_distribute_parallel_for: 10453 case OMPD_teams_distribute_parallel_for_simd: 10454 case OMPD_teams: 10455 case OMPD_teams_distribute: 10456 case OMPD_teams_distribute_simd: 10457 // Do not capture num_teams-clause expressions. 10458 break; 10459 case OMPD_distribute_parallel_for: 10460 case OMPD_distribute_parallel_for_simd: 10461 case OMPD_task: 10462 case OMPD_taskloop: 10463 case OMPD_taskloop_simd: 10464 case OMPD_master_taskloop: 10465 case OMPD_parallel_master_taskloop: 10466 case OMPD_target_data: 10467 case OMPD_target_enter_data: 10468 case OMPD_target_exit_data: 10469 case OMPD_target_update: 10470 case OMPD_cancel: 10471 case OMPD_parallel: 10472 case OMPD_parallel_sections: 10473 case OMPD_parallel_for: 10474 case OMPD_parallel_for_simd: 10475 case OMPD_target: 10476 case OMPD_target_simd: 10477 case OMPD_target_parallel: 10478 case OMPD_target_parallel_for: 10479 case OMPD_target_parallel_for_simd: 10480 case OMPD_threadprivate: 10481 case OMPD_allocate: 10482 case OMPD_taskyield: 10483 case OMPD_barrier: 10484 case OMPD_taskwait: 10485 case OMPD_cancellation_point: 10486 case OMPD_flush: 10487 case OMPD_declare_reduction: 10488 case OMPD_declare_mapper: 10489 case OMPD_declare_simd: 10490 case OMPD_declare_variant: 10491 case OMPD_declare_target: 10492 case OMPD_end_declare_target: 10493 case OMPD_simd: 10494 case OMPD_for: 10495 case OMPD_for_simd: 10496 case OMPD_sections: 10497 case OMPD_section: 10498 case OMPD_single: 10499 case OMPD_master: 10500 case OMPD_critical: 10501 case OMPD_taskgroup: 10502 case OMPD_distribute: 10503 case OMPD_ordered: 10504 case OMPD_atomic: 10505 case OMPD_distribute_simd: 10506 case OMPD_requires: 10507 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10508 case OMPD_unknown: 10509 llvm_unreachable("Unknown OpenMP directive"); 10510 } 10511 break; 10512 case OMPC_thread_limit: 10513 switch (DKind) { 10514 case OMPD_target_teams: 10515 case OMPD_target_teams_distribute: 10516 case OMPD_target_teams_distribute_simd: 10517 case OMPD_target_teams_distribute_parallel_for: 10518 case OMPD_target_teams_distribute_parallel_for_simd: 10519 CaptureRegion = OMPD_target; 10520 break; 10521 case OMPD_teams_distribute_parallel_for: 10522 case OMPD_teams_distribute_parallel_for_simd: 10523 case OMPD_teams: 10524 case OMPD_teams_distribute: 10525 case OMPD_teams_distribute_simd: 10526 // Do not capture thread_limit-clause expressions. 10527 break; 10528 case OMPD_distribute_parallel_for: 10529 case OMPD_distribute_parallel_for_simd: 10530 case OMPD_task: 10531 case OMPD_taskloop: 10532 case OMPD_taskloop_simd: 10533 case OMPD_master_taskloop: 10534 case OMPD_parallel_master_taskloop: 10535 case OMPD_target_data: 10536 case OMPD_target_enter_data: 10537 case OMPD_target_exit_data: 10538 case OMPD_target_update: 10539 case OMPD_cancel: 10540 case OMPD_parallel: 10541 case OMPD_parallel_sections: 10542 case OMPD_parallel_for: 10543 case OMPD_parallel_for_simd: 10544 case OMPD_target: 10545 case OMPD_target_simd: 10546 case OMPD_target_parallel: 10547 case OMPD_target_parallel_for: 10548 case OMPD_target_parallel_for_simd: 10549 case OMPD_threadprivate: 10550 case OMPD_allocate: 10551 case OMPD_taskyield: 10552 case OMPD_barrier: 10553 case OMPD_taskwait: 10554 case OMPD_cancellation_point: 10555 case OMPD_flush: 10556 case OMPD_declare_reduction: 10557 case OMPD_declare_mapper: 10558 case OMPD_declare_simd: 10559 case OMPD_declare_variant: 10560 case OMPD_declare_target: 10561 case OMPD_end_declare_target: 10562 case OMPD_simd: 10563 case OMPD_for: 10564 case OMPD_for_simd: 10565 case OMPD_sections: 10566 case OMPD_section: 10567 case OMPD_single: 10568 case OMPD_master: 10569 case OMPD_critical: 10570 case OMPD_taskgroup: 10571 case OMPD_distribute: 10572 case OMPD_ordered: 10573 case OMPD_atomic: 10574 case OMPD_distribute_simd: 10575 case OMPD_requires: 10576 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10577 case OMPD_unknown: 10578 llvm_unreachable("Unknown OpenMP directive"); 10579 } 10580 break; 10581 case OMPC_schedule: 10582 switch (DKind) { 10583 case OMPD_parallel_for: 10584 case OMPD_parallel_for_simd: 10585 case OMPD_distribute_parallel_for: 10586 case OMPD_distribute_parallel_for_simd: 10587 case OMPD_teams_distribute_parallel_for: 10588 case OMPD_teams_distribute_parallel_for_simd: 10589 case OMPD_target_parallel_for: 10590 case OMPD_target_parallel_for_simd: 10591 case OMPD_target_teams_distribute_parallel_for: 10592 case OMPD_target_teams_distribute_parallel_for_simd: 10593 CaptureRegion = OMPD_parallel; 10594 break; 10595 case OMPD_for: 10596 case OMPD_for_simd: 10597 // Do not capture schedule-clause expressions. 10598 break; 10599 case OMPD_task: 10600 case OMPD_taskloop: 10601 case OMPD_taskloop_simd: 10602 case OMPD_master_taskloop: 10603 case OMPD_parallel_master_taskloop: 10604 case OMPD_target_data: 10605 case OMPD_target_enter_data: 10606 case OMPD_target_exit_data: 10607 case OMPD_target_update: 10608 case OMPD_teams: 10609 case OMPD_teams_distribute: 10610 case OMPD_teams_distribute_simd: 10611 case OMPD_target_teams_distribute: 10612 case OMPD_target_teams_distribute_simd: 10613 case OMPD_target: 10614 case OMPD_target_simd: 10615 case OMPD_target_parallel: 10616 case OMPD_cancel: 10617 case OMPD_parallel: 10618 case OMPD_parallel_sections: 10619 case OMPD_threadprivate: 10620 case OMPD_allocate: 10621 case OMPD_taskyield: 10622 case OMPD_barrier: 10623 case OMPD_taskwait: 10624 case OMPD_cancellation_point: 10625 case OMPD_flush: 10626 case OMPD_declare_reduction: 10627 case OMPD_declare_mapper: 10628 case OMPD_declare_simd: 10629 case OMPD_declare_variant: 10630 case OMPD_declare_target: 10631 case OMPD_end_declare_target: 10632 case OMPD_simd: 10633 case OMPD_sections: 10634 case OMPD_section: 10635 case OMPD_single: 10636 case OMPD_master: 10637 case OMPD_critical: 10638 case OMPD_taskgroup: 10639 case OMPD_distribute: 10640 case OMPD_ordered: 10641 case OMPD_atomic: 10642 case OMPD_distribute_simd: 10643 case OMPD_target_teams: 10644 case OMPD_requires: 10645 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10646 case OMPD_unknown: 10647 llvm_unreachable("Unknown OpenMP directive"); 10648 } 10649 break; 10650 case OMPC_dist_schedule: 10651 switch (DKind) { 10652 case OMPD_teams_distribute_parallel_for: 10653 case OMPD_teams_distribute_parallel_for_simd: 10654 case OMPD_teams_distribute: 10655 case OMPD_teams_distribute_simd: 10656 case OMPD_target_teams_distribute_parallel_for: 10657 case OMPD_target_teams_distribute_parallel_for_simd: 10658 case OMPD_target_teams_distribute: 10659 case OMPD_target_teams_distribute_simd: 10660 CaptureRegion = OMPD_teams; 10661 break; 10662 case OMPD_distribute_parallel_for: 10663 case OMPD_distribute_parallel_for_simd: 10664 case OMPD_distribute: 10665 case OMPD_distribute_simd: 10666 // Do not capture thread_limit-clause expressions. 10667 break; 10668 case OMPD_parallel_for: 10669 case OMPD_parallel_for_simd: 10670 case OMPD_target_parallel_for_simd: 10671 case OMPD_target_parallel_for: 10672 case OMPD_task: 10673 case OMPD_taskloop: 10674 case OMPD_taskloop_simd: 10675 case OMPD_master_taskloop: 10676 case OMPD_parallel_master_taskloop: 10677 case OMPD_target_data: 10678 case OMPD_target_enter_data: 10679 case OMPD_target_exit_data: 10680 case OMPD_target_update: 10681 case OMPD_teams: 10682 case OMPD_target: 10683 case OMPD_target_simd: 10684 case OMPD_target_parallel: 10685 case OMPD_cancel: 10686 case OMPD_parallel: 10687 case OMPD_parallel_sections: 10688 case OMPD_threadprivate: 10689 case OMPD_allocate: 10690 case OMPD_taskyield: 10691 case OMPD_barrier: 10692 case OMPD_taskwait: 10693 case OMPD_cancellation_point: 10694 case OMPD_flush: 10695 case OMPD_declare_reduction: 10696 case OMPD_declare_mapper: 10697 case OMPD_declare_simd: 10698 case OMPD_declare_variant: 10699 case OMPD_declare_target: 10700 case OMPD_end_declare_target: 10701 case OMPD_simd: 10702 case OMPD_for: 10703 case OMPD_for_simd: 10704 case OMPD_sections: 10705 case OMPD_section: 10706 case OMPD_single: 10707 case OMPD_master: 10708 case OMPD_critical: 10709 case OMPD_taskgroup: 10710 case OMPD_ordered: 10711 case OMPD_atomic: 10712 case OMPD_target_teams: 10713 case OMPD_requires: 10714 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10715 case OMPD_unknown: 10716 llvm_unreachable("Unknown OpenMP directive"); 10717 } 10718 break; 10719 case OMPC_device: 10720 switch (DKind) { 10721 case OMPD_target_update: 10722 case OMPD_target_enter_data: 10723 case OMPD_target_exit_data: 10724 case OMPD_target: 10725 case OMPD_target_simd: 10726 case OMPD_target_teams: 10727 case OMPD_target_parallel: 10728 case OMPD_target_teams_distribute: 10729 case OMPD_target_teams_distribute_simd: 10730 case OMPD_target_parallel_for: 10731 case OMPD_target_parallel_for_simd: 10732 case OMPD_target_teams_distribute_parallel_for: 10733 case OMPD_target_teams_distribute_parallel_for_simd: 10734 CaptureRegion = OMPD_task; 10735 break; 10736 case OMPD_target_data: 10737 // Do not capture device-clause expressions. 10738 break; 10739 case OMPD_teams_distribute_parallel_for: 10740 case OMPD_teams_distribute_parallel_for_simd: 10741 case OMPD_teams: 10742 case OMPD_teams_distribute: 10743 case OMPD_teams_distribute_simd: 10744 case OMPD_distribute_parallel_for: 10745 case OMPD_distribute_parallel_for_simd: 10746 case OMPD_task: 10747 case OMPD_taskloop: 10748 case OMPD_taskloop_simd: 10749 case OMPD_master_taskloop: 10750 case OMPD_parallel_master_taskloop: 10751 case OMPD_cancel: 10752 case OMPD_parallel: 10753 case OMPD_parallel_sections: 10754 case OMPD_parallel_for: 10755 case OMPD_parallel_for_simd: 10756 case OMPD_threadprivate: 10757 case OMPD_allocate: 10758 case OMPD_taskyield: 10759 case OMPD_barrier: 10760 case OMPD_taskwait: 10761 case OMPD_cancellation_point: 10762 case OMPD_flush: 10763 case OMPD_declare_reduction: 10764 case OMPD_declare_mapper: 10765 case OMPD_declare_simd: 10766 case OMPD_declare_variant: 10767 case OMPD_declare_target: 10768 case OMPD_end_declare_target: 10769 case OMPD_simd: 10770 case OMPD_for: 10771 case OMPD_for_simd: 10772 case OMPD_sections: 10773 case OMPD_section: 10774 case OMPD_single: 10775 case OMPD_master: 10776 case OMPD_critical: 10777 case OMPD_taskgroup: 10778 case OMPD_distribute: 10779 case OMPD_ordered: 10780 case OMPD_atomic: 10781 case OMPD_distribute_simd: 10782 case OMPD_requires: 10783 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10784 case OMPD_unknown: 10785 llvm_unreachable("Unknown OpenMP directive"); 10786 } 10787 break; 10788 case OMPC_grainsize: 10789 case OMPC_num_tasks: 10790 case OMPC_final: 10791 switch (DKind) { 10792 case OMPD_task: 10793 case OMPD_taskloop: 10794 case OMPD_taskloop_simd: 10795 case OMPD_master_taskloop: 10796 break; 10797 case OMPD_parallel_master_taskloop: 10798 CaptureRegion = OMPD_parallel; 10799 break; 10800 case OMPD_target_update: 10801 case OMPD_target_enter_data: 10802 case OMPD_target_exit_data: 10803 case OMPD_target: 10804 case OMPD_target_simd: 10805 case OMPD_target_teams: 10806 case OMPD_target_parallel: 10807 case OMPD_target_teams_distribute: 10808 case OMPD_target_teams_distribute_simd: 10809 case OMPD_target_parallel_for: 10810 case OMPD_target_parallel_for_simd: 10811 case OMPD_target_teams_distribute_parallel_for: 10812 case OMPD_target_teams_distribute_parallel_for_simd: 10813 case OMPD_target_data: 10814 case OMPD_teams_distribute_parallel_for: 10815 case OMPD_teams_distribute_parallel_for_simd: 10816 case OMPD_teams: 10817 case OMPD_teams_distribute: 10818 case OMPD_teams_distribute_simd: 10819 case OMPD_distribute_parallel_for: 10820 case OMPD_distribute_parallel_for_simd: 10821 case OMPD_cancel: 10822 case OMPD_parallel: 10823 case OMPD_parallel_sections: 10824 case OMPD_parallel_for: 10825 case OMPD_parallel_for_simd: 10826 case OMPD_threadprivate: 10827 case OMPD_allocate: 10828 case OMPD_taskyield: 10829 case OMPD_barrier: 10830 case OMPD_taskwait: 10831 case OMPD_cancellation_point: 10832 case OMPD_flush: 10833 case OMPD_declare_reduction: 10834 case OMPD_declare_mapper: 10835 case OMPD_declare_simd: 10836 case OMPD_declare_variant: 10837 case OMPD_declare_target: 10838 case OMPD_end_declare_target: 10839 case OMPD_simd: 10840 case OMPD_for: 10841 case OMPD_for_simd: 10842 case OMPD_sections: 10843 case OMPD_section: 10844 case OMPD_single: 10845 case OMPD_master: 10846 case OMPD_critical: 10847 case OMPD_taskgroup: 10848 case OMPD_distribute: 10849 case OMPD_ordered: 10850 case OMPD_atomic: 10851 case OMPD_distribute_simd: 10852 case OMPD_requires: 10853 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 10854 case OMPD_unknown: 10855 llvm_unreachable("Unknown OpenMP directive"); 10856 } 10857 break; 10858 case OMPC_firstprivate: 10859 case OMPC_lastprivate: 10860 case OMPC_reduction: 10861 case OMPC_task_reduction: 10862 case OMPC_in_reduction: 10863 case OMPC_linear: 10864 case OMPC_default: 10865 case OMPC_proc_bind: 10866 case OMPC_safelen: 10867 case OMPC_simdlen: 10868 case OMPC_allocator: 10869 case OMPC_collapse: 10870 case OMPC_private: 10871 case OMPC_shared: 10872 case OMPC_aligned: 10873 case OMPC_copyin: 10874 case OMPC_copyprivate: 10875 case OMPC_ordered: 10876 case OMPC_nowait: 10877 case OMPC_untied: 10878 case OMPC_mergeable: 10879 case OMPC_threadprivate: 10880 case OMPC_allocate: 10881 case OMPC_flush: 10882 case OMPC_read: 10883 case OMPC_write: 10884 case OMPC_update: 10885 case OMPC_capture: 10886 case OMPC_seq_cst: 10887 case OMPC_depend: 10888 case OMPC_threads: 10889 case OMPC_simd: 10890 case OMPC_map: 10891 case OMPC_priority: 10892 case OMPC_nogroup: 10893 case OMPC_hint: 10894 case OMPC_defaultmap: 10895 case OMPC_unknown: 10896 case OMPC_uniform: 10897 case OMPC_to: 10898 case OMPC_from: 10899 case OMPC_use_device_ptr: 10900 case OMPC_is_device_ptr: 10901 case OMPC_unified_address: 10902 case OMPC_unified_shared_memory: 10903 case OMPC_reverse_offload: 10904 case OMPC_dynamic_allocators: 10905 case OMPC_atomic_default_mem_order: 10906 case OMPC_device_type: 10907 case OMPC_match: 10908 llvm_unreachable("Unexpected OpenMP clause."); 10909 } 10910 return CaptureRegion; 10911 } 10912 10913 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10914 Expr *Condition, SourceLocation StartLoc, 10915 SourceLocation LParenLoc, 10916 SourceLocation NameModifierLoc, 10917 SourceLocation ColonLoc, 10918 SourceLocation EndLoc) { 10919 Expr *ValExpr = Condition; 10920 Stmt *HelperValStmt = nullptr; 10921 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10922 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10923 !Condition->isInstantiationDependent() && 10924 !Condition->containsUnexpandedParameterPack()) { 10925 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10926 if (Val.isInvalid()) 10927 return nullptr; 10928 10929 ValExpr = Val.get(); 10930 10931 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10932 CaptureRegion = 10933 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10934 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10935 ValExpr = MakeFullExpr(ValExpr).get(); 10936 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10937 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10938 HelperValStmt = buildPreInits(Context, Captures); 10939 } 10940 } 10941 10942 return new (Context) 10943 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10944 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10945 } 10946 10947 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10948 SourceLocation StartLoc, 10949 SourceLocation LParenLoc, 10950 SourceLocation EndLoc) { 10951 Expr *ValExpr = Condition; 10952 Stmt *HelperValStmt = nullptr; 10953 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10954 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10955 !Condition->isInstantiationDependent() && 10956 !Condition->containsUnexpandedParameterPack()) { 10957 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10958 if (Val.isInvalid()) 10959 return nullptr; 10960 10961 ValExpr = MakeFullExpr(Val.get()).get(); 10962 10963 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10964 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final); 10965 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10966 ValExpr = MakeFullExpr(ValExpr).get(); 10967 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10968 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10969 HelperValStmt = buildPreInits(Context, Captures); 10970 } 10971 } 10972 10973 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 10974 StartLoc, LParenLoc, EndLoc); 10975 } 10976 10977 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10978 Expr *Op) { 10979 if (!Op) 10980 return ExprError(); 10981 10982 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10983 public: 10984 IntConvertDiagnoser() 10985 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10986 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10987 QualType T) override { 10988 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10989 } 10990 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10991 QualType T) override { 10992 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10993 } 10994 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10995 QualType T, 10996 QualType ConvTy) override { 10997 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10998 } 10999 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11000 QualType ConvTy) override { 11001 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11002 << ConvTy->isEnumeralType() << ConvTy; 11003 } 11004 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11005 QualType T) override { 11006 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11007 } 11008 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11009 QualType ConvTy) override { 11010 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11011 << ConvTy->isEnumeralType() << ConvTy; 11012 } 11013 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11014 QualType) override { 11015 llvm_unreachable("conversion functions are permitted"); 11016 } 11017 } ConvertDiagnoser; 11018 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11019 } 11020 11021 static bool 11022 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11023 bool StrictlyPositive, bool BuildCapture = false, 11024 OpenMPDirectiveKind DKind = OMPD_unknown, 11025 OpenMPDirectiveKind *CaptureRegion = nullptr, 11026 Stmt **HelperValStmt = nullptr) { 11027 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11028 !ValExpr->isInstantiationDependent()) { 11029 SourceLocation Loc = ValExpr->getExprLoc(); 11030 ExprResult Value = 11031 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11032 if (Value.isInvalid()) 11033 return false; 11034 11035 ValExpr = Value.get(); 11036 // The expression must evaluate to a non-negative integer value. 11037 llvm::APSInt Result; 11038 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11039 Result.isSigned() && 11040 !((!StrictlyPositive && Result.isNonNegative()) || 11041 (StrictlyPositive && Result.isStrictlyPositive()))) { 11042 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11043 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11044 << ValExpr->getSourceRange(); 11045 return false; 11046 } 11047 if (!BuildCapture) 11048 return true; 11049 *CaptureRegion = getOpenMPCaptureRegionForClause(DKind, CKind); 11050 if (*CaptureRegion != OMPD_unknown && 11051 !SemaRef.CurContext->isDependentContext()) { 11052 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11053 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11054 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11055 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11056 } 11057 } 11058 return true; 11059 } 11060 11061 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11062 SourceLocation StartLoc, 11063 SourceLocation LParenLoc, 11064 SourceLocation EndLoc) { 11065 Expr *ValExpr = NumThreads; 11066 Stmt *HelperValStmt = nullptr; 11067 11068 // OpenMP [2.5, Restrictions] 11069 // The num_threads expression must evaluate to a positive integer value. 11070 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11071 /*StrictlyPositive=*/true)) 11072 return nullptr; 11073 11074 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11075 OpenMPDirectiveKind CaptureRegion = 11076 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 11077 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11078 ValExpr = MakeFullExpr(ValExpr).get(); 11079 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11080 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11081 HelperValStmt = buildPreInits(Context, Captures); 11082 } 11083 11084 return new (Context) OMPNumThreadsClause( 11085 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11086 } 11087 11088 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11089 OpenMPClauseKind CKind, 11090 bool StrictlyPositive) { 11091 if (!E) 11092 return ExprError(); 11093 if (E->isValueDependent() || E->isTypeDependent() || 11094 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11095 return E; 11096 llvm::APSInt Result; 11097 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11098 if (ICE.isInvalid()) 11099 return ExprError(); 11100 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11101 (!StrictlyPositive && !Result.isNonNegative())) { 11102 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11103 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11104 << E->getSourceRange(); 11105 return ExprError(); 11106 } 11107 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11108 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11109 << E->getSourceRange(); 11110 return ExprError(); 11111 } 11112 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11113 DSAStack->setAssociatedLoops(Result.getExtValue()); 11114 else if (CKind == OMPC_ordered) 11115 DSAStack->setAssociatedLoops(Result.getExtValue()); 11116 return ICE; 11117 } 11118 11119 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11120 SourceLocation LParenLoc, 11121 SourceLocation EndLoc) { 11122 // OpenMP [2.8.1, simd construct, Description] 11123 // The parameter of the safelen clause must be a constant 11124 // positive integer expression. 11125 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11126 if (Safelen.isInvalid()) 11127 return nullptr; 11128 return new (Context) 11129 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11130 } 11131 11132 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11133 SourceLocation LParenLoc, 11134 SourceLocation EndLoc) { 11135 // OpenMP [2.8.1, simd construct, Description] 11136 // The parameter of the simdlen clause must be a constant 11137 // positive integer expression. 11138 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11139 if (Simdlen.isInvalid()) 11140 return nullptr; 11141 return new (Context) 11142 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11143 } 11144 11145 /// Tries to find omp_allocator_handle_t type. 11146 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11147 DSAStackTy *Stack) { 11148 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11149 if (!OMPAllocatorHandleT.isNull()) 11150 return true; 11151 // Build the predefined allocator expressions. 11152 bool ErrorFound = false; 11153 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11154 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11155 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11156 StringRef Allocator = 11157 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11158 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11159 auto *VD = dyn_cast_or_null<ValueDecl>( 11160 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11161 if (!VD) { 11162 ErrorFound = true; 11163 break; 11164 } 11165 QualType AllocatorType = 11166 VD->getType().getNonLValueExprType(S.getASTContext()); 11167 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11168 if (!Res.isUsable()) { 11169 ErrorFound = true; 11170 break; 11171 } 11172 if (OMPAllocatorHandleT.isNull()) 11173 OMPAllocatorHandleT = AllocatorType; 11174 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11175 ErrorFound = true; 11176 break; 11177 } 11178 Stack->setAllocator(AllocatorKind, Res.get()); 11179 } 11180 if (ErrorFound) { 11181 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11182 return false; 11183 } 11184 OMPAllocatorHandleT.addConst(); 11185 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11186 return true; 11187 } 11188 11189 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11190 SourceLocation LParenLoc, 11191 SourceLocation EndLoc) { 11192 // OpenMP [2.11.3, allocate Directive, Description] 11193 // allocator is an expression of omp_allocator_handle_t type. 11194 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11195 return nullptr; 11196 11197 ExprResult Allocator = DefaultLvalueConversion(A); 11198 if (Allocator.isInvalid()) 11199 return nullptr; 11200 Allocator = PerformImplicitConversion(Allocator.get(), 11201 DSAStack->getOMPAllocatorHandleT(), 11202 Sema::AA_Initializing, 11203 /*AllowExplicit=*/true); 11204 if (Allocator.isInvalid()) 11205 return nullptr; 11206 return new (Context) 11207 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11208 } 11209 11210 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11211 SourceLocation StartLoc, 11212 SourceLocation LParenLoc, 11213 SourceLocation EndLoc) { 11214 // OpenMP [2.7.1, loop construct, Description] 11215 // OpenMP [2.8.1, simd construct, Description] 11216 // OpenMP [2.9.6, distribute construct, Description] 11217 // The parameter of the collapse clause must be a constant 11218 // positive integer expression. 11219 ExprResult NumForLoopsResult = 11220 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11221 if (NumForLoopsResult.isInvalid()) 11222 return nullptr; 11223 return new (Context) 11224 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11225 } 11226 11227 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11228 SourceLocation EndLoc, 11229 SourceLocation LParenLoc, 11230 Expr *NumForLoops) { 11231 // OpenMP [2.7.1, loop construct, Description] 11232 // OpenMP [2.8.1, simd construct, Description] 11233 // OpenMP [2.9.6, distribute construct, Description] 11234 // The parameter of the ordered clause must be a constant 11235 // positive integer expression if any. 11236 if (NumForLoops && LParenLoc.isValid()) { 11237 ExprResult NumForLoopsResult = 11238 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11239 if (NumForLoopsResult.isInvalid()) 11240 return nullptr; 11241 NumForLoops = NumForLoopsResult.get(); 11242 } else { 11243 NumForLoops = nullptr; 11244 } 11245 auto *Clause = OMPOrderedClause::Create( 11246 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11247 StartLoc, LParenLoc, EndLoc); 11248 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11249 return Clause; 11250 } 11251 11252 OMPClause *Sema::ActOnOpenMPSimpleClause( 11253 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11254 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11255 OMPClause *Res = nullptr; 11256 switch (Kind) { 11257 case OMPC_default: 11258 Res = 11259 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11260 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11261 break; 11262 case OMPC_proc_bind: 11263 Res = ActOnOpenMPProcBindClause( 11264 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11265 LParenLoc, EndLoc); 11266 break; 11267 case OMPC_atomic_default_mem_order: 11268 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11269 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11270 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11271 break; 11272 case OMPC_if: 11273 case OMPC_final: 11274 case OMPC_num_threads: 11275 case OMPC_safelen: 11276 case OMPC_simdlen: 11277 case OMPC_allocator: 11278 case OMPC_collapse: 11279 case OMPC_schedule: 11280 case OMPC_private: 11281 case OMPC_firstprivate: 11282 case OMPC_lastprivate: 11283 case OMPC_shared: 11284 case OMPC_reduction: 11285 case OMPC_task_reduction: 11286 case OMPC_in_reduction: 11287 case OMPC_linear: 11288 case OMPC_aligned: 11289 case OMPC_copyin: 11290 case OMPC_copyprivate: 11291 case OMPC_ordered: 11292 case OMPC_nowait: 11293 case OMPC_untied: 11294 case OMPC_mergeable: 11295 case OMPC_threadprivate: 11296 case OMPC_allocate: 11297 case OMPC_flush: 11298 case OMPC_read: 11299 case OMPC_write: 11300 case OMPC_update: 11301 case OMPC_capture: 11302 case OMPC_seq_cst: 11303 case OMPC_depend: 11304 case OMPC_device: 11305 case OMPC_threads: 11306 case OMPC_simd: 11307 case OMPC_map: 11308 case OMPC_num_teams: 11309 case OMPC_thread_limit: 11310 case OMPC_priority: 11311 case OMPC_grainsize: 11312 case OMPC_nogroup: 11313 case OMPC_num_tasks: 11314 case OMPC_hint: 11315 case OMPC_dist_schedule: 11316 case OMPC_defaultmap: 11317 case OMPC_unknown: 11318 case OMPC_uniform: 11319 case OMPC_to: 11320 case OMPC_from: 11321 case OMPC_use_device_ptr: 11322 case OMPC_is_device_ptr: 11323 case OMPC_unified_address: 11324 case OMPC_unified_shared_memory: 11325 case OMPC_reverse_offload: 11326 case OMPC_dynamic_allocators: 11327 case OMPC_device_type: 11328 case OMPC_match: 11329 llvm_unreachable("Clause is not allowed."); 11330 } 11331 return Res; 11332 } 11333 11334 static std::string 11335 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11336 ArrayRef<unsigned> Exclude = llvm::None) { 11337 SmallString<256> Buffer; 11338 llvm::raw_svector_ostream Out(Buffer); 11339 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11340 unsigned Skipped = Exclude.size(); 11341 auto S = Exclude.begin(), E = Exclude.end(); 11342 for (unsigned I = First; I < Last; ++I) { 11343 if (std::find(S, E, I) != E) { 11344 --Skipped; 11345 continue; 11346 } 11347 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11348 if (I == Bound - Skipped) 11349 Out << " or "; 11350 else if (I != Bound + 1 - Skipped) 11351 Out << ", "; 11352 } 11353 return Out.str(); 11354 } 11355 11356 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11357 SourceLocation KindKwLoc, 11358 SourceLocation StartLoc, 11359 SourceLocation LParenLoc, 11360 SourceLocation EndLoc) { 11361 if (Kind == OMPC_DEFAULT_unknown) { 11362 static_assert(OMPC_DEFAULT_unknown > 0, 11363 "OMPC_DEFAULT_unknown not greater than 0"); 11364 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11365 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11366 /*Last=*/OMPC_DEFAULT_unknown) 11367 << getOpenMPClauseName(OMPC_default); 11368 return nullptr; 11369 } 11370 switch (Kind) { 11371 case OMPC_DEFAULT_none: 11372 DSAStack->setDefaultDSANone(KindKwLoc); 11373 break; 11374 case OMPC_DEFAULT_shared: 11375 DSAStack->setDefaultDSAShared(KindKwLoc); 11376 break; 11377 case OMPC_DEFAULT_unknown: 11378 llvm_unreachable("Clause kind is not allowed."); 11379 break; 11380 } 11381 return new (Context) 11382 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11383 } 11384 11385 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11386 SourceLocation KindKwLoc, 11387 SourceLocation StartLoc, 11388 SourceLocation LParenLoc, 11389 SourceLocation EndLoc) { 11390 if (Kind == OMPC_PROC_BIND_unknown) { 11391 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11392 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11393 /*Last=*/OMPC_PROC_BIND_unknown) 11394 << getOpenMPClauseName(OMPC_proc_bind); 11395 return nullptr; 11396 } 11397 return new (Context) 11398 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11399 } 11400 11401 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11402 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11403 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11404 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11405 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11406 << getListOfPossibleValues( 11407 OMPC_atomic_default_mem_order, /*First=*/0, 11408 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11409 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11410 return nullptr; 11411 } 11412 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11413 LParenLoc, EndLoc); 11414 } 11415 11416 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11417 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11418 SourceLocation StartLoc, SourceLocation LParenLoc, 11419 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11420 SourceLocation EndLoc) { 11421 OMPClause *Res = nullptr; 11422 switch (Kind) { 11423 case OMPC_schedule: 11424 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11425 assert(Argument.size() == NumberOfElements && 11426 ArgumentLoc.size() == NumberOfElements); 11427 Res = ActOnOpenMPScheduleClause( 11428 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11429 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11430 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11431 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11432 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11433 break; 11434 case OMPC_if: 11435 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11436 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11437 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11438 DelimLoc, EndLoc); 11439 break; 11440 case OMPC_dist_schedule: 11441 Res = ActOnOpenMPDistScheduleClause( 11442 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11443 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11444 break; 11445 case OMPC_defaultmap: 11446 enum { Modifier, DefaultmapKind }; 11447 Res = ActOnOpenMPDefaultmapClause( 11448 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11449 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11450 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11451 EndLoc); 11452 break; 11453 case OMPC_final: 11454 case OMPC_num_threads: 11455 case OMPC_safelen: 11456 case OMPC_simdlen: 11457 case OMPC_allocator: 11458 case OMPC_collapse: 11459 case OMPC_default: 11460 case OMPC_proc_bind: 11461 case OMPC_private: 11462 case OMPC_firstprivate: 11463 case OMPC_lastprivate: 11464 case OMPC_shared: 11465 case OMPC_reduction: 11466 case OMPC_task_reduction: 11467 case OMPC_in_reduction: 11468 case OMPC_linear: 11469 case OMPC_aligned: 11470 case OMPC_copyin: 11471 case OMPC_copyprivate: 11472 case OMPC_ordered: 11473 case OMPC_nowait: 11474 case OMPC_untied: 11475 case OMPC_mergeable: 11476 case OMPC_threadprivate: 11477 case OMPC_allocate: 11478 case OMPC_flush: 11479 case OMPC_read: 11480 case OMPC_write: 11481 case OMPC_update: 11482 case OMPC_capture: 11483 case OMPC_seq_cst: 11484 case OMPC_depend: 11485 case OMPC_device: 11486 case OMPC_threads: 11487 case OMPC_simd: 11488 case OMPC_map: 11489 case OMPC_num_teams: 11490 case OMPC_thread_limit: 11491 case OMPC_priority: 11492 case OMPC_grainsize: 11493 case OMPC_nogroup: 11494 case OMPC_num_tasks: 11495 case OMPC_hint: 11496 case OMPC_unknown: 11497 case OMPC_uniform: 11498 case OMPC_to: 11499 case OMPC_from: 11500 case OMPC_use_device_ptr: 11501 case OMPC_is_device_ptr: 11502 case OMPC_unified_address: 11503 case OMPC_unified_shared_memory: 11504 case OMPC_reverse_offload: 11505 case OMPC_dynamic_allocators: 11506 case OMPC_atomic_default_mem_order: 11507 case OMPC_device_type: 11508 case OMPC_match: 11509 llvm_unreachable("Clause is not allowed."); 11510 } 11511 return Res; 11512 } 11513 11514 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11515 OpenMPScheduleClauseModifier M2, 11516 SourceLocation M1Loc, SourceLocation M2Loc) { 11517 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11518 SmallVector<unsigned, 2> Excluded; 11519 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11520 Excluded.push_back(M2); 11521 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11522 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11523 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11524 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11525 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11526 << getListOfPossibleValues(OMPC_schedule, 11527 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11528 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11529 Excluded) 11530 << getOpenMPClauseName(OMPC_schedule); 11531 return true; 11532 } 11533 return false; 11534 } 11535 11536 OMPClause *Sema::ActOnOpenMPScheduleClause( 11537 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11538 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11539 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11540 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11541 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11542 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11543 return nullptr; 11544 // OpenMP, 2.7.1, Loop Construct, Restrictions 11545 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11546 // but not both. 11547 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11548 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11549 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11550 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11551 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11552 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11553 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11554 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11555 return nullptr; 11556 } 11557 if (Kind == OMPC_SCHEDULE_unknown) { 11558 std::string Values; 11559 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11560 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11561 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11562 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11563 Exclude); 11564 } else { 11565 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11566 /*Last=*/OMPC_SCHEDULE_unknown); 11567 } 11568 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11569 << Values << getOpenMPClauseName(OMPC_schedule); 11570 return nullptr; 11571 } 11572 // OpenMP, 2.7.1, Loop Construct, Restrictions 11573 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11574 // schedule(guided). 11575 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11576 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11577 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11578 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11579 diag::err_omp_schedule_nonmonotonic_static); 11580 return nullptr; 11581 } 11582 Expr *ValExpr = ChunkSize; 11583 Stmt *HelperValStmt = nullptr; 11584 if (ChunkSize) { 11585 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11586 !ChunkSize->isInstantiationDependent() && 11587 !ChunkSize->containsUnexpandedParameterPack()) { 11588 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11589 ExprResult Val = 11590 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11591 if (Val.isInvalid()) 11592 return nullptr; 11593 11594 ValExpr = Val.get(); 11595 11596 // OpenMP [2.7.1, Restrictions] 11597 // chunk_size must be a loop invariant integer expression with a positive 11598 // value. 11599 llvm::APSInt Result; 11600 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11601 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11602 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11603 << "schedule" << 1 << ChunkSize->getSourceRange(); 11604 return nullptr; 11605 } 11606 } else if (getOpenMPCaptureRegionForClause( 11607 DSAStack->getCurrentDirective(), OMPC_schedule) != 11608 OMPD_unknown && 11609 !CurContext->isDependentContext()) { 11610 ValExpr = MakeFullExpr(ValExpr).get(); 11611 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11612 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11613 HelperValStmt = buildPreInits(Context, Captures); 11614 } 11615 } 11616 } 11617 11618 return new (Context) 11619 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11620 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11621 } 11622 11623 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11624 SourceLocation StartLoc, 11625 SourceLocation EndLoc) { 11626 OMPClause *Res = nullptr; 11627 switch (Kind) { 11628 case OMPC_ordered: 11629 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11630 break; 11631 case OMPC_nowait: 11632 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11633 break; 11634 case OMPC_untied: 11635 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11636 break; 11637 case OMPC_mergeable: 11638 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11639 break; 11640 case OMPC_read: 11641 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11642 break; 11643 case OMPC_write: 11644 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11645 break; 11646 case OMPC_update: 11647 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11648 break; 11649 case OMPC_capture: 11650 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11651 break; 11652 case OMPC_seq_cst: 11653 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11654 break; 11655 case OMPC_threads: 11656 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11657 break; 11658 case OMPC_simd: 11659 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11660 break; 11661 case OMPC_nogroup: 11662 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11663 break; 11664 case OMPC_unified_address: 11665 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11666 break; 11667 case OMPC_unified_shared_memory: 11668 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11669 break; 11670 case OMPC_reverse_offload: 11671 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11672 break; 11673 case OMPC_dynamic_allocators: 11674 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11675 break; 11676 case OMPC_if: 11677 case OMPC_final: 11678 case OMPC_num_threads: 11679 case OMPC_safelen: 11680 case OMPC_simdlen: 11681 case OMPC_allocator: 11682 case OMPC_collapse: 11683 case OMPC_schedule: 11684 case OMPC_private: 11685 case OMPC_firstprivate: 11686 case OMPC_lastprivate: 11687 case OMPC_shared: 11688 case OMPC_reduction: 11689 case OMPC_task_reduction: 11690 case OMPC_in_reduction: 11691 case OMPC_linear: 11692 case OMPC_aligned: 11693 case OMPC_copyin: 11694 case OMPC_copyprivate: 11695 case OMPC_default: 11696 case OMPC_proc_bind: 11697 case OMPC_threadprivate: 11698 case OMPC_allocate: 11699 case OMPC_flush: 11700 case OMPC_depend: 11701 case OMPC_device: 11702 case OMPC_map: 11703 case OMPC_num_teams: 11704 case OMPC_thread_limit: 11705 case OMPC_priority: 11706 case OMPC_grainsize: 11707 case OMPC_num_tasks: 11708 case OMPC_hint: 11709 case OMPC_dist_schedule: 11710 case OMPC_defaultmap: 11711 case OMPC_unknown: 11712 case OMPC_uniform: 11713 case OMPC_to: 11714 case OMPC_from: 11715 case OMPC_use_device_ptr: 11716 case OMPC_is_device_ptr: 11717 case OMPC_atomic_default_mem_order: 11718 case OMPC_device_type: 11719 case OMPC_match: 11720 llvm_unreachable("Clause is not allowed."); 11721 } 11722 return Res; 11723 } 11724 11725 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11726 SourceLocation EndLoc) { 11727 DSAStack->setNowaitRegion(); 11728 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11729 } 11730 11731 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11732 SourceLocation EndLoc) { 11733 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11734 } 11735 11736 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11737 SourceLocation EndLoc) { 11738 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11739 } 11740 11741 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11742 SourceLocation EndLoc) { 11743 return new (Context) OMPReadClause(StartLoc, EndLoc); 11744 } 11745 11746 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11747 SourceLocation EndLoc) { 11748 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11749 } 11750 11751 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11752 SourceLocation EndLoc) { 11753 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11754 } 11755 11756 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11757 SourceLocation EndLoc) { 11758 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11759 } 11760 11761 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11762 SourceLocation EndLoc) { 11763 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11764 } 11765 11766 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11767 SourceLocation EndLoc) { 11768 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11769 } 11770 11771 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11772 SourceLocation EndLoc) { 11773 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11774 } 11775 11776 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11777 SourceLocation EndLoc) { 11778 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11779 } 11780 11781 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11782 SourceLocation EndLoc) { 11783 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11784 } 11785 11786 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11787 SourceLocation EndLoc) { 11788 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11789 } 11790 11791 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11792 SourceLocation EndLoc) { 11793 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11794 } 11795 11796 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11797 SourceLocation EndLoc) { 11798 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11799 } 11800 11801 OMPClause *Sema::ActOnOpenMPVarListClause( 11802 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11803 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11804 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11805 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11806 OpenMPLinearClauseKind LinKind, 11807 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11808 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11809 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11810 SourceLocation StartLoc = Locs.StartLoc; 11811 SourceLocation LParenLoc = Locs.LParenLoc; 11812 SourceLocation EndLoc = Locs.EndLoc; 11813 OMPClause *Res = nullptr; 11814 switch (Kind) { 11815 case OMPC_private: 11816 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11817 break; 11818 case OMPC_firstprivate: 11819 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11820 break; 11821 case OMPC_lastprivate: 11822 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11823 break; 11824 case OMPC_shared: 11825 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11826 break; 11827 case OMPC_reduction: 11828 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11829 EndLoc, ReductionOrMapperIdScopeSpec, 11830 ReductionOrMapperId); 11831 break; 11832 case OMPC_task_reduction: 11833 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11834 EndLoc, ReductionOrMapperIdScopeSpec, 11835 ReductionOrMapperId); 11836 break; 11837 case OMPC_in_reduction: 11838 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11839 EndLoc, ReductionOrMapperIdScopeSpec, 11840 ReductionOrMapperId); 11841 break; 11842 case OMPC_linear: 11843 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11844 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11845 break; 11846 case OMPC_aligned: 11847 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11848 ColonLoc, EndLoc); 11849 break; 11850 case OMPC_copyin: 11851 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11852 break; 11853 case OMPC_copyprivate: 11854 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11855 break; 11856 case OMPC_flush: 11857 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11858 break; 11859 case OMPC_depend: 11860 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11861 StartLoc, LParenLoc, EndLoc); 11862 break; 11863 case OMPC_map: 11864 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11865 ReductionOrMapperIdScopeSpec, 11866 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11867 DepLinMapLoc, ColonLoc, VarList, Locs); 11868 break; 11869 case OMPC_to: 11870 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11871 ReductionOrMapperId, Locs); 11872 break; 11873 case OMPC_from: 11874 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11875 ReductionOrMapperId, Locs); 11876 break; 11877 case OMPC_use_device_ptr: 11878 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11879 break; 11880 case OMPC_is_device_ptr: 11881 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11882 break; 11883 case OMPC_allocate: 11884 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11885 ColonLoc, EndLoc); 11886 break; 11887 case OMPC_if: 11888 case OMPC_final: 11889 case OMPC_num_threads: 11890 case OMPC_safelen: 11891 case OMPC_simdlen: 11892 case OMPC_allocator: 11893 case OMPC_collapse: 11894 case OMPC_default: 11895 case OMPC_proc_bind: 11896 case OMPC_schedule: 11897 case OMPC_ordered: 11898 case OMPC_nowait: 11899 case OMPC_untied: 11900 case OMPC_mergeable: 11901 case OMPC_threadprivate: 11902 case OMPC_read: 11903 case OMPC_write: 11904 case OMPC_update: 11905 case OMPC_capture: 11906 case OMPC_seq_cst: 11907 case OMPC_device: 11908 case OMPC_threads: 11909 case OMPC_simd: 11910 case OMPC_num_teams: 11911 case OMPC_thread_limit: 11912 case OMPC_priority: 11913 case OMPC_grainsize: 11914 case OMPC_nogroup: 11915 case OMPC_num_tasks: 11916 case OMPC_hint: 11917 case OMPC_dist_schedule: 11918 case OMPC_defaultmap: 11919 case OMPC_unknown: 11920 case OMPC_uniform: 11921 case OMPC_unified_address: 11922 case OMPC_unified_shared_memory: 11923 case OMPC_reverse_offload: 11924 case OMPC_dynamic_allocators: 11925 case OMPC_atomic_default_mem_order: 11926 case OMPC_device_type: 11927 case OMPC_match: 11928 llvm_unreachable("Clause is not allowed."); 11929 } 11930 return Res; 11931 } 11932 11933 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11934 ExprObjectKind OK, SourceLocation Loc) { 11935 ExprResult Res = BuildDeclRefExpr( 11936 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11937 if (!Res.isUsable()) 11938 return ExprError(); 11939 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11940 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11941 if (!Res.isUsable()) 11942 return ExprError(); 11943 } 11944 if (VK != VK_LValue && Res.get()->isGLValue()) { 11945 Res = DefaultLvalueConversion(Res.get()); 11946 if (!Res.isUsable()) 11947 return ExprError(); 11948 } 11949 return Res; 11950 } 11951 11952 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11953 SourceLocation StartLoc, 11954 SourceLocation LParenLoc, 11955 SourceLocation EndLoc) { 11956 SmallVector<Expr *, 8> Vars; 11957 SmallVector<Expr *, 8> PrivateCopies; 11958 for (Expr *RefExpr : VarList) { 11959 assert(RefExpr && "NULL expr in OpenMP private clause."); 11960 SourceLocation ELoc; 11961 SourceRange ERange; 11962 Expr *SimpleRefExpr = RefExpr; 11963 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11964 if (Res.second) { 11965 // It will be analyzed later. 11966 Vars.push_back(RefExpr); 11967 PrivateCopies.push_back(nullptr); 11968 } 11969 ValueDecl *D = Res.first; 11970 if (!D) 11971 continue; 11972 11973 QualType Type = D->getType(); 11974 auto *VD = dyn_cast<VarDecl>(D); 11975 11976 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11977 // A variable that appears in a private clause must not have an incomplete 11978 // type or a reference type. 11979 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11980 continue; 11981 Type = Type.getNonReferenceType(); 11982 11983 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11984 // A variable that is privatized must not have a const-qualified type 11985 // unless it is of class type with a mutable member. This restriction does 11986 // not apply to the firstprivate clause. 11987 // 11988 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11989 // A variable that appears in a private clause must not have a 11990 // const-qualified type unless it is of class type with a mutable member. 11991 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11992 continue; 11993 11994 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11995 // in a Construct] 11996 // Variables with the predetermined data-sharing attributes may not be 11997 // listed in data-sharing attributes clauses, except for the cases 11998 // listed below. For these exceptions only, listing a predetermined 11999 // variable in a data-sharing attribute clause is allowed and overrides 12000 // the variable's predetermined data-sharing attributes. 12001 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12002 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12003 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12004 << getOpenMPClauseName(OMPC_private); 12005 reportOriginalDsa(*this, DSAStack, D, DVar); 12006 continue; 12007 } 12008 12009 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12010 // Variably modified types are not supported for tasks. 12011 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12012 isOpenMPTaskingDirective(CurrDir)) { 12013 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12014 << getOpenMPClauseName(OMPC_private) << Type 12015 << getOpenMPDirectiveName(CurrDir); 12016 bool IsDecl = 12017 !VD || 12018 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12019 Diag(D->getLocation(), 12020 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12021 << D; 12022 continue; 12023 } 12024 12025 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12026 // A list item cannot appear in both a map clause and a data-sharing 12027 // attribute clause on the same construct 12028 // 12029 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12030 // A list item cannot appear in both a map clause and a data-sharing 12031 // attribute clause on the same construct unless the construct is a 12032 // combined construct. 12033 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12034 CurrDir == OMPD_target) { 12035 OpenMPClauseKind ConflictKind; 12036 if (DSAStack->checkMappableExprComponentListsForDecl( 12037 VD, /*CurrentRegionOnly=*/true, 12038 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12039 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12040 ConflictKind = WhereFoundClauseKind; 12041 return true; 12042 })) { 12043 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12044 << getOpenMPClauseName(OMPC_private) 12045 << getOpenMPClauseName(ConflictKind) 12046 << getOpenMPDirectiveName(CurrDir); 12047 reportOriginalDsa(*this, DSAStack, D, DVar); 12048 continue; 12049 } 12050 } 12051 12052 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12053 // A variable of class type (or array thereof) that appears in a private 12054 // clause requires an accessible, unambiguous default constructor for the 12055 // class type. 12056 // Generate helper private variable and initialize it with the default 12057 // value. The address of the original variable is replaced by the address of 12058 // the new private variable in CodeGen. This new variable is not added to 12059 // IdResolver, so the code in the OpenMP region uses original variable for 12060 // proper diagnostics. 12061 Type = Type.getUnqualifiedType(); 12062 VarDecl *VDPrivate = 12063 buildVarDecl(*this, ELoc, Type, D->getName(), 12064 D->hasAttrs() ? &D->getAttrs() : nullptr, 12065 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12066 ActOnUninitializedDecl(VDPrivate); 12067 if (VDPrivate->isInvalidDecl()) 12068 continue; 12069 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12070 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12071 12072 DeclRefExpr *Ref = nullptr; 12073 if (!VD && !CurContext->isDependentContext()) 12074 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12075 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12076 Vars.push_back((VD || CurContext->isDependentContext()) 12077 ? RefExpr->IgnoreParens() 12078 : Ref); 12079 PrivateCopies.push_back(VDPrivateRefExpr); 12080 } 12081 12082 if (Vars.empty()) 12083 return nullptr; 12084 12085 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12086 PrivateCopies); 12087 } 12088 12089 namespace { 12090 class DiagsUninitializedSeveretyRAII { 12091 private: 12092 DiagnosticsEngine &Diags; 12093 SourceLocation SavedLoc; 12094 bool IsIgnored = false; 12095 12096 public: 12097 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12098 bool IsIgnored) 12099 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12100 if (!IsIgnored) { 12101 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12102 /*Map*/ diag::Severity::Ignored, Loc); 12103 } 12104 } 12105 ~DiagsUninitializedSeveretyRAII() { 12106 if (!IsIgnored) 12107 Diags.popMappings(SavedLoc); 12108 } 12109 }; 12110 } 12111 12112 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12113 SourceLocation StartLoc, 12114 SourceLocation LParenLoc, 12115 SourceLocation EndLoc) { 12116 SmallVector<Expr *, 8> Vars; 12117 SmallVector<Expr *, 8> PrivateCopies; 12118 SmallVector<Expr *, 8> Inits; 12119 SmallVector<Decl *, 4> ExprCaptures; 12120 bool IsImplicitClause = 12121 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12122 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12123 12124 for (Expr *RefExpr : VarList) { 12125 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12126 SourceLocation ELoc; 12127 SourceRange ERange; 12128 Expr *SimpleRefExpr = RefExpr; 12129 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12130 if (Res.second) { 12131 // It will be analyzed later. 12132 Vars.push_back(RefExpr); 12133 PrivateCopies.push_back(nullptr); 12134 Inits.push_back(nullptr); 12135 } 12136 ValueDecl *D = Res.first; 12137 if (!D) 12138 continue; 12139 12140 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12141 QualType Type = D->getType(); 12142 auto *VD = dyn_cast<VarDecl>(D); 12143 12144 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12145 // A variable that appears in a private clause must not have an incomplete 12146 // type or a reference type. 12147 if (RequireCompleteType(ELoc, Type, 12148 diag::err_omp_firstprivate_incomplete_type)) 12149 continue; 12150 Type = Type.getNonReferenceType(); 12151 12152 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12153 // A variable of class type (or array thereof) that appears in a private 12154 // clause requires an accessible, unambiguous copy constructor for the 12155 // class type. 12156 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12157 12158 // If an implicit firstprivate variable found it was checked already. 12159 DSAStackTy::DSAVarData TopDVar; 12160 if (!IsImplicitClause) { 12161 DSAStackTy::DSAVarData DVar = 12162 DSAStack->getTopDSA(D, /*FromParent=*/false); 12163 TopDVar = DVar; 12164 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12165 bool IsConstant = ElemType.isConstant(Context); 12166 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12167 // A list item that specifies a given variable may not appear in more 12168 // than one clause on the same directive, except that a variable may be 12169 // specified in both firstprivate and lastprivate clauses. 12170 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12171 // A list item may appear in a firstprivate or lastprivate clause but not 12172 // both. 12173 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12174 (isOpenMPDistributeDirective(CurrDir) || 12175 DVar.CKind != OMPC_lastprivate) && 12176 DVar.RefExpr) { 12177 Diag(ELoc, diag::err_omp_wrong_dsa) 12178 << getOpenMPClauseName(DVar.CKind) 12179 << getOpenMPClauseName(OMPC_firstprivate); 12180 reportOriginalDsa(*this, DSAStack, D, DVar); 12181 continue; 12182 } 12183 12184 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12185 // in a Construct] 12186 // Variables with the predetermined data-sharing attributes may not be 12187 // listed in data-sharing attributes clauses, except for the cases 12188 // listed below. For these exceptions only, listing a predetermined 12189 // variable in a data-sharing attribute clause is allowed and overrides 12190 // the variable's predetermined data-sharing attributes. 12191 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12192 // in a Construct, C/C++, p.2] 12193 // Variables with const-qualified type having no mutable member may be 12194 // listed in a firstprivate clause, even if they are static data members. 12195 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12196 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12197 Diag(ELoc, diag::err_omp_wrong_dsa) 12198 << getOpenMPClauseName(DVar.CKind) 12199 << getOpenMPClauseName(OMPC_firstprivate); 12200 reportOriginalDsa(*this, DSAStack, D, DVar); 12201 continue; 12202 } 12203 12204 // OpenMP [2.9.3.4, Restrictions, p.2] 12205 // A list item that is private within a parallel region must not appear 12206 // in a firstprivate clause on a worksharing construct if any of the 12207 // worksharing regions arising from the worksharing construct ever bind 12208 // to any of the parallel regions arising from the parallel construct. 12209 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12210 // A list item that is private within a teams region must not appear in a 12211 // firstprivate clause on a distribute construct if any of the distribute 12212 // regions arising from the distribute construct ever bind to any of the 12213 // teams regions arising from the teams construct. 12214 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12215 // A list item that appears in a reduction clause of a teams construct 12216 // must not appear in a firstprivate clause on a distribute construct if 12217 // any of the distribute regions arising from the distribute construct 12218 // ever bind to any of the teams regions arising from the teams construct. 12219 if ((isOpenMPWorksharingDirective(CurrDir) || 12220 isOpenMPDistributeDirective(CurrDir)) && 12221 !isOpenMPParallelDirective(CurrDir) && 12222 !isOpenMPTeamsDirective(CurrDir)) { 12223 DVar = DSAStack->getImplicitDSA(D, true); 12224 if (DVar.CKind != OMPC_shared && 12225 (isOpenMPParallelDirective(DVar.DKind) || 12226 isOpenMPTeamsDirective(DVar.DKind) || 12227 DVar.DKind == OMPD_unknown)) { 12228 Diag(ELoc, diag::err_omp_required_access) 12229 << getOpenMPClauseName(OMPC_firstprivate) 12230 << getOpenMPClauseName(OMPC_shared); 12231 reportOriginalDsa(*this, DSAStack, D, DVar); 12232 continue; 12233 } 12234 } 12235 // OpenMP [2.9.3.4, Restrictions, p.3] 12236 // A list item that appears in a reduction clause of a parallel construct 12237 // must not appear in a firstprivate clause on a worksharing or task 12238 // construct if any of the worksharing or task regions arising from the 12239 // worksharing or task construct ever bind to any of the parallel regions 12240 // arising from the parallel construct. 12241 // OpenMP [2.9.3.4, Restrictions, p.4] 12242 // A list item that appears in a reduction clause in worksharing 12243 // construct must not appear in a firstprivate clause in a task construct 12244 // encountered during execution of any of the worksharing regions arising 12245 // from the worksharing construct. 12246 if (isOpenMPTaskingDirective(CurrDir)) { 12247 DVar = DSAStack->hasInnermostDSA( 12248 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12249 [](OpenMPDirectiveKind K) { 12250 return isOpenMPParallelDirective(K) || 12251 isOpenMPWorksharingDirective(K) || 12252 isOpenMPTeamsDirective(K); 12253 }, 12254 /*FromParent=*/true); 12255 if (DVar.CKind == OMPC_reduction && 12256 (isOpenMPParallelDirective(DVar.DKind) || 12257 isOpenMPWorksharingDirective(DVar.DKind) || 12258 isOpenMPTeamsDirective(DVar.DKind))) { 12259 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12260 << getOpenMPDirectiveName(DVar.DKind); 12261 reportOriginalDsa(*this, DSAStack, D, DVar); 12262 continue; 12263 } 12264 } 12265 12266 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12267 // A list item cannot appear in both a map clause and a data-sharing 12268 // attribute clause on the same construct 12269 // 12270 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12271 // A list item cannot appear in both a map clause and a data-sharing 12272 // attribute clause on the same construct unless the construct is a 12273 // combined construct. 12274 if ((LangOpts.OpenMP <= 45 && 12275 isOpenMPTargetExecutionDirective(CurrDir)) || 12276 CurrDir == OMPD_target) { 12277 OpenMPClauseKind ConflictKind; 12278 if (DSAStack->checkMappableExprComponentListsForDecl( 12279 VD, /*CurrentRegionOnly=*/true, 12280 [&ConflictKind]( 12281 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12282 OpenMPClauseKind WhereFoundClauseKind) { 12283 ConflictKind = WhereFoundClauseKind; 12284 return true; 12285 })) { 12286 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12287 << getOpenMPClauseName(OMPC_firstprivate) 12288 << getOpenMPClauseName(ConflictKind) 12289 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12290 reportOriginalDsa(*this, DSAStack, D, DVar); 12291 continue; 12292 } 12293 } 12294 } 12295 12296 // Variably modified types are not supported for tasks. 12297 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12298 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12299 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12300 << getOpenMPClauseName(OMPC_firstprivate) << Type 12301 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12302 bool IsDecl = 12303 !VD || 12304 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12305 Diag(D->getLocation(), 12306 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12307 << D; 12308 continue; 12309 } 12310 12311 Type = Type.getUnqualifiedType(); 12312 VarDecl *VDPrivate = 12313 buildVarDecl(*this, ELoc, Type, D->getName(), 12314 D->hasAttrs() ? &D->getAttrs() : nullptr, 12315 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12316 // Generate helper private variable and initialize it with the value of the 12317 // original variable. The address of the original variable is replaced by 12318 // the address of the new private variable in the CodeGen. This new variable 12319 // is not added to IdResolver, so the code in the OpenMP region uses 12320 // original variable for proper diagnostics and variable capturing. 12321 Expr *VDInitRefExpr = nullptr; 12322 // For arrays generate initializer for single element and replace it by the 12323 // original array element in CodeGen. 12324 if (Type->isArrayType()) { 12325 VarDecl *VDInit = 12326 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12327 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12328 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12329 ElemType = ElemType.getUnqualifiedType(); 12330 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12331 ".firstprivate.temp"); 12332 InitializedEntity Entity = 12333 InitializedEntity::InitializeVariable(VDInitTemp); 12334 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12335 12336 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12337 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12338 if (Result.isInvalid()) 12339 VDPrivate->setInvalidDecl(); 12340 else 12341 VDPrivate->setInit(Result.getAs<Expr>()); 12342 // Remove temp variable declaration. 12343 Context.Deallocate(VDInitTemp); 12344 } else { 12345 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12346 ".firstprivate.temp"); 12347 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12348 RefExpr->getExprLoc()); 12349 AddInitializerToDecl(VDPrivate, 12350 DefaultLvalueConversion(VDInitRefExpr).get(), 12351 /*DirectInit=*/false); 12352 } 12353 if (VDPrivate->isInvalidDecl()) { 12354 if (IsImplicitClause) { 12355 Diag(RefExpr->getExprLoc(), 12356 diag::note_omp_task_predetermined_firstprivate_here); 12357 } 12358 continue; 12359 } 12360 CurContext->addDecl(VDPrivate); 12361 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12362 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12363 RefExpr->getExprLoc()); 12364 DeclRefExpr *Ref = nullptr; 12365 if (!VD && !CurContext->isDependentContext()) { 12366 if (TopDVar.CKind == OMPC_lastprivate) { 12367 Ref = TopDVar.PrivateCopy; 12368 } else { 12369 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12370 if (!isOpenMPCapturedDecl(D)) 12371 ExprCaptures.push_back(Ref->getDecl()); 12372 } 12373 } 12374 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12375 Vars.push_back((VD || CurContext->isDependentContext()) 12376 ? RefExpr->IgnoreParens() 12377 : Ref); 12378 PrivateCopies.push_back(VDPrivateRefExpr); 12379 Inits.push_back(VDInitRefExpr); 12380 } 12381 12382 if (Vars.empty()) 12383 return nullptr; 12384 12385 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12386 Vars, PrivateCopies, Inits, 12387 buildPreInits(Context, ExprCaptures)); 12388 } 12389 12390 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12391 SourceLocation StartLoc, 12392 SourceLocation LParenLoc, 12393 SourceLocation EndLoc) { 12394 SmallVector<Expr *, 8> Vars; 12395 SmallVector<Expr *, 8> SrcExprs; 12396 SmallVector<Expr *, 8> DstExprs; 12397 SmallVector<Expr *, 8> AssignmentOps; 12398 SmallVector<Decl *, 4> ExprCaptures; 12399 SmallVector<Expr *, 4> ExprPostUpdates; 12400 for (Expr *RefExpr : VarList) { 12401 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12402 SourceLocation ELoc; 12403 SourceRange ERange; 12404 Expr *SimpleRefExpr = RefExpr; 12405 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12406 if (Res.second) { 12407 // It will be analyzed later. 12408 Vars.push_back(RefExpr); 12409 SrcExprs.push_back(nullptr); 12410 DstExprs.push_back(nullptr); 12411 AssignmentOps.push_back(nullptr); 12412 } 12413 ValueDecl *D = Res.first; 12414 if (!D) 12415 continue; 12416 12417 QualType Type = D->getType(); 12418 auto *VD = dyn_cast<VarDecl>(D); 12419 12420 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12421 // A variable that appears in a lastprivate clause must not have an 12422 // incomplete type or a reference type. 12423 if (RequireCompleteType(ELoc, Type, 12424 diag::err_omp_lastprivate_incomplete_type)) 12425 continue; 12426 Type = Type.getNonReferenceType(); 12427 12428 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12429 // A variable that is privatized must not have a const-qualified type 12430 // unless it is of class type with a mutable member. This restriction does 12431 // not apply to the firstprivate clause. 12432 // 12433 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12434 // A variable that appears in a lastprivate clause must not have a 12435 // const-qualified type unless it is of class type with a mutable member. 12436 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12437 continue; 12438 12439 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12440 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12441 // in a Construct] 12442 // Variables with the predetermined data-sharing attributes may not be 12443 // listed in data-sharing attributes clauses, except for the cases 12444 // listed below. 12445 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12446 // A list item may appear in a firstprivate or lastprivate clause but not 12447 // both. 12448 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12449 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12450 (isOpenMPDistributeDirective(CurrDir) || 12451 DVar.CKind != OMPC_firstprivate) && 12452 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12453 Diag(ELoc, diag::err_omp_wrong_dsa) 12454 << getOpenMPClauseName(DVar.CKind) 12455 << getOpenMPClauseName(OMPC_lastprivate); 12456 reportOriginalDsa(*this, DSAStack, D, DVar); 12457 continue; 12458 } 12459 12460 // OpenMP [2.14.3.5, Restrictions, p.2] 12461 // A list item that is private within a parallel region, or that appears in 12462 // the reduction clause of a parallel construct, must not appear in a 12463 // lastprivate clause on a worksharing construct if any of the corresponding 12464 // worksharing regions ever binds to any of the corresponding parallel 12465 // regions. 12466 DSAStackTy::DSAVarData TopDVar = DVar; 12467 if (isOpenMPWorksharingDirective(CurrDir) && 12468 !isOpenMPParallelDirective(CurrDir) && 12469 !isOpenMPTeamsDirective(CurrDir)) { 12470 DVar = DSAStack->getImplicitDSA(D, true); 12471 if (DVar.CKind != OMPC_shared) { 12472 Diag(ELoc, diag::err_omp_required_access) 12473 << getOpenMPClauseName(OMPC_lastprivate) 12474 << getOpenMPClauseName(OMPC_shared); 12475 reportOriginalDsa(*this, DSAStack, D, DVar); 12476 continue; 12477 } 12478 } 12479 12480 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12481 // A variable of class type (or array thereof) that appears in a 12482 // lastprivate clause requires an accessible, unambiguous default 12483 // constructor for the class type, unless the list item is also specified 12484 // in a firstprivate clause. 12485 // A variable of class type (or array thereof) that appears in a 12486 // lastprivate clause requires an accessible, unambiguous copy assignment 12487 // operator for the class type. 12488 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12489 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12490 Type.getUnqualifiedType(), ".lastprivate.src", 12491 D->hasAttrs() ? &D->getAttrs() : nullptr); 12492 DeclRefExpr *PseudoSrcExpr = 12493 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12494 VarDecl *DstVD = 12495 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12496 D->hasAttrs() ? &D->getAttrs() : nullptr); 12497 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12498 // For arrays generate assignment operation for single element and replace 12499 // it by the original array element in CodeGen. 12500 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12501 PseudoDstExpr, PseudoSrcExpr); 12502 if (AssignmentOp.isInvalid()) 12503 continue; 12504 AssignmentOp = 12505 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12506 if (AssignmentOp.isInvalid()) 12507 continue; 12508 12509 DeclRefExpr *Ref = nullptr; 12510 if (!VD && !CurContext->isDependentContext()) { 12511 if (TopDVar.CKind == OMPC_firstprivate) { 12512 Ref = TopDVar.PrivateCopy; 12513 } else { 12514 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12515 if (!isOpenMPCapturedDecl(D)) 12516 ExprCaptures.push_back(Ref->getDecl()); 12517 } 12518 if (TopDVar.CKind == OMPC_firstprivate || 12519 (!isOpenMPCapturedDecl(D) && 12520 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12521 ExprResult RefRes = DefaultLvalueConversion(Ref); 12522 if (!RefRes.isUsable()) 12523 continue; 12524 ExprResult PostUpdateRes = 12525 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12526 RefRes.get()); 12527 if (!PostUpdateRes.isUsable()) 12528 continue; 12529 ExprPostUpdates.push_back( 12530 IgnoredValueConversions(PostUpdateRes.get()).get()); 12531 } 12532 } 12533 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12534 Vars.push_back((VD || CurContext->isDependentContext()) 12535 ? RefExpr->IgnoreParens() 12536 : Ref); 12537 SrcExprs.push_back(PseudoSrcExpr); 12538 DstExprs.push_back(PseudoDstExpr); 12539 AssignmentOps.push_back(AssignmentOp.get()); 12540 } 12541 12542 if (Vars.empty()) 12543 return nullptr; 12544 12545 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12546 Vars, SrcExprs, DstExprs, AssignmentOps, 12547 buildPreInits(Context, ExprCaptures), 12548 buildPostUpdate(*this, ExprPostUpdates)); 12549 } 12550 12551 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12552 SourceLocation StartLoc, 12553 SourceLocation LParenLoc, 12554 SourceLocation EndLoc) { 12555 SmallVector<Expr *, 8> Vars; 12556 for (Expr *RefExpr : VarList) { 12557 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12558 SourceLocation ELoc; 12559 SourceRange ERange; 12560 Expr *SimpleRefExpr = RefExpr; 12561 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12562 if (Res.second) { 12563 // It will be analyzed later. 12564 Vars.push_back(RefExpr); 12565 } 12566 ValueDecl *D = Res.first; 12567 if (!D) 12568 continue; 12569 12570 auto *VD = dyn_cast<VarDecl>(D); 12571 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12572 // in a Construct] 12573 // Variables with the predetermined data-sharing attributes may not be 12574 // listed in data-sharing attributes clauses, except for the cases 12575 // listed below. For these exceptions only, listing a predetermined 12576 // variable in a data-sharing attribute clause is allowed and overrides 12577 // the variable's predetermined data-sharing attributes. 12578 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12579 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12580 DVar.RefExpr) { 12581 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12582 << getOpenMPClauseName(OMPC_shared); 12583 reportOriginalDsa(*this, DSAStack, D, DVar); 12584 continue; 12585 } 12586 12587 DeclRefExpr *Ref = nullptr; 12588 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12589 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12590 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12591 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12592 ? RefExpr->IgnoreParens() 12593 : Ref); 12594 } 12595 12596 if (Vars.empty()) 12597 return nullptr; 12598 12599 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12600 } 12601 12602 namespace { 12603 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12604 DSAStackTy *Stack; 12605 12606 public: 12607 bool VisitDeclRefExpr(DeclRefExpr *E) { 12608 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12609 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12610 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12611 return false; 12612 if (DVar.CKind != OMPC_unknown) 12613 return true; 12614 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12615 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12616 /*FromParent=*/true); 12617 return DVarPrivate.CKind != OMPC_unknown; 12618 } 12619 return false; 12620 } 12621 bool VisitStmt(Stmt *S) { 12622 for (Stmt *Child : S->children()) { 12623 if (Child && Visit(Child)) 12624 return true; 12625 } 12626 return false; 12627 } 12628 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12629 }; 12630 } // namespace 12631 12632 namespace { 12633 // Transform MemberExpression for specified FieldDecl of current class to 12634 // DeclRefExpr to specified OMPCapturedExprDecl. 12635 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12636 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12637 ValueDecl *Field = nullptr; 12638 DeclRefExpr *CapturedExpr = nullptr; 12639 12640 public: 12641 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12642 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12643 12644 ExprResult TransformMemberExpr(MemberExpr *E) { 12645 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12646 E->getMemberDecl() == Field) { 12647 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12648 return CapturedExpr; 12649 } 12650 return BaseTransform::TransformMemberExpr(E); 12651 } 12652 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12653 }; 12654 } // namespace 12655 12656 template <typename T, typename U> 12657 static T filterLookupForUDReductionAndMapper( 12658 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12659 for (U &Set : Lookups) { 12660 for (auto *D : Set) { 12661 if (T Res = Gen(cast<ValueDecl>(D))) 12662 return Res; 12663 } 12664 } 12665 return T(); 12666 } 12667 12668 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12669 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12670 12671 for (auto RD : D->redecls()) { 12672 // Don't bother with extra checks if we already know this one isn't visible. 12673 if (RD == D) 12674 continue; 12675 12676 auto ND = cast<NamedDecl>(RD); 12677 if (LookupResult::isVisible(SemaRef, ND)) 12678 return ND; 12679 } 12680 12681 return nullptr; 12682 } 12683 12684 static void 12685 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12686 SourceLocation Loc, QualType Ty, 12687 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12688 // Find all of the associated namespaces and classes based on the 12689 // arguments we have. 12690 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12691 Sema::AssociatedClassSet AssociatedClasses; 12692 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12693 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12694 AssociatedClasses); 12695 12696 // C++ [basic.lookup.argdep]p3: 12697 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12698 // and let Y be the lookup set produced by argument dependent 12699 // lookup (defined as follows). If X contains [...] then Y is 12700 // empty. Otherwise Y is the set of declarations found in the 12701 // namespaces associated with the argument types as described 12702 // below. The set of declarations found by the lookup of the name 12703 // is the union of X and Y. 12704 // 12705 // Here, we compute Y and add its members to the overloaded 12706 // candidate set. 12707 for (auto *NS : AssociatedNamespaces) { 12708 // When considering an associated namespace, the lookup is the 12709 // same as the lookup performed when the associated namespace is 12710 // used as a qualifier (3.4.3.2) except that: 12711 // 12712 // -- Any using-directives in the associated namespace are 12713 // ignored. 12714 // 12715 // -- Any namespace-scope friend functions declared in 12716 // associated classes are visible within their respective 12717 // namespaces even if they are not visible during an ordinary 12718 // lookup (11.4). 12719 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12720 for (auto *D : R) { 12721 auto *Underlying = D; 12722 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12723 Underlying = USD->getTargetDecl(); 12724 12725 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12726 !isa<OMPDeclareMapperDecl>(Underlying)) 12727 continue; 12728 12729 if (!SemaRef.isVisible(D)) { 12730 D = findAcceptableDecl(SemaRef, D); 12731 if (!D) 12732 continue; 12733 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12734 Underlying = USD->getTargetDecl(); 12735 } 12736 Lookups.emplace_back(); 12737 Lookups.back().addDecl(Underlying); 12738 } 12739 } 12740 } 12741 12742 static ExprResult 12743 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12744 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12745 const DeclarationNameInfo &ReductionId, QualType Ty, 12746 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12747 if (ReductionIdScopeSpec.isInvalid()) 12748 return ExprError(); 12749 SmallVector<UnresolvedSet<8>, 4> Lookups; 12750 if (S) { 12751 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12752 Lookup.suppressDiagnostics(); 12753 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12754 NamedDecl *D = Lookup.getRepresentativeDecl(); 12755 do { 12756 S = S->getParent(); 12757 } while (S && !S->isDeclScope(D)); 12758 if (S) 12759 S = S->getParent(); 12760 Lookups.emplace_back(); 12761 Lookups.back().append(Lookup.begin(), Lookup.end()); 12762 Lookup.clear(); 12763 } 12764 } else if (auto *ULE = 12765 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12766 Lookups.push_back(UnresolvedSet<8>()); 12767 Decl *PrevD = nullptr; 12768 for (NamedDecl *D : ULE->decls()) { 12769 if (D == PrevD) 12770 Lookups.push_back(UnresolvedSet<8>()); 12771 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12772 Lookups.back().addDecl(DRD); 12773 PrevD = D; 12774 } 12775 } 12776 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12777 Ty->isInstantiationDependentType() || 12778 Ty->containsUnexpandedParameterPack() || 12779 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12780 return !D->isInvalidDecl() && 12781 (D->getType()->isDependentType() || 12782 D->getType()->isInstantiationDependentType() || 12783 D->getType()->containsUnexpandedParameterPack()); 12784 })) { 12785 UnresolvedSet<8> ResSet; 12786 for (const UnresolvedSet<8> &Set : Lookups) { 12787 if (Set.empty()) 12788 continue; 12789 ResSet.append(Set.begin(), Set.end()); 12790 // The last item marks the end of all declarations at the specified scope. 12791 ResSet.addDecl(Set[Set.size() - 1]); 12792 } 12793 return UnresolvedLookupExpr::Create( 12794 SemaRef.Context, /*NamingClass=*/nullptr, 12795 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12796 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12797 } 12798 // Lookup inside the classes. 12799 // C++ [over.match.oper]p3: 12800 // For a unary operator @ with an operand of a type whose 12801 // cv-unqualified version is T1, and for a binary operator @ with 12802 // a left operand of a type whose cv-unqualified version is T1 and 12803 // a right operand of a type whose cv-unqualified version is T2, 12804 // three sets of candidate functions, designated member 12805 // candidates, non-member candidates and built-in candidates, are 12806 // constructed as follows: 12807 // -- If T1 is a complete class type or a class currently being 12808 // defined, the set of member candidates is the result of the 12809 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12810 // the set of member candidates is empty. 12811 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12812 Lookup.suppressDiagnostics(); 12813 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12814 // Complete the type if it can be completed. 12815 // If the type is neither complete nor being defined, bail out now. 12816 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12817 TyRec->getDecl()->getDefinition()) { 12818 Lookup.clear(); 12819 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12820 if (Lookup.empty()) { 12821 Lookups.emplace_back(); 12822 Lookups.back().append(Lookup.begin(), Lookup.end()); 12823 } 12824 } 12825 } 12826 // Perform ADL. 12827 if (SemaRef.getLangOpts().CPlusPlus) 12828 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12829 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12830 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12831 if (!D->isInvalidDecl() && 12832 SemaRef.Context.hasSameType(D->getType(), Ty)) 12833 return D; 12834 return nullptr; 12835 })) 12836 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12837 VK_LValue, Loc); 12838 if (SemaRef.getLangOpts().CPlusPlus) { 12839 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12840 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12841 if (!D->isInvalidDecl() && 12842 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12843 !Ty.isMoreQualifiedThan(D->getType())) 12844 return D; 12845 return nullptr; 12846 })) { 12847 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12848 /*DetectVirtual=*/false); 12849 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12850 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12851 VD->getType().getUnqualifiedType()))) { 12852 if (SemaRef.CheckBaseClassAccess( 12853 Loc, VD->getType(), Ty, Paths.front(), 12854 /*DiagID=*/0) != Sema::AR_inaccessible) { 12855 SemaRef.BuildBasePathArray(Paths, BasePath); 12856 return SemaRef.BuildDeclRefExpr( 12857 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12858 } 12859 } 12860 } 12861 } 12862 } 12863 if (ReductionIdScopeSpec.isSet()) { 12864 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12865 return ExprError(); 12866 } 12867 return ExprEmpty(); 12868 } 12869 12870 namespace { 12871 /// Data for the reduction-based clauses. 12872 struct ReductionData { 12873 /// List of original reduction items. 12874 SmallVector<Expr *, 8> Vars; 12875 /// List of private copies of the reduction items. 12876 SmallVector<Expr *, 8> Privates; 12877 /// LHS expressions for the reduction_op expressions. 12878 SmallVector<Expr *, 8> LHSs; 12879 /// RHS expressions for the reduction_op expressions. 12880 SmallVector<Expr *, 8> RHSs; 12881 /// Reduction operation expression. 12882 SmallVector<Expr *, 8> ReductionOps; 12883 /// Taskgroup descriptors for the corresponding reduction items in 12884 /// in_reduction clauses. 12885 SmallVector<Expr *, 8> TaskgroupDescriptors; 12886 /// List of captures for clause. 12887 SmallVector<Decl *, 4> ExprCaptures; 12888 /// List of postupdate expressions. 12889 SmallVector<Expr *, 4> ExprPostUpdates; 12890 ReductionData() = delete; 12891 /// Reserves required memory for the reduction data. 12892 ReductionData(unsigned Size) { 12893 Vars.reserve(Size); 12894 Privates.reserve(Size); 12895 LHSs.reserve(Size); 12896 RHSs.reserve(Size); 12897 ReductionOps.reserve(Size); 12898 TaskgroupDescriptors.reserve(Size); 12899 ExprCaptures.reserve(Size); 12900 ExprPostUpdates.reserve(Size); 12901 } 12902 /// Stores reduction item and reduction operation only (required for dependent 12903 /// reduction item). 12904 void push(Expr *Item, Expr *ReductionOp) { 12905 Vars.emplace_back(Item); 12906 Privates.emplace_back(nullptr); 12907 LHSs.emplace_back(nullptr); 12908 RHSs.emplace_back(nullptr); 12909 ReductionOps.emplace_back(ReductionOp); 12910 TaskgroupDescriptors.emplace_back(nullptr); 12911 } 12912 /// Stores reduction data. 12913 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12914 Expr *TaskgroupDescriptor) { 12915 Vars.emplace_back(Item); 12916 Privates.emplace_back(Private); 12917 LHSs.emplace_back(LHS); 12918 RHSs.emplace_back(RHS); 12919 ReductionOps.emplace_back(ReductionOp); 12920 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12921 } 12922 }; 12923 } // namespace 12924 12925 static bool checkOMPArraySectionConstantForReduction( 12926 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12927 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12928 const Expr *Length = OASE->getLength(); 12929 if (Length == nullptr) { 12930 // For array sections of the form [1:] or [:], we would need to analyze 12931 // the lower bound... 12932 if (OASE->getColonLoc().isValid()) 12933 return false; 12934 12935 // This is an array subscript which has implicit length 1! 12936 SingleElement = true; 12937 ArraySizes.push_back(llvm::APSInt::get(1)); 12938 } else { 12939 Expr::EvalResult Result; 12940 if (!Length->EvaluateAsInt(Result, Context)) 12941 return false; 12942 12943 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12944 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12945 ArraySizes.push_back(ConstantLengthValue); 12946 } 12947 12948 // Get the base of this array section and walk up from there. 12949 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12950 12951 // We require length = 1 for all array sections except the right-most to 12952 // guarantee that the memory region is contiguous and has no holes in it. 12953 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12954 Length = TempOASE->getLength(); 12955 if (Length == nullptr) { 12956 // For array sections of the form [1:] or [:], we would need to analyze 12957 // the lower bound... 12958 if (OASE->getColonLoc().isValid()) 12959 return false; 12960 12961 // This is an array subscript which has implicit length 1! 12962 ArraySizes.push_back(llvm::APSInt::get(1)); 12963 } else { 12964 Expr::EvalResult Result; 12965 if (!Length->EvaluateAsInt(Result, Context)) 12966 return false; 12967 12968 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12969 if (ConstantLengthValue.getSExtValue() != 1) 12970 return false; 12971 12972 ArraySizes.push_back(ConstantLengthValue); 12973 } 12974 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12975 } 12976 12977 // If we have a single element, we don't need to add the implicit lengths. 12978 if (!SingleElement) { 12979 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12980 // Has implicit length 1! 12981 ArraySizes.push_back(llvm::APSInt::get(1)); 12982 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12983 } 12984 } 12985 12986 // This array section can be privatized as a single value or as a constant 12987 // sized array. 12988 return true; 12989 } 12990 12991 static bool actOnOMPReductionKindClause( 12992 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12993 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12994 SourceLocation ColonLoc, SourceLocation EndLoc, 12995 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12996 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12997 DeclarationName DN = ReductionId.getName(); 12998 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12999 BinaryOperatorKind BOK = BO_Comma; 13000 13001 ASTContext &Context = S.Context; 13002 // OpenMP [2.14.3.6, reduction clause] 13003 // C 13004 // reduction-identifier is either an identifier or one of the following 13005 // operators: +, -, *, &, |, ^, && and || 13006 // C++ 13007 // reduction-identifier is either an id-expression or one of the following 13008 // operators: +, -, *, &, |, ^, && and || 13009 switch (OOK) { 13010 case OO_Plus: 13011 case OO_Minus: 13012 BOK = BO_Add; 13013 break; 13014 case OO_Star: 13015 BOK = BO_Mul; 13016 break; 13017 case OO_Amp: 13018 BOK = BO_And; 13019 break; 13020 case OO_Pipe: 13021 BOK = BO_Or; 13022 break; 13023 case OO_Caret: 13024 BOK = BO_Xor; 13025 break; 13026 case OO_AmpAmp: 13027 BOK = BO_LAnd; 13028 break; 13029 case OO_PipePipe: 13030 BOK = BO_LOr; 13031 break; 13032 case OO_New: 13033 case OO_Delete: 13034 case OO_Array_New: 13035 case OO_Array_Delete: 13036 case OO_Slash: 13037 case OO_Percent: 13038 case OO_Tilde: 13039 case OO_Exclaim: 13040 case OO_Equal: 13041 case OO_Less: 13042 case OO_Greater: 13043 case OO_LessEqual: 13044 case OO_GreaterEqual: 13045 case OO_PlusEqual: 13046 case OO_MinusEqual: 13047 case OO_StarEqual: 13048 case OO_SlashEqual: 13049 case OO_PercentEqual: 13050 case OO_CaretEqual: 13051 case OO_AmpEqual: 13052 case OO_PipeEqual: 13053 case OO_LessLess: 13054 case OO_GreaterGreater: 13055 case OO_LessLessEqual: 13056 case OO_GreaterGreaterEqual: 13057 case OO_EqualEqual: 13058 case OO_ExclaimEqual: 13059 case OO_Spaceship: 13060 case OO_PlusPlus: 13061 case OO_MinusMinus: 13062 case OO_Comma: 13063 case OO_ArrowStar: 13064 case OO_Arrow: 13065 case OO_Call: 13066 case OO_Subscript: 13067 case OO_Conditional: 13068 case OO_Coawait: 13069 case NUM_OVERLOADED_OPERATORS: 13070 llvm_unreachable("Unexpected reduction identifier"); 13071 case OO_None: 13072 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13073 if (II->isStr("max")) 13074 BOK = BO_GT; 13075 else if (II->isStr("min")) 13076 BOK = BO_LT; 13077 } 13078 break; 13079 } 13080 SourceRange ReductionIdRange; 13081 if (ReductionIdScopeSpec.isValid()) 13082 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13083 else 13084 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13085 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13086 13087 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13088 bool FirstIter = true; 13089 for (Expr *RefExpr : VarList) { 13090 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13091 // OpenMP [2.1, C/C++] 13092 // A list item is a variable or array section, subject to the restrictions 13093 // specified in Section 2.4 on page 42 and in each of the sections 13094 // describing clauses and directives for which a list appears. 13095 // OpenMP [2.14.3.3, Restrictions, p.1] 13096 // A variable that is part of another variable (as an array or 13097 // structure element) cannot appear in a private clause. 13098 if (!FirstIter && IR != ER) 13099 ++IR; 13100 FirstIter = false; 13101 SourceLocation ELoc; 13102 SourceRange ERange; 13103 Expr *SimpleRefExpr = RefExpr; 13104 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13105 /*AllowArraySection=*/true); 13106 if (Res.second) { 13107 // Try to find 'declare reduction' corresponding construct before using 13108 // builtin/overloaded operators. 13109 QualType Type = Context.DependentTy; 13110 CXXCastPath BasePath; 13111 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13112 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13113 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13114 Expr *ReductionOp = nullptr; 13115 if (S.CurContext->isDependentContext() && 13116 (DeclareReductionRef.isUnset() || 13117 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13118 ReductionOp = DeclareReductionRef.get(); 13119 // It will be analyzed later. 13120 RD.push(RefExpr, ReductionOp); 13121 } 13122 ValueDecl *D = Res.first; 13123 if (!D) 13124 continue; 13125 13126 Expr *TaskgroupDescriptor = nullptr; 13127 QualType Type; 13128 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13129 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13130 if (ASE) { 13131 Type = ASE->getType().getNonReferenceType(); 13132 } else if (OASE) { 13133 QualType BaseType = 13134 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13135 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13136 Type = ATy->getElementType(); 13137 else 13138 Type = BaseType->getPointeeType(); 13139 Type = Type.getNonReferenceType(); 13140 } else { 13141 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13142 } 13143 auto *VD = dyn_cast<VarDecl>(D); 13144 13145 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13146 // A variable that appears in a private clause must not have an incomplete 13147 // type or a reference type. 13148 if (S.RequireCompleteType(ELoc, D->getType(), 13149 diag::err_omp_reduction_incomplete_type)) 13150 continue; 13151 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13152 // A list item that appears in a reduction clause must not be 13153 // const-qualified. 13154 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13155 /*AcceptIfMutable*/ false, ASE || OASE)) 13156 continue; 13157 13158 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13159 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13160 // If a list-item is a reference type then it must bind to the same object 13161 // for all threads of the team. 13162 if (!ASE && !OASE) { 13163 if (VD) { 13164 VarDecl *VDDef = VD->getDefinition(); 13165 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13166 DSARefChecker Check(Stack); 13167 if (Check.Visit(VDDef->getInit())) { 13168 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13169 << getOpenMPClauseName(ClauseKind) << ERange; 13170 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13171 continue; 13172 } 13173 } 13174 } 13175 13176 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13177 // in a Construct] 13178 // Variables with the predetermined data-sharing attributes may not be 13179 // listed in data-sharing attributes clauses, except for the cases 13180 // listed below. For these exceptions only, listing a predetermined 13181 // variable in a data-sharing attribute clause is allowed and overrides 13182 // the variable's predetermined data-sharing attributes. 13183 // OpenMP [2.14.3.6, Restrictions, p.3] 13184 // Any number of reduction clauses can be specified on the directive, 13185 // but a list item can appear only once in the reduction clauses for that 13186 // directive. 13187 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13188 if (DVar.CKind == OMPC_reduction) { 13189 S.Diag(ELoc, diag::err_omp_once_referenced) 13190 << getOpenMPClauseName(ClauseKind); 13191 if (DVar.RefExpr) 13192 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13193 continue; 13194 } 13195 if (DVar.CKind != OMPC_unknown) { 13196 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13197 << getOpenMPClauseName(DVar.CKind) 13198 << getOpenMPClauseName(OMPC_reduction); 13199 reportOriginalDsa(S, Stack, D, DVar); 13200 continue; 13201 } 13202 13203 // OpenMP [2.14.3.6, Restrictions, p.1] 13204 // A list item that appears in a reduction clause of a worksharing 13205 // construct must be shared in the parallel regions to which any of the 13206 // worksharing regions arising from the worksharing construct bind. 13207 if (isOpenMPWorksharingDirective(CurrDir) && 13208 !isOpenMPParallelDirective(CurrDir) && 13209 !isOpenMPTeamsDirective(CurrDir)) { 13210 DVar = Stack->getImplicitDSA(D, true); 13211 if (DVar.CKind != OMPC_shared) { 13212 S.Diag(ELoc, diag::err_omp_required_access) 13213 << getOpenMPClauseName(OMPC_reduction) 13214 << getOpenMPClauseName(OMPC_shared); 13215 reportOriginalDsa(S, Stack, D, DVar); 13216 continue; 13217 } 13218 } 13219 } 13220 13221 // Try to find 'declare reduction' corresponding construct before using 13222 // builtin/overloaded operators. 13223 CXXCastPath BasePath; 13224 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13225 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13226 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13227 if (DeclareReductionRef.isInvalid()) 13228 continue; 13229 if (S.CurContext->isDependentContext() && 13230 (DeclareReductionRef.isUnset() || 13231 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13232 RD.push(RefExpr, DeclareReductionRef.get()); 13233 continue; 13234 } 13235 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13236 // Not allowed reduction identifier is found. 13237 S.Diag(ReductionId.getBeginLoc(), 13238 diag::err_omp_unknown_reduction_identifier) 13239 << Type << ReductionIdRange; 13240 continue; 13241 } 13242 13243 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13244 // The type of a list item that appears in a reduction clause must be valid 13245 // for the reduction-identifier. For a max or min reduction in C, the type 13246 // of the list item must be an allowed arithmetic data type: char, int, 13247 // float, double, or _Bool, possibly modified with long, short, signed, or 13248 // unsigned. For a max or min reduction in C++, the type of the list item 13249 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13250 // double, or bool, possibly modified with long, short, signed, or unsigned. 13251 if (DeclareReductionRef.isUnset()) { 13252 if ((BOK == BO_GT || BOK == BO_LT) && 13253 !(Type->isScalarType() || 13254 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13255 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13256 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13257 if (!ASE && !OASE) { 13258 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13259 VarDecl::DeclarationOnly; 13260 S.Diag(D->getLocation(), 13261 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13262 << D; 13263 } 13264 continue; 13265 } 13266 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13267 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13268 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13269 << getOpenMPClauseName(ClauseKind); 13270 if (!ASE && !OASE) { 13271 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13272 VarDecl::DeclarationOnly; 13273 S.Diag(D->getLocation(), 13274 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13275 << D; 13276 } 13277 continue; 13278 } 13279 } 13280 13281 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13282 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13283 D->hasAttrs() ? &D->getAttrs() : nullptr); 13284 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13285 D->hasAttrs() ? &D->getAttrs() : nullptr); 13286 QualType PrivateTy = Type; 13287 13288 // Try if we can determine constant lengths for all array sections and avoid 13289 // the VLA. 13290 bool ConstantLengthOASE = false; 13291 if (OASE) { 13292 bool SingleElement; 13293 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13294 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13295 Context, OASE, SingleElement, ArraySizes); 13296 13297 // If we don't have a single element, we must emit a constant array type. 13298 if (ConstantLengthOASE && !SingleElement) { 13299 for (llvm::APSInt &Size : ArraySizes) 13300 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13301 ArrayType::Normal, 13302 /*IndexTypeQuals=*/0); 13303 } 13304 } 13305 13306 if ((OASE && !ConstantLengthOASE) || 13307 (!OASE && !ASE && 13308 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13309 if (!Context.getTargetInfo().isVLASupported()) { 13310 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13311 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13312 S.Diag(ELoc, diag::note_vla_unsupported); 13313 } else { 13314 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13315 S.targetDiag(ELoc, diag::note_vla_unsupported); 13316 } 13317 continue; 13318 } 13319 // For arrays/array sections only: 13320 // Create pseudo array type for private copy. The size for this array will 13321 // be generated during codegen. 13322 // For array subscripts or single variables Private Ty is the same as Type 13323 // (type of the variable or single array element). 13324 PrivateTy = Context.getVariableArrayType( 13325 Type, 13326 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13327 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13328 } else if (!ASE && !OASE && 13329 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13330 PrivateTy = D->getType().getNonReferenceType(); 13331 } 13332 // Private copy. 13333 VarDecl *PrivateVD = 13334 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13335 D->hasAttrs() ? &D->getAttrs() : nullptr, 13336 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13337 // Add initializer for private variable. 13338 Expr *Init = nullptr; 13339 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13340 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13341 if (DeclareReductionRef.isUsable()) { 13342 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13343 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13344 if (DRD->getInitializer()) { 13345 Init = DRDRef; 13346 RHSVD->setInit(DRDRef); 13347 RHSVD->setInitStyle(VarDecl::CallInit); 13348 } 13349 } else { 13350 switch (BOK) { 13351 case BO_Add: 13352 case BO_Xor: 13353 case BO_Or: 13354 case BO_LOr: 13355 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13356 if (Type->isScalarType() || Type->isAnyComplexType()) 13357 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13358 break; 13359 case BO_Mul: 13360 case BO_LAnd: 13361 if (Type->isScalarType() || Type->isAnyComplexType()) { 13362 // '*' and '&&' reduction ops - initializer is '1'. 13363 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13364 } 13365 break; 13366 case BO_And: { 13367 // '&' reduction op - initializer is '~0'. 13368 QualType OrigType = Type; 13369 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13370 Type = ComplexTy->getElementType(); 13371 if (Type->isRealFloatingType()) { 13372 llvm::APFloat InitValue = 13373 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13374 /*isIEEE=*/true); 13375 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13376 Type, ELoc); 13377 } else if (Type->isScalarType()) { 13378 uint64_t Size = Context.getTypeSize(Type); 13379 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13380 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13381 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13382 } 13383 if (Init && OrigType->isAnyComplexType()) { 13384 // Init = 0xFFFF + 0xFFFFi; 13385 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13386 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13387 } 13388 Type = OrigType; 13389 break; 13390 } 13391 case BO_LT: 13392 case BO_GT: { 13393 // 'min' reduction op - initializer is 'Largest representable number in 13394 // the reduction list item type'. 13395 // 'max' reduction op - initializer is 'Least representable number in 13396 // the reduction list item type'. 13397 if (Type->isIntegerType() || Type->isPointerType()) { 13398 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13399 uint64_t Size = Context.getTypeSize(Type); 13400 QualType IntTy = 13401 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13402 llvm::APInt InitValue = 13403 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13404 : llvm::APInt::getMinValue(Size) 13405 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13406 : llvm::APInt::getMaxValue(Size); 13407 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13408 if (Type->isPointerType()) { 13409 // Cast to pointer type. 13410 ExprResult CastExpr = S.BuildCStyleCastExpr( 13411 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13412 if (CastExpr.isInvalid()) 13413 continue; 13414 Init = CastExpr.get(); 13415 } 13416 } else if (Type->isRealFloatingType()) { 13417 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13418 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13419 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13420 Type, ELoc); 13421 } 13422 break; 13423 } 13424 case BO_PtrMemD: 13425 case BO_PtrMemI: 13426 case BO_MulAssign: 13427 case BO_Div: 13428 case BO_Rem: 13429 case BO_Sub: 13430 case BO_Shl: 13431 case BO_Shr: 13432 case BO_LE: 13433 case BO_GE: 13434 case BO_EQ: 13435 case BO_NE: 13436 case BO_Cmp: 13437 case BO_AndAssign: 13438 case BO_XorAssign: 13439 case BO_OrAssign: 13440 case BO_Assign: 13441 case BO_AddAssign: 13442 case BO_SubAssign: 13443 case BO_DivAssign: 13444 case BO_RemAssign: 13445 case BO_ShlAssign: 13446 case BO_ShrAssign: 13447 case BO_Comma: 13448 llvm_unreachable("Unexpected reduction operation"); 13449 } 13450 } 13451 if (Init && DeclareReductionRef.isUnset()) 13452 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13453 else if (!Init) 13454 S.ActOnUninitializedDecl(RHSVD); 13455 if (RHSVD->isInvalidDecl()) 13456 continue; 13457 if (!RHSVD->hasInit() && 13458 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13459 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13460 << Type << ReductionIdRange; 13461 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13462 VarDecl::DeclarationOnly; 13463 S.Diag(D->getLocation(), 13464 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13465 << D; 13466 continue; 13467 } 13468 // Store initializer for single element in private copy. Will be used during 13469 // codegen. 13470 PrivateVD->setInit(RHSVD->getInit()); 13471 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13472 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13473 ExprResult ReductionOp; 13474 if (DeclareReductionRef.isUsable()) { 13475 QualType RedTy = DeclareReductionRef.get()->getType(); 13476 QualType PtrRedTy = Context.getPointerType(RedTy); 13477 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13478 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13479 if (!BasePath.empty()) { 13480 LHS = S.DefaultLvalueConversion(LHS.get()); 13481 RHS = S.DefaultLvalueConversion(RHS.get()); 13482 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13483 CK_UncheckedDerivedToBase, LHS.get(), 13484 &BasePath, LHS.get()->getValueKind()); 13485 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13486 CK_UncheckedDerivedToBase, RHS.get(), 13487 &BasePath, RHS.get()->getValueKind()); 13488 } 13489 FunctionProtoType::ExtProtoInfo EPI; 13490 QualType Params[] = {PtrRedTy, PtrRedTy}; 13491 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13492 auto *OVE = new (Context) OpaqueValueExpr( 13493 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13494 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13495 Expr *Args[] = {LHS.get(), RHS.get()}; 13496 ReductionOp = 13497 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13498 } else { 13499 ReductionOp = S.BuildBinOp( 13500 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13501 if (ReductionOp.isUsable()) { 13502 if (BOK != BO_LT && BOK != BO_GT) { 13503 ReductionOp = 13504 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13505 BO_Assign, LHSDRE, ReductionOp.get()); 13506 } else { 13507 auto *ConditionalOp = new (Context) 13508 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13509 Type, VK_LValue, OK_Ordinary); 13510 ReductionOp = 13511 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13512 BO_Assign, LHSDRE, ConditionalOp); 13513 } 13514 if (ReductionOp.isUsable()) 13515 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13516 /*DiscardedValue*/ false); 13517 } 13518 if (!ReductionOp.isUsable()) 13519 continue; 13520 } 13521 13522 // OpenMP [2.15.4.6, Restrictions, p.2] 13523 // A list item that appears in an in_reduction clause of a task construct 13524 // must appear in a task_reduction clause of a construct associated with a 13525 // taskgroup region that includes the participating task in its taskgroup 13526 // set. The construct associated with the innermost region that meets this 13527 // condition must specify the same reduction-identifier as the in_reduction 13528 // clause. 13529 if (ClauseKind == OMPC_in_reduction) { 13530 SourceRange ParentSR; 13531 BinaryOperatorKind ParentBOK; 13532 const Expr *ParentReductionOp; 13533 Expr *ParentBOKTD, *ParentReductionOpTD; 13534 DSAStackTy::DSAVarData ParentBOKDSA = 13535 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13536 ParentBOKTD); 13537 DSAStackTy::DSAVarData ParentReductionOpDSA = 13538 Stack->getTopMostTaskgroupReductionData( 13539 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13540 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13541 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13542 if (!IsParentBOK && !IsParentReductionOp) { 13543 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13544 continue; 13545 } 13546 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13547 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13548 IsParentReductionOp) { 13549 bool EmitError = true; 13550 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13551 llvm::FoldingSetNodeID RedId, ParentRedId; 13552 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13553 DeclareReductionRef.get()->Profile(RedId, Context, 13554 /*Canonical=*/true); 13555 EmitError = RedId != ParentRedId; 13556 } 13557 if (EmitError) { 13558 S.Diag(ReductionId.getBeginLoc(), 13559 diag::err_omp_reduction_identifier_mismatch) 13560 << ReductionIdRange << RefExpr->getSourceRange(); 13561 S.Diag(ParentSR.getBegin(), 13562 diag::note_omp_previous_reduction_identifier) 13563 << ParentSR 13564 << (IsParentBOK ? ParentBOKDSA.RefExpr 13565 : ParentReductionOpDSA.RefExpr) 13566 ->getSourceRange(); 13567 continue; 13568 } 13569 } 13570 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13571 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13572 } 13573 13574 DeclRefExpr *Ref = nullptr; 13575 Expr *VarsExpr = RefExpr->IgnoreParens(); 13576 if (!VD && !S.CurContext->isDependentContext()) { 13577 if (ASE || OASE) { 13578 TransformExprToCaptures RebuildToCapture(S, D); 13579 VarsExpr = 13580 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13581 Ref = RebuildToCapture.getCapturedExpr(); 13582 } else { 13583 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13584 } 13585 if (!S.isOpenMPCapturedDecl(D)) { 13586 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13587 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13588 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13589 if (!RefRes.isUsable()) 13590 continue; 13591 ExprResult PostUpdateRes = 13592 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13593 RefRes.get()); 13594 if (!PostUpdateRes.isUsable()) 13595 continue; 13596 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13597 Stack->getCurrentDirective() == OMPD_taskgroup) { 13598 S.Diag(RefExpr->getExprLoc(), 13599 diag::err_omp_reduction_non_addressable_expression) 13600 << RefExpr->getSourceRange(); 13601 continue; 13602 } 13603 RD.ExprPostUpdates.emplace_back( 13604 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13605 } 13606 } 13607 } 13608 // All reduction items are still marked as reduction (to do not increase 13609 // code base size). 13610 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13611 if (CurrDir == OMPD_taskgroup) { 13612 if (DeclareReductionRef.isUsable()) 13613 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13614 DeclareReductionRef.get()); 13615 else 13616 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13617 } 13618 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13619 TaskgroupDescriptor); 13620 } 13621 return RD.Vars.empty(); 13622 } 13623 13624 OMPClause *Sema::ActOnOpenMPReductionClause( 13625 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13626 SourceLocation ColonLoc, SourceLocation EndLoc, 13627 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13628 ArrayRef<Expr *> UnresolvedReductions) { 13629 ReductionData RD(VarList.size()); 13630 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13631 StartLoc, LParenLoc, ColonLoc, EndLoc, 13632 ReductionIdScopeSpec, ReductionId, 13633 UnresolvedReductions, RD)) 13634 return nullptr; 13635 13636 return OMPReductionClause::Create( 13637 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13638 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13639 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13640 buildPreInits(Context, RD.ExprCaptures), 13641 buildPostUpdate(*this, RD.ExprPostUpdates)); 13642 } 13643 13644 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13645 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13646 SourceLocation ColonLoc, SourceLocation EndLoc, 13647 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13648 ArrayRef<Expr *> UnresolvedReductions) { 13649 ReductionData RD(VarList.size()); 13650 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13651 StartLoc, LParenLoc, ColonLoc, EndLoc, 13652 ReductionIdScopeSpec, ReductionId, 13653 UnresolvedReductions, RD)) 13654 return nullptr; 13655 13656 return OMPTaskReductionClause::Create( 13657 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13658 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13659 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13660 buildPreInits(Context, RD.ExprCaptures), 13661 buildPostUpdate(*this, RD.ExprPostUpdates)); 13662 } 13663 13664 OMPClause *Sema::ActOnOpenMPInReductionClause( 13665 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13666 SourceLocation ColonLoc, SourceLocation EndLoc, 13667 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13668 ArrayRef<Expr *> UnresolvedReductions) { 13669 ReductionData RD(VarList.size()); 13670 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13671 StartLoc, LParenLoc, ColonLoc, EndLoc, 13672 ReductionIdScopeSpec, ReductionId, 13673 UnresolvedReductions, RD)) 13674 return nullptr; 13675 13676 return OMPInReductionClause::Create( 13677 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13678 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13679 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13680 buildPreInits(Context, RD.ExprCaptures), 13681 buildPostUpdate(*this, RD.ExprPostUpdates)); 13682 } 13683 13684 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13685 SourceLocation LinLoc) { 13686 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13687 LinKind == OMPC_LINEAR_unknown) { 13688 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13689 return true; 13690 } 13691 return false; 13692 } 13693 13694 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13695 OpenMPLinearClauseKind LinKind, 13696 QualType Type) { 13697 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13698 // A variable must not have an incomplete type or a reference type. 13699 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13700 return true; 13701 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13702 !Type->isReferenceType()) { 13703 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13704 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13705 return true; 13706 } 13707 Type = Type.getNonReferenceType(); 13708 13709 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13710 // A variable that is privatized must not have a const-qualified type 13711 // unless it is of class type with a mutable member. This restriction does 13712 // not apply to the firstprivate clause. 13713 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13714 return true; 13715 13716 // A list item must be of integral or pointer type. 13717 Type = Type.getUnqualifiedType().getCanonicalType(); 13718 const auto *Ty = Type.getTypePtrOrNull(); 13719 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13720 !Ty->isPointerType())) { 13721 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13722 if (D) { 13723 bool IsDecl = 13724 !VD || 13725 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13726 Diag(D->getLocation(), 13727 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13728 << D; 13729 } 13730 return true; 13731 } 13732 return false; 13733 } 13734 13735 OMPClause *Sema::ActOnOpenMPLinearClause( 13736 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13737 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13738 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13739 SmallVector<Expr *, 8> Vars; 13740 SmallVector<Expr *, 8> Privates; 13741 SmallVector<Expr *, 8> Inits; 13742 SmallVector<Decl *, 4> ExprCaptures; 13743 SmallVector<Expr *, 4> ExprPostUpdates; 13744 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13745 LinKind = OMPC_LINEAR_val; 13746 for (Expr *RefExpr : VarList) { 13747 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13748 SourceLocation ELoc; 13749 SourceRange ERange; 13750 Expr *SimpleRefExpr = RefExpr; 13751 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13752 if (Res.second) { 13753 // It will be analyzed later. 13754 Vars.push_back(RefExpr); 13755 Privates.push_back(nullptr); 13756 Inits.push_back(nullptr); 13757 } 13758 ValueDecl *D = Res.first; 13759 if (!D) 13760 continue; 13761 13762 QualType Type = D->getType(); 13763 auto *VD = dyn_cast<VarDecl>(D); 13764 13765 // OpenMP [2.14.3.7, linear clause] 13766 // A list-item cannot appear in more than one linear clause. 13767 // A list-item that appears in a linear clause cannot appear in any 13768 // other data-sharing attribute clause. 13769 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13770 if (DVar.RefExpr) { 13771 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13772 << getOpenMPClauseName(OMPC_linear); 13773 reportOriginalDsa(*this, DSAStack, D, DVar); 13774 continue; 13775 } 13776 13777 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13778 continue; 13779 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13780 13781 // Build private copy of original var. 13782 VarDecl *Private = 13783 buildVarDecl(*this, ELoc, Type, D->getName(), 13784 D->hasAttrs() ? &D->getAttrs() : nullptr, 13785 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13786 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13787 // Build var to save initial value. 13788 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13789 Expr *InitExpr; 13790 DeclRefExpr *Ref = nullptr; 13791 if (!VD && !CurContext->isDependentContext()) { 13792 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13793 if (!isOpenMPCapturedDecl(D)) { 13794 ExprCaptures.push_back(Ref->getDecl()); 13795 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13796 ExprResult RefRes = DefaultLvalueConversion(Ref); 13797 if (!RefRes.isUsable()) 13798 continue; 13799 ExprResult PostUpdateRes = 13800 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13801 SimpleRefExpr, RefRes.get()); 13802 if (!PostUpdateRes.isUsable()) 13803 continue; 13804 ExprPostUpdates.push_back( 13805 IgnoredValueConversions(PostUpdateRes.get()).get()); 13806 } 13807 } 13808 } 13809 if (LinKind == OMPC_LINEAR_uval) 13810 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13811 else 13812 InitExpr = VD ? SimpleRefExpr : Ref; 13813 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13814 /*DirectInit=*/false); 13815 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13816 13817 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13818 Vars.push_back((VD || CurContext->isDependentContext()) 13819 ? RefExpr->IgnoreParens() 13820 : Ref); 13821 Privates.push_back(PrivateRef); 13822 Inits.push_back(InitRef); 13823 } 13824 13825 if (Vars.empty()) 13826 return nullptr; 13827 13828 Expr *StepExpr = Step; 13829 Expr *CalcStepExpr = nullptr; 13830 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13831 !Step->isInstantiationDependent() && 13832 !Step->containsUnexpandedParameterPack()) { 13833 SourceLocation StepLoc = Step->getBeginLoc(); 13834 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13835 if (Val.isInvalid()) 13836 return nullptr; 13837 StepExpr = Val.get(); 13838 13839 // Build var to save the step value. 13840 VarDecl *SaveVar = 13841 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13842 ExprResult SaveRef = 13843 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13844 ExprResult CalcStep = 13845 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13846 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13847 13848 // Warn about zero linear step (it would be probably better specified as 13849 // making corresponding variables 'const'). 13850 llvm::APSInt Result; 13851 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13852 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13853 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13854 << (Vars.size() > 1); 13855 if (!IsConstant && CalcStep.isUsable()) { 13856 // Calculate the step beforehand instead of doing this on each iteration. 13857 // (This is not used if the number of iterations may be kfold-ed). 13858 CalcStepExpr = CalcStep.get(); 13859 } 13860 } 13861 13862 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13863 ColonLoc, EndLoc, Vars, Privates, Inits, 13864 StepExpr, CalcStepExpr, 13865 buildPreInits(Context, ExprCaptures), 13866 buildPostUpdate(*this, ExprPostUpdates)); 13867 } 13868 13869 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13870 Expr *NumIterations, Sema &SemaRef, 13871 Scope *S, DSAStackTy *Stack) { 13872 // Walk the vars and build update/final expressions for the CodeGen. 13873 SmallVector<Expr *, 8> Updates; 13874 SmallVector<Expr *, 8> Finals; 13875 SmallVector<Expr *, 8> UsedExprs; 13876 Expr *Step = Clause.getStep(); 13877 Expr *CalcStep = Clause.getCalcStep(); 13878 // OpenMP [2.14.3.7, linear clause] 13879 // If linear-step is not specified it is assumed to be 1. 13880 if (!Step) 13881 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13882 else if (CalcStep) 13883 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13884 bool HasErrors = false; 13885 auto CurInit = Clause.inits().begin(); 13886 auto CurPrivate = Clause.privates().begin(); 13887 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13888 for (Expr *RefExpr : Clause.varlists()) { 13889 SourceLocation ELoc; 13890 SourceRange ERange; 13891 Expr *SimpleRefExpr = RefExpr; 13892 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13893 ValueDecl *D = Res.first; 13894 if (Res.second || !D) { 13895 Updates.push_back(nullptr); 13896 Finals.push_back(nullptr); 13897 HasErrors = true; 13898 continue; 13899 } 13900 auto &&Info = Stack->isLoopControlVariable(D); 13901 // OpenMP [2.15.11, distribute simd Construct] 13902 // A list item may not appear in a linear clause, unless it is the loop 13903 // iteration variable. 13904 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13905 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13906 SemaRef.Diag(ELoc, 13907 diag::err_omp_linear_distribute_var_non_loop_iteration); 13908 Updates.push_back(nullptr); 13909 Finals.push_back(nullptr); 13910 HasErrors = true; 13911 continue; 13912 } 13913 Expr *InitExpr = *CurInit; 13914 13915 // Build privatized reference to the current linear var. 13916 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13917 Expr *CapturedRef; 13918 if (LinKind == OMPC_LINEAR_uval) 13919 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13920 else 13921 CapturedRef = 13922 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13923 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13924 /*RefersToCapture=*/true); 13925 13926 // Build update: Var = InitExpr + IV * Step 13927 ExprResult Update; 13928 if (!Info.first) 13929 Update = buildCounterUpdate( 13930 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13931 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13932 else 13933 Update = *CurPrivate; 13934 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13935 /*DiscardedValue*/ false); 13936 13937 // Build final: Var = InitExpr + NumIterations * Step 13938 ExprResult Final; 13939 if (!Info.first) 13940 Final = 13941 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13942 InitExpr, NumIterations, Step, /*Subtract=*/false, 13943 /*IsNonRectangularLB=*/false); 13944 else 13945 Final = *CurPrivate; 13946 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13947 /*DiscardedValue*/ false); 13948 13949 if (!Update.isUsable() || !Final.isUsable()) { 13950 Updates.push_back(nullptr); 13951 Finals.push_back(nullptr); 13952 UsedExprs.push_back(nullptr); 13953 HasErrors = true; 13954 } else { 13955 Updates.push_back(Update.get()); 13956 Finals.push_back(Final.get()); 13957 if (!Info.first) 13958 UsedExprs.push_back(SimpleRefExpr); 13959 } 13960 ++CurInit; 13961 ++CurPrivate; 13962 } 13963 if (Expr *S = Clause.getStep()) 13964 UsedExprs.push_back(S); 13965 // Fill the remaining part with the nullptr. 13966 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13967 Clause.setUpdates(Updates); 13968 Clause.setFinals(Finals); 13969 Clause.setUsedExprs(UsedExprs); 13970 return HasErrors; 13971 } 13972 13973 OMPClause *Sema::ActOnOpenMPAlignedClause( 13974 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13975 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13976 SmallVector<Expr *, 8> Vars; 13977 for (Expr *RefExpr : VarList) { 13978 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13979 SourceLocation ELoc; 13980 SourceRange ERange; 13981 Expr *SimpleRefExpr = RefExpr; 13982 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13983 if (Res.second) { 13984 // It will be analyzed later. 13985 Vars.push_back(RefExpr); 13986 } 13987 ValueDecl *D = Res.first; 13988 if (!D) 13989 continue; 13990 13991 QualType QType = D->getType(); 13992 auto *VD = dyn_cast<VarDecl>(D); 13993 13994 // OpenMP [2.8.1, simd construct, Restrictions] 13995 // The type of list items appearing in the aligned clause must be 13996 // array, pointer, reference to array, or reference to pointer. 13997 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13998 const Type *Ty = QType.getTypePtrOrNull(); 13999 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14000 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14001 << QType << getLangOpts().CPlusPlus << ERange; 14002 bool IsDecl = 14003 !VD || 14004 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14005 Diag(D->getLocation(), 14006 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14007 << D; 14008 continue; 14009 } 14010 14011 // OpenMP [2.8.1, simd construct, Restrictions] 14012 // A list-item cannot appear in more than one aligned clause. 14013 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14014 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 14015 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14016 << getOpenMPClauseName(OMPC_aligned); 14017 continue; 14018 } 14019 14020 DeclRefExpr *Ref = nullptr; 14021 if (!VD && isOpenMPCapturedDecl(D)) 14022 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14023 Vars.push_back(DefaultFunctionArrayConversion( 14024 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14025 .get()); 14026 } 14027 14028 // OpenMP [2.8.1, simd construct, Description] 14029 // The parameter of the aligned clause, alignment, must be a constant 14030 // positive integer expression. 14031 // If no optional parameter is specified, implementation-defined default 14032 // alignments for SIMD instructions on the target platforms are assumed. 14033 if (Alignment != nullptr) { 14034 ExprResult AlignResult = 14035 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14036 if (AlignResult.isInvalid()) 14037 return nullptr; 14038 Alignment = AlignResult.get(); 14039 } 14040 if (Vars.empty()) 14041 return nullptr; 14042 14043 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14044 EndLoc, Vars, Alignment); 14045 } 14046 14047 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14048 SourceLocation StartLoc, 14049 SourceLocation LParenLoc, 14050 SourceLocation EndLoc) { 14051 SmallVector<Expr *, 8> Vars; 14052 SmallVector<Expr *, 8> SrcExprs; 14053 SmallVector<Expr *, 8> DstExprs; 14054 SmallVector<Expr *, 8> AssignmentOps; 14055 for (Expr *RefExpr : VarList) { 14056 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14057 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14058 // It will be analyzed later. 14059 Vars.push_back(RefExpr); 14060 SrcExprs.push_back(nullptr); 14061 DstExprs.push_back(nullptr); 14062 AssignmentOps.push_back(nullptr); 14063 continue; 14064 } 14065 14066 SourceLocation ELoc = RefExpr->getExprLoc(); 14067 // OpenMP [2.1, C/C++] 14068 // A list item is a variable name. 14069 // OpenMP [2.14.4.1, Restrictions, p.1] 14070 // A list item that appears in a copyin clause must be threadprivate. 14071 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14072 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14073 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14074 << 0 << RefExpr->getSourceRange(); 14075 continue; 14076 } 14077 14078 Decl *D = DE->getDecl(); 14079 auto *VD = cast<VarDecl>(D); 14080 14081 QualType Type = VD->getType(); 14082 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14083 // It will be analyzed later. 14084 Vars.push_back(DE); 14085 SrcExprs.push_back(nullptr); 14086 DstExprs.push_back(nullptr); 14087 AssignmentOps.push_back(nullptr); 14088 continue; 14089 } 14090 14091 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14092 // A list item that appears in a copyin clause must be threadprivate. 14093 if (!DSAStack->isThreadPrivate(VD)) { 14094 Diag(ELoc, diag::err_omp_required_access) 14095 << getOpenMPClauseName(OMPC_copyin) 14096 << getOpenMPDirectiveName(OMPD_threadprivate); 14097 continue; 14098 } 14099 14100 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14101 // A variable of class type (or array thereof) that appears in a 14102 // copyin clause requires an accessible, unambiguous copy assignment 14103 // operator for the class type. 14104 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14105 VarDecl *SrcVD = 14106 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14107 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14108 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14109 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14110 VarDecl *DstVD = 14111 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14112 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14113 DeclRefExpr *PseudoDstExpr = 14114 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14115 // For arrays generate assignment operation for single element and replace 14116 // it by the original array element in CodeGen. 14117 ExprResult AssignmentOp = 14118 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14119 PseudoSrcExpr); 14120 if (AssignmentOp.isInvalid()) 14121 continue; 14122 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14123 /*DiscardedValue*/ false); 14124 if (AssignmentOp.isInvalid()) 14125 continue; 14126 14127 DSAStack->addDSA(VD, DE, OMPC_copyin); 14128 Vars.push_back(DE); 14129 SrcExprs.push_back(PseudoSrcExpr); 14130 DstExprs.push_back(PseudoDstExpr); 14131 AssignmentOps.push_back(AssignmentOp.get()); 14132 } 14133 14134 if (Vars.empty()) 14135 return nullptr; 14136 14137 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14138 SrcExprs, DstExprs, AssignmentOps); 14139 } 14140 14141 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14142 SourceLocation StartLoc, 14143 SourceLocation LParenLoc, 14144 SourceLocation EndLoc) { 14145 SmallVector<Expr *, 8> Vars; 14146 SmallVector<Expr *, 8> SrcExprs; 14147 SmallVector<Expr *, 8> DstExprs; 14148 SmallVector<Expr *, 8> AssignmentOps; 14149 for (Expr *RefExpr : VarList) { 14150 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14151 SourceLocation ELoc; 14152 SourceRange ERange; 14153 Expr *SimpleRefExpr = RefExpr; 14154 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14155 if (Res.second) { 14156 // It will be analyzed later. 14157 Vars.push_back(RefExpr); 14158 SrcExprs.push_back(nullptr); 14159 DstExprs.push_back(nullptr); 14160 AssignmentOps.push_back(nullptr); 14161 } 14162 ValueDecl *D = Res.first; 14163 if (!D) 14164 continue; 14165 14166 QualType Type = D->getType(); 14167 auto *VD = dyn_cast<VarDecl>(D); 14168 14169 // OpenMP [2.14.4.2, Restrictions, p.2] 14170 // A list item that appears in a copyprivate clause may not appear in a 14171 // private or firstprivate clause on the single construct. 14172 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14173 DSAStackTy::DSAVarData DVar = 14174 DSAStack->getTopDSA(D, /*FromParent=*/false); 14175 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14176 DVar.RefExpr) { 14177 Diag(ELoc, diag::err_omp_wrong_dsa) 14178 << getOpenMPClauseName(DVar.CKind) 14179 << getOpenMPClauseName(OMPC_copyprivate); 14180 reportOriginalDsa(*this, DSAStack, D, DVar); 14181 continue; 14182 } 14183 14184 // OpenMP [2.11.4.2, Restrictions, p.1] 14185 // All list items that appear in a copyprivate clause must be either 14186 // threadprivate or private in the enclosing context. 14187 if (DVar.CKind == OMPC_unknown) { 14188 DVar = DSAStack->getImplicitDSA(D, false); 14189 if (DVar.CKind == OMPC_shared) { 14190 Diag(ELoc, diag::err_omp_required_access) 14191 << getOpenMPClauseName(OMPC_copyprivate) 14192 << "threadprivate or private in the enclosing context"; 14193 reportOriginalDsa(*this, DSAStack, D, DVar); 14194 continue; 14195 } 14196 } 14197 } 14198 14199 // Variably modified types are not supported. 14200 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14201 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14202 << getOpenMPClauseName(OMPC_copyprivate) << Type 14203 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14204 bool IsDecl = 14205 !VD || 14206 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14207 Diag(D->getLocation(), 14208 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14209 << D; 14210 continue; 14211 } 14212 14213 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14214 // A variable of class type (or array thereof) that appears in a 14215 // copyin clause requires an accessible, unambiguous copy assignment 14216 // operator for the class type. 14217 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14218 .getUnqualifiedType(); 14219 VarDecl *SrcVD = 14220 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14221 D->hasAttrs() ? &D->getAttrs() : nullptr); 14222 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14223 VarDecl *DstVD = 14224 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14225 D->hasAttrs() ? &D->getAttrs() : nullptr); 14226 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14227 ExprResult AssignmentOp = BuildBinOp( 14228 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14229 if (AssignmentOp.isInvalid()) 14230 continue; 14231 AssignmentOp = 14232 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14233 if (AssignmentOp.isInvalid()) 14234 continue; 14235 14236 // No need to mark vars as copyprivate, they are already threadprivate or 14237 // implicitly private. 14238 assert(VD || isOpenMPCapturedDecl(D)); 14239 Vars.push_back( 14240 VD ? RefExpr->IgnoreParens() 14241 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14242 SrcExprs.push_back(PseudoSrcExpr); 14243 DstExprs.push_back(PseudoDstExpr); 14244 AssignmentOps.push_back(AssignmentOp.get()); 14245 } 14246 14247 if (Vars.empty()) 14248 return nullptr; 14249 14250 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14251 Vars, SrcExprs, DstExprs, AssignmentOps); 14252 } 14253 14254 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14255 SourceLocation StartLoc, 14256 SourceLocation LParenLoc, 14257 SourceLocation EndLoc) { 14258 if (VarList.empty()) 14259 return nullptr; 14260 14261 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14262 } 14263 14264 OMPClause * 14265 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14266 SourceLocation DepLoc, SourceLocation ColonLoc, 14267 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14268 SourceLocation LParenLoc, SourceLocation EndLoc) { 14269 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14270 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14271 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14272 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14273 return nullptr; 14274 } 14275 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14276 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14277 DepKind == OMPC_DEPEND_sink)) { 14278 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14279 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14280 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14281 /*Last=*/OMPC_DEPEND_unknown, Except) 14282 << getOpenMPClauseName(OMPC_depend); 14283 return nullptr; 14284 } 14285 SmallVector<Expr *, 8> Vars; 14286 DSAStackTy::OperatorOffsetTy OpsOffs; 14287 llvm::APSInt DepCounter(/*BitWidth=*/32); 14288 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14289 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14290 if (const Expr *OrderedCountExpr = 14291 DSAStack->getParentOrderedRegionParam().first) { 14292 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14293 TotalDepCount.setIsUnsigned(/*Val=*/true); 14294 } 14295 } 14296 for (Expr *RefExpr : VarList) { 14297 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14298 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14299 // It will be analyzed later. 14300 Vars.push_back(RefExpr); 14301 continue; 14302 } 14303 14304 SourceLocation ELoc = RefExpr->getExprLoc(); 14305 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14306 if (DepKind == OMPC_DEPEND_sink) { 14307 if (DSAStack->getParentOrderedRegionParam().first && 14308 DepCounter >= TotalDepCount) { 14309 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14310 continue; 14311 } 14312 ++DepCounter; 14313 // OpenMP [2.13.9, Summary] 14314 // depend(dependence-type : vec), where dependence-type is: 14315 // 'sink' and where vec is the iteration vector, which has the form: 14316 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14317 // where n is the value specified by the ordered clause in the loop 14318 // directive, xi denotes the loop iteration variable of the i-th nested 14319 // loop associated with the loop directive, and di is a constant 14320 // non-negative integer. 14321 if (CurContext->isDependentContext()) { 14322 // It will be analyzed later. 14323 Vars.push_back(RefExpr); 14324 continue; 14325 } 14326 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14327 OverloadedOperatorKind OOK = OO_None; 14328 SourceLocation OOLoc; 14329 Expr *LHS = SimpleExpr; 14330 Expr *RHS = nullptr; 14331 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14332 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14333 OOLoc = BO->getOperatorLoc(); 14334 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14335 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14336 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14337 OOK = OCE->getOperator(); 14338 OOLoc = OCE->getOperatorLoc(); 14339 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14340 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14341 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14342 OOK = MCE->getMethodDecl() 14343 ->getNameInfo() 14344 .getName() 14345 .getCXXOverloadedOperator(); 14346 OOLoc = MCE->getCallee()->getExprLoc(); 14347 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14348 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14349 } 14350 SourceLocation ELoc; 14351 SourceRange ERange; 14352 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14353 if (Res.second) { 14354 // It will be analyzed later. 14355 Vars.push_back(RefExpr); 14356 } 14357 ValueDecl *D = Res.first; 14358 if (!D) 14359 continue; 14360 14361 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14362 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14363 continue; 14364 } 14365 if (RHS) { 14366 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14367 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14368 if (RHSRes.isInvalid()) 14369 continue; 14370 } 14371 if (!CurContext->isDependentContext() && 14372 DSAStack->getParentOrderedRegionParam().first && 14373 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14374 const ValueDecl *VD = 14375 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14376 if (VD) 14377 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14378 << 1 << VD; 14379 else 14380 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14381 continue; 14382 } 14383 OpsOffs.emplace_back(RHS, OOK); 14384 } else { 14385 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14386 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14387 (ASE && 14388 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14389 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14390 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14391 << RefExpr->getSourceRange(); 14392 continue; 14393 } 14394 14395 ExprResult Res; 14396 { 14397 Sema::TentativeAnalysisScope Trap(*this); 14398 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14399 RefExpr->IgnoreParenImpCasts()); 14400 } 14401 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14402 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14403 << RefExpr->getSourceRange(); 14404 continue; 14405 } 14406 } 14407 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14408 } 14409 14410 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14411 TotalDepCount > VarList.size() && 14412 DSAStack->getParentOrderedRegionParam().first && 14413 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14414 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14415 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14416 } 14417 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14418 Vars.empty()) 14419 return nullptr; 14420 14421 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14422 DepKind, DepLoc, ColonLoc, Vars, 14423 TotalDepCount.getZExtValue()); 14424 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14425 DSAStack->isParentOrderedRegion()) 14426 DSAStack->addDoacrossDependClause(C, OpsOffs); 14427 return C; 14428 } 14429 14430 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14431 SourceLocation LParenLoc, 14432 SourceLocation EndLoc) { 14433 Expr *ValExpr = Device; 14434 Stmt *HelperValStmt = nullptr; 14435 14436 // OpenMP [2.9.1, Restrictions] 14437 // The device expression must evaluate to a non-negative integer value. 14438 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14439 /*StrictlyPositive=*/false)) 14440 return nullptr; 14441 14442 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14443 OpenMPDirectiveKind CaptureRegion = 14444 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14445 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14446 ValExpr = MakeFullExpr(ValExpr).get(); 14447 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14448 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14449 HelperValStmt = buildPreInits(Context, Captures); 14450 } 14451 14452 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14453 StartLoc, LParenLoc, EndLoc); 14454 } 14455 14456 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14457 DSAStackTy *Stack, QualType QTy, 14458 bool FullCheck = true) { 14459 NamedDecl *ND; 14460 if (QTy->isIncompleteType(&ND)) { 14461 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14462 return false; 14463 } 14464 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14465 !QTy.isTrivialType(SemaRef.Context)) 14466 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14467 return true; 14468 } 14469 14470 /// Return true if it can be proven that the provided array expression 14471 /// (array section or array subscript) does NOT specify the whole size of the 14472 /// array whose base type is \a BaseQTy. 14473 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14474 const Expr *E, 14475 QualType BaseQTy) { 14476 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14477 14478 // If this is an array subscript, it refers to the whole size if the size of 14479 // the dimension is constant and equals 1. Also, an array section assumes the 14480 // format of an array subscript if no colon is used. 14481 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14482 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14483 return ATy->getSize().getSExtValue() != 1; 14484 // Size can't be evaluated statically. 14485 return false; 14486 } 14487 14488 assert(OASE && "Expecting array section if not an array subscript."); 14489 const Expr *LowerBound = OASE->getLowerBound(); 14490 const Expr *Length = OASE->getLength(); 14491 14492 // If there is a lower bound that does not evaluates to zero, we are not 14493 // covering the whole dimension. 14494 if (LowerBound) { 14495 Expr::EvalResult Result; 14496 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14497 return false; // Can't get the integer value as a constant. 14498 14499 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14500 if (ConstLowerBound.getSExtValue()) 14501 return true; 14502 } 14503 14504 // If we don't have a length we covering the whole dimension. 14505 if (!Length) 14506 return false; 14507 14508 // If the base is a pointer, we don't have a way to get the size of the 14509 // pointee. 14510 if (BaseQTy->isPointerType()) 14511 return false; 14512 14513 // We can only check if the length is the same as the size of the dimension 14514 // if we have a constant array. 14515 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14516 if (!CATy) 14517 return false; 14518 14519 Expr::EvalResult Result; 14520 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14521 return false; // Can't get the integer value as a constant. 14522 14523 llvm::APSInt ConstLength = Result.Val.getInt(); 14524 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14525 } 14526 14527 // Return true if it can be proven that the provided array expression (array 14528 // section or array subscript) does NOT specify a single element of the array 14529 // whose base type is \a BaseQTy. 14530 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14531 const Expr *E, 14532 QualType BaseQTy) { 14533 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14534 14535 // An array subscript always refer to a single element. Also, an array section 14536 // assumes the format of an array subscript if no colon is used. 14537 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14538 return false; 14539 14540 assert(OASE && "Expecting array section if not an array subscript."); 14541 const Expr *Length = OASE->getLength(); 14542 14543 // If we don't have a length we have to check if the array has unitary size 14544 // for this dimension. Also, we should always expect a length if the base type 14545 // is pointer. 14546 if (!Length) { 14547 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14548 return ATy->getSize().getSExtValue() != 1; 14549 // We cannot assume anything. 14550 return false; 14551 } 14552 14553 // Check if the length evaluates to 1. 14554 Expr::EvalResult Result; 14555 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14556 return false; // Can't get the integer value as a constant. 14557 14558 llvm::APSInt ConstLength = Result.Val.getInt(); 14559 return ConstLength.getSExtValue() != 1; 14560 } 14561 14562 // Return the expression of the base of the mappable expression or null if it 14563 // cannot be determined and do all the necessary checks to see if the expression 14564 // is valid as a standalone mappable expression. In the process, record all the 14565 // components of the expression. 14566 static const Expr *checkMapClauseExpressionBase( 14567 Sema &SemaRef, Expr *E, 14568 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14569 OpenMPClauseKind CKind, bool NoDiagnose) { 14570 SourceLocation ELoc = E->getExprLoc(); 14571 SourceRange ERange = E->getSourceRange(); 14572 14573 // The base of elements of list in a map clause have to be either: 14574 // - a reference to variable or field. 14575 // - a member expression. 14576 // - an array expression. 14577 // 14578 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14579 // reference to 'r'. 14580 // 14581 // If we have: 14582 // 14583 // struct SS { 14584 // Bla S; 14585 // foo() { 14586 // #pragma omp target map (S.Arr[:12]); 14587 // } 14588 // } 14589 // 14590 // We want to retrieve the member expression 'this->S'; 14591 14592 const Expr *RelevantExpr = nullptr; 14593 14594 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14595 // If a list item is an array section, it must specify contiguous storage. 14596 // 14597 // For this restriction it is sufficient that we make sure only references 14598 // to variables or fields and array expressions, and that no array sections 14599 // exist except in the rightmost expression (unless they cover the whole 14600 // dimension of the array). E.g. these would be invalid: 14601 // 14602 // r.ArrS[3:5].Arr[6:7] 14603 // 14604 // r.ArrS[3:5].x 14605 // 14606 // but these would be valid: 14607 // r.ArrS[3].Arr[6:7] 14608 // 14609 // r.ArrS[3].x 14610 14611 bool AllowUnitySizeArraySection = true; 14612 bool AllowWholeSizeArraySection = true; 14613 14614 while (!RelevantExpr) { 14615 E = E->IgnoreParenImpCasts(); 14616 14617 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14618 if (!isa<VarDecl>(CurE->getDecl())) 14619 return nullptr; 14620 14621 RelevantExpr = CurE; 14622 14623 // If we got a reference to a declaration, we should not expect any array 14624 // section before that. 14625 AllowUnitySizeArraySection = false; 14626 AllowWholeSizeArraySection = false; 14627 14628 // Record the component. 14629 CurComponents.emplace_back(CurE, CurE->getDecl()); 14630 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14631 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14632 14633 if (isa<CXXThisExpr>(BaseE)) 14634 // We found a base expression: this->Val. 14635 RelevantExpr = CurE; 14636 else 14637 E = BaseE; 14638 14639 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14640 if (!NoDiagnose) { 14641 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14642 << CurE->getSourceRange(); 14643 return nullptr; 14644 } 14645 if (RelevantExpr) 14646 return nullptr; 14647 continue; 14648 } 14649 14650 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14651 14652 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14653 // A bit-field cannot appear in a map clause. 14654 // 14655 if (FD->isBitField()) { 14656 if (!NoDiagnose) { 14657 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14658 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14659 return nullptr; 14660 } 14661 if (RelevantExpr) 14662 return nullptr; 14663 continue; 14664 } 14665 14666 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14667 // If the type of a list item is a reference to a type T then the type 14668 // will be considered to be T for all purposes of this clause. 14669 QualType CurType = BaseE->getType().getNonReferenceType(); 14670 14671 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14672 // A list item cannot be a variable that is a member of a structure with 14673 // a union type. 14674 // 14675 if (CurType->isUnionType()) { 14676 if (!NoDiagnose) { 14677 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14678 << CurE->getSourceRange(); 14679 return nullptr; 14680 } 14681 continue; 14682 } 14683 14684 // If we got a member expression, we should not expect any array section 14685 // before that: 14686 // 14687 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14688 // If a list item is an element of a structure, only the rightmost symbol 14689 // of the variable reference can be an array section. 14690 // 14691 AllowUnitySizeArraySection = false; 14692 AllowWholeSizeArraySection = false; 14693 14694 // Record the component. 14695 CurComponents.emplace_back(CurE, FD); 14696 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14697 E = CurE->getBase()->IgnoreParenImpCasts(); 14698 14699 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14700 if (!NoDiagnose) { 14701 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14702 << 0 << CurE->getSourceRange(); 14703 return nullptr; 14704 } 14705 continue; 14706 } 14707 14708 // If we got an array subscript that express the whole dimension we 14709 // can have any array expressions before. If it only expressing part of 14710 // the dimension, we can only have unitary-size array expressions. 14711 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14712 E->getType())) 14713 AllowWholeSizeArraySection = false; 14714 14715 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14716 Expr::EvalResult Result; 14717 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14718 if (!Result.Val.getInt().isNullValue()) { 14719 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14720 diag::err_omp_invalid_map_this_expr); 14721 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14722 diag::note_omp_invalid_subscript_on_this_ptr_map); 14723 } 14724 } 14725 RelevantExpr = TE; 14726 } 14727 14728 // Record the component - we don't have any declaration associated. 14729 CurComponents.emplace_back(CurE, nullptr); 14730 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14731 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14732 E = CurE->getBase()->IgnoreParenImpCasts(); 14733 14734 QualType CurType = 14735 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14736 14737 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14738 // If the type of a list item is a reference to a type T then the type 14739 // will be considered to be T for all purposes of this clause. 14740 if (CurType->isReferenceType()) 14741 CurType = CurType->getPointeeType(); 14742 14743 bool IsPointer = CurType->isAnyPointerType(); 14744 14745 if (!IsPointer && !CurType->isArrayType()) { 14746 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14747 << 0 << CurE->getSourceRange(); 14748 return nullptr; 14749 } 14750 14751 bool NotWhole = 14752 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14753 bool NotUnity = 14754 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14755 14756 if (AllowWholeSizeArraySection) { 14757 // Any array section is currently allowed. Allowing a whole size array 14758 // section implies allowing a unity array section as well. 14759 // 14760 // If this array section refers to the whole dimension we can still 14761 // accept other array sections before this one, except if the base is a 14762 // pointer. Otherwise, only unitary sections are accepted. 14763 if (NotWhole || IsPointer) 14764 AllowWholeSizeArraySection = false; 14765 } else if (AllowUnitySizeArraySection && NotUnity) { 14766 // A unity or whole array section is not allowed and that is not 14767 // compatible with the properties of the current array section. 14768 SemaRef.Diag( 14769 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14770 << CurE->getSourceRange(); 14771 return nullptr; 14772 } 14773 14774 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14775 Expr::EvalResult ResultR; 14776 Expr::EvalResult ResultL; 14777 if (CurE->getLength()->EvaluateAsInt(ResultR, 14778 SemaRef.getASTContext())) { 14779 if (!ResultR.Val.getInt().isOneValue()) { 14780 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14781 diag::err_omp_invalid_map_this_expr); 14782 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14783 diag::note_omp_invalid_length_on_this_ptr_mapping); 14784 } 14785 } 14786 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14787 ResultL, SemaRef.getASTContext())) { 14788 if (!ResultL.Val.getInt().isNullValue()) { 14789 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14790 diag::err_omp_invalid_map_this_expr); 14791 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14792 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14793 } 14794 } 14795 RelevantExpr = TE; 14796 } 14797 14798 // Record the component - we don't have any declaration associated. 14799 CurComponents.emplace_back(CurE, nullptr); 14800 } else { 14801 if (!NoDiagnose) { 14802 // If nothing else worked, this is not a valid map clause expression. 14803 SemaRef.Diag( 14804 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14805 << ERange; 14806 } 14807 return nullptr; 14808 } 14809 } 14810 14811 return RelevantExpr; 14812 } 14813 14814 // Return true if expression E associated with value VD has conflicts with other 14815 // map information. 14816 static bool checkMapConflicts( 14817 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14818 bool CurrentRegionOnly, 14819 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14820 OpenMPClauseKind CKind) { 14821 assert(VD && E); 14822 SourceLocation ELoc = E->getExprLoc(); 14823 SourceRange ERange = E->getSourceRange(); 14824 14825 // In order to easily check the conflicts we need to match each component of 14826 // the expression under test with the components of the expressions that are 14827 // already in the stack. 14828 14829 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14830 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14831 "Map clause expression with unexpected base!"); 14832 14833 // Variables to help detecting enclosing problems in data environment nests. 14834 bool IsEnclosedByDataEnvironmentExpr = false; 14835 const Expr *EnclosingExpr = nullptr; 14836 14837 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14838 VD, CurrentRegionOnly, 14839 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14840 ERange, CKind, &EnclosingExpr, 14841 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14842 StackComponents, 14843 OpenMPClauseKind) { 14844 assert(!StackComponents.empty() && 14845 "Map clause expression with no components!"); 14846 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14847 "Map clause expression with unexpected base!"); 14848 (void)VD; 14849 14850 // The whole expression in the stack. 14851 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14852 14853 // Expressions must start from the same base. Here we detect at which 14854 // point both expressions diverge from each other and see if we can 14855 // detect if the memory referred to both expressions is contiguous and 14856 // do not overlap. 14857 auto CI = CurComponents.rbegin(); 14858 auto CE = CurComponents.rend(); 14859 auto SI = StackComponents.rbegin(); 14860 auto SE = StackComponents.rend(); 14861 for (; CI != CE && SI != SE; ++CI, ++SI) { 14862 14863 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14864 // At most one list item can be an array item derived from a given 14865 // variable in map clauses of the same construct. 14866 if (CurrentRegionOnly && 14867 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14868 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14869 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14870 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14871 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14872 diag::err_omp_multiple_array_items_in_map_clause) 14873 << CI->getAssociatedExpression()->getSourceRange(); 14874 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14875 diag::note_used_here) 14876 << SI->getAssociatedExpression()->getSourceRange(); 14877 return true; 14878 } 14879 14880 // Do both expressions have the same kind? 14881 if (CI->getAssociatedExpression()->getStmtClass() != 14882 SI->getAssociatedExpression()->getStmtClass()) 14883 break; 14884 14885 // Are we dealing with different variables/fields? 14886 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14887 break; 14888 } 14889 // Check if the extra components of the expressions in the enclosing 14890 // data environment are redundant for the current base declaration. 14891 // If they are, the maps completely overlap, which is legal. 14892 for (; SI != SE; ++SI) { 14893 QualType Type; 14894 if (const auto *ASE = 14895 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14896 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14897 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14898 SI->getAssociatedExpression())) { 14899 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14900 Type = 14901 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14902 } 14903 if (Type.isNull() || Type->isAnyPointerType() || 14904 checkArrayExpressionDoesNotReferToWholeSize( 14905 SemaRef, SI->getAssociatedExpression(), Type)) 14906 break; 14907 } 14908 14909 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14910 // List items of map clauses in the same construct must not share 14911 // original storage. 14912 // 14913 // If the expressions are exactly the same or one is a subset of the 14914 // other, it means they are sharing storage. 14915 if (CI == CE && SI == SE) { 14916 if (CurrentRegionOnly) { 14917 if (CKind == OMPC_map) { 14918 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14919 } else { 14920 assert(CKind == OMPC_to || CKind == OMPC_from); 14921 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14922 << ERange; 14923 } 14924 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14925 << RE->getSourceRange(); 14926 return true; 14927 } 14928 // If we find the same expression in the enclosing data environment, 14929 // that is legal. 14930 IsEnclosedByDataEnvironmentExpr = true; 14931 return false; 14932 } 14933 14934 QualType DerivedType = 14935 std::prev(CI)->getAssociatedDeclaration()->getType(); 14936 SourceLocation DerivedLoc = 14937 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14938 14939 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14940 // If the type of a list item is a reference to a type T then the type 14941 // will be considered to be T for all purposes of this clause. 14942 DerivedType = DerivedType.getNonReferenceType(); 14943 14944 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14945 // A variable for which the type is pointer and an array section 14946 // derived from that variable must not appear as list items of map 14947 // clauses of the same construct. 14948 // 14949 // Also, cover one of the cases in: 14950 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14951 // If any part of the original storage of a list item has corresponding 14952 // storage in the device data environment, all of the original storage 14953 // must have corresponding storage in the device data environment. 14954 // 14955 if (DerivedType->isAnyPointerType()) { 14956 if (CI == CE || SI == SE) { 14957 SemaRef.Diag( 14958 DerivedLoc, 14959 diag::err_omp_pointer_mapped_along_with_derived_section) 14960 << DerivedLoc; 14961 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14962 << RE->getSourceRange(); 14963 return true; 14964 } 14965 if (CI->getAssociatedExpression()->getStmtClass() != 14966 SI->getAssociatedExpression()->getStmtClass() || 14967 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14968 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14969 assert(CI != CE && SI != SE); 14970 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14971 << DerivedLoc; 14972 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14973 << RE->getSourceRange(); 14974 return true; 14975 } 14976 } 14977 14978 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14979 // List items of map clauses in the same construct must not share 14980 // original storage. 14981 // 14982 // An expression is a subset of the other. 14983 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14984 if (CKind == OMPC_map) { 14985 if (CI != CE || SI != SE) { 14986 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14987 // a pointer. 14988 auto Begin = 14989 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14990 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14991 auto It = Begin; 14992 while (It != End && !It->getAssociatedDeclaration()) 14993 std::advance(It, 1); 14994 assert(It != End && 14995 "Expected at least one component with the declaration."); 14996 if (It != Begin && It->getAssociatedDeclaration() 14997 ->getType() 14998 .getCanonicalType() 14999 ->isAnyPointerType()) { 15000 IsEnclosedByDataEnvironmentExpr = false; 15001 EnclosingExpr = nullptr; 15002 return false; 15003 } 15004 } 15005 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15006 } else { 15007 assert(CKind == OMPC_to || CKind == OMPC_from); 15008 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15009 << ERange; 15010 } 15011 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15012 << RE->getSourceRange(); 15013 return true; 15014 } 15015 15016 // The current expression uses the same base as other expression in the 15017 // data environment but does not contain it completely. 15018 if (!CurrentRegionOnly && SI != SE) 15019 EnclosingExpr = RE; 15020 15021 // The current expression is a subset of the expression in the data 15022 // environment. 15023 IsEnclosedByDataEnvironmentExpr |= 15024 (!CurrentRegionOnly && CI != CE && SI == SE); 15025 15026 return false; 15027 }); 15028 15029 if (CurrentRegionOnly) 15030 return FoundError; 15031 15032 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15033 // If any part of the original storage of a list item has corresponding 15034 // storage in the device data environment, all of the original storage must 15035 // have corresponding storage in the device data environment. 15036 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15037 // If a list item is an element of a structure, and a different element of 15038 // the structure has a corresponding list item in the device data environment 15039 // prior to a task encountering the construct associated with the map clause, 15040 // then the list item must also have a corresponding list item in the device 15041 // data environment prior to the task encountering the construct. 15042 // 15043 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15044 SemaRef.Diag(ELoc, 15045 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15046 << ERange; 15047 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15048 << EnclosingExpr->getSourceRange(); 15049 return true; 15050 } 15051 15052 return FoundError; 15053 } 15054 15055 // Look up the user-defined mapper given the mapper name and mapped type, and 15056 // build a reference to it. 15057 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15058 CXXScopeSpec &MapperIdScopeSpec, 15059 const DeclarationNameInfo &MapperId, 15060 QualType Type, 15061 Expr *UnresolvedMapper) { 15062 if (MapperIdScopeSpec.isInvalid()) 15063 return ExprError(); 15064 // Get the actual type for the array type. 15065 if (Type->isArrayType()) { 15066 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15067 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15068 } 15069 // Find all user-defined mappers with the given MapperId. 15070 SmallVector<UnresolvedSet<8>, 4> Lookups; 15071 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15072 Lookup.suppressDiagnostics(); 15073 if (S) { 15074 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15075 NamedDecl *D = Lookup.getRepresentativeDecl(); 15076 while (S && !S->isDeclScope(D)) 15077 S = S->getParent(); 15078 if (S) 15079 S = S->getParent(); 15080 Lookups.emplace_back(); 15081 Lookups.back().append(Lookup.begin(), Lookup.end()); 15082 Lookup.clear(); 15083 } 15084 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15085 // Extract the user-defined mappers with the given MapperId. 15086 Lookups.push_back(UnresolvedSet<8>()); 15087 for (NamedDecl *D : ULE->decls()) { 15088 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15089 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15090 Lookups.back().addDecl(DMD); 15091 } 15092 } 15093 // Defer the lookup for dependent types. The results will be passed through 15094 // UnresolvedMapper on instantiation. 15095 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15096 Type->isInstantiationDependentType() || 15097 Type->containsUnexpandedParameterPack() || 15098 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15099 return !D->isInvalidDecl() && 15100 (D->getType()->isDependentType() || 15101 D->getType()->isInstantiationDependentType() || 15102 D->getType()->containsUnexpandedParameterPack()); 15103 })) { 15104 UnresolvedSet<8> URS; 15105 for (const UnresolvedSet<8> &Set : Lookups) { 15106 if (Set.empty()) 15107 continue; 15108 URS.append(Set.begin(), Set.end()); 15109 } 15110 return UnresolvedLookupExpr::Create( 15111 SemaRef.Context, /*NamingClass=*/nullptr, 15112 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15113 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15114 } 15115 SourceLocation Loc = MapperId.getLoc(); 15116 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15117 // The type must be of struct, union or class type in C and C++ 15118 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15119 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15120 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15121 return ExprError(); 15122 } 15123 // Perform argument dependent lookup. 15124 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15125 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15126 // Return the first user-defined mapper with the desired type. 15127 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15128 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15129 if (!D->isInvalidDecl() && 15130 SemaRef.Context.hasSameType(D->getType(), Type)) 15131 return D; 15132 return nullptr; 15133 })) 15134 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15135 // Find the first user-defined mapper with a type derived from the desired 15136 // type. 15137 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15138 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15139 if (!D->isInvalidDecl() && 15140 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15141 !Type.isMoreQualifiedThan(D->getType())) 15142 return D; 15143 return nullptr; 15144 })) { 15145 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15146 /*DetectVirtual=*/false); 15147 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15148 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15149 VD->getType().getUnqualifiedType()))) { 15150 if (SemaRef.CheckBaseClassAccess( 15151 Loc, VD->getType(), Type, Paths.front(), 15152 /*DiagID=*/0) != Sema::AR_inaccessible) { 15153 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15154 } 15155 } 15156 } 15157 } 15158 // Report error if a mapper is specified, but cannot be found. 15159 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15160 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15161 << Type << MapperId.getName(); 15162 return ExprError(); 15163 } 15164 return ExprEmpty(); 15165 } 15166 15167 namespace { 15168 // Utility struct that gathers all the related lists associated with a mappable 15169 // expression. 15170 struct MappableVarListInfo { 15171 // The list of expressions. 15172 ArrayRef<Expr *> VarList; 15173 // The list of processed expressions. 15174 SmallVector<Expr *, 16> ProcessedVarList; 15175 // The mappble components for each expression. 15176 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15177 // The base declaration of the variable. 15178 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15179 // The reference to the user-defined mapper associated with every expression. 15180 SmallVector<Expr *, 16> UDMapperList; 15181 15182 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15183 // We have a list of components and base declarations for each entry in the 15184 // variable list. 15185 VarComponents.reserve(VarList.size()); 15186 VarBaseDeclarations.reserve(VarList.size()); 15187 } 15188 }; 15189 } 15190 15191 // Check the validity of the provided variable list for the provided clause kind 15192 // \a CKind. In the check process the valid expressions, mappable expression 15193 // components, variables, and user-defined mappers are extracted and used to 15194 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15195 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15196 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15197 static void checkMappableExpressionList( 15198 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15199 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15200 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15201 ArrayRef<Expr *> UnresolvedMappers, 15202 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15203 bool IsMapTypeImplicit = false) { 15204 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15205 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15206 "Unexpected clause kind with mappable expressions!"); 15207 15208 // If the identifier of user-defined mapper is not specified, it is "default". 15209 // We do not change the actual name in this clause to distinguish whether a 15210 // mapper is specified explicitly, i.e., it is not explicitly specified when 15211 // MapperId.getName() is empty. 15212 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15213 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15214 MapperId.setName(DeclNames.getIdentifier( 15215 &SemaRef.getASTContext().Idents.get("default"))); 15216 } 15217 15218 // Iterators to find the current unresolved mapper expression. 15219 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15220 bool UpdateUMIt = false; 15221 Expr *UnresolvedMapper = nullptr; 15222 15223 // Keep track of the mappable components and base declarations in this clause. 15224 // Each entry in the list is going to have a list of components associated. We 15225 // record each set of the components so that we can build the clause later on. 15226 // In the end we should have the same amount of declarations and component 15227 // lists. 15228 15229 for (Expr *RE : MVLI.VarList) { 15230 assert(RE && "Null expr in omp to/from/map clause"); 15231 SourceLocation ELoc = RE->getExprLoc(); 15232 15233 // Find the current unresolved mapper expression. 15234 if (UpdateUMIt && UMIt != UMEnd) { 15235 UMIt++; 15236 assert( 15237 UMIt != UMEnd && 15238 "Expect the size of UnresolvedMappers to match with that of VarList"); 15239 } 15240 UpdateUMIt = true; 15241 if (UMIt != UMEnd) 15242 UnresolvedMapper = *UMIt; 15243 15244 const Expr *VE = RE->IgnoreParenLValueCasts(); 15245 15246 if (VE->isValueDependent() || VE->isTypeDependent() || 15247 VE->isInstantiationDependent() || 15248 VE->containsUnexpandedParameterPack()) { 15249 // Try to find the associated user-defined mapper. 15250 ExprResult ER = buildUserDefinedMapperRef( 15251 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15252 VE->getType().getCanonicalType(), UnresolvedMapper); 15253 if (ER.isInvalid()) 15254 continue; 15255 MVLI.UDMapperList.push_back(ER.get()); 15256 // We can only analyze this information once the missing information is 15257 // resolved. 15258 MVLI.ProcessedVarList.push_back(RE); 15259 continue; 15260 } 15261 15262 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15263 15264 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15265 SemaRef.Diag(ELoc, 15266 diag::err_omp_expected_named_var_member_or_array_expression) 15267 << RE->getSourceRange(); 15268 continue; 15269 } 15270 15271 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15272 ValueDecl *CurDeclaration = nullptr; 15273 15274 // Obtain the array or member expression bases if required. Also, fill the 15275 // components array with all the components identified in the process. 15276 const Expr *BE = checkMapClauseExpressionBase( 15277 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15278 if (!BE) 15279 continue; 15280 15281 assert(!CurComponents.empty() && 15282 "Invalid mappable expression information."); 15283 15284 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15285 // Add store "this" pointer to class in DSAStackTy for future checking 15286 DSAS->addMappedClassesQualTypes(TE->getType()); 15287 // Try to find the associated user-defined mapper. 15288 ExprResult ER = buildUserDefinedMapperRef( 15289 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15290 VE->getType().getCanonicalType(), UnresolvedMapper); 15291 if (ER.isInvalid()) 15292 continue; 15293 MVLI.UDMapperList.push_back(ER.get()); 15294 // Skip restriction checking for variable or field declarations 15295 MVLI.ProcessedVarList.push_back(RE); 15296 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15297 MVLI.VarComponents.back().append(CurComponents.begin(), 15298 CurComponents.end()); 15299 MVLI.VarBaseDeclarations.push_back(nullptr); 15300 continue; 15301 } 15302 15303 // For the following checks, we rely on the base declaration which is 15304 // expected to be associated with the last component. The declaration is 15305 // expected to be a variable or a field (if 'this' is being mapped). 15306 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15307 assert(CurDeclaration && "Null decl on map clause."); 15308 assert( 15309 CurDeclaration->isCanonicalDecl() && 15310 "Expecting components to have associated only canonical declarations."); 15311 15312 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15313 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15314 15315 assert((VD || FD) && "Only variables or fields are expected here!"); 15316 (void)FD; 15317 15318 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15319 // threadprivate variables cannot appear in a map clause. 15320 // OpenMP 4.5 [2.10.5, target update Construct] 15321 // threadprivate variables cannot appear in a from clause. 15322 if (VD && DSAS->isThreadPrivate(VD)) { 15323 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15324 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15325 << getOpenMPClauseName(CKind); 15326 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15327 continue; 15328 } 15329 15330 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15331 // A list item cannot appear in both a map clause and a data-sharing 15332 // attribute clause on the same construct. 15333 15334 // Check conflicts with other map clause expressions. We check the conflicts 15335 // with the current construct separately from the enclosing data 15336 // environment, because the restrictions are different. We only have to 15337 // check conflicts across regions for the map clauses. 15338 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15339 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15340 break; 15341 if (CKind == OMPC_map && 15342 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15343 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15344 break; 15345 15346 // OpenMP 4.5 [2.10.5, target update Construct] 15347 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15348 // If the type of a list item is a reference to a type T then the type will 15349 // be considered to be T for all purposes of this clause. 15350 auto I = llvm::find_if( 15351 CurComponents, 15352 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15353 return MC.getAssociatedDeclaration(); 15354 }); 15355 assert(I != CurComponents.end() && "Null decl on map clause."); 15356 QualType Type = 15357 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15358 15359 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15360 // A list item in a to or from clause must have a mappable type. 15361 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15362 // A list item must have a mappable type. 15363 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15364 DSAS, Type)) 15365 continue; 15366 15367 if (CKind == OMPC_map) { 15368 // target enter data 15369 // OpenMP [2.10.2, Restrictions, p. 99] 15370 // A map-type must be specified in all map clauses and must be either 15371 // to or alloc. 15372 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15373 if (DKind == OMPD_target_enter_data && 15374 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15375 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15376 << (IsMapTypeImplicit ? 1 : 0) 15377 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15378 << getOpenMPDirectiveName(DKind); 15379 continue; 15380 } 15381 15382 // target exit_data 15383 // OpenMP [2.10.3, Restrictions, p. 102] 15384 // A map-type must be specified in all map clauses and must be either 15385 // from, release, or delete. 15386 if (DKind == OMPD_target_exit_data && 15387 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15388 MapType == OMPC_MAP_delete)) { 15389 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15390 << (IsMapTypeImplicit ? 1 : 0) 15391 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15392 << getOpenMPDirectiveName(DKind); 15393 continue; 15394 } 15395 15396 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15397 // A list item cannot appear in both a map clause and a data-sharing 15398 // attribute clause on the same construct 15399 // 15400 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15401 // A list item cannot appear in both a map clause and a data-sharing 15402 // attribute clause on the same construct unless the construct is a 15403 // combined construct. 15404 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15405 isOpenMPTargetExecutionDirective(DKind)) || 15406 DKind == OMPD_target)) { 15407 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15408 if (isOpenMPPrivate(DVar.CKind)) { 15409 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15410 << getOpenMPClauseName(DVar.CKind) 15411 << getOpenMPClauseName(OMPC_map) 15412 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15413 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15414 continue; 15415 } 15416 } 15417 } 15418 15419 // Try to find the associated user-defined mapper. 15420 ExprResult ER = buildUserDefinedMapperRef( 15421 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15422 Type.getCanonicalType(), UnresolvedMapper); 15423 if (ER.isInvalid()) 15424 continue; 15425 MVLI.UDMapperList.push_back(ER.get()); 15426 15427 // Save the current expression. 15428 MVLI.ProcessedVarList.push_back(RE); 15429 15430 // Store the components in the stack so that they can be used to check 15431 // against other clauses later on. 15432 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15433 /*WhereFoundClauseKind=*/OMPC_map); 15434 15435 // Save the components and declaration to create the clause. For purposes of 15436 // the clause creation, any component list that has has base 'this' uses 15437 // null as base declaration. 15438 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15439 MVLI.VarComponents.back().append(CurComponents.begin(), 15440 CurComponents.end()); 15441 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15442 : CurDeclaration); 15443 } 15444 } 15445 15446 OMPClause *Sema::ActOnOpenMPMapClause( 15447 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15448 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15449 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15450 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15451 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15452 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15453 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15454 OMPC_MAP_MODIFIER_unknown, 15455 OMPC_MAP_MODIFIER_unknown}; 15456 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15457 15458 // Process map-type-modifiers, flag errors for duplicate modifiers. 15459 unsigned Count = 0; 15460 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15461 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15462 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15463 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15464 continue; 15465 } 15466 assert(Count < OMPMapClause::NumberOfModifiers && 15467 "Modifiers exceed the allowed number of map type modifiers"); 15468 Modifiers[Count] = MapTypeModifiers[I]; 15469 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15470 ++Count; 15471 } 15472 15473 MappableVarListInfo MVLI(VarList); 15474 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15475 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15476 MapType, IsMapTypeImplicit); 15477 15478 // We need to produce a map clause even if we don't have variables so that 15479 // other diagnostics related with non-existing map clauses are accurate. 15480 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15481 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15482 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15483 MapperIdScopeSpec.getWithLocInContext(Context), 15484 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15485 } 15486 15487 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15488 TypeResult ParsedType) { 15489 assert(ParsedType.isUsable()); 15490 15491 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15492 if (ReductionType.isNull()) 15493 return QualType(); 15494 15495 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15496 // A type name in a declare reduction directive cannot be a function type, an 15497 // array type, a reference type, or a type qualified with const, volatile or 15498 // restrict. 15499 if (ReductionType.hasQualifiers()) { 15500 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15501 return QualType(); 15502 } 15503 15504 if (ReductionType->isFunctionType()) { 15505 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15506 return QualType(); 15507 } 15508 if (ReductionType->isReferenceType()) { 15509 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15510 return QualType(); 15511 } 15512 if (ReductionType->isArrayType()) { 15513 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15514 return QualType(); 15515 } 15516 return ReductionType; 15517 } 15518 15519 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15520 Scope *S, DeclContext *DC, DeclarationName Name, 15521 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15522 AccessSpecifier AS, Decl *PrevDeclInScope) { 15523 SmallVector<Decl *, 8> Decls; 15524 Decls.reserve(ReductionTypes.size()); 15525 15526 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15527 forRedeclarationInCurContext()); 15528 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15529 // A reduction-identifier may not be re-declared in the current scope for the 15530 // same type or for a type that is compatible according to the base language 15531 // rules. 15532 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15533 OMPDeclareReductionDecl *PrevDRD = nullptr; 15534 bool InCompoundScope = true; 15535 if (S != nullptr) { 15536 // Find previous declaration with the same name not referenced in other 15537 // declarations. 15538 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15539 InCompoundScope = 15540 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15541 LookupName(Lookup, S); 15542 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15543 /*AllowInlineNamespace=*/false); 15544 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15545 LookupResult::Filter Filter = Lookup.makeFilter(); 15546 while (Filter.hasNext()) { 15547 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15548 if (InCompoundScope) { 15549 auto I = UsedAsPrevious.find(PrevDecl); 15550 if (I == UsedAsPrevious.end()) 15551 UsedAsPrevious[PrevDecl] = false; 15552 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15553 UsedAsPrevious[D] = true; 15554 } 15555 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15556 PrevDecl->getLocation(); 15557 } 15558 Filter.done(); 15559 if (InCompoundScope) { 15560 for (const auto &PrevData : UsedAsPrevious) { 15561 if (!PrevData.second) { 15562 PrevDRD = PrevData.first; 15563 break; 15564 } 15565 } 15566 } 15567 } else if (PrevDeclInScope != nullptr) { 15568 auto *PrevDRDInScope = PrevDRD = 15569 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15570 do { 15571 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15572 PrevDRDInScope->getLocation(); 15573 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15574 } while (PrevDRDInScope != nullptr); 15575 } 15576 for (const auto &TyData : ReductionTypes) { 15577 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15578 bool Invalid = false; 15579 if (I != PreviousRedeclTypes.end()) { 15580 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15581 << TyData.first; 15582 Diag(I->second, diag::note_previous_definition); 15583 Invalid = true; 15584 } 15585 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15586 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15587 Name, TyData.first, PrevDRD); 15588 DC->addDecl(DRD); 15589 DRD->setAccess(AS); 15590 Decls.push_back(DRD); 15591 if (Invalid) 15592 DRD->setInvalidDecl(); 15593 else 15594 PrevDRD = DRD; 15595 } 15596 15597 return DeclGroupPtrTy::make( 15598 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15599 } 15600 15601 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15602 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15603 15604 // Enter new function scope. 15605 PushFunctionScope(); 15606 setFunctionHasBranchProtectedScope(); 15607 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15608 15609 if (S != nullptr) 15610 PushDeclContext(S, DRD); 15611 else 15612 CurContext = DRD; 15613 15614 PushExpressionEvaluationContext( 15615 ExpressionEvaluationContext::PotentiallyEvaluated); 15616 15617 QualType ReductionType = DRD->getType(); 15618 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15619 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15620 // uses semantics of argument handles by value, but it should be passed by 15621 // reference. C lang does not support references, so pass all parameters as 15622 // pointers. 15623 // Create 'T omp_in;' variable. 15624 VarDecl *OmpInParm = 15625 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15626 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15627 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15628 // uses semantics of argument handles by value, but it should be passed by 15629 // reference. C lang does not support references, so pass all parameters as 15630 // pointers. 15631 // Create 'T omp_out;' variable. 15632 VarDecl *OmpOutParm = 15633 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15634 if (S != nullptr) { 15635 PushOnScopeChains(OmpInParm, S); 15636 PushOnScopeChains(OmpOutParm, S); 15637 } else { 15638 DRD->addDecl(OmpInParm); 15639 DRD->addDecl(OmpOutParm); 15640 } 15641 Expr *InE = 15642 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15643 Expr *OutE = 15644 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15645 DRD->setCombinerData(InE, OutE); 15646 } 15647 15648 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15649 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15650 DiscardCleanupsInEvaluationContext(); 15651 PopExpressionEvaluationContext(); 15652 15653 PopDeclContext(); 15654 PopFunctionScopeInfo(); 15655 15656 if (Combiner != nullptr) 15657 DRD->setCombiner(Combiner); 15658 else 15659 DRD->setInvalidDecl(); 15660 } 15661 15662 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15663 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15664 15665 // Enter new function scope. 15666 PushFunctionScope(); 15667 setFunctionHasBranchProtectedScope(); 15668 15669 if (S != nullptr) 15670 PushDeclContext(S, DRD); 15671 else 15672 CurContext = DRD; 15673 15674 PushExpressionEvaluationContext( 15675 ExpressionEvaluationContext::PotentiallyEvaluated); 15676 15677 QualType ReductionType = DRD->getType(); 15678 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15679 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15680 // uses semantics of argument handles by value, but it should be passed by 15681 // reference. C lang does not support references, so pass all parameters as 15682 // pointers. 15683 // Create 'T omp_priv;' variable. 15684 VarDecl *OmpPrivParm = 15685 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15686 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15687 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15688 // uses semantics of argument handles by value, but it should be passed by 15689 // reference. C lang does not support references, so pass all parameters as 15690 // pointers. 15691 // Create 'T omp_orig;' variable. 15692 VarDecl *OmpOrigParm = 15693 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15694 if (S != nullptr) { 15695 PushOnScopeChains(OmpPrivParm, S); 15696 PushOnScopeChains(OmpOrigParm, S); 15697 } else { 15698 DRD->addDecl(OmpPrivParm); 15699 DRD->addDecl(OmpOrigParm); 15700 } 15701 Expr *OrigE = 15702 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15703 Expr *PrivE = 15704 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15705 DRD->setInitializerData(OrigE, PrivE); 15706 return OmpPrivParm; 15707 } 15708 15709 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15710 VarDecl *OmpPrivParm) { 15711 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15712 DiscardCleanupsInEvaluationContext(); 15713 PopExpressionEvaluationContext(); 15714 15715 PopDeclContext(); 15716 PopFunctionScopeInfo(); 15717 15718 if (Initializer != nullptr) { 15719 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15720 } else if (OmpPrivParm->hasInit()) { 15721 DRD->setInitializer(OmpPrivParm->getInit(), 15722 OmpPrivParm->isDirectInit() 15723 ? OMPDeclareReductionDecl::DirectInit 15724 : OMPDeclareReductionDecl::CopyInit); 15725 } else { 15726 DRD->setInvalidDecl(); 15727 } 15728 } 15729 15730 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15731 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15732 for (Decl *D : DeclReductions.get()) { 15733 if (IsValid) { 15734 if (S) 15735 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15736 /*AddToContext=*/false); 15737 } else { 15738 D->setInvalidDecl(); 15739 } 15740 } 15741 return DeclReductions; 15742 } 15743 15744 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15745 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15746 QualType T = TInfo->getType(); 15747 if (D.isInvalidType()) 15748 return true; 15749 15750 if (getLangOpts().CPlusPlus) { 15751 // Check that there are no default arguments (C++ only). 15752 CheckExtraCXXDefaultArguments(D); 15753 } 15754 15755 return CreateParsedType(T, TInfo); 15756 } 15757 15758 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15759 TypeResult ParsedType) { 15760 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15761 15762 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15763 assert(!MapperType.isNull() && "Expect valid mapper type"); 15764 15765 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15766 // The type must be of struct, union or class type in C and C++ 15767 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15768 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15769 return QualType(); 15770 } 15771 return MapperType; 15772 } 15773 15774 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15775 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15776 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15777 Decl *PrevDeclInScope) { 15778 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15779 forRedeclarationInCurContext()); 15780 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15781 // A mapper-identifier may not be redeclared in the current scope for the 15782 // same type or for a type that is compatible according to the base language 15783 // rules. 15784 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15785 OMPDeclareMapperDecl *PrevDMD = nullptr; 15786 bool InCompoundScope = true; 15787 if (S != nullptr) { 15788 // Find previous declaration with the same name not referenced in other 15789 // declarations. 15790 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15791 InCompoundScope = 15792 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15793 LookupName(Lookup, S); 15794 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15795 /*AllowInlineNamespace=*/false); 15796 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15797 LookupResult::Filter Filter = Lookup.makeFilter(); 15798 while (Filter.hasNext()) { 15799 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15800 if (InCompoundScope) { 15801 auto I = UsedAsPrevious.find(PrevDecl); 15802 if (I == UsedAsPrevious.end()) 15803 UsedAsPrevious[PrevDecl] = false; 15804 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15805 UsedAsPrevious[D] = true; 15806 } 15807 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15808 PrevDecl->getLocation(); 15809 } 15810 Filter.done(); 15811 if (InCompoundScope) { 15812 for (const auto &PrevData : UsedAsPrevious) { 15813 if (!PrevData.second) { 15814 PrevDMD = PrevData.first; 15815 break; 15816 } 15817 } 15818 } 15819 } else if (PrevDeclInScope) { 15820 auto *PrevDMDInScope = PrevDMD = 15821 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15822 do { 15823 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15824 PrevDMDInScope->getLocation(); 15825 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15826 } while (PrevDMDInScope != nullptr); 15827 } 15828 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15829 bool Invalid = false; 15830 if (I != PreviousRedeclTypes.end()) { 15831 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15832 << MapperType << Name; 15833 Diag(I->second, diag::note_previous_definition); 15834 Invalid = true; 15835 } 15836 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15837 MapperType, VN, PrevDMD); 15838 DC->addDecl(DMD); 15839 DMD->setAccess(AS); 15840 if (Invalid) 15841 DMD->setInvalidDecl(); 15842 15843 // Enter new function scope. 15844 PushFunctionScope(); 15845 setFunctionHasBranchProtectedScope(); 15846 15847 CurContext = DMD; 15848 15849 return DMD; 15850 } 15851 15852 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15853 Scope *S, 15854 QualType MapperType, 15855 SourceLocation StartLoc, 15856 DeclarationName VN) { 15857 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15858 if (S) 15859 PushOnScopeChains(VD, S); 15860 else 15861 DMD->addDecl(VD); 15862 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15863 DMD->setMapperVarRef(MapperVarRefExpr); 15864 } 15865 15866 Sema::DeclGroupPtrTy 15867 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15868 ArrayRef<OMPClause *> ClauseList) { 15869 PopDeclContext(); 15870 PopFunctionScopeInfo(); 15871 15872 if (D) { 15873 if (S) 15874 PushOnScopeChains(D, S, /*AddToContext=*/false); 15875 D->CreateClauses(Context, ClauseList); 15876 } 15877 15878 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15879 } 15880 15881 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15882 SourceLocation StartLoc, 15883 SourceLocation LParenLoc, 15884 SourceLocation EndLoc) { 15885 Expr *ValExpr = NumTeams; 15886 Stmt *HelperValStmt = nullptr; 15887 15888 // OpenMP [teams Constrcut, Restrictions] 15889 // The num_teams expression must evaluate to a positive integer value. 15890 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15891 /*StrictlyPositive=*/true)) 15892 return nullptr; 15893 15894 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15895 OpenMPDirectiveKind CaptureRegion = 15896 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15897 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15898 ValExpr = MakeFullExpr(ValExpr).get(); 15899 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15900 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15901 HelperValStmt = buildPreInits(Context, Captures); 15902 } 15903 15904 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15905 StartLoc, LParenLoc, EndLoc); 15906 } 15907 15908 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15909 SourceLocation StartLoc, 15910 SourceLocation LParenLoc, 15911 SourceLocation EndLoc) { 15912 Expr *ValExpr = ThreadLimit; 15913 Stmt *HelperValStmt = nullptr; 15914 15915 // OpenMP [teams Constrcut, Restrictions] 15916 // The thread_limit expression must evaluate to a positive integer value. 15917 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15918 /*StrictlyPositive=*/true)) 15919 return nullptr; 15920 15921 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15922 OpenMPDirectiveKind CaptureRegion = 15923 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15924 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15925 ValExpr = MakeFullExpr(ValExpr).get(); 15926 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15927 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15928 HelperValStmt = buildPreInits(Context, Captures); 15929 } 15930 15931 return new (Context) OMPThreadLimitClause( 15932 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15933 } 15934 15935 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15936 SourceLocation StartLoc, 15937 SourceLocation LParenLoc, 15938 SourceLocation EndLoc) { 15939 Expr *ValExpr = Priority; 15940 15941 // OpenMP [2.9.1, task Constrcut] 15942 // The priority-value is a non-negative numerical scalar expression. 15943 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 15944 /*StrictlyPositive=*/false)) 15945 return nullptr; 15946 15947 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15948 } 15949 15950 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15951 SourceLocation StartLoc, 15952 SourceLocation LParenLoc, 15953 SourceLocation EndLoc) { 15954 Expr *ValExpr = Grainsize; 15955 Stmt *HelperValStmt = nullptr; 15956 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15957 15958 // OpenMP [2.9.2, taskloop Constrcut] 15959 // The parameter of the grainsize clause must be a positive integer 15960 // expression. 15961 if (!isNonNegativeIntegerValue( 15962 ValExpr, *this, OMPC_grainsize, 15963 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 15964 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 15965 return nullptr; 15966 15967 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 15968 StartLoc, LParenLoc, EndLoc); 15969 } 15970 15971 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15972 SourceLocation StartLoc, 15973 SourceLocation LParenLoc, 15974 SourceLocation EndLoc) { 15975 Expr *ValExpr = NumTasks; 15976 Stmt *HelperValStmt = nullptr; 15977 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15978 15979 // OpenMP [2.9.2, taskloop Constrcut] 15980 // The parameter of the num_tasks clause must be a positive integer 15981 // expression. 15982 if (!isNonNegativeIntegerValue( 15983 ValExpr, *this, OMPC_num_tasks, 15984 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 15985 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 15986 return nullptr; 15987 15988 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 15989 StartLoc, LParenLoc, EndLoc); 15990 } 15991 15992 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15993 SourceLocation LParenLoc, 15994 SourceLocation EndLoc) { 15995 // OpenMP [2.13.2, critical construct, Description] 15996 // ... where hint-expression is an integer constant expression that evaluates 15997 // to a valid lock hint. 15998 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15999 if (HintExpr.isInvalid()) 16000 return nullptr; 16001 return new (Context) 16002 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16003 } 16004 16005 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16006 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16007 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16008 SourceLocation EndLoc) { 16009 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16010 std::string Values; 16011 Values += "'"; 16012 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16013 Values += "'"; 16014 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16015 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16016 return nullptr; 16017 } 16018 Expr *ValExpr = ChunkSize; 16019 Stmt *HelperValStmt = nullptr; 16020 if (ChunkSize) { 16021 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16022 !ChunkSize->isInstantiationDependent() && 16023 !ChunkSize->containsUnexpandedParameterPack()) { 16024 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16025 ExprResult Val = 16026 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16027 if (Val.isInvalid()) 16028 return nullptr; 16029 16030 ValExpr = Val.get(); 16031 16032 // OpenMP [2.7.1, Restrictions] 16033 // chunk_size must be a loop invariant integer expression with a positive 16034 // value. 16035 llvm::APSInt Result; 16036 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16037 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16038 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16039 << "dist_schedule" << ChunkSize->getSourceRange(); 16040 return nullptr; 16041 } 16042 } else if (getOpenMPCaptureRegionForClause( 16043 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 16044 OMPD_unknown && 16045 !CurContext->isDependentContext()) { 16046 ValExpr = MakeFullExpr(ValExpr).get(); 16047 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16048 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16049 HelperValStmt = buildPreInits(Context, Captures); 16050 } 16051 } 16052 } 16053 16054 return new (Context) 16055 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16056 Kind, ValExpr, HelperValStmt); 16057 } 16058 16059 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16060 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16061 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16062 SourceLocation KindLoc, SourceLocation EndLoc) { 16063 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 16064 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 16065 std::string Value; 16066 SourceLocation Loc; 16067 Value += "'"; 16068 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16069 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16070 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16071 Loc = MLoc; 16072 } else { 16073 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16074 OMPC_DEFAULTMAP_scalar); 16075 Loc = KindLoc; 16076 } 16077 Value += "'"; 16078 Diag(Loc, diag::err_omp_unexpected_clause_value) 16079 << Value << getOpenMPClauseName(OMPC_defaultmap); 16080 return nullptr; 16081 } 16082 DSAStack->setDefaultDMAToFromScalar(StartLoc); 16083 16084 return new (Context) 16085 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16086 } 16087 16088 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16089 DeclContext *CurLexicalContext = getCurLexicalContext(); 16090 if (!CurLexicalContext->isFileContext() && 16091 !CurLexicalContext->isExternCContext() && 16092 !CurLexicalContext->isExternCXXContext() && 16093 !isa<CXXRecordDecl>(CurLexicalContext) && 16094 !isa<ClassTemplateDecl>(CurLexicalContext) && 16095 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16096 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16097 Diag(Loc, diag::err_omp_region_not_file_context); 16098 return false; 16099 } 16100 ++DeclareTargetNestingLevel; 16101 return true; 16102 } 16103 16104 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16105 assert(DeclareTargetNestingLevel > 0 && 16106 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16107 --DeclareTargetNestingLevel; 16108 } 16109 16110 NamedDecl * 16111 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16112 const DeclarationNameInfo &Id, 16113 NamedDeclSetType &SameDirectiveDecls) { 16114 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16115 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16116 16117 if (Lookup.isAmbiguous()) 16118 return nullptr; 16119 Lookup.suppressDiagnostics(); 16120 16121 if (!Lookup.isSingleResult()) { 16122 VarOrFuncDeclFilterCCC CCC(*this); 16123 if (TypoCorrection Corrected = 16124 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16125 CTK_ErrorRecovery)) { 16126 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16127 << Id.getName()); 16128 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16129 return nullptr; 16130 } 16131 16132 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16133 return nullptr; 16134 } 16135 16136 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16137 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16138 !isa<FunctionTemplateDecl>(ND)) { 16139 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16140 return nullptr; 16141 } 16142 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16143 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16144 return ND; 16145 } 16146 16147 void Sema::ActOnOpenMPDeclareTargetName( 16148 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16149 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16150 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16151 isa<FunctionTemplateDecl>(ND)) && 16152 "Expected variable, function or function template."); 16153 16154 // Diagnose marking after use as it may lead to incorrect diagnosis and 16155 // codegen. 16156 if (LangOpts.OpenMP >= 50 && 16157 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16158 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16159 16160 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16161 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16162 if (DevTy.hasValue() && *DevTy != DT) { 16163 Diag(Loc, diag::err_omp_device_type_mismatch) 16164 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16165 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16166 return; 16167 } 16168 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16169 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16170 if (!Res) { 16171 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16172 SourceRange(Loc, Loc)); 16173 ND->addAttr(A); 16174 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16175 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16176 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16177 } else if (*Res != MT) { 16178 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16179 } 16180 } 16181 16182 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16183 Sema &SemaRef, Decl *D) { 16184 if (!D || !isa<VarDecl>(D)) 16185 return; 16186 auto *VD = cast<VarDecl>(D); 16187 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16188 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16189 if (SemaRef.LangOpts.OpenMP >= 50 && 16190 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16191 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16192 VD->hasGlobalStorage()) { 16193 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16194 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16195 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16196 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16197 // If a lambda declaration and definition appears between a 16198 // declare target directive and the matching end declare target 16199 // directive, all variables that are captured by the lambda 16200 // expression must also appear in a to clause. 16201 SemaRef.Diag(VD->getLocation(), 16202 diag::err_omp_lambda_capture_in_declare_target_not_to); 16203 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16204 << VD << 0 << SR; 16205 return; 16206 } 16207 } 16208 if (MapTy.hasValue()) 16209 return; 16210 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16211 SemaRef.Diag(SL, diag::note_used_here) << SR; 16212 } 16213 16214 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16215 Sema &SemaRef, DSAStackTy *Stack, 16216 ValueDecl *VD) { 16217 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16218 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16219 /*FullCheck=*/false); 16220 } 16221 16222 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16223 SourceLocation IdLoc) { 16224 if (!D || D->isInvalidDecl()) 16225 return; 16226 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16227 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16228 if (auto *VD = dyn_cast<VarDecl>(D)) { 16229 // Only global variables can be marked as declare target. 16230 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16231 !VD->isStaticDataMember()) 16232 return; 16233 // 2.10.6: threadprivate variable cannot appear in a declare target 16234 // directive. 16235 if (DSAStack->isThreadPrivate(VD)) { 16236 Diag(SL, diag::err_omp_threadprivate_in_target); 16237 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16238 return; 16239 } 16240 } 16241 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16242 D = FTD->getTemplatedDecl(); 16243 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16244 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16245 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16246 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16247 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16248 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16249 return; 16250 } 16251 // Mark the function as must be emitted for the device. 16252 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16253 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16254 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16255 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16256 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16257 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16258 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16259 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16260 } 16261 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16262 // Problem if any with var declared with incomplete type will be reported 16263 // as normal, so no need to check it here. 16264 if ((E || !VD->getType()->isIncompleteType()) && 16265 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16266 return; 16267 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16268 // Checking declaration inside declare target region. 16269 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16270 isa<FunctionTemplateDecl>(D)) { 16271 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16272 Context, OMPDeclareTargetDeclAttr::MT_To, 16273 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16274 D->addAttr(A); 16275 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16276 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16277 } 16278 return; 16279 } 16280 } 16281 if (!E) 16282 return; 16283 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16284 } 16285 16286 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16287 CXXScopeSpec &MapperIdScopeSpec, 16288 DeclarationNameInfo &MapperId, 16289 const OMPVarListLocTy &Locs, 16290 ArrayRef<Expr *> UnresolvedMappers) { 16291 MappableVarListInfo MVLI(VarList); 16292 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16293 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16294 if (MVLI.ProcessedVarList.empty()) 16295 return nullptr; 16296 16297 return OMPToClause::Create( 16298 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16299 MVLI.VarComponents, MVLI.UDMapperList, 16300 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16301 } 16302 16303 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16304 CXXScopeSpec &MapperIdScopeSpec, 16305 DeclarationNameInfo &MapperId, 16306 const OMPVarListLocTy &Locs, 16307 ArrayRef<Expr *> UnresolvedMappers) { 16308 MappableVarListInfo MVLI(VarList); 16309 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16310 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16311 if (MVLI.ProcessedVarList.empty()) 16312 return nullptr; 16313 16314 return OMPFromClause::Create( 16315 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16316 MVLI.VarComponents, MVLI.UDMapperList, 16317 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16318 } 16319 16320 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16321 const OMPVarListLocTy &Locs) { 16322 MappableVarListInfo MVLI(VarList); 16323 SmallVector<Expr *, 8> PrivateCopies; 16324 SmallVector<Expr *, 8> Inits; 16325 16326 for (Expr *RefExpr : VarList) { 16327 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16328 SourceLocation ELoc; 16329 SourceRange ERange; 16330 Expr *SimpleRefExpr = RefExpr; 16331 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16332 if (Res.second) { 16333 // It will be analyzed later. 16334 MVLI.ProcessedVarList.push_back(RefExpr); 16335 PrivateCopies.push_back(nullptr); 16336 Inits.push_back(nullptr); 16337 } 16338 ValueDecl *D = Res.first; 16339 if (!D) 16340 continue; 16341 16342 QualType Type = D->getType(); 16343 Type = Type.getNonReferenceType().getUnqualifiedType(); 16344 16345 auto *VD = dyn_cast<VarDecl>(D); 16346 16347 // Item should be a pointer or reference to pointer. 16348 if (!Type->isPointerType()) { 16349 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16350 << 0 << RefExpr->getSourceRange(); 16351 continue; 16352 } 16353 16354 // Build the private variable and the expression that refers to it. 16355 auto VDPrivate = 16356 buildVarDecl(*this, ELoc, Type, D->getName(), 16357 D->hasAttrs() ? &D->getAttrs() : nullptr, 16358 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16359 if (VDPrivate->isInvalidDecl()) 16360 continue; 16361 16362 CurContext->addDecl(VDPrivate); 16363 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16364 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16365 16366 // Add temporary variable to initialize the private copy of the pointer. 16367 VarDecl *VDInit = 16368 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16369 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16370 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16371 AddInitializerToDecl(VDPrivate, 16372 DefaultLvalueConversion(VDInitRefExpr).get(), 16373 /*DirectInit=*/false); 16374 16375 // If required, build a capture to implement the privatization initialized 16376 // with the current list item value. 16377 DeclRefExpr *Ref = nullptr; 16378 if (!VD) 16379 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16380 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16381 PrivateCopies.push_back(VDPrivateRefExpr); 16382 Inits.push_back(VDInitRefExpr); 16383 16384 // We need to add a data sharing attribute for this variable to make sure it 16385 // is correctly captured. A variable that shows up in a use_device_ptr has 16386 // similar properties of a first private variable. 16387 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16388 16389 // Create a mappable component for the list item. List items in this clause 16390 // only need a component. 16391 MVLI.VarBaseDeclarations.push_back(D); 16392 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16393 MVLI.VarComponents.back().push_back( 16394 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16395 } 16396 16397 if (MVLI.ProcessedVarList.empty()) 16398 return nullptr; 16399 16400 return OMPUseDevicePtrClause::Create( 16401 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16402 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16403 } 16404 16405 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16406 const OMPVarListLocTy &Locs) { 16407 MappableVarListInfo MVLI(VarList); 16408 for (Expr *RefExpr : VarList) { 16409 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16410 SourceLocation ELoc; 16411 SourceRange ERange; 16412 Expr *SimpleRefExpr = RefExpr; 16413 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16414 if (Res.second) { 16415 // It will be analyzed later. 16416 MVLI.ProcessedVarList.push_back(RefExpr); 16417 } 16418 ValueDecl *D = Res.first; 16419 if (!D) 16420 continue; 16421 16422 QualType Type = D->getType(); 16423 // item should be a pointer or array or reference to pointer or array 16424 if (!Type.getNonReferenceType()->isPointerType() && 16425 !Type.getNonReferenceType()->isArrayType()) { 16426 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16427 << 0 << RefExpr->getSourceRange(); 16428 continue; 16429 } 16430 16431 // Check if the declaration in the clause does not show up in any data 16432 // sharing attribute. 16433 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16434 if (isOpenMPPrivate(DVar.CKind)) { 16435 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16436 << getOpenMPClauseName(DVar.CKind) 16437 << getOpenMPClauseName(OMPC_is_device_ptr) 16438 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16439 reportOriginalDsa(*this, DSAStack, D, DVar); 16440 continue; 16441 } 16442 16443 const Expr *ConflictExpr; 16444 if (DSAStack->checkMappableExprComponentListsForDecl( 16445 D, /*CurrentRegionOnly=*/true, 16446 [&ConflictExpr]( 16447 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16448 OpenMPClauseKind) -> bool { 16449 ConflictExpr = R.front().getAssociatedExpression(); 16450 return true; 16451 })) { 16452 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16453 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16454 << ConflictExpr->getSourceRange(); 16455 continue; 16456 } 16457 16458 // Store the components in the stack so that they can be used to check 16459 // against other clauses later on. 16460 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16461 DSAStack->addMappableExpressionComponents( 16462 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16463 16464 // Record the expression we've just processed. 16465 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16466 16467 // Create a mappable component for the list item. List items in this clause 16468 // only need a component. We use a null declaration to signal fields in 16469 // 'this'. 16470 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16471 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16472 "Unexpected device pointer expression!"); 16473 MVLI.VarBaseDeclarations.push_back( 16474 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16475 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16476 MVLI.VarComponents.back().push_back(MC); 16477 } 16478 16479 if (MVLI.ProcessedVarList.empty()) 16480 return nullptr; 16481 16482 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16483 MVLI.VarBaseDeclarations, 16484 MVLI.VarComponents); 16485 } 16486 16487 OMPClause *Sema::ActOnOpenMPAllocateClause( 16488 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16489 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16490 if (Allocator) { 16491 // OpenMP [2.11.4 allocate Clause, Description] 16492 // allocator is an expression of omp_allocator_handle_t type. 16493 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16494 return nullptr; 16495 16496 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16497 if (AllocatorRes.isInvalid()) 16498 return nullptr; 16499 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16500 DSAStack->getOMPAllocatorHandleT(), 16501 Sema::AA_Initializing, 16502 /*AllowExplicit=*/true); 16503 if (AllocatorRes.isInvalid()) 16504 return nullptr; 16505 Allocator = AllocatorRes.get(); 16506 } else { 16507 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16508 // allocate clauses that appear on a target construct or on constructs in a 16509 // target region must specify an allocator expression unless a requires 16510 // directive with the dynamic_allocators clause is present in the same 16511 // compilation unit. 16512 if (LangOpts.OpenMPIsDevice && 16513 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16514 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16515 } 16516 // Analyze and build list of variables. 16517 SmallVector<Expr *, 8> Vars; 16518 for (Expr *RefExpr : VarList) { 16519 assert(RefExpr && "NULL expr in OpenMP private clause."); 16520 SourceLocation ELoc; 16521 SourceRange ERange; 16522 Expr *SimpleRefExpr = RefExpr; 16523 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16524 if (Res.second) { 16525 // It will be analyzed later. 16526 Vars.push_back(RefExpr); 16527 } 16528 ValueDecl *D = Res.first; 16529 if (!D) 16530 continue; 16531 16532 auto *VD = dyn_cast<VarDecl>(D); 16533 DeclRefExpr *Ref = nullptr; 16534 if (!VD && !CurContext->isDependentContext()) 16535 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16536 Vars.push_back((VD || CurContext->isDependentContext()) 16537 ? RefExpr->IgnoreParens() 16538 : Ref); 16539 } 16540 16541 if (Vars.empty()) 16542 return nullptr; 16543 16544 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16545 ColonLoc, EndLoc, Vars); 16546 } 16547