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 case OMPC_num_tasks: 4595 case OMPC_final: 4596 case OMPC_priority: 4597 // Do not analyze if no parent parallel directive. 4598 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective())) 4599 break; 4600 continue; 4601 case OMPC_ordered: 4602 case OMPC_device: 4603 case OMPC_num_teams: 4604 case OMPC_thread_limit: 4605 case OMPC_hint: 4606 case OMPC_collapse: 4607 case OMPC_safelen: 4608 case OMPC_simdlen: 4609 case OMPC_default: 4610 case OMPC_proc_bind: 4611 case OMPC_private: 4612 case OMPC_firstprivate: 4613 case OMPC_lastprivate: 4614 case OMPC_shared: 4615 case OMPC_reduction: 4616 case OMPC_task_reduction: 4617 case OMPC_in_reduction: 4618 case OMPC_linear: 4619 case OMPC_aligned: 4620 case OMPC_copyin: 4621 case OMPC_copyprivate: 4622 case OMPC_nowait: 4623 case OMPC_untied: 4624 case OMPC_mergeable: 4625 case OMPC_allocate: 4626 case OMPC_read: 4627 case OMPC_write: 4628 case OMPC_update: 4629 case OMPC_capture: 4630 case OMPC_seq_cst: 4631 case OMPC_depend: 4632 case OMPC_threads: 4633 case OMPC_simd: 4634 case OMPC_map: 4635 case OMPC_nogroup: 4636 case OMPC_defaultmap: 4637 case OMPC_to: 4638 case OMPC_from: 4639 case OMPC_use_device_ptr: 4640 case OMPC_is_device_ptr: 4641 continue; 4642 case OMPC_allocator: 4643 case OMPC_flush: 4644 case OMPC_threadprivate: 4645 case OMPC_uniform: 4646 case OMPC_unknown: 4647 case OMPC_unified_address: 4648 case OMPC_unified_shared_memory: 4649 case OMPC_reverse_offload: 4650 case OMPC_dynamic_allocators: 4651 case OMPC_atomic_default_mem_order: 4652 case OMPC_device_type: 4653 case OMPC_match: 4654 llvm_unreachable("Unexpected clause"); 4655 } 4656 for (Stmt *CC : C->children()) { 4657 if (CC) 4658 DSAChecker.Visit(CC); 4659 } 4660 } 4661 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4662 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4663 } 4664 for (const auto &P : VarsWithInheritedDSA) { 4665 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4666 continue; 4667 ErrorFound = true; 4668 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4669 << P.first << P.second->getSourceRange(); 4670 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4671 } 4672 4673 if (!AllowedNameModifiers.empty()) 4674 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4675 ErrorFound; 4676 4677 if (ErrorFound) 4678 return StmtError(); 4679 4680 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4681 Res.getAs<OMPExecutableDirective>() 4682 ->getStructuredBlock() 4683 ->setIsOMPStructuredBlock(true); 4684 } 4685 4686 if (!CurContext->isDependentContext() && 4687 isOpenMPTargetExecutionDirective(Kind) && 4688 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4689 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4690 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4691 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4692 // Register target to DSA Stack. 4693 DSAStack->addTargetDirLocation(StartLoc); 4694 } 4695 4696 return Res; 4697 } 4698 4699 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4700 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4701 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4702 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4703 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4704 assert(Aligneds.size() == Alignments.size()); 4705 assert(Linears.size() == LinModifiers.size()); 4706 assert(Linears.size() == Steps.size()); 4707 if (!DG || DG.get().isNull()) 4708 return DeclGroupPtrTy(); 4709 4710 const int SimdId = 0; 4711 if (!DG.get().isSingleDecl()) { 4712 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4713 << SimdId; 4714 return DG; 4715 } 4716 Decl *ADecl = DG.get().getSingleDecl(); 4717 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4718 ADecl = FTD->getTemplatedDecl(); 4719 4720 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4721 if (!FD) { 4722 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4723 return DeclGroupPtrTy(); 4724 } 4725 4726 // OpenMP [2.8.2, declare simd construct, Description] 4727 // The parameter of the simdlen clause must be a constant positive integer 4728 // expression. 4729 ExprResult SL; 4730 if (Simdlen) 4731 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4732 // OpenMP [2.8.2, declare simd construct, Description] 4733 // The special this pointer can be used as if was one of the arguments to the 4734 // function in any of the linear, aligned, or uniform clauses. 4735 // The uniform clause declares one or more arguments to have an invariant 4736 // value for all concurrent invocations of the function in the execution of a 4737 // single SIMD loop. 4738 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4739 const Expr *UniformedLinearThis = nullptr; 4740 for (const Expr *E : Uniforms) { 4741 E = E->IgnoreParenImpCasts(); 4742 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4743 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4744 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4745 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4746 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4747 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4748 continue; 4749 } 4750 if (isa<CXXThisExpr>(E)) { 4751 UniformedLinearThis = E; 4752 continue; 4753 } 4754 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4755 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4756 } 4757 // OpenMP [2.8.2, declare simd construct, Description] 4758 // The aligned clause declares that the object to which each list item points 4759 // is aligned to the number of bytes expressed in the optional parameter of 4760 // the aligned clause. 4761 // The special this pointer can be used as if was one of the arguments to the 4762 // function in any of the linear, aligned, or uniform clauses. 4763 // The type of list items appearing in the aligned clause must be array, 4764 // pointer, reference to array, or reference to pointer. 4765 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4766 const Expr *AlignedThis = nullptr; 4767 for (const Expr *E : Aligneds) { 4768 E = E->IgnoreParenImpCasts(); 4769 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4770 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4771 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4772 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4773 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4774 ->getCanonicalDecl() == CanonPVD) { 4775 // OpenMP [2.8.1, simd construct, Restrictions] 4776 // A list-item cannot appear in more than one aligned clause. 4777 if (AlignedArgs.count(CanonPVD) > 0) { 4778 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4779 << 1 << E->getSourceRange(); 4780 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4781 diag::note_omp_explicit_dsa) 4782 << getOpenMPClauseName(OMPC_aligned); 4783 continue; 4784 } 4785 AlignedArgs[CanonPVD] = E; 4786 QualType QTy = PVD->getType() 4787 .getNonReferenceType() 4788 .getUnqualifiedType() 4789 .getCanonicalType(); 4790 const Type *Ty = QTy.getTypePtrOrNull(); 4791 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4792 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4793 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4794 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4795 } 4796 continue; 4797 } 4798 } 4799 if (isa<CXXThisExpr>(E)) { 4800 if (AlignedThis) { 4801 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4802 << 2 << E->getSourceRange(); 4803 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4804 << getOpenMPClauseName(OMPC_aligned); 4805 } 4806 AlignedThis = E; 4807 continue; 4808 } 4809 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4810 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4811 } 4812 // The optional parameter of the aligned clause, alignment, must be a constant 4813 // positive integer expression. If no optional parameter is specified, 4814 // implementation-defined default alignments for SIMD instructions on the 4815 // target platforms are assumed. 4816 SmallVector<const Expr *, 4> NewAligns; 4817 for (Expr *E : Alignments) { 4818 ExprResult Align; 4819 if (E) 4820 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4821 NewAligns.push_back(Align.get()); 4822 } 4823 // OpenMP [2.8.2, declare simd construct, Description] 4824 // The linear clause declares one or more list items to be private to a SIMD 4825 // lane and to have a linear relationship with respect to the iteration space 4826 // of a loop. 4827 // The special this pointer can be used as if was one of the arguments to the 4828 // function in any of the linear, aligned, or uniform clauses. 4829 // When a linear-step expression is specified in a linear clause it must be 4830 // either a constant integer expression or an integer-typed parameter that is 4831 // specified in a uniform clause on the directive. 4832 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4833 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4834 auto MI = LinModifiers.begin(); 4835 for (const Expr *E : Linears) { 4836 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4837 ++MI; 4838 E = E->IgnoreParenImpCasts(); 4839 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4840 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4841 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4842 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4843 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4844 ->getCanonicalDecl() == CanonPVD) { 4845 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4846 // A list-item cannot appear in more than one linear clause. 4847 if (LinearArgs.count(CanonPVD) > 0) { 4848 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4849 << getOpenMPClauseName(OMPC_linear) 4850 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4851 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4852 diag::note_omp_explicit_dsa) 4853 << getOpenMPClauseName(OMPC_linear); 4854 continue; 4855 } 4856 // Each argument can appear in at most one uniform or linear clause. 4857 if (UniformedArgs.count(CanonPVD) > 0) { 4858 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4859 << getOpenMPClauseName(OMPC_linear) 4860 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4861 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4862 diag::note_omp_explicit_dsa) 4863 << getOpenMPClauseName(OMPC_uniform); 4864 continue; 4865 } 4866 LinearArgs[CanonPVD] = E; 4867 if (E->isValueDependent() || E->isTypeDependent() || 4868 E->isInstantiationDependent() || 4869 E->containsUnexpandedParameterPack()) 4870 continue; 4871 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4872 PVD->getOriginalType()); 4873 continue; 4874 } 4875 } 4876 if (isa<CXXThisExpr>(E)) { 4877 if (UniformedLinearThis) { 4878 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4879 << getOpenMPClauseName(OMPC_linear) 4880 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4881 << E->getSourceRange(); 4882 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4883 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4884 : OMPC_linear); 4885 continue; 4886 } 4887 UniformedLinearThis = E; 4888 if (E->isValueDependent() || E->isTypeDependent() || 4889 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4890 continue; 4891 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4892 E->getType()); 4893 continue; 4894 } 4895 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4896 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4897 } 4898 Expr *Step = nullptr; 4899 Expr *NewStep = nullptr; 4900 SmallVector<Expr *, 4> NewSteps; 4901 for (Expr *E : Steps) { 4902 // Skip the same step expression, it was checked already. 4903 if (Step == E || !E) { 4904 NewSteps.push_back(E ? NewStep : nullptr); 4905 continue; 4906 } 4907 Step = E; 4908 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4909 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4910 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4911 if (UniformedArgs.count(CanonPVD) == 0) { 4912 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4913 << Step->getSourceRange(); 4914 } else if (E->isValueDependent() || E->isTypeDependent() || 4915 E->isInstantiationDependent() || 4916 E->containsUnexpandedParameterPack() || 4917 CanonPVD->getType()->hasIntegerRepresentation()) { 4918 NewSteps.push_back(Step); 4919 } else { 4920 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4921 << Step->getSourceRange(); 4922 } 4923 continue; 4924 } 4925 NewStep = Step; 4926 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4927 !Step->isInstantiationDependent() && 4928 !Step->containsUnexpandedParameterPack()) { 4929 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4930 .get(); 4931 if (NewStep) 4932 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4933 } 4934 NewSteps.push_back(NewStep); 4935 } 4936 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4937 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4938 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4939 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4940 const_cast<Expr **>(Linears.data()), Linears.size(), 4941 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4942 NewSteps.data(), NewSteps.size(), SR); 4943 ADecl->addAttr(NewAttr); 4944 return DG; 4945 } 4946 4947 Optional<std::pair<FunctionDecl *, Expr *>> 4948 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 4949 Expr *VariantRef, SourceRange SR) { 4950 if (!DG || DG.get().isNull()) 4951 return None; 4952 4953 const int VariantId = 1; 4954 // Must be applied only to single decl. 4955 if (!DG.get().isSingleDecl()) { 4956 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4957 << VariantId << SR; 4958 return None; 4959 } 4960 Decl *ADecl = DG.get().getSingleDecl(); 4961 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4962 ADecl = FTD->getTemplatedDecl(); 4963 4964 // Decl must be a function. 4965 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4966 if (!FD) { 4967 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 4968 << VariantId << SR; 4969 return None; 4970 } 4971 4972 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 4973 return FD->hasAttrs() && 4974 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 4975 FD->hasAttr<TargetAttr>()); 4976 }; 4977 // OpenMP is not compatible with CPU-specific attributes. 4978 if (HasMultiVersionAttributes(FD)) { 4979 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 4980 << SR; 4981 return None; 4982 } 4983 4984 // Allow #pragma omp declare variant only if the function is not used. 4985 if (FD->isUsed(false)) 4986 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 4987 << FD->getLocation(); 4988 4989 // Check if the function was emitted already. 4990 const FunctionDecl *Definition; 4991 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 4992 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 4993 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 4994 << FD->getLocation(); 4995 4996 // The VariantRef must point to function. 4997 if (!VariantRef) { 4998 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 4999 return None; 5000 } 5001 5002 // Do not check templates, wait until instantiation. 5003 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5004 VariantRef->containsUnexpandedParameterPack() || 5005 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5006 return std::make_pair(FD, VariantRef); 5007 5008 // Convert VariantRef expression to the type of the original function to 5009 // resolve possible conflicts. 5010 ExprResult VariantRefCast; 5011 if (LangOpts.CPlusPlus) { 5012 QualType FnPtrType; 5013 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5014 if (Method && !Method->isStatic()) { 5015 const Type *ClassType = 5016 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5017 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5018 ExprResult ER; 5019 { 5020 // Build adrr_of unary op to correctly handle type checks for member 5021 // functions. 5022 Sema::TentativeAnalysisScope Trap(*this); 5023 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5024 VariantRef); 5025 } 5026 if (!ER.isUsable()) { 5027 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5028 << VariantId << VariantRef->getSourceRange(); 5029 return None; 5030 } 5031 VariantRef = ER.get(); 5032 } else { 5033 FnPtrType = Context.getPointerType(FD->getType()); 5034 } 5035 ImplicitConversionSequence ICS = 5036 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5037 /*SuppressUserConversions=*/false, 5038 /*AllowExplicit=*/false, 5039 /*InOverloadResolution=*/false, 5040 /*CStyle=*/false, 5041 /*AllowObjCWritebackConversion=*/false); 5042 if (ICS.isFailure()) { 5043 Diag(VariantRef->getExprLoc(), 5044 diag::err_omp_declare_variant_incompat_types) 5045 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 5046 return None; 5047 } 5048 VariantRefCast = PerformImplicitConversion( 5049 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5050 if (!VariantRefCast.isUsable()) 5051 return None; 5052 // Drop previously built artificial addr_of unary op for member functions. 5053 if (Method && !Method->isStatic()) { 5054 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5055 if (auto *UO = dyn_cast<UnaryOperator>( 5056 PossibleAddrOfVariantRef->IgnoreImplicit())) 5057 VariantRefCast = UO->getSubExpr(); 5058 } 5059 } else { 5060 VariantRefCast = VariantRef; 5061 } 5062 5063 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5064 if (!ER.isUsable() || 5065 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5066 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5067 << VariantId << VariantRef->getSourceRange(); 5068 return None; 5069 } 5070 5071 // The VariantRef must point to function. 5072 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5073 if (!DRE) { 5074 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5075 << VariantId << VariantRef->getSourceRange(); 5076 return None; 5077 } 5078 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5079 if (!NewFD) { 5080 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5081 << VariantId << VariantRef->getSourceRange(); 5082 return None; 5083 } 5084 5085 // Check if variant function is not marked with declare variant directive. 5086 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5087 Diag(VariantRef->getExprLoc(), 5088 diag::warn_omp_declare_variant_marked_as_declare_variant) 5089 << VariantRef->getSourceRange(); 5090 SourceRange SR = 5091 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5092 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5093 return None; 5094 } 5095 5096 enum DoesntSupport { 5097 VirtFuncs = 1, 5098 Constructors = 3, 5099 Destructors = 4, 5100 DeletedFuncs = 5, 5101 DefaultedFuncs = 6, 5102 ConstexprFuncs = 7, 5103 ConstevalFuncs = 8, 5104 }; 5105 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5106 if (CXXFD->isVirtual()) { 5107 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5108 << VirtFuncs; 5109 return None; 5110 } 5111 5112 if (isa<CXXConstructorDecl>(FD)) { 5113 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5114 << Constructors; 5115 return None; 5116 } 5117 5118 if (isa<CXXDestructorDecl>(FD)) { 5119 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5120 << Destructors; 5121 return None; 5122 } 5123 } 5124 5125 if (FD->isDeleted()) { 5126 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5127 << DeletedFuncs; 5128 return None; 5129 } 5130 5131 if (FD->isDefaulted()) { 5132 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5133 << DefaultedFuncs; 5134 return None; 5135 } 5136 5137 if (FD->isConstexpr()) { 5138 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5139 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5140 return None; 5141 } 5142 5143 // Check general compatibility. 5144 if (areMultiversionVariantFunctionsCompatible( 5145 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5146 PartialDiagnosticAt( 5147 SR.getBegin(), 5148 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5149 PartialDiagnosticAt( 5150 VariantRef->getExprLoc(), 5151 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5152 PartialDiagnosticAt(VariantRef->getExprLoc(), 5153 PDiag(diag::err_omp_declare_variant_diff) 5154 << FD->getLocation()), 5155 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5156 /*CLinkageMayDiffer=*/true)) 5157 return None; 5158 return std::make_pair(FD, cast<Expr>(DRE)); 5159 } 5160 5161 void Sema::ActOnOpenMPDeclareVariantDirective( 5162 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5163 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { 5164 if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || 5165 Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) 5166 return; 5167 Expr *Score = nullptr; 5168 OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown; 5169 if (Data.CtxScore.isUsable()) { 5170 ST = OMPDeclareVariantAttr::ScoreSpecified; 5171 Score = Data.CtxScore.get(); 5172 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5173 !Score->isInstantiationDependent() && 5174 !Score->containsUnexpandedParameterPack()) { 5175 llvm::APSInt Result; 5176 ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result); 5177 if (ICE.isInvalid()) 5178 return; 5179 } 5180 } 5181 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5182 Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, 5183 Data.ImplVendors.begin(), Data.ImplVendors.size(), SR); 5184 FD->addAttr(NewAttr); 5185 } 5186 5187 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5188 FunctionDecl *Func, 5189 bool MightBeOdrUse) { 5190 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5191 5192 if (!Func->isDependentContext() && Func->hasAttrs()) { 5193 for (OMPDeclareVariantAttr *A : 5194 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5195 // TODO: add checks for active OpenMP context where possible. 5196 Expr *VariantRef = A->getVariantFuncRef(); 5197 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5198 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5199 if (!F->isDefined() && F->isTemplateInstantiation()) 5200 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5201 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5202 } 5203 } 5204 } 5205 5206 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5207 Stmt *AStmt, 5208 SourceLocation StartLoc, 5209 SourceLocation EndLoc) { 5210 if (!AStmt) 5211 return StmtError(); 5212 5213 auto *CS = cast<CapturedStmt>(AStmt); 5214 // 1.2.2 OpenMP Language Terminology 5215 // Structured block - An executable statement with a single entry at the 5216 // top and a single exit at the bottom. 5217 // The point of exit cannot be a branch out of the structured block. 5218 // longjmp() and throw() must not violate the entry/exit criteria. 5219 CS->getCapturedDecl()->setNothrow(); 5220 5221 setFunctionHasBranchProtectedScope(); 5222 5223 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5224 DSAStack->isCancelRegion()); 5225 } 5226 5227 namespace { 5228 /// Iteration space of a single for loop. 5229 struct LoopIterationSpace final { 5230 /// True if the condition operator is the strict compare operator (<, > or 5231 /// !=). 5232 bool IsStrictCompare = false; 5233 /// Condition of the loop. 5234 Expr *PreCond = nullptr; 5235 /// This expression calculates the number of iterations in the loop. 5236 /// It is always possible to calculate it before starting the loop. 5237 Expr *NumIterations = nullptr; 5238 /// The loop counter variable. 5239 Expr *CounterVar = nullptr; 5240 /// Private loop counter variable. 5241 Expr *PrivateCounterVar = nullptr; 5242 /// This is initializer for the initial value of #CounterVar. 5243 Expr *CounterInit = nullptr; 5244 /// This is step for the #CounterVar used to generate its update: 5245 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5246 Expr *CounterStep = nullptr; 5247 /// Should step be subtracted? 5248 bool Subtract = false; 5249 /// Source range of the loop init. 5250 SourceRange InitSrcRange; 5251 /// Source range of the loop condition. 5252 SourceRange CondSrcRange; 5253 /// Source range of the loop increment. 5254 SourceRange IncSrcRange; 5255 /// Minimum value that can have the loop control variable. Used to support 5256 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5257 /// since only such variables can be used in non-loop invariant expressions. 5258 Expr *MinValue = nullptr; 5259 /// Maximum value that can have the loop control variable. Used to support 5260 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5261 /// since only such variables can be used in non-loop invariant expressions. 5262 Expr *MaxValue = nullptr; 5263 /// true, if the lower bound depends on the outer loop control var. 5264 bool IsNonRectangularLB = false; 5265 /// true, if the upper bound depends on the outer loop control var. 5266 bool IsNonRectangularUB = false; 5267 /// Index of the loop this loop depends on and forms non-rectangular loop 5268 /// nest. 5269 unsigned LoopDependentIdx = 0; 5270 /// Final condition for the non-rectangular loop nest support. It is used to 5271 /// check that the number of iterations for this particular counter must be 5272 /// finished. 5273 Expr *FinalCondition = nullptr; 5274 }; 5275 5276 /// Helper class for checking canonical form of the OpenMP loops and 5277 /// extracting iteration space of each loop in the loop nest, that will be used 5278 /// for IR generation. 5279 class OpenMPIterationSpaceChecker { 5280 /// Reference to Sema. 5281 Sema &SemaRef; 5282 /// Data-sharing stack. 5283 DSAStackTy &Stack; 5284 /// A location for diagnostics (when there is no some better location). 5285 SourceLocation DefaultLoc; 5286 /// A location for diagnostics (when increment is not compatible). 5287 SourceLocation ConditionLoc; 5288 /// A source location for referring to loop init later. 5289 SourceRange InitSrcRange; 5290 /// A source location for referring to condition later. 5291 SourceRange ConditionSrcRange; 5292 /// A source location for referring to increment later. 5293 SourceRange IncrementSrcRange; 5294 /// Loop variable. 5295 ValueDecl *LCDecl = nullptr; 5296 /// Reference to loop variable. 5297 Expr *LCRef = nullptr; 5298 /// Lower bound (initializer for the var). 5299 Expr *LB = nullptr; 5300 /// Upper bound. 5301 Expr *UB = nullptr; 5302 /// Loop step (increment). 5303 Expr *Step = nullptr; 5304 /// This flag is true when condition is one of: 5305 /// Var < UB 5306 /// Var <= UB 5307 /// UB > Var 5308 /// UB >= Var 5309 /// This will have no value when the condition is != 5310 llvm::Optional<bool> TestIsLessOp; 5311 /// This flag is true when condition is strict ( < or > ). 5312 bool TestIsStrictOp = false; 5313 /// This flag is true when step is subtracted on each iteration. 5314 bool SubtractStep = false; 5315 /// The outer loop counter this loop depends on (if any). 5316 const ValueDecl *DepDecl = nullptr; 5317 /// Contains number of loop (starts from 1) on which loop counter init 5318 /// expression of this loop depends on. 5319 Optional<unsigned> InitDependOnLC; 5320 /// Contains number of loop (starts from 1) on which loop counter condition 5321 /// expression of this loop depends on. 5322 Optional<unsigned> CondDependOnLC; 5323 /// Checks if the provide statement depends on the loop counter. 5324 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5325 /// Original condition required for checking of the exit condition for 5326 /// non-rectangular loop. 5327 Expr *Condition = nullptr; 5328 5329 public: 5330 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5331 SourceLocation DefaultLoc) 5332 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5333 ConditionLoc(DefaultLoc) {} 5334 /// Check init-expr for canonical loop form and save loop counter 5335 /// variable - #Var and its initialization value - #LB. 5336 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5337 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5338 /// for less/greater and for strict/non-strict comparison. 5339 bool checkAndSetCond(Expr *S); 5340 /// Check incr-expr for canonical loop form and return true if it 5341 /// does not conform, otherwise save loop step (#Step). 5342 bool checkAndSetInc(Expr *S); 5343 /// Return the loop counter variable. 5344 ValueDecl *getLoopDecl() const { return LCDecl; } 5345 /// Return the reference expression to loop counter variable. 5346 Expr *getLoopDeclRefExpr() const { return LCRef; } 5347 /// Source range of the loop init. 5348 SourceRange getInitSrcRange() const { return InitSrcRange; } 5349 /// Source range of the loop condition. 5350 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5351 /// Source range of the loop increment. 5352 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5353 /// True if the step should be subtracted. 5354 bool shouldSubtractStep() const { return SubtractStep; } 5355 /// True, if the compare operator is strict (<, > or !=). 5356 bool isStrictTestOp() const { return TestIsStrictOp; } 5357 /// Build the expression to calculate the number of iterations. 5358 Expr *buildNumIterations( 5359 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5360 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5361 /// Build the precondition expression for the loops. 5362 Expr * 5363 buildPreCond(Scope *S, Expr *Cond, 5364 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5365 /// Build reference expression to the counter be used for codegen. 5366 DeclRefExpr * 5367 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5368 DSAStackTy &DSA) const; 5369 /// Build reference expression to the private counter be used for 5370 /// codegen. 5371 Expr *buildPrivateCounterVar() const; 5372 /// Build initialization of the counter be used for codegen. 5373 Expr *buildCounterInit() const; 5374 /// Build step of the counter be used for codegen. 5375 Expr *buildCounterStep() const; 5376 /// Build loop data with counter value for depend clauses in ordered 5377 /// directives. 5378 Expr * 5379 buildOrderedLoopData(Scope *S, Expr *Counter, 5380 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5381 SourceLocation Loc, Expr *Inc = nullptr, 5382 OverloadedOperatorKind OOK = OO_Amp); 5383 /// Builds the minimum value for the loop counter. 5384 std::pair<Expr *, Expr *> buildMinMaxValues( 5385 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5386 /// Builds final condition for the non-rectangular loops. 5387 Expr *buildFinalCondition(Scope *S) const; 5388 /// Return true if any expression is dependent. 5389 bool dependent() const; 5390 /// Returns true if the initializer forms non-rectangular loop. 5391 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5392 /// Returns true if the condition forms non-rectangular loop. 5393 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5394 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5395 unsigned getLoopDependentIdx() const { 5396 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5397 } 5398 5399 private: 5400 /// Check the right-hand side of an assignment in the increment 5401 /// expression. 5402 bool checkAndSetIncRHS(Expr *RHS); 5403 /// Helper to set loop counter variable and its initializer. 5404 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5405 bool EmitDiags); 5406 /// Helper to set upper bound. 5407 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5408 SourceRange SR, SourceLocation SL); 5409 /// Helper to set loop increment. 5410 bool setStep(Expr *NewStep, bool Subtract); 5411 }; 5412 5413 bool OpenMPIterationSpaceChecker::dependent() const { 5414 if (!LCDecl) { 5415 assert(!LB && !UB && !Step); 5416 return false; 5417 } 5418 return LCDecl->getType()->isDependentType() || 5419 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5420 (Step && Step->isValueDependent()); 5421 } 5422 5423 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5424 Expr *NewLCRefExpr, 5425 Expr *NewLB, bool EmitDiags) { 5426 // State consistency checking to ensure correct usage. 5427 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5428 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5429 if (!NewLCDecl || !NewLB) 5430 return true; 5431 LCDecl = getCanonicalDecl(NewLCDecl); 5432 LCRef = NewLCRefExpr; 5433 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5434 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5435 if ((Ctor->isCopyOrMoveConstructor() || 5436 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5437 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5438 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5439 LB = NewLB; 5440 if (EmitDiags) 5441 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5442 return false; 5443 } 5444 5445 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5446 llvm::Optional<bool> LessOp, 5447 bool StrictOp, SourceRange SR, 5448 SourceLocation SL) { 5449 // State consistency checking to ensure correct usage. 5450 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5451 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5452 if (!NewUB) 5453 return true; 5454 UB = NewUB; 5455 if (LessOp) 5456 TestIsLessOp = LessOp; 5457 TestIsStrictOp = StrictOp; 5458 ConditionSrcRange = SR; 5459 ConditionLoc = SL; 5460 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5461 return false; 5462 } 5463 5464 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5465 // State consistency checking to ensure correct usage. 5466 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5467 if (!NewStep) 5468 return true; 5469 if (!NewStep->isValueDependent()) { 5470 // Check that the step is integer expression. 5471 SourceLocation StepLoc = NewStep->getBeginLoc(); 5472 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5473 StepLoc, getExprAsWritten(NewStep)); 5474 if (Val.isInvalid()) 5475 return true; 5476 NewStep = Val.get(); 5477 5478 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5479 // If test-expr is of form var relational-op b and relational-op is < or 5480 // <= then incr-expr must cause var to increase on each iteration of the 5481 // loop. If test-expr is of form var relational-op b and relational-op is 5482 // > or >= then incr-expr must cause var to decrease on each iteration of 5483 // the loop. 5484 // If test-expr is of form b relational-op var and relational-op is < or 5485 // <= then incr-expr must cause var to decrease on each iteration of the 5486 // loop. If test-expr is of form b relational-op var and relational-op is 5487 // > or >= then incr-expr must cause var to increase on each iteration of 5488 // the loop. 5489 llvm::APSInt Result; 5490 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5491 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5492 bool IsConstNeg = 5493 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5494 bool IsConstPos = 5495 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5496 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5497 5498 // != with increment is treated as <; != with decrement is treated as > 5499 if (!TestIsLessOp.hasValue()) 5500 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5501 if (UB && (IsConstZero || 5502 (TestIsLessOp.getValue() ? 5503 (IsConstNeg || (IsUnsigned && Subtract)) : 5504 (IsConstPos || (IsUnsigned && !Subtract))))) { 5505 SemaRef.Diag(NewStep->getExprLoc(), 5506 diag::err_omp_loop_incr_not_compatible) 5507 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5508 SemaRef.Diag(ConditionLoc, 5509 diag::note_omp_loop_cond_requres_compatible_incr) 5510 << TestIsLessOp.getValue() << ConditionSrcRange; 5511 return true; 5512 } 5513 if (TestIsLessOp.getValue() == Subtract) { 5514 NewStep = 5515 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5516 .get(); 5517 Subtract = !Subtract; 5518 } 5519 } 5520 5521 Step = NewStep; 5522 SubtractStep = Subtract; 5523 return false; 5524 } 5525 5526 namespace { 5527 /// Checker for the non-rectangular loops. Checks if the initializer or 5528 /// condition expression references loop counter variable. 5529 class LoopCounterRefChecker final 5530 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5531 Sema &SemaRef; 5532 DSAStackTy &Stack; 5533 const ValueDecl *CurLCDecl = nullptr; 5534 const ValueDecl *DepDecl = nullptr; 5535 const ValueDecl *PrevDepDecl = nullptr; 5536 bool IsInitializer = true; 5537 unsigned BaseLoopId = 0; 5538 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5539 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5540 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5541 << (IsInitializer ? 0 : 1); 5542 return false; 5543 } 5544 const auto &&Data = Stack.isLoopControlVariable(VD); 5545 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5546 // The type of the loop iterator on which we depend may not have a random 5547 // access iterator type. 5548 if (Data.first && VD->getType()->isRecordType()) { 5549 SmallString<128> Name; 5550 llvm::raw_svector_ostream OS(Name); 5551 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5552 /*Qualified=*/true); 5553 SemaRef.Diag(E->getExprLoc(), 5554 diag::err_omp_wrong_dependency_iterator_type) 5555 << OS.str(); 5556 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5557 return false; 5558 } 5559 if (Data.first && 5560 (DepDecl || (PrevDepDecl && 5561 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5562 if (!DepDecl && PrevDepDecl) 5563 DepDecl = PrevDepDecl; 5564 SmallString<128> Name; 5565 llvm::raw_svector_ostream OS(Name); 5566 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5567 /*Qualified=*/true); 5568 SemaRef.Diag(E->getExprLoc(), 5569 diag::err_omp_invariant_or_linear_dependency) 5570 << OS.str(); 5571 return false; 5572 } 5573 if (Data.first) { 5574 DepDecl = VD; 5575 BaseLoopId = Data.first; 5576 } 5577 return Data.first; 5578 } 5579 5580 public: 5581 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5582 const ValueDecl *VD = E->getDecl(); 5583 if (isa<VarDecl>(VD)) 5584 return checkDecl(E, VD); 5585 return false; 5586 } 5587 bool VisitMemberExpr(const MemberExpr *E) { 5588 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5589 const ValueDecl *VD = E->getMemberDecl(); 5590 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5591 return checkDecl(E, VD); 5592 } 5593 return false; 5594 } 5595 bool VisitStmt(const Stmt *S) { 5596 bool Res = false; 5597 for (const Stmt *Child : S->children()) 5598 Res = (Child && Visit(Child)) || Res; 5599 return Res; 5600 } 5601 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5602 const ValueDecl *CurLCDecl, bool IsInitializer, 5603 const ValueDecl *PrevDepDecl = nullptr) 5604 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5605 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5606 unsigned getBaseLoopId() const { 5607 assert(CurLCDecl && "Expected loop dependency."); 5608 return BaseLoopId; 5609 } 5610 const ValueDecl *getDepDecl() const { 5611 assert(CurLCDecl && "Expected loop dependency."); 5612 return DepDecl; 5613 } 5614 }; 5615 } // namespace 5616 5617 Optional<unsigned> 5618 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5619 bool IsInitializer) { 5620 // Check for the non-rectangular loops. 5621 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5622 DepDecl); 5623 if (LoopStmtChecker.Visit(S)) { 5624 DepDecl = LoopStmtChecker.getDepDecl(); 5625 return LoopStmtChecker.getBaseLoopId(); 5626 } 5627 return llvm::None; 5628 } 5629 5630 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5631 // Check init-expr for canonical loop form and save loop counter 5632 // variable - #Var and its initialization value - #LB. 5633 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5634 // var = lb 5635 // integer-type var = lb 5636 // random-access-iterator-type var = lb 5637 // pointer-type var = lb 5638 // 5639 if (!S) { 5640 if (EmitDiags) { 5641 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5642 } 5643 return true; 5644 } 5645 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5646 if (!ExprTemp->cleanupsHaveSideEffects()) 5647 S = ExprTemp->getSubExpr(); 5648 5649 InitSrcRange = S->getSourceRange(); 5650 if (Expr *E = dyn_cast<Expr>(S)) 5651 S = E->IgnoreParens(); 5652 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5653 if (BO->getOpcode() == BO_Assign) { 5654 Expr *LHS = BO->getLHS()->IgnoreParens(); 5655 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5656 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5657 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5658 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5659 EmitDiags); 5660 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5661 } 5662 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5663 if (ME->isArrow() && 5664 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5665 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5666 EmitDiags); 5667 } 5668 } 5669 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5670 if (DS->isSingleDecl()) { 5671 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5672 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5673 // Accept non-canonical init form here but emit ext. warning. 5674 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5675 SemaRef.Diag(S->getBeginLoc(), 5676 diag::ext_omp_loop_not_canonical_init) 5677 << S->getSourceRange(); 5678 return setLCDeclAndLB( 5679 Var, 5680 buildDeclRefExpr(SemaRef, Var, 5681 Var->getType().getNonReferenceType(), 5682 DS->getBeginLoc()), 5683 Var->getInit(), EmitDiags); 5684 } 5685 } 5686 } 5687 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5688 if (CE->getOperator() == OO_Equal) { 5689 Expr *LHS = CE->getArg(0); 5690 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5691 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5692 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5693 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5694 EmitDiags); 5695 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5696 } 5697 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5698 if (ME->isArrow() && 5699 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5700 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5701 EmitDiags); 5702 } 5703 } 5704 } 5705 5706 if (dependent() || SemaRef.CurContext->isDependentContext()) 5707 return false; 5708 if (EmitDiags) { 5709 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5710 << S->getSourceRange(); 5711 } 5712 return true; 5713 } 5714 5715 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5716 /// variable (which may be the loop variable) if possible. 5717 static const ValueDecl *getInitLCDecl(const Expr *E) { 5718 if (!E) 5719 return nullptr; 5720 E = getExprAsWritten(E); 5721 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5722 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5723 if ((Ctor->isCopyOrMoveConstructor() || 5724 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5725 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5726 E = CE->getArg(0)->IgnoreParenImpCasts(); 5727 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5728 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5729 return getCanonicalDecl(VD); 5730 } 5731 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5732 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5733 return getCanonicalDecl(ME->getMemberDecl()); 5734 return nullptr; 5735 } 5736 5737 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5738 // Check test-expr for canonical form, save upper-bound UB, flags for 5739 // less/greater and for strict/non-strict comparison. 5740 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5741 // var relational-op b 5742 // b relational-op var 5743 // 5744 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5745 if (!S) { 5746 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5747 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5748 return true; 5749 } 5750 Condition = S; 5751 S = getExprAsWritten(S); 5752 SourceLocation CondLoc = S->getBeginLoc(); 5753 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5754 if (BO->isRelationalOp()) { 5755 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5756 return setUB(BO->getRHS(), 5757 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5758 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5759 BO->getSourceRange(), BO->getOperatorLoc()); 5760 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5761 return setUB(BO->getLHS(), 5762 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5763 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5764 BO->getSourceRange(), BO->getOperatorLoc()); 5765 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5766 return setUB( 5767 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5768 /*LessOp=*/llvm::None, 5769 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5770 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5771 if (CE->getNumArgs() == 2) { 5772 auto Op = CE->getOperator(); 5773 switch (Op) { 5774 case OO_Greater: 5775 case OO_GreaterEqual: 5776 case OO_Less: 5777 case OO_LessEqual: 5778 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5779 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5780 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5781 CE->getOperatorLoc()); 5782 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5783 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5784 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5785 CE->getOperatorLoc()); 5786 break; 5787 case OO_ExclaimEqual: 5788 if (IneqCondIsCanonical) 5789 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5790 : CE->getArg(0), 5791 /*LessOp=*/llvm::None, 5792 /*StrictOp=*/true, CE->getSourceRange(), 5793 CE->getOperatorLoc()); 5794 break; 5795 default: 5796 break; 5797 } 5798 } 5799 } 5800 if (dependent() || SemaRef.CurContext->isDependentContext()) 5801 return false; 5802 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5803 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5804 return true; 5805 } 5806 5807 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5808 // RHS of canonical loop form increment can be: 5809 // var + incr 5810 // incr + var 5811 // var - incr 5812 // 5813 RHS = RHS->IgnoreParenImpCasts(); 5814 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5815 if (BO->isAdditiveOp()) { 5816 bool IsAdd = BO->getOpcode() == BO_Add; 5817 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5818 return setStep(BO->getRHS(), !IsAdd); 5819 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5820 return setStep(BO->getLHS(), /*Subtract=*/false); 5821 } 5822 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5823 bool IsAdd = CE->getOperator() == OO_Plus; 5824 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5825 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5826 return setStep(CE->getArg(1), !IsAdd); 5827 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5828 return setStep(CE->getArg(0), /*Subtract=*/false); 5829 } 5830 } 5831 if (dependent() || SemaRef.CurContext->isDependentContext()) 5832 return false; 5833 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5834 << RHS->getSourceRange() << LCDecl; 5835 return true; 5836 } 5837 5838 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5839 // Check incr-expr for canonical loop form and return true if it 5840 // does not conform. 5841 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5842 // ++var 5843 // var++ 5844 // --var 5845 // var-- 5846 // var += incr 5847 // var -= incr 5848 // var = var + incr 5849 // var = incr + var 5850 // var = var - incr 5851 // 5852 if (!S) { 5853 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5854 return true; 5855 } 5856 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5857 if (!ExprTemp->cleanupsHaveSideEffects()) 5858 S = ExprTemp->getSubExpr(); 5859 5860 IncrementSrcRange = S->getSourceRange(); 5861 S = S->IgnoreParens(); 5862 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5863 if (UO->isIncrementDecrementOp() && 5864 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5865 return setStep(SemaRef 5866 .ActOnIntegerConstant(UO->getBeginLoc(), 5867 (UO->isDecrementOp() ? -1 : 1)) 5868 .get(), 5869 /*Subtract=*/false); 5870 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5871 switch (BO->getOpcode()) { 5872 case BO_AddAssign: 5873 case BO_SubAssign: 5874 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5875 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5876 break; 5877 case BO_Assign: 5878 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5879 return checkAndSetIncRHS(BO->getRHS()); 5880 break; 5881 default: 5882 break; 5883 } 5884 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5885 switch (CE->getOperator()) { 5886 case OO_PlusPlus: 5887 case OO_MinusMinus: 5888 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5889 return setStep(SemaRef 5890 .ActOnIntegerConstant( 5891 CE->getBeginLoc(), 5892 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5893 .get(), 5894 /*Subtract=*/false); 5895 break; 5896 case OO_PlusEqual: 5897 case OO_MinusEqual: 5898 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5899 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5900 break; 5901 case OO_Equal: 5902 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5903 return checkAndSetIncRHS(CE->getArg(1)); 5904 break; 5905 default: 5906 break; 5907 } 5908 } 5909 if (dependent() || SemaRef.CurContext->isDependentContext()) 5910 return false; 5911 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5912 << S->getSourceRange() << LCDecl; 5913 return true; 5914 } 5915 5916 static ExprResult 5917 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5918 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5919 if (SemaRef.CurContext->isDependentContext()) 5920 return ExprResult(Capture); 5921 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5922 return SemaRef.PerformImplicitConversion( 5923 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5924 /*AllowExplicit=*/true); 5925 auto I = Captures.find(Capture); 5926 if (I != Captures.end()) 5927 return buildCapture(SemaRef, Capture, I->second); 5928 DeclRefExpr *Ref = nullptr; 5929 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5930 Captures[Capture] = Ref; 5931 return Res; 5932 } 5933 5934 /// Build the expression to calculate the number of iterations. 5935 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5936 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5937 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5938 ExprResult Diff; 5939 QualType VarType = LCDecl->getType().getNonReferenceType(); 5940 if (VarType->isIntegerType() || VarType->isPointerType() || 5941 SemaRef.getLangOpts().CPlusPlus) { 5942 Expr *LBVal = LB; 5943 Expr *UBVal = UB; 5944 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5945 // max(LB(MinVal), LB(MaxVal)) 5946 if (InitDependOnLC) { 5947 const LoopIterationSpace &IS = 5948 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5949 InitDependOnLC.getValueOr( 5950 CondDependOnLC.getValueOr(0))]; 5951 if (!IS.MinValue || !IS.MaxValue) 5952 return nullptr; 5953 // OuterVar = Min 5954 ExprResult MinValue = 5955 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5956 if (!MinValue.isUsable()) 5957 return nullptr; 5958 5959 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5960 IS.CounterVar, MinValue.get()); 5961 if (!LBMinVal.isUsable()) 5962 return nullptr; 5963 // OuterVar = Min, LBVal 5964 LBMinVal = 5965 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5966 if (!LBMinVal.isUsable()) 5967 return nullptr; 5968 // (OuterVar = Min, LBVal) 5969 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5970 if (!LBMinVal.isUsable()) 5971 return nullptr; 5972 5973 // OuterVar = Max 5974 ExprResult MaxValue = 5975 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5976 if (!MaxValue.isUsable()) 5977 return nullptr; 5978 5979 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5980 IS.CounterVar, MaxValue.get()); 5981 if (!LBMaxVal.isUsable()) 5982 return nullptr; 5983 // OuterVar = Max, LBVal 5984 LBMaxVal = 5985 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5986 if (!LBMaxVal.isUsable()) 5987 return nullptr; 5988 // (OuterVar = Max, LBVal) 5989 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5990 if (!LBMaxVal.isUsable()) 5991 return nullptr; 5992 5993 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 5994 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 5995 if (!LBMin || !LBMax) 5996 return nullptr; 5997 // LB(MinVal) < LB(MaxVal) 5998 ExprResult MinLessMaxRes = 5999 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6000 if (!MinLessMaxRes.isUsable()) 6001 return nullptr; 6002 Expr *MinLessMax = 6003 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6004 if (!MinLessMax) 6005 return nullptr; 6006 if (TestIsLessOp.getValue()) { 6007 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6008 // LB(MaxVal)) 6009 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6010 MinLessMax, LBMin, LBMax); 6011 if (!MinLB.isUsable()) 6012 return nullptr; 6013 LBVal = MinLB.get(); 6014 } else { 6015 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6016 // LB(MaxVal)) 6017 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6018 MinLessMax, LBMax, LBMin); 6019 if (!MaxLB.isUsable()) 6020 return nullptr; 6021 LBVal = MaxLB.get(); 6022 } 6023 } 6024 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6025 // min(UB(MinVal), UB(MaxVal)) 6026 if (CondDependOnLC) { 6027 const LoopIterationSpace &IS = 6028 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6029 InitDependOnLC.getValueOr( 6030 CondDependOnLC.getValueOr(0))]; 6031 if (!IS.MinValue || !IS.MaxValue) 6032 return nullptr; 6033 // OuterVar = Min 6034 ExprResult MinValue = 6035 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6036 if (!MinValue.isUsable()) 6037 return nullptr; 6038 6039 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6040 IS.CounterVar, MinValue.get()); 6041 if (!UBMinVal.isUsable()) 6042 return nullptr; 6043 // OuterVar = Min, UBVal 6044 UBMinVal = 6045 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6046 if (!UBMinVal.isUsable()) 6047 return nullptr; 6048 // (OuterVar = Min, UBVal) 6049 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6050 if (!UBMinVal.isUsable()) 6051 return nullptr; 6052 6053 // OuterVar = Max 6054 ExprResult MaxValue = 6055 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6056 if (!MaxValue.isUsable()) 6057 return nullptr; 6058 6059 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6060 IS.CounterVar, MaxValue.get()); 6061 if (!UBMaxVal.isUsable()) 6062 return nullptr; 6063 // OuterVar = Max, UBVal 6064 UBMaxVal = 6065 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6066 if (!UBMaxVal.isUsable()) 6067 return nullptr; 6068 // (OuterVar = Max, UBVal) 6069 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6070 if (!UBMaxVal.isUsable()) 6071 return nullptr; 6072 6073 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6074 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6075 if (!UBMin || !UBMax) 6076 return nullptr; 6077 // UB(MinVal) > UB(MaxVal) 6078 ExprResult MinGreaterMaxRes = 6079 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6080 if (!MinGreaterMaxRes.isUsable()) 6081 return nullptr; 6082 Expr *MinGreaterMax = 6083 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6084 if (!MinGreaterMax) 6085 return nullptr; 6086 if (TestIsLessOp.getValue()) { 6087 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6088 // UB(MaxVal)) 6089 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6090 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6091 if (!MaxUB.isUsable()) 6092 return nullptr; 6093 UBVal = MaxUB.get(); 6094 } else { 6095 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6096 // UB(MaxVal)) 6097 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6098 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6099 if (!MinUB.isUsable()) 6100 return nullptr; 6101 UBVal = MinUB.get(); 6102 } 6103 } 6104 // Upper - Lower 6105 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6106 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6107 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6108 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6109 if (!Upper || !Lower) 6110 return nullptr; 6111 6112 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6113 6114 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6115 // BuildBinOp already emitted error, this one is to point user to upper 6116 // and lower bound, and to tell what is passed to 'operator-'. 6117 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6118 << Upper->getSourceRange() << Lower->getSourceRange(); 6119 return nullptr; 6120 } 6121 } 6122 6123 if (!Diff.isUsable()) 6124 return nullptr; 6125 6126 // Upper - Lower [- 1] 6127 if (TestIsStrictOp) 6128 Diff = SemaRef.BuildBinOp( 6129 S, DefaultLoc, BO_Sub, Diff.get(), 6130 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6131 if (!Diff.isUsable()) 6132 return nullptr; 6133 6134 // Upper - Lower [- 1] + Step 6135 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6136 if (!NewStep.isUsable()) 6137 return nullptr; 6138 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6139 if (!Diff.isUsable()) 6140 return nullptr; 6141 6142 // Parentheses (for dumping/debugging purposes only). 6143 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6144 if (!Diff.isUsable()) 6145 return nullptr; 6146 6147 // (Upper - Lower [- 1] + Step) / Step 6148 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6149 if (!Diff.isUsable()) 6150 return nullptr; 6151 6152 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6153 QualType Type = Diff.get()->getType(); 6154 ASTContext &C = SemaRef.Context; 6155 bool UseVarType = VarType->hasIntegerRepresentation() && 6156 C.getTypeSize(Type) > C.getTypeSize(VarType); 6157 if (!Type->isIntegerType() || UseVarType) { 6158 unsigned NewSize = 6159 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6160 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6161 : Type->hasSignedIntegerRepresentation(); 6162 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6163 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6164 Diff = SemaRef.PerformImplicitConversion( 6165 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6166 if (!Diff.isUsable()) 6167 return nullptr; 6168 } 6169 } 6170 if (LimitedType) { 6171 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6172 if (NewSize != C.getTypeSize(Type)) { 6173 if (NewSize < C.getTypeSize(Type)) { 6174 assert(NewSize == 64 && "incorrect loop var size"); 6175 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6176 << InitSrcRange << ConditionSrcRange; 6177 } 6178 QualType NewType = C.getIntTypeForBitwidth( 6179 NewSize, Type->hasSignedIntegerRepresentation() || 6180 C.getTypeSize(Type) < NewSize); 6181 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6182 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6183 Sema::AA_Converting, true); 6184 if (!Diff.isUsable()) 6185 return nullptr; 6186 } 6187 } 6188 } 6189 6190 return Diff.get(); 6191 } 6192 6193 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6194 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6195 // Do not build for iterators, they cannot be used in non-rectangular loop 6196 // nests. 6197 if (LCDecl->getType()->isRecordType()) 6198 return std::make_pair(nullptr, nullptr); 6199 // If we subtract, the min is in the condition, otherwise the min is in the 6200 // init value. 6201 Expr *MinExpr = nullptr; 6202 Expr *MaxExpr = nullptr; 6203 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6204 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6205 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6206 : CondDependOnLC.hasValue(); 6207 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6208 : InitDependOnLC.hasValue(); 6209 Expr *Lower = 6210 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6211 Expr *Upper = 6212 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6213 if (!Upper || !Lower) 6214 return std::make_pair(nullptr, nullptr); 6215 6216 if (TestIsLessOp.getValue()) 6217 MinExpr = Lower; 6218 else 6219 MaxExpr = Upper; 6220 6221 // Build minimum/maximum value based on number of iterations. 6222 ExprResult Diff; 6223 QualType VarType = LCDecl->getType().getNonReferenceType(); 6224 6225 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6226 if (!Diff.isUsable()) 6227 return std::make_pair(nullptr, nullptr); 6228 6229 // Upper - Lower [- 1] 6230 if (TestIsStrictOp) 6231 Diff = SemaRef.BuildBinOp( 6232 S, DefaultLoc, BO_Sub, Diff.get(), 6233 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6234 if (!Diff.isUsable()) 6235 return std::make_pair(nullptr, nullptr); 6236 6237 // Upper - Lower [- 1] + Step 6238 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6239 if (!NewStep.isUsable()) 6240 return std::make_pair(nullptr, nullptr); 6241 6242 // Parentheses (for dumping/debugging purposes only). 6243 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6244 if (!Diff.isUsable()) 6245 return std::make_pair(nullptr, nullptr); 6246 6247 // (Upper - Lower [- 1]) / Step 6248 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6249 if (!Diff.isUsable()) 6250 return std::make_pair(nullptr, nullptr); 6251 6252 // ((Upper - Lower [- 1]) / Step) * Step 6253 // Parentheses (for dumping/debugging purposes only). 6254 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6255 if (!Diff.isUsable()) 6256 return std::make_pair(nullptr, nullptr); 6257 6258 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6259 if (!Diff.isUsable()) 6260 return std::make_pair(nullptr, nullptr); 6261 6262 // Convert to the original type or ptrdiff_t, if original type is pointer. 6263 if (!VarType->isAnyPointerType() && 6264 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6265 Diff = SemaRef.PerformImplicitConversion( 6266 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6267 } else if (VarType->isAnyPointerType() && 6268 !SemaRef.Context.hasSameType( 6269 Diff.get()->getType(), 6270 SemaRef.Context.getUnsignedPointerDiffType())) { 6271 Diff = SemaRef.PerformImplicitConversion( 6272 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6273 Sema::AA_Converting, /*AllowExplicit=*/true); 6274 } 6275 if (!Diff.isUsable()) 6276 return std::make_pair(nullptr, nullptr); 6277 6278 // Parentheses (for dumping/debugging purposes only). 6279 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6280 if (!Diff.isUsable()) 6281 return std::make_pair(nullptr, nullptr); 6282 6283 if (TestIsLessOp.getValue()) { 6284 // MinExpr = Lower; 6285 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6286 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6287 if (!Diff.isUsable()) 6288 return std::make_pair(nullptr, nullptr); 6289 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6290 if (!Diff.isUsable()) 6291 return std::make_pair(nullptr, nullptr); 6292 MaxExpr = Diff.get(); 6293 } else { 6294 // MaxExpr = Upper; 6295 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6296 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6297 if (!Diff.isUsable()) 6298 return std::make_pair(nullptr, nullptr); 6299 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6300 if (!Diff.isUsable()) 6301 return std::make_pair(nullptr, nullptr); 6302 MinExpr = Diff.get(); 6303 } 6304 6305 return std::make_pair(MinExpr, MaxExpr); 6306 } 6307 6308 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6309 if (InitDependOnLC || CondDependOnLC) 6310 return Condition; 6311 return nullptr; 6312 } 6313 6314 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6315 Scope *S, Expr *Cond, 6316 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6317 // Do not build a precondition when the condition/initialization is dependent 6318 // to prevent pessimistic early loop exit. 6319 // TODO: this can be improved by calculating min/max values but not sure that 6320 // it will be very effective. 6321 if (CondDependOnLC || InitDependOnLC) 6322 return SemaRef.PerformImplicitConversion( 6323 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6324 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6325 /*AllowExplicit=*/true).get(); 6326 6327 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6328 Sema::TentativeAnalysisScope Trap(SemaRef); 6329 6330 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6331 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6332 if (!NewLB.isUsable() || !NewUB.isUsable()) 6333 return nullptr; 6334 6335 ExprResult CondExpr = 6336 SemaRef.BuildBinOp(S, DefaultLoc, 6337 TestIsLessOp.getValue() ? 6338 (TestIsStrictOp ? BO_LT : BO_LE) : 6339 (TestIsStrictOp ? BO_GT : BO_GE), 6340 NewLB.get(), NewUB.get()); 6341 if (CondExpr.isUsable()) { 6342 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6343 SemaRef.Context.BoolTy)) 6344 CondExpr = SemaRef.PerformImplicitConversion( 6345 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6346 /*AllowExplicit=*/true); 6347 } 6348 6349 // Otherwise use original loop condition and evaluate it in runtime. 6350 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6351 } 6352 6353 /// Build reference expression to the counter be used for codegen. 6354 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6355 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6356 DSAStackTy &DSA) const { 6357 auto *VD = dyn_cast<VarDecl>(LCDecl); 6358 if (!VD) { 6359 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6360 DeclRefExpr *Ref = buildDeclRefExpr( 6361 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6362 const DSAStackTy::DSAVarData Data = 6363 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6364 // If the loop control decl is explicitly marked as private, do not mark it 6365 // as captured again. 6366 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6367 Captures.insert(std::make_pair(LCRef, Ref)); 6368 return Ref; 6369 } 6370 return cast<DeclRefExpr>(LCRef); 6371 } 6372 6373 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6374 if (LCDecl && !LCDecl->isInvalidDecl()) { 6375 QualType Type = LCDecl->getType().getNonReferenceType(); 6376 VarDecl *PrivateVar = buildVarDecl( 6377 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6378 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6379 isa<VarDecl>(LCDecl) 6380 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6381 : nullptr); 6382 if (PrivateVar->isInvalidDecl()) 6383 return nullptr; 6384 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6385 } 6386 return nullptr; 6387 } 6388 6389 /// Build initialization of the counter to be used for codegen. 6390 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6391 6392 /// Build step of the counter be used for codegen. 6393 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6394 6395 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6396 Scope *S, Expr *Counter, 6397 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6398 Expr *Inc, OverloadedOperatorKind OOK) { 6399 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6400 if (!Cnt) 6401 return nullptr; 6402 if (Inc) { 6403 assert((OOK == OO_Plus || OOK == OO_Minus) && 6404 "Expected only + or - operations for depend clauses."); 6405 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6406 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6407 if (!Cnt) 6408 return nullptr; 6409 } 6410 ExprResult Diff; 6411 QualType VarType = LCDecl->getType().getNonReferenceType(); 6412 if (VarType->isIntegerType() || VarType->isPointerType() || 6413 SemaRef.getLangOpts().CPlusPlus) { 6414 // Upper - Lower 6415 Expr *Upper = TestIsLessOp.getValue() 6416 ? Cnt 6417 : tryBuildCapture(SemaRef, UB, Captures).get(); 6418 Expr *Lower = TestIsLessOp.getValue() 6419 ? tryBuildCapture(SemaRef, LB, Captures).get() 6420 : Cnt; 6421 if (!Upper || !Lower) 6422 return nullptr; 6423 6424 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6425 6426 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6427 // BuildBinOp already emitted error, this one is to point user to upper 6428 // and lower bound, and to tell what is passed to 'operator-'. 6429 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6430 << Upper->getSourceRange() << Lower->getSourceRange(); 6431 return nullptr; 6432 } 6433 } 6434 6435 if (!Diff.isUsable()) 6436 return nullptr; 6437 6438 // Parentheses (for dumping/debugging purposes only). 6439 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6440 if (!Diff.isUsable()) 6441 return nullptr; 6442 6443 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6444 if (!NewStep.isUsable()) 6445 return nullptr; 6446 // (Upper - Lower) / Step 6447 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6448 if (!Diff.isUsable()) 6449 return nullptr; 6450 6451 return Diff.get(); 6452 } 6453 } // namespace 6454 6455 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6456 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6457 assert(Init && "Expected loop in canonical form."); 6458 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6459 if (AssociatedLoops > 0 && 6460 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6461 DSAStack->loopStart(); 6462 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6463 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6464 if (ValueDecl *D = ISC.getLoopDecl()) { 6465 auto *VD = dyn_cast<VarDecl>(D); 6466 DeclRefExpr *PrivateRef = nullptr; 6467 if (!VD) { 6468 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6469 VD = Private; 6470 } else { 6471 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6472 /*WithInit=*/false); 6473 VD = cast<VarDecl>(PrivateRef->getDecl()); 6474 } 6475 } 6476 DSAStack->addLoopControlVariable(D, VD); 6477 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6478 if (LD != D->getCanonicalDecl()) { 6479 DSAStack->resetPossibleLoopCounter(); 6480 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6481 MarkDeclarationsReferencedInExpr( 6482 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6483 Var->getType().getNonLValueExprType(Context), 6484 ForLoc, /*RefersToCapture=*/true)); 6485 } 6486 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6487 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6488 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6489 // associated for-loop of a simd construct with just one associated 6490 // for-loop may be listed in a linear clause with a constant-linear-step 6491 // that is the increment of the associated for-loop. The loop iteration 6492 // variable(s) in the associated for-loop(s) of a for or parallel for 6493 // construct may be listed in a private or lastprivate clause. 6494 DSAStackTy::DSAVarData DVar = 6495 DSAStack->getTopDSA(D, /*FromParent=*/false); 6496 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6497 // is declared in the loop and it is predetermined as a private. 6498 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6499 OpenMPClauseKind PredeterminedCKind = 6500 isOpenMPSimdDirective(DKind) 6501 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6502 : OMPC_private; 6503 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6504 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6505 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6506 DVar.CKind != OMPC_private))) || 6507 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6508 DKind == OMPD_master_taskloop || 6509 DKind == OMPD_parallel_master_taskloop || 6510 isOpenMPDistributeDirective(DKind)) && 6511 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6512 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6513 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6514 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6515 << getOpenMPClauseName(DVar.CKind) 6516 << getOpenMPDirectiveName(DKind) 6517 << getOpenMPClauseName(PredeterminedCKind); 6518 if (DVar.RefExpr == nullptr) 6519 DVar.CKind = PredeterminedCKind; 6520 reportOriginalDsa(*this, DSAStack, D, DVar, 6521 /*IsLoopIterVar=*/true); 6522 } else if (LoopDeclRefExpr) { 6523 // Make the loop iteration variable private (for worksharing 6524 // constructs), linear (for simd directives with the only one 6525 // associated loop) or lastprivate (for simd directives with several 6526 // collapsed or ordered loops). 6527 if (DVar.CKind == OMPC_unknown) 6528 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6529 PrivateRef); 6530 } 6531 } 6532 } 6533 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6534 } 6535 } 6536 6537 /// Called on a for stmt to check and extract its iteration space 6538 /// for further processing (such as collapsing). 6539 static bool checkOpenMPIterationSpace( 6540 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6541 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6542 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6543 Expr *OrderedLoopCountExpr, 6544 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6545 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6546 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6547 // OpenMP [2.9.1, Canonical Loop Form] 6548 // for (init-expr; test-expr; incr-expr) structured-block 6549 // for (range-decl: range-expr) structured-block 6550 auto *For = dyn_cast_or_null<ForStmt>(S); 6551 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6552 // Ranged for is supported only in OpenMP 5.0. 6553 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6554 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6555 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6556 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6557 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6558 if (TotalNestedLoopCount > 1) { 6559 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6560 SemaRef.Diag(DSA.getConstructLoc(), 6561 diag::note_omp_collapse_ordered_expr) 6562 << 2 << CollapseLoopCountExpr->getSourceRange() 6563 << OrderedLoopCountExpr->getSourceRange(); 6564 else if (CollapseLoopCountExpr) 6565 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6566 diag::note_omp_collapse_ordered_expr) 6567 << 0 << CollapseLoopCountExpr->getSourceRange(); 6568 else 6569 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6570 diag::note_omp_collapse_ordered_expr) 6571 << 1 << OrderedLoopCountExpr->getSourceRange(); 6572 } 6573 return true; 6574 } 6575 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6576 "No loop body."); 6577 6578 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6579 For ? For->getForLoc() : CXXFor->getForLoc()); 6580 6581 // Check init. 6582 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6583 if (ISC.checkAndSetInit(Init)) 6584 return true; 6585 6586 bool HasErrors = false; 6587 6588 // Check loop variable's type. 6589 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6590 // OpenMP [2.6, Canonical Loop Form] 6591 // Var is one of the following: 6592 // A variable of signed or unsigned integer type. 6593 // For C++, a variable of a random access iterator type. 6594 // For C, a variable of a pointer type. 6595 QualType VarType = LCDecl->getType().getNonReferenceType(); 6596 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6597 !VarType->isPointerType() && 6598 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6599 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6600 << SemaRef.getLangOpts().CPlusPlus; 6601 HasErrors = true; 6602 } 6603 6604 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6605 // a Construct 6606 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6607 // parallel for construct is (are) private. 6608 // The loop iteration variable in the associated for-loop of a simd 6609 // construct with just one associated for-loop is linear with a 6610 // constant-linear-step that is the increment of the associated for-loop. 6611 // Exclude loop var from the list of variables with implicitly defined data 6612 // sharing attributes. 6613 VarsWithImplicitDSA.erase(LCDecl); 6614 6615 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6616 6617 // Check test-expr. 6618 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6619 6620 // Check incr-expr. 6621 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6622 } 6623 6624 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6625 return HasErrors; 6626 6627 // Build the loop's iteration space representation. 6628 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6629 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6630 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6631 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6632 (isOpenMPWorksharingDirective(DKind) || 6633 isOpenMPTaskLoopDirective(DKind) || 6634 isOpenMPDistributeDirective(DKind)), 6635 Captures); 6636 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6637 ISC.buildCounterVar(Captures, DSA); 6638 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6639 ISC.buildPrivateCounterVar(); 6640 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6641 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6642 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6643 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6644 ISC.getConditionSrcRange(); 6645 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6646 ISC.getIncrementSrcRange(); 6647 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6648 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6649 ISC.isStrictTestOp(); 6650 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6651 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6652 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6653 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6654 ISC.buildFinalCondition(DSA.getCurScope()); 6655 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6656 ISC.doesInitDependOnLC(); 6657 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6658 ISC.doesCondDependOnLC(); 6659 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6660 ISC.getLoopDependentIdx(); 6661 6662 HasErrors |= 6663 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6664 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6665 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6666 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6667 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6668 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6669 if (!HasErrors && DSA.isOrderedRegion()) { 6670 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6671 if (CurrentNestedLoopCount < 6672 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6673 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6674 CurrentNestedLoopCount, 6675 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6676 DSA.getOrderedRegionParam().second->setLoopCounter( 6677 CurrentNestedLoopCount, 6678 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6679 } 6680 } 6681 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6682 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6683 // Erroneous case - clause has some problems. 6684 continue; 6685 } 6686 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6687 Pair.second.size() <= CurrentNestedLoopCount) { 6688 // Erroneous case - clause has some problems. 6689 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6690 continue; 6691 } 6692 Expr *CntValue; 6693 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6694 CntValue = ISC.buildOrderedLoopData( 6695 DSA.getCurScope(), 6696 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6697 Pair.first->getDependencyLoc()); 6698 else 6699 CntValue = ISC.buildOrderedLoopData( 6700 DSA.getCurScope(), 6701 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6702 Pair.first->getDependencyLoc(), 6703 Pair.second[CurrentNestedLoopCount].first, 6704 Pair.second[CurrentNestedLoopCount].second); 6705 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6706 } 6707 } 6708 6709 return HasErrors; 6710 } 6711 6712 /// Build 'VarRef = Start. 6713 static ExprResult 6714 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6715 ExprResult Start, bool IsNonRectangularLB, 6716 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6717 // Build 'VarRef = Start. 6718 ExprResult NewStart = IsNonRectangularLB 6719 ? Start.get() 6720 : tryBuildCapture(SemaRef, Start.get(), Captures); 6721 if (!NewStart.isUsable()) 6722 return ExprError(); 6723 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6724 VarRef.get()->getType())) { 6725 NewStart = SemaRef.PerformImplicitConversion( 6726 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6727 /*AllowExplicit=*/true); 6728 if (!NewStart.isUsable()) 6729 return ExprError(); 6730 } 6731 6732 ExprResult Init = 6733 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6734 return Init; 6735 } 6736 6737 /// Build 'VarRef = Start + Iter * Step'. 6738 static ExprResult buildCounterUpdate( 6739 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6740 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6741 bool IsNonRectangularLB, 6742 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6743 // Add parentheses (for debugging purposes only). 6744 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6745 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6746 !Step.isUsable()) 6747 return ExprError(); 6748 6749 ExprResult NewStep = Step; 6750 if (Captures) 6751 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6752 if (NewStep.isInvalid()) 6753 return ExprError(); 6754 ExprResult Update = 6755 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6756 if (!Update.isUsable()) 6757 return ExprError(); 6758 6759 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6760 // 'VarRef = Start (+|-) Iter * Step'. 6761 if (!Start.isUsable()) 6762 return ExprError(); 6763 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6764 if (!NewStart.isUsable()) 6765 return ExprError(); 6766 if (Captures && !IsNonRectangularLB) 6767 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6768 if (NewStart.isInvalid()) 6769 return ExprError(); 6770 6771 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6772 ExprResult SavedUpdate = Update; 6773 ExprResult UpdateVal; 6774 if (VarRef.get()->getType()->isOverloadableType() || 6775 NewStart.get()->getType()->isOverloadableType() || 6776 Update.get()->getType()->isOverloadableType()) { 6777 Sema::TentativeAnalysisScope Trap(SemaRef); 6778 6779 Update = 6780 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6781 if (Update.isUsable()) { 6782 UpdateVal = 6783 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6784 VarRef.get(), SavedUpdate.get()); 6785 if (UpdateVal.isUsable()) { 6786 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6787 UpdateVal.get()); 6788 } 6789 } 6790 } 6791 6792 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6793 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6794 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6795 NewStart.get(), SavedUpdate.get()); 6796 if (!Update.isUsable()) 6797 return ExprError(); 6798 6799 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6800 VarRef.get()->getType())) { 6801 Update = SemaRef.PerformImplicitConversion( 6802 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6803 if (!Update.isUsable()) 6804 return ExprError(); 6805 } 6806 6807 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6808 } 6809 return Update; 6810 } 6811 6812 /// Convert integer expression \a E to make it have at least \a Bits 6813 /// bits. 6814 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6815 if (E == nullptr) 6816 return ExprError(); 6817 ASTContext &C = SemaRef.Context; 6818 QualType OldType = E->getType(); 6819 unsigned HasBits = C.getTypeSize(OldType); 6820 if (HasBits >= Bits) 6821 return ExprResult(E); 6822 // OK to convert to signed, because new type has more bits than old. 6823 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6824 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6825 true); 6826 } 6827 6828 /// Check if the given expression \a E is a constant integer that fits 6829 /// into \a Bits bits. 6830 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6831 if (E == nullptr) 6832 return false; 6833 llvm::APSInt Result; 6834 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6835 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6836 return false; 6837 } 6838 6839 /// Build preinits statement for the given declarations. 6840 static Stmt *buildPreInits(ASTContext &Context, 6841 MutableArrayRef<Decl *> PreInits) { 6842 if (!PreInits.empty()) { 6843 return new (Context) DeclStmt( 6844 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6845 SourceLocation(), SourceLocation()); 6846 } 6847 return nullptr; 6848 } 6849 6850 /// Build preinits statement for the given declarations. 6851 static Stmt * 6852 buildPreInits(ASTContext &Context, 6853 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6854 if (!Captures.empty()) { 6855 SmallVector<Decl *, 16> PreInits; 6856 for (const auto &Pair : Captures) 6857 PreInits.push_back(Pair.second->getDecl()); 6858 return buildPreInits(Context, PreInits); 6859 } 6860 return nullptr; 6861 } 6862 6863 /// Build postupdate expression for the given list of postupdates expressions. 6864 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6865 Expr *PostUpdate = nullptr; 6866 if (!PostUpdates.empty()) { 6867 for (Expr *E : PostUpdates) { 6868 Expr *ConvE = S.BuildCStyleCastExpr( 6869 E->getExprLoc(), 6870 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6871 E->getExprLoc(), E) 6872 .get(); 6873 PostUpdate = PostUpdate 6874 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6875 PostUpdate, ConvE) 6876 .get() 6877 : ConvE; 6878 } 6879 } 6880 return PostUpdate; 6881 } 6882 6883 /// Called on a for stmt to check itself and nested loops (if any). 6884 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6885 /// number of collapsed loops otherwise. 6886 static unsigned 6887 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6888 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6889 DSAStackTy &DSA, 6890 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6891 OMPLoopDirective::HelperExprs &Built) { 6892 unsigned NestedLoopCount = 1; 6893 if (CollapseLoopCountExpr) { 6894 // Found 'collapse' clause - calculate collapse number. 6895 Expr::EvalResult Result; 6896 if (!CollapseLoopCountExpr->isValueDependent() && 6897 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6898 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6899 } else { 6900 Built.clear(/*Size=*/1); 6901 return 1; 6902 } 6903 } 6904 unsigned OrderedLoopCount = 1; 6905 if (OrderedLoopCountExpr) { 6906 // Found 'ordered' clause - calculate collapse number. 6907 Expr::EvalResult EVResult; 6908 if (!OrderedLoopCountExpr->isValueDependent() && 6909 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6910 SemaRef.getASTContext())) { 6911 llvm::APSInt Result = EVResult.Val.getInt(); 6912 if (Result.getLimitedValue() < NestedLoopCount) { 6913 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6914 diag::err_omp_wrong_ordered_loop_count) 6915 << OrderedLoopCountExpr->getSourceRange(); 6916 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6917 diag::note_collapse_loop_count) 6918 << CollapseLoopCountExpr->getSourceRange(); 6919 } 6920 OrderedLoopCount = Result.getLimitedValue(); 6921 } else { 6922 Built.clear(/*Size=*/1); 6923 return 1; 6924 } 6925 } 6926 // This is helper routine for loop directives (e.g., 'for', 'simd', 6927 // 'for simd', etc.). 6928 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6929 SmallVector<LoopIterationSpace, 4> IterSpaces( 6930 std::max(OrderedLoopCount, NestedLoopCount)); 6931 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6932 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6933 if (checkOpenMPIterationSpace( 6934 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6935 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6936 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6937 return 0; 6938 // Move on to the next nested for loop, or to the loop body. 6939 // OpenMP [2.8.1, simd construct, Restrictions] 6940 // All loops associated with the construct must be perfectly nested; that 6941 // is, there must be no intervening code nor any OpenMP directive between 6942 // any two loops. 6943 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6944 CurStmt = For->getBody(); 6945 } else { 6946 assert(isa<CXXForRangeStmt>(CurStmt) && 6947 "Expected canonical for or range-based for loops."); 6948 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6949 } 6950 CurStmt = CurStmt->IgnoreContainers(); 6951 } 6952 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6953 if (checkOpenMPIterationSpace( 6954 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6955 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6956 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6957 return 0; 6958 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6959 // Handle initialization of captured loop iterator variables. 6960 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6961 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6962 Captures[DRE] = DRE; 6963 } 6964 } 6965 // Move on to the next nested for loop, or to the loop body. 6966 // OpenMP [2.8.1, simd construct, Restrictions] 6967 // All loops associated with the construct must be perfectly nested; that 6968 // is, there must be no intervening code nor any OpenMP directive between 6969 // any two loops. 6970 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6971 CurStmt = For->getBody(); 6972 } else { 6973 assert(isa<CXXForRangeStmt>(CurStmt) && 6974 "Expected canonical for or range-based for loops."); 6975 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6976 } 6977 CurStmt = CurStmt->IgnoreContainers(); 6978 } 6979 6980 Built.clear(/* size */ NestedLoopCount); 6981 6982 if (SemaRef.CurContext->isDependentContext()) 6983 return NestedLoopCount; 6984 6985 // An example of what is generated for the following code: 6986 // 6987 // #pragma omp simd collapse(2) ordered(2) 6988 // for (i = 0; i < NI; ++i) 6989 // for (k = 0; k < NK; ++k) 6990 // for (j = J0; j < NJ; j+=2) { 6991 // <loop body> 6992 // } 6993 // 6994 // We generate the code below. 6995 // Note: the loop body may be outlined in CodeGen. 6996 // Note: some counters may be C++ classes, operator- is used to find number of 6997 // iterations and operator+= to calculate counter value. 6998 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6999 // or i64 is currently supported). 7000 // 7001 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7002 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7003 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7004 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7005 // // similar updates for vars in clauses (e.g. 'linear') 7006 // <loop body (using local i and j)> 7007 // } 7008 // i = NI; // assign final values of counters 7009 // j = NJ; 7010 // 7011 7012 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7013 // the iteration counts of the collapsed for loops. 7014 // Precondition tests if there is at least one iteration (all conditions are 7015 // true). 7016 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7017 Expr *N0 = IterSpaces[0].NumIterations; 7018 ExprResult LastIteration32 = 7019 widenIterationCount(/*Bits=*/32, 7020 SemaRef 7021 .PerformImplicitConversion( 7022 N0->IgnoreImpCasts(), N0->getType(), 7023 Sema::AA_Converting, /*AllowExplicit=*/true) 7024 .get(), 7025 SemaRef); 7026 ExprResult LastIteration64 = widenIterationCount( 7027 /*Bits=*/64, 7028 SemaRef 7029 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7030 Sema::AA_Converting, 7031 /*AllowExplicit=*/true) 7032 .get(), 7033 SemaRef); 7034 7035 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7036 return NestedLoopCount; 7037 7038 ASTContext &C = SemaRef.Context; 7039 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7040 7041 Scope *CurScope = DSA.getCurScope(); 7042 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7043 if (PreCond.isUsable()) { 7044 PreCond = 7045 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7046 PreCond.get(), IterSpaces[Cnt].PreCond); 7047 } 7048 Expr *N = IterSpaces[Cnt].NumIterations; 7049 SourceLocation Loc = N->getExprLoc(); 7050 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7051 if (LastIteration32.isUsable()) 7052 LastIteration32 = SemaRef.BuildBinOp( 7053 CurScope, Loc, BO_Mul, LastIteration32.get(), 7054 SemaRef 7055 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7056 Sema::AA_Converting, 7057 /*AllowExplicit=*/true) 7058 .get()); 7059 if (LastIteration64.isUsable()) 7060 LastIteration64 = SemaRef.BuildBinOp( 7061 CurScope, Loc, BO_Mul, LastIteration64.get(), 7062 SemaRef 7063 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7064 Sema::AA_Converting, 7065 /*AllowExplicit=*/true) 7066 .get()); 7067 } 7068 7069 // Choose either the 32-bit or 64-bit version. 7070 ExprResult LastIteration = LastIteration64; 7071 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7072 (LastIteration32.isUsable() && 7073 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7074 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7075 fitsInto( 7076 /*Bits=*/32, 7077 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7078 LastIteration64.get(), SemaRef)))) 7079 LastIteration = LastIteration32; 7080 QualType VType = LastIteration.get()->getType(); 7081 QualType RealVType = VType; 7082 QualType StrideVType = VType; 7083 if (isOpenMPTaskLoopDirective(DKind)) { 7084 VType = 7085 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7086 StrideVType = 7087 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7088 } 7089 7090 if (!LastIteration.isUsable()) 7091 return 0; 7092 7093 // Save the number of iterations. 7094 ExprResult NumIterations = LastIteration; 7095 { 7096 LastIteration = SemaRef.BuildBinOp( 7097 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7098 LastIteration.get(), 7099 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7100 if (!LastIteration.isUsable()) 7101 return 0; 7102 } 7103 7104 // Calculate the last iteration number beforehand instead of doing this on 7105 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7106 llvm::APSInt Result; 7107 bool IsConstant = 7108 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7109 ExprResult CalcLastIteration; 7110 if (!IsConstant) { 7111 ExprResult SaveRef = 7112 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7113 LastIteration = SaveRef; 7114 7115 // Prepare SaveRef + 1. 7116 NumIterations = SemaRef.BuildBinOp( 7117 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7118 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7119 if (!NumIterations.isUsable()) 7120 return 0; 7121 } 7122 7123 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7124 7125 // Build variables passed into runtime, necessary for worksharing directives. 7126 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7127 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7128 isOpenMPDistributeDirective(DKind)) { 7129 // Lower bound variable, initialized with zero. 7130 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7131 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7132 SemaRef.AddInitializerToDecl(LBDecl, 7133 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7134 /*DirectInit*/ false); 7135 7136 // Upper bound variable, initialized with last iteration number. 7137 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7138 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7139 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7140 /*DirectInit*/ false); 7141 7142 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7143 // This will be used to implement clause 'lastprivate'. 7144 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7145 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7146 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7147 SemaRef.AddInitializerToDecl(ILDecl, 7148 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7149 /*DirectInit*/ false); 7150 7151 // Stride variable returned by runtime (we initialize it to 1 by default). 7152 VarDecl *STDecl = 7153 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7154 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7155 SemaRef.AddInitializerToDecl(STDecl, 7156 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7157 /*DirectInit*/ false); 7158 7159 // Build expression: UB = min(UB, LastIteration) 7160 // It is necessary for CodeGen of directives with static scheduling. 7161 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7162 UB.get(), LastIteration.get()); 7163 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7164 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7165 LastIteration.get(), UB.get()); 7166 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7167 CondOp.get()); 7168 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7169 7170 // If we have a combined directive that combines 'distribute', 'for' or 7171 // 'simd' we need to be able to access the bounds of the schedule of the 7172 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7173 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7174 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7175 // Lower bound variable, initialized with zero. 7176 VarDecl *CombLBDecl = 7177 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7178 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7179 SemaRef.AddInitializerToDecl( 7180 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7181 /*DirectInit*/ false); 7182 7183 // Upper bound variable, initialized with last iteration number. 7184 VarDecl *CombUBDecl = 7185 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7186 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7187 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7188 /*DirectInit*/ false); 7189 7190 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7191 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7192 ExprResult CombCondOp = 7193 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7194 LastIteration.get(), CombUB.get()); 7195 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7196 CombCondOp.get()); 7197 CombEUB = 7198 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7199 7200 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7201 // We expect to have at least 2 more parameters than the 'parallel' 7202 // directive does - the lower and upper bounds of the previous schedule. 7203 assert(CD->getNumParams() >= 4 && 7204 "Unexpected number of parameters in loop combined directive"); 7205 7206 // Set the proper type for the bounds given what we learned from the 7207 // enclosed loops. 7208 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7209 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7210 7211 // Previous lower and upper bounds are obtained from the region 7212 // parameters. 7213 PrevLB = 7214 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7215 PrevUB = 7216 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7217 } 7218 } 7219 7220 // Build the iteration variable and its initialization before loop. 7221 ExprResult IV; 7222 ExprResult Init, CombInit; 7223 { 7224 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7225 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7226 Expr *RHS = 7227 (isOpenMPWorksharingDirective(DKind) || 7228 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7229 ? LB.get() 7230 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7231 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7232 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7233 7234 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7235 Expr *CombRHS = 7236 (isOpenMPWorksharingDirective(DKind) || 7237 isOpenMPTaskLoopDirective(DKind) || 7238 isOpenMPDistributeDirective(DKind)) 7239 ? CombLB.get() 7240 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7241 CombInit = 7242 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7243 CombInit = 7244 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7245 } 7246 } 7247 7248 bool UseStrictCompare = 7249 RealVType->hasUnsignedIntegerRepresentation() && 7250 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7251 return LIS.IsStrictCompare; 7252 }); 7253 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7254 // unsigned IV)) for worksharing loops. 7255 SourceLocation CondLoc = AStmt->getBeginLoc(); 7256 Expr *BoundUB = UB.get(); 7257 if (UseStrictCompare) { 7258 BoundUB = 7259 SemaRef 7260 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7261 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7262 .get(); 7263 BoundUB = 7264 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7265 } 7266 ExprResult Cond = 7267 (isOpenMPWorksharingDirective(DKind) || 7268 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7269 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7270 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7271 BoundUB) 7272 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7273 NumIterations.get()); 7274 ExprResult CombDistCond; 7275 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7276 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7277 NumIterations.get()); 7278 } 7279 7280 ExprResult CombCond; 7281 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7282 Expr *BoundCombUB = CombUB.get(); 7283 if (UseStrictCompare) { 7284 BoundCombUB = 7285 SemaRef 7286 .BuildBinOp( 7287 CurScope, CondLoc, BO_Add, BoundCombUB, 7288 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7289 .get(); 7290 BoundCombUB = 7291 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7292 .get(); 7293 } 7294 CombCond = 7295 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7296 IV.get(), BoundCombUB); 7297 } 7298 // Loop increment (IV = IV + 1) 7299 SourceLocation IncLoc = AStmt->getBeginLoc(); 7300 ExprResult Inc = 7301 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7302 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7303 if (!Inc.isUsable()) 7304 return 0; 7305 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7306 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7307 if (!Inc.isUsable()) 7308 return 0; 7309 7310 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7311 // Used for directives with static scheduling. 7312 // In combined construct, add combined version that use CombLB and CombUB 7313 // base variables for the update 7314 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7315 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7316 isOpenMPDistributeDirective(DKind)) { 7317 // LB + ST 7318 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7319 if (!NextLB.isUsable()) 7320 return 0; 7321 // LB = LB + ST 7322 NextLB = 7323 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7324 NextLB = 7325 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7326 if (!NextLB.isUsable()) 7327 return 0; 7328 // UB + ST 7329 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7330 if (!NextUB.isUsable()) 7331 return 0; 7332 // UB = UB + ST 7333 NextUB = 7334 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7335 NextUB = 7336 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7337 if (!NextUB.isUsable()) 7338 return 0; 7339 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7340 CombNextLB = 7341 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7342 if (!NextLB.isUsable()) 7343 return 0; 7344 // LB = LB + ST 7345 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7346 CombNextLB.get()); 7347 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7348 /*DiscardedValue*/ false); 7349 if (!CombNextLB.isUsable()) 7350 return 0; 7351 // UB + ST 7352 CombNextUB = 7353 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7354 if (!CombNextUB.isUsable()) 7355 return 0; 7356 // UB = UB + ST 7357 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7358 CombNextUB.get()); 7359 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7360 /*DiscardedValue*/ false); 7361 if (!CombNextUB.isUsable()) 7362 return 0; 7363 } 7364 } 7365 7366 // Create increment expression for distribute loop when combined in a same 7367 // directive with for as IV = IV + ST; ensure upper bound expression based 7368 // on PrevUB instead of NumIterations - used to implement 'for' when found 7369 // in combination with 'distribute', like in 'distribute parallel for' 7370 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7371 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7372 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7373 DistCond = SemaRef.BuildBinOp( 7374 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7375 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7376 7377 DistInc = 7378 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7379 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7380 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7381 DistInc.get()); 7382 DistInc = 7383 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7384 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7385 7386 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7387 // construct 7388 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7389 ExprResult IsUBGreater = 7390 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7391 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7392 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7393 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7394 CondOp.get()); 7395 PrevEUB = 7396 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7397 7398 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7399 // parallel for is in combination with a distribute directive with 7400 // schedule(static, 1) 7401 Expr *BoundPrevUB = PrevUB.get(); 7402 if (UseStrictCompare) { 7403 BoundPrevUB = 7404 SemaRef 7405 .BuildBinOp( 7406 CurScope, CondLoc, BO_Add, BoundPrevUB, 7407 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7408 .get(); 7409 BoundPrevUB = 7410 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7411 .get(); 7412 } 7413 ParForInDistCond = 7414 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7415 IV.get(), BoundPrevUB); 7416 } 7417 7418 // Build updates and final values of the loop counters. 7419 bool HasErrors = false; 7420 Built.Counters.resize(NestedLoopCount); 7421 Built.Inits.resize(NestedLoopCount); 7422 Built.Updates.resize(NestedLoopCount); 7423 Built.Finals.resize(NestedLoopCount); 7424 Built.DependentCounters.resize(NestedLoopCount); 7425 Built.DependentInits.resize(NestedLoopCount); 7426 Built.FinalsConditions.resize(NestedLoopCount); 7427 { 7428 // We implement the following algorithm for obtaining the 7429 // original loop iteration variable values based on the 7430 // value of the collapsed loop iteration variable IV. 7431 // 7432 // Let n+1 be the number of collapsed loops in the nest. 7433 // Iteration variables (I0, I1, .... In) 7434 // Iteration counts (N0, N1, ... Nn) 7435 // 7436 // Acc = IV; 7437 // 7438 // To compute Ik for loop k, 0 <= k <= n, generate: 7439 // Prod = N(k+1) * N(k+2) * ... * Nn; 7440 // Ik = Acc / Prod; 7441 // Acc -= Ik * Prod; 7442 // 7443 ExprResult Acc = IV; 7444 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7445 LoopIterationSpace &IS = IterSpaces[Cnt]; 7446 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7447 ExprResult Iter; 7448 7449 // Compute prod 7450 ExprResult Prod = 7451 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7452 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7453 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7454 IterSpaces[K].NumIterations); 7455 7456 // Iter = Acc / Prod 7457 // If there is at least one more inner loop to avoid 7458 // multiplication by 1. 7459 if (Cnt + 1 < NestedLoopCount) 7460 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7461 Acc.get(), Prod.get()); 7462 else 7463 Iter = Acc; 7464 if (!Iter.isUsable()) { 7465 HasErrors = true; 7466 break; 7467 } 7468 7469 // Update Acc: 7470 // Acc -= Iter * Prod 7471 // Check if there is at least one more inner loop to avoid 7472 // multiplication by 1. 7473 if (Cnt + 1 < NestedLoopCount) 7474 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7475 Iter.get(), Prod.get()); 7476 else 7477 Prod = Iter; 7478 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7479 Acc.get(), Prod.get()); 7480 7481 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7482 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7483 DeclRefExpr *CounterVar = buildDeclRefExpr( 7484 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7485 /*RefersToCapture=*/true); 7486 ExprResult Init = 7487 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7488 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7489 if (!Init.isUsable()) { 7490 HasErrors = true; 7491 break; 7492 } 7493 ExprResult Update = buildCounterUpdate( 7494 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7495 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7496 if (!Update.isUsable()) { 7497 HasErrors = true; 7498 break; 7499 } 7500 7501 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7502 ExprResult Final = 7503 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7504 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7505 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7506 if (!Final.isUsable()) { 7507 HasErrors = true; 7508 break; 7509 } 7510 7511 if (!Update.isUsable() || !Final.isUsable()) { 7512 HasErrors = true; 7513 break; 7514 } 7515 // Save results 7516 Built.Counters[Cnt] = IS.CounterVar; 7517 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7518 Built.Inits[Cnt] = Init.get(); 7519 Built.Updates[Cnt] = Update.get(); 7520 Built.Finals[Cnt] = Final.get(); 7521 Built.DependentCounters[Cnt] = nullptr; 7522 Built.DependentInits[Cnt] = nullptr; 7523 Built.FinalsConditions[Cnt] = nullptr; 7524 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7525 Built.DependentCounters[Cnt] = 7526 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7527 Built.DependentInits[Cnt] = 7528 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7529 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7530 } 7531 } 7532 } 7533 7534 if (HasErrors) 7535 return 0; 7536 7537 // Save results 7538 Built.IterationVarRef = IV.get(); 7539 Built.LastIteration = LastIteration.get(); 7540 Built.NumIterations = NumIterations.get(); 7541 Built.CalcLastIteration = SemaRef 7542 .ActOnFinishFullExpr(CalcLastIteration.get(), 7543 /*DiscardedValue=*/false) 7544 .get(); 7545 Built.PreCond = PreCond.get(); 7546 Built.PreInits = buildPreInits(C, Captures); 7547 Built.Cond = Cond.get(); 7548 Built.Init = Init.get(); 7549 Built.Inc = Inc.get(); 7550 Built.LB = LB.get(); 7551 Built.UB = UB.get(); 7552 Built.IL = IL.get(); 7553 Built.ST = ST.get(); 7554 Built.EUB = EUB.get(); 7555 Built.NLB = NextLB.get(); 7556 Built.NUB = NextUB.get(); 7557 Built.PrevLB = PrevLB.get(); 7558 Built.PrevUB = PrevUB.get(); 7559 Built.DistInc = DistInc.get(); 7560 Built.PrevEUB = PrevEUB.get(); 7561 Built.DistCombinedFields.LB = CombLB.get(); 7562 Built.DistCombinedFields.UB = CombUB.get(); 7563 Built.DistCombinedFields.EUB = CombEUB.get(); 7564 Built.DistCombinedFields.Init = CombInit.get(); 7565 Built.DistCombinedFields.Cond = CombCond.get(); 7566 Built.DistCombinedFields.NLB = CombNextLB.get(); 7567 Built.DistCombinedFields.NUB = CombNextUB.get(); 7568 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7569 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7570 7571 return NestedLoopCount; 7572 } 7573 7574 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7575 auto CollapseClauses = 7576 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7577 if (CollapseClauses.begin() != CollapseClauses.end()) 7578 return (*CollapseClauses.begin())->getNumForLoops(); 7579 return nullptr; 7580 } 7581 7582 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7583 auto OrderedClauses = 7584 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7585 if (OrderedClauses.begin() != OrderedClauses.end()) 7586 return (*OrderedClauses.begin())->getNumForLoops(); 7587 return nullptr; 7588 } 7589 7590 static bool checkSimdlenSafelenSpecified(Sema &S, 7591 const ArrayRef<OMPClause *> Clauses) { 7592 const OMPSafelenClause *Safelen = nullptr; 7593 const OMPSimdlenClause *Simdlen = nullptr; 7594 7595 for (const OMPClause *Clause : Clauses) { 7596 if (Clause->getClauseKind() == OMPC_safelen) 7597 Safelen = cast<OMPSafelenClause>(Clause); 7598 else if (Clause->getClauseKind() == OMPC_simdlen) 7599 Simdlen = cast<OMPSimdlenClause>(Clause); 7600 if (Safelen && Simdlen) 7601 break; 7602 } 7603 7604 if (Simdlen && Safelen) { 7605 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7606 const Expr *SafelenLength = Safelen->getSafelen(); 7607 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7608 SimdlenLength->isInstantiationDependent() || 7609 SimdlenLength->containsUnexpandedParameterPack()) 7610 return false; 7611 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7612 SafelenLength->isInstantiationDependent() || 7613 SafelenLength->containsUnexpandedParameterPack()) 7614 return false; 7615 Expr::EvalResult SimdlenResult, SafelenResult; 7616 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7617 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7618 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7619 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7620 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7621 // If both simdlen and safelen clauses are specified, the value of the 7622 // simdlen parameter must be less than or equal to the value of the safelen 7623 // parameter. 7624 if (SimdlenRes > SafelenRes) { 7625 S.Diag(SimdlenLength->getExprLoc(), 7626 diag::err_omp_wrong_simdlen_safelen_values) 7627 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7628 return true; 7629 } 7630 } 7631 return false; 7632 } 7633 7634 StmtResult 7635 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7636 SourceLocation StartLoc, SourceLocation EndLoc, 7637 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7638 if (!AStmt) 7639 return StmtError(); 7640 7641 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7642 OMPLoopDirective::HelperExprs B; 7643 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7644 // define the nested loops number. 7645 unsigned NestedLoopCount = checkOpenMPLoop( 7646 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7647 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7648 if (NestedLoopCount == 0) 7649 return StmtError(); 7650 7651 assert((CurContext->isDependentContext() || B.builtAll()) && 7652 "omp simd loop exprs were not built"); 7653 7654 if (!CurContext->isDependentContext()) { 7655 // Finalize the clauses that need pre-built expressions for CodeGen. 7656 for (OMPClause *C : Clauses) { 7657 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7658 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7659 B.NumIterations, *this, CurScope, 7660 DSAStack)) 7661 return StmtError(); 7662 } 7663 } 7664 7665 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7666 return StmtError(); 7667 7668 setFunctionHasBranchProtectedScope(); 7669 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7670 Clauses, AStmt, B); 7671 } 7672 7673 StmtResult 7674 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7675 SourceLocation StartLoc, SourceLocation EndLoc, 7676 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7677 if (!AStmt) 7678 return StmtError(); 7679 7680 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7681 OMPLoopDirective::HelperExprs B; 7682 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7683 // define the nested loops number. 7684 unsigned NestedLoopCount = checkOpenMPLoop( 7685 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7686 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7687 if (NestedLoopCount == 0) 7688 return StmtError(); 7689 7690 assert((CurContext->isDependentContext() || B.builtAll()) && 7691 "omp for loop exprs were not built"); 7692 7693 if (!CurContext->isDependentContext()) { 7694 // Finalize the clauses that need pre-built expressions for CodeGen. 7695 for (OMPClause *C : Clauses) { 7696 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7697 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7698 B.NumIterations, *this, CurScope, 7699 DSAStack)) 7700 return StmtError(); 7701 } 7702 } 7703 7704 setFunctionHasBranchProtectedScope(); 7705 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7706 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7707 } 7708 7709 StmtResult Sema::ActOnOpenMPForSimdDirective( 7710 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7711 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7712 if (!AStmt) 7713 return StmtError(); 7714 7715 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7716 OMPLoopDirective::HelperExprs B; 7717 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7718 // define the nested loops number. 7719 unsigned NestedLoopCount = 7720 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7721 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7722 VarsWithImplicitDSA, B); 7723 if (NestedLoopCount == 0) 7724 return StmtError(); 7725 7726 assert((CurContext->isDependentContext() || B.builtAll()) && 7727 "omp for simd loop exprs were not built"); 7728 7729 if (!CurContext->isDependentContext()) { 7730 // Finalize the clauses that need pre-built expressions for CodeGen. 7731 for (OMPClause *C : Clauses) { 7732 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7733 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7734 B.NumIterations, *this, CurScope, 7735 DSAStack)) 7736 return StmtError(); 7737 } 7738 } 7739 7740 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7741 return StmtError(); 7742 7743 setFunctionHasBranchProtectedScope(); 7744 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7745 Clauses, AStmt, B); 7746 } 7747 7748 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7749 Stmt *AStmt, 7750 SourceLocation StartLoc, 7751 SourceLocation EndLoc) { 7752 if (!AStmt) 7753 return StmtError(); 7754 7755 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7756 auto BaseStmt = AStmt; 7757 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7758 BaseStmt = CS->getCapturedStmt(); 7759 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7760 auto S = C->children(); 7761 if (S.begin() == S.end()) 7762 return StmtError(); 7763 // All associated statements must be '#pragma omp section' except for 7764 // the first one. 7765 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7766 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7767 if (SectionStmt) 7768 Diag(SectionStmt->getBeginLoc(), 7769 diag::err_omp_sections_substmt_not_section); 7770 return StmtError(); 7771 } 7772 cast<OMPSectionDirective>(SectionStmt) 7773 ->setHasCancel(DSAStack->isCancelRegion()); 7774 } 7775 } else { 7776 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7777 return StmtError(); 7778 } 7779 7780 setFunctionHasBranchProtectedScope(); 7781 7782 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7783 DSAStack->isCancelRegion()); 7784 } 7785 7786 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7787 SourceLocation StartLoc, 7788 SourceLocation EndLoc) { 7789 if (!AStmt) 7790 return StmtError(); 7791 7792 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7793 7794 setFunctionHasBranchProtectedScope(); 7795 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7796 7797 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7798 DSAStack->isCancelRegion()); 7799 } 7800 7801 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7802 Stmt *AStmt, 7803 SourceLocation StartLoc, 7804 SourceLocation EndLoc) { 7805 if (!AStmt) 7806 return StmtError(); 7807 7808 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7809 7810 setFunctionHasBranchProtectedScope(); 7811 7812 // OpenMP [2.7.3, single Construct, Restrictions] 7813 // The copyprivate clause must not be used with the nowait clause. 7814 const OMPClause *Nowait = nullptr; 7815 const OMPClause *Copyprivate = nullptr; 7816 for (const OMPClause *Clause : Clauses) { 7817 if (Clause->getClauseKind() == OMPC_nowait) 7818 Nowait = Clause; 7819 else if (Clause->getClauseKind() == OMPC_copyprivate) 7820 Copyprivate = Clause; 7821 if (Copyprivate && Nowait) { 7822 Diag(Copyprivate->getBeginLoc(), 7823 diag::err_omp_single_copyprivate_with_nowait); 7824 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7825 return StmtError(); 7826 } 7827 } 7828 7829 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7830 } 7831 7832 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7833 SourceLocation StartLoc, 7834 SourceLocation EndLoc) { 7835 if (!AStmt) 7836 return StmtError(); 7837 7838 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7839 7840 setFunctionHasBranchProtectedScope(); 7841 7842 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7843 } 7844 7845 StmtResult Sema::ActOnOpenMPCriticalDirective( 7846 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7847 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7848 if (!AStmt) 7849 return StmtError(); 7850 7851 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7852 7853 bool ErrorFound = false; 7854 llvm::APSInt Hint; 7855 SourceLocation HintLoc; 7856 bool DependentHint = false; 7857 for (const OMPClause *C : Clauses) { 7858 if (C->getClauseKind() == OMPC_hint) { 7859 if (!DirName.getName()) { 7860 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7861 ErrorFound = true; 7862 } 7863 Expr *E = cast<OMPHintClause>(C)->getHint(); 7864 if (E->isTypeDependent() || E->isValueDependent() || 7865 E->isInstantiationDependent()) { 7866 DependentHint = true; 7867 } else { 7868 Hint = E->EvaluateKnownConstInt(Context); 7869 HintLoc = C->getBeginLoc(); 7870 } 7871 } 7872 } 7873 if (ErrorFound) 7874 return StmtError(); 7875 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7876 if (Pair.first && DirName.getName() && !DependentHint) { 7877 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7878 Diag(StartLoc, diag::err_omp_critical_with_hint); 7879 if (HintLoc.isValid()) 7880 Diag(HintLoc, diag::note_omp_critical_hint_here) 7881 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7882 else 7883 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7884 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7885 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7886 << 1 7887 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7888 /*Radix=*/10, /*Signed=*/false); 7889 } else { 7890 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7891 } 7892 } 7893 } 7894 7895 setFunctionHasBranchProtectedScope(); 7896 7897 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7898 Clauses, AStmt); 7899 if (!Pair.first && DirName.getName() && !DependentHint) 7900 DSAStack->addCriticalWithHint(Dir, Hint); 7901 return Dir; 7902 } 7903 7904 StmtResult Sema::ActOnOpenMPParallelForDirective( 7905 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7906 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7907 if (!AStmt) 7908 return StmtError(); 7909 7910 auto *CS = cast<CapturedStmt>(AStmt); 7911 // 1.2.2 OpenMP Language Terminology 7912 // Structured block - An executable statement with a single entry at the 7913 // top and a single exit at the bottom. 7914 // The point of exit cannot be a branch out of the structured block. 7915 // longjmp() and throw() must not violate the entry/exit criteria. 7916 CS->getCapturedDecl()->setNothrow(); 7917 7918 OMPLoopDirective::HelperExprs B; 7919 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7920 // define the nested loops number. 7921 unsigned NestedLoopCount = 7922 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7923 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7924 VarsWithImplicitDSA, B); 7925 if (NestedLoopCount == 0) 7926 return StmtError(); 7927 7928 assert((CurContext->isDependentContext() || B.builtAll()) && 7929 "omp parallel for loop exprs were not built"); 7930 7931 if (!CurContext->isDependentContext()) { 7932 // Finalize the clauses that need pre-built expressions for CodeGen. 7933 for (OMPClause *C : Clauses) { 7934 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7935 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7936 B.NumIterations, *this, CurScope, 7937 DSAStack)) 7938 return StmtError(); 7939 } 7940 } 7941 7942 setFunctionHasBranchProtectedScope(); 7943 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7944 NestedLoopCount, Clauses, AStmt, B, 7945 DSAStack->isCancelRegion()); 7946 } 7947 7948 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7949 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7950 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7951 if (!AStmt) 7952 return StmtError(); 7953 7954 auto *CS = cast<CapturedStmt>(AStmt); 7955 // 1.2.2 OpenMP Language Terminology 7956 // Structured block - An executable statement with a single entry at the 7957 // top and a single exit at the bottom. 7958 // The point of exit cannot be a branch out of the structured block. 7959 // longjmp() and throw() must not violate the entry/exit criteria. 7960 CS->getCapturedDecl()->setNothrow(); 7961 7962 OMPLoopDirective::HelperExprs B; 7963 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7964 // define the nested loops number. 7965 unsigned NestedLoopCount = 7966 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7967 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7968 VarsWithImplicitDSA, B); 7969 if (NestedLoopCount == 0) 7970 return StmtError(); 7971 7972 if (!CurContext->isDependentContext()) { 7973 // Finalize the clauses that need pre-built expressions for CodeGen. 7974 for (OMPClause *C : Clauses) { 7975 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7976 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7977 B.NumIterations, *this, CurScope, 7978 DSAStack)) 7979 return StmtError(); 7980 } 7981 } 7982 7983 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7984 return StmtError(); 7985 7986 setFunctionHasBranchProtectedScope(); 7987 return OMPParallelForSimdDirective::Create( 7988 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7989 } 7990 7991 StmtResult 7992 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7993 Stmt *AStmt, SourceLocation StartLoc, 7994 SourceLocation EndLoc) { 7995 if (!AStmt) 7996 return StmtError(); 7997 7998 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7999 auto BaseStmt = AStmt; 8000 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8001 BaseStmt = CS->getCapturedStmt(); 8002 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8003 auto S = C->children(); 8004 if (S.begin() == S.end()) 8005 return StmtError(); 8006 // All associated statements must be '#pragma omp section' except for 8007 // the first one. 8008 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8009 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8010 if (SectionStmt) 8011 Diag(SectionStmt->getBeginLoc(), 8012 diag::err_omp_parallel_sections_substmt_not_section); 8013 return StmtError(); 8014 } 8015 cast<OMPSectionDirective>(SectionStmt) 8016 ->setHasCancel(DSAStack->isCancelRegion()); 8017 } 8018 } else { 8019 Diag(AStmt->getBeginLoc(), 8020 diag::err_omp_parallel_sections_not_compound_stmt); 8021 return StmtError(); 8022 } 8023 8024 setFunctionHasBranchProtectedScope(); 8025 8026 return OMPParallelSectionsDirective::Create( 8027 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8028 } 8029 8030 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8031 Stmt *AStmt, SourceLocation StartLoc, 8032 SourceLocation EndLoc) { 8033 if (!AStmt) 8034 return StmtError(); 8035 8036 auto *CS = cast<CapturedStmt>(AStmt); 8037 // 1.2.2 OpenMP Language Terminology 8038 // Structured block - An executable statement with a single entry at the 8039 // top and a single exit at the bottom. 8040 // The point of exit cannot be a branch out of the structured block. 8041 // longjmp() and throw() must not violate the entry/exit criteria. 8042 CS->getCapturedDecl()->setNothrow(); 8043 8044 setFunctionHasBranchProtectedScope(); 8045 8046 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8047 DSAStack->isCancelRegion()); 8048 } 8049 8050 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8051 SourceLocation EndLoc) { 8052 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8053 } 8054 8055 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8056 SourceLocation EndLoc) { 8057 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8058 } 8059 8060 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8061 SourceLocation EndLoc) { 8062 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8063 } 8064 8065 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8066 Stmt *AStmt, 8067 SourceLocation StartLoc, 8068 SourceLocation EndLoc) { 8069 if (!AStmt) 8070 return StmtError(); 8071 8072 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8073 8074 setFunctionHasBranchProtectedScope(); 8075 8076 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8077 AStmt, 8078 DSAStack->getTaskgroupReductionRef()); 8079 } 8080 8081 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8082 SourceLocation StartLoc, 8083 SourceLocation EndLoc) { 8084 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8085 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8086 } 8087 8088 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8089 Stmt *AStmt, 8090 SourceLocation StartLoc, 8091 SourceLocation EndLoc) { 8092 const OMPClause *DependFound = nullptr; 8093 const OMPClause *DependSourceClause = nullptr; 8094 const OMPClause *DependSinkClause = nullptr; 8095 bool ErrorFound = false; 8096 const OMPThreadsClause *TC = nullptr; 8097 const OMPSIMDClause *SC = nullptr; 8098 for (const OMPClause *C : Clauses) { 8099 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8100 DependFound = C; 8101 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8102 if (DependSourceClause) { 8103 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8104 << getOpenMPDirectiveName(OMPD_ordered) 8105 << getOpenMPClauseName(OMPC_depend) << 2; 8106 ErrorFound = true; 8107 } else { 8108 DependSourceClause = C; 8109 } 8110 if (DependSinkClause) { 8111 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8112 << 0; 8113 ErrorFound = true; 8114 } 8115 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8116 if (DependSourceClause) { 8117 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8118 << 1; 8119 ErrorFound = true; 8120 } 8121 DependSinkClause = C; 8122 } 8123 } else if (C->getClauseKind() == OMPC_threads) { 8124 TC = cast<OMPThreadsClause>(C); 8125 } else if (C->getClauseKind() == OMPC_simd) { 8126 SC = cast<OMPSIMDClause>(C); 8127 } 8128 } 8129 if (!ErrorFound && !SC && 8130 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8131 // OpenMP [2.8.1,simd Construct, Restrictions] 8132 // An ordered construct with the simd clause is the only OpenMP construct 8133 // that can appear in the simd region. 8134 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 8135 ErrorFound = true; 8136 } else if (DependFound && (TC || SC)) { 8137 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8138 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8139 ErrorFound = true; 8140 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8141 Diag(DependFound->getBeginLoc(), 8142 diag::err_omp_ordered_directive_without_param); 8143 ErrorFound = true; 8144 } else if (TC || Clauses.empty()) { 8145 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8146 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8147 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8148 << (TC != nullptr); 8149 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8150 ErrorFound = true; 8151 } 8152 } 8153 if ((!AStmt && !DependFound) || ErrorFound) 8154 return StmtError(); 8155 8156 if (AStmt) { 8157 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8158 8159 setFunctionHasBranchProtectedScope(); 8160 } 8161 8162 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8163 } 8164 8165 namespace { 8166 /// Helper class for checking expression in 'omp atomic [update]' 8167 /// construct. 8168 class OpenMPAtomicUpdateChecker { 8169 /// Error results for atomic update expressions. 8170 enum ExprAnalysisErrorCode { 8171 /// A statement is not an expression statement. 8172 NotAnExpression, 8173 /// Expression is not builtin binary or unary operation. 8174 NotABinaryOrUnaryExpression, 8175 /// Unary operation is not post-/pre- increment/decrement operation. 8176 NotAnUnaryIncDecExpression, 8177 /// An expression is not of scalar type. 8178 NotAScalarType, 8179 /// A binary operation is not an assignment operation. 8180 NotAnAssignmentOp, 8181 /// RHS part of the binary operation is not a binary expression. 8182 NotABinaryExpression, 8183 /// RHS part is not additive/multiplicative/shift/biwise binary 8184 /// expression. 8185 NotABinaryOperator, 8186 /// RHS binary operation does not have reference to the updated LHS 8187 /// part. 8188 NotAnUpdateExpression, 8189 /// No errors is found. 8190 NoError 8191 }; 8192 /// Reference to Sema. 8193 Sema &SemaRef; 8194 /// A location for note diagnostics (when error is found). 8195 SourceLocation NoteLoc; 8196 /// 'x' lvalue part of the source atomic expression. 8197 Expr *X; 8198 /// 'expr' rvalue part of the source atomic expression. 8199 Expr *E; 8200 /// Helper expression of the form 8201 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8202 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8203 Expr *UpdateExpr; 8204 /// Is 'x' a LHS in a RHS part of full update expression. It is 8205 /// important for non-associative operations. 8206 bool IsXLHSInRHSPart; 8207 BinaryOperatorKind Op; 8208 SourceLocation OpLoc; 8209 /// true if the source expression is a postfix unary operation, false 8210 /// if it is a prefix unary operation. 8211 bool IsPostfixUpdate; 8212 8213 public: 8214 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8215 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8216 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8217 /// Check specified statement that it is suitable for 'atomic update' 8218 /// constructs and extract 'x', 'expr' and Operation from the original 8219 /// expression. If DiagId and NoteId == 0, then only check is performed 8220 /// without error notification. 8221 /// \param DiagId Diagnostic which should be emitted if error is found. 8222 /// \param NoteId Diagnostic note for the main error message. 8223 /// \return true if statement is not an update expression, false otherwise. 8224 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8225 /// Return the 'x' lvalue part of the source atomic expression. 8226 Expr *getX() const { return X; } 8227 /// Return the 'expr' rvalue part of the source atomic expression. 8228 Expr *getExpr() const { return E; } 8229 /// Return the update expression used in calculation of the updated 8230 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8231 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8232 Expr *getUpdateExpr() const { return UpdateExpr; } 8233 /// Return true if 'x' is LHS in RHS part of full update expression, 8234 /// false otherwise. 8235 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8236 8237 /// true if the source expression is a postfix unary operation, false 8238 /// if it is a prefix unary operation. 8239 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8240 8241 private: 8242 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8243 unsigned NoteId = 0); 8244 }; 8245 } // namespace 8246 8247 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8248 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8249 ExprAnalysisErrorCode ErrorFound = NoError; 8250 SourceLocation ErrorLoc, NoteLoc; 8251 SourceRange ErrorRange, NoteRange; 8252 // Allowed constructs are: 8253 // x = x binop expr; 8254 // x = expr binop x; 8255 if (AtomicBinOp->getOpcode() == BO_Assign) { 8256 X = AtomicBinOp->getLHS(); 8257 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8258 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8259 if (AtomicInnerBinOp->isMultiplicativeOp() || 8260 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8261 AtomicInnerBinOp->isBitwiseOp()) { 8262 Op = AtomicInnerBinOp->getOpcode(); 8263 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8264 Expr *LHS = AtomicInnerBinOp->getLHS(); 8265 Expr *RHS = AtomicInnerBinOp->getRHS(); 8266 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8267 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8268 /*Canonical=*/true); 8269 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8270 /*Canonical=*/true); 8271 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8272 /*Canonical=*/true); 8273 if (XId == LHSId) { 8274 E = RHS; 8275 IsXLHSInRHSPart = true; 8276 } else if (XId == RHSId) { 8277 E = LHS; 8278 IsXLHSInRHSPart = false; 8279 } else { 8280 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8281 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8282 NoteLoc = X->getExprLoc(); 8283 NoteRange = X->getSourceRange(); 8284 ErrorFound = NotAnUpdateExpression; 8285 } 8286 } else { 8287 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8288 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8289 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8290 NoteRange = SourceRange(NoteLoc, NoteLoc); 8291 ErrorFound = NotABinaryOperator; 8292 } 8293 } else { 8294 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8295 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8296 ErrorFound = NotABinaryExpression; 8297 } 8298 } else { 8299 ErrorLoc = AtomicBinOp->getExprLoc(); 8300 ErrorRange = AtomicBinOp->getSourceRange(); 8301 NoteLoc = AtomicBinOp->getOperatorLoc(); 8302 NoteRange = SourceRange(NoteLoc, NoteLoc); 8303 ErrorFound = NotAnAssignmentOp; 8304 } 8305 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8306 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8307 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8308 return true; 8309 } 8310 if (SemaRef.CurContext->isDependentContext()) 8311 E = X = UpdateExpr = nullptr; 8312 return ErrorFound != NoError; 8313 } 8314 8315 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8316 unsigned NoteId) { 8317 ExprAnalysisErrorCode ErrorFound = NoError; 8318 SourceLocation ErrorLoc, NoteLoc; 8319 SourceRange ErrorRange, NoteRange; 8320 // Allowed constructs are: 8321 // x++; 8322 // x--; 8323 // ++x; 8324 // --x; 8325 // x binop= expr; 8326 // x = x binop expr; 8327 // x = expr binop x; 8328 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8329 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8330 if (AtomicBody->getType()->isScalarType() || 8331 AtomicBody->isInstantiationDependent()) { 8332 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8333 AtomicBody->IgnoreParenImpCasts())) { 8334 // Check for Compound Assignment Operation 8335 Op = BinaryOperator::getOpForCompoundAssignment( 8336 AtomicCompAssignOp->getOpcode()); 8337 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8338 E = AtomicCompAssignOp->getRHS(); 8339 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8340 IsXLHSInRHSPart = true; 8341 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8342 AtomicBody->IgnoreParenImpCasts())) { 8343 // Check for Binary Operation 8344 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8345 return true; 8346 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8347 AtomicBody->IgnoreParenImpCasts())) { 8348 // Check for Unary Operation 8349 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8350 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8351 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8352 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8353 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8354 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8355 IsXLHSInRHSPart = true; 8356 } else { 8357 ErrorFound = NotAnUnaryIncDecExpression; 8358 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8359 ErrorRange = AtomicUnaryOp->getSourceRange(); 8360 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8361 NoteRange = SourceRange(NoteLoc, NoteLoc); 8362 } 8363 } else if (!AtomicBody->isInstantiationDependent()) { 8364 ErrorFound = NotABinaryOrUnaryExpression; 8365 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8366 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8367 } 8368 } else { 8369 ErrorFound = NotAScalarType; 8370 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8371 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8372 } 8373 } else { 8374 ErrorFound = NotAnExpression; 8375 NoteLoc = ErrorLoc = S->getBeginLoc(); 8376 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8377 } 8378 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8379 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8380 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8381 return true; 8382 } 8383 if (SemaRef.CurContext->isDependentContext()) 8384 E = X = UpdateExpr = nullptr; 8385 if (ErrorFound == NoError && E && X) { 8386 // Build an update expression of form 'OpaqueValueExpr(x) binop 8387 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8388 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8389 auto *OVEX = new (SemaRef.getASTContext()) 8390 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8391 auto *OVEExpr = new (SemaRef.getASTContext()) 8392 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8393 ExprResult Update = 8394 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8395 IsXLHSInRHSPart ? OVEExpr : OVEX); 8396 if (Update.isInvalid()) 8397 return true; 8398 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8399 Sema::AA_Casting); 8400 if (Update.isInvalid()) 8401 return true; 8402 UpdateExpr = Update.get(); 8403 } 8404 return ErrorFound != NoError; 8405 } 8406 8407 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8408 Stmt *AStmt, 8409 SourceLocation StartLoc, 8410 SourceLocation EndLoc) { 8411 if (!AStmt) 8412 return StmtError(); 8413 8414 auto *CS = cast<CapturedStmt>(AStmt); 8415 // 1.2.2 OpenMP Language Terminology 8416 // Structured block - An executable statement with a single entry at the 8417 // top and a single exit at the bottom. 8418 // The point of exit cannot be a branch out of the structured block. 8419 // longjmp() and throw() must not violate the entry/exit criteria. 8420 OpenMPClauseKind AtomicKind = OMPC_unknown; 8421 SourceLocation AtomicKindLoc; 8422 for (const OMPClause *C : Clauses) { 8423 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8424 C->getClauseKind() == OMPC_update || 8425 C->getClauseKind() == OMPC_capture) { 8426 if (AtomicKind != OMPC_unknown) { 8427 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8428 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8429 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8430 << getOpenMPClauseName(AtomicKind); 8431 } else { 8432 AtomicKind = C->getClauseKind(); 8433 AtomicKindLoc = C->getBeginLoc(); 8434 } 8435 } 8436 } 8437 8438 Stmt *Body = CS->getCapturedStmt(); 8439 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8440 Body = EWC->getSubExpr(); 8441 8442 Expr *X = nullptr; 8443 Expr *V = nullptr; 8444 Expr *E = nullptr; 8445 Expr *UE = nullptr; 8446 bool IsXLHSInRHSPart = false; 8447 bool IsPostfixUpdate = false; 8448 // OpenMP [2.12.6, atomic Construct] 8449 // In the next expressions: 8450 // * x and v (as applicable) are both l-value expressions with scalar type. 8451 // * During the execution of an atomic region, multiple syntactic 8452 // occurrences of x must designate the same storage location. 8453 // * Neither of v and expr (as applicable) may access the storage location 8454 // designated by x. 8455 // * Neither of x and expr (as applicable) may access the storage location 8456 // designated by v. 8457 // * expr is an expression with scalar type. 8458 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8459 // * binop, binop=, ++, and -- are not overloaded operators. 8460 // * The expression x binop expr must be numerically equivalent to x binop 8461 // (expr). This requirement is satisfied if the operators in expr have 8462 // precedence greater than binop, or by using parentheses around expr or 8463 // subexpressions of expr. 8464 // * The expression expr binop x must be numerically equivalent to (expr) 8465 // binop x. This requirement is satisfied if the operators in expr have 8466 // precedence equal to or greater than binop, or by using parentheses around 8467 // expr or subexpressions of expr. 8468 // * For forms that allow multiple occurrences of x, the number of times 8469 // that x is evaluated is unspecified. 8470 if (AtomicKind == OMPC_read) { 8471 enum { 8472 NotAnExpression, 8473 NotAnAssignmentOp, 8474 NotAScalarType, 8475 NotAnLValue, 8476 NoError 8477 } ErrorFound = NoError; 8478 SourceLocation ErrorLoc, NoteLoc; 8479 SourceRange ErrorRange, NoteRange; 8480 // If clause is read: 8481 // v = x; 8482 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8483 const auto *AtomicBinOp = 8484 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8485 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8486 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8487 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8488 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8489 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8490 if (!X->isLValue() || !V->isLValue()) { 8491 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8492 ErrorFound = NotAnLValue; 8493 ErrorLoc = AtomicBinOp->getExprLoc(); 8494 ErrorRange = AtomicBinOp->getSourceRange(); 8495 NoteLoc = NotLValueExpr->getExprLoc(); 8496 NoteRange = NotLValueExpr->getSourceRange(); 8497 } 8498 } else if (!X->isInstantiationDependent() || 8499 !V->isInstantiationDependent()) { 8500 const Expr *NotScalarExpr = 8501 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8502 ? V 8503 : X; 8504 ErrorFound = NotAScalarType; 8505 ErrorLoc = AtomicBinOp->getExprLoc(); 8506 ErrorRange = AtomicBinOp->getSourceRange(); 8507 NoteLoc = NotScalarExpr->getExprLoc(); 8508 NoteRange = NotScalarExpr->getSourceRange(); 8509 } 8510 } else if (!AtomicBody->isInstantiationDependent()) { 8511 ErrorFound = NotAnAssignmentOp; 8512 ErrorLoc = AtomicBody->getExprLoc(); 8513 ErrorRange = AtomicBody->getSourceRange(); 8514 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8515 : AtomicBody->getExprLoc(); 8516 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8517 : AtomicBody->getSourceRange(); 8518 } 8519 } else { 8520 ErrorFound = NotAnExpression; 8521 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8522 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8523 } 8524 if (ErrorFound != NoError) { 8525 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8526 << ErrorRange; 8527 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8528 << NoteRange; 8529 return StmtError(); 8530 } 8531 if (CurContext->isDependentContext()) 8532 V = X = nullptr; 8533 } else if (AtomicKind == OMPC_write) { 8534 enum { 8535 NotAnExpression, 8536 NotAnAssignmentOp, 8537 NotAScalarType, 8538 NotAnLValue, 8539 NoError 8540 } ErrorFound = NoError; 8541 SourceLocation ErrorLoc, NoteLoc; 8542 SourceRange ErrorRange, NoteRange; 8543 // If clause is write: 8544 // x = expr; 8545 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8546 const auto *AtomicBinOp = 8547 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8548 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8549 X = AtomicBinOp->getLHS(); 8550 E = AtomicBinOp->getRHS(); 8551 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8552 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8553 if (!X->isLValue()) { 8554 ErrorFound = NotAnLValue; 8555 ErrorLoc = AtomicBinOp->getExprLoc(); 8556 ErrorRange = AtomicBinOp->getSourceRange(); 8557 NoteLoc = X->getExprLoc(); 8558 NoteRange = X->getSourceRange(); 8559 } 8560 } else if (!X->isInstantiationDependent() || 8561 !E->isInstantiationDependent()) { 8562 const Expr *NotScalarExpr = 8563 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8564 ? E 8565 : X; 8566 ErrorFound = NotAScalarType; 8567 ErrorLoc = AtomicBinOp->getExprLoc(); 8568 ErrorRange = AtomicBinOp->getSourceRange(); 8569 NoteLoc = NotScalarExpr->getExprLoc(); 8570 NoteRange = NotScalarExpr->getSourceRange(); 8571 } 8572 } else if (!AtomicBody->isInstantiationDependent()) { 8573 ErrorFound = NotAnAssignmentOp; 8574 ErrorLoc = AtomicBody->getExprLoc(); 8575 ErrorRange = AtomicBody->getSourceRange(); 8576 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8577 : AtomicBody->getExprLoc(); 8578 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8579 : AtomicBody->getSourceRange(); 8580 } 8581 } else { 8582 ErrorFound = NotAnExpression; 8583 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8584 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8585 } 8586 if (ErrorFound != NoError) { 8587 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8588 << ErrorRange; 8589 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8590 << NoteRange; 8591 return StmtError(); 8592 } 8593 if (CurContext->isDependentContext()) 8594 E = X = nullptr; 8595 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8596 // If clause is update: 8597 // x++; 8598 // x--; 8599 // ++x; 8600 // --x; 8601 // x binop= expr; 8602 // x = x binop expr; 8603 // x = expr binop x; 8604 OpenMPAtomicUpdateChecker Checker(*this); 8605 if (Checker.checkStatement( 8606 Body, (AtomicKind == OMPC_update) 8607 ? diag::err_omp_atomic_update_not_expression_statement 8608 : diag::err_omp_atomic_not_expression_statement, 8609 diag::note_omp_atomic_update)) 8610 return StmtError(); 8611 if (!CurContext->isDependentContext()) { 8612 E = Checker.getExpr(); 8613 X = Checker.getX(); 8614 UE = Checker.getUpdateExpr(); 8615 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8616 } 8617 } else if (AtomicKind == OMPC_capture) { 8618 enum { 8619 NotAnAssignmentOp, 8620 NotACompoundStatement, 8621 NotTwoSubstatements, 8622 NotASpecificExpression, 8623 NoError 8624 } ErrorFound = NoError; 8625 SourceLocation ErrorLoc, NoteLoc; 8626 SourceRange ErrorRange, NoteRange; 8627 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8628 // If clause is a capture: 8629 // v = x++; 8630 // v = x--; 8631 // v = ++x; 8632 // v = --x; 8633 // v = x binop= expr; 8634 // v = x = x binop expr; 8635 // v = x = expr binop x; 8636 const auto *AtomicBinOp = 8637 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8638 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8639 V = AtomicBinOp->getLHS(); 8640 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8641 OpenMPAtomicUpdateChecker Checker(*this); 8642 if (Checker.checkStatement( 8643 Body, diag::err_omp_atomic_capture_not_expression_statement, 8644 diag::note_omp_atomic_update)) 8645 return StmtError(); 8646 E = Checker.getExpr(); 8647 X = Checker.getX(); 8648 UE = Checker.getUpdateExpr(); 8649 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8650 IsPostfixUpdate = Checker.isPostfixUpdate(); 8651 } else if (!AtomicBody->isInstantiationDependent()) { 8652 ErrorLoc = AtomicBody->getExprLoc(); 8653 ErrorRange = AtomicBody->getSourceRange(); 8654 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8655 : AtomicBody->getExprLoc(); 8656 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8657 : AtomicBody->getSourceRange(); 8658 ErrorFound = NotAnAssignmentOp; 8659 } 8660 if (ErrorFound != NoError) { 8661 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8662 << ErrorRange; 8663 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8664 return StmtError(); 8665 } 8666 if (CurContext->isDependentContext()) 8667 UE = V = E = X = nullptr; 8668 } else { 8669 // If clause is a capture: 8670 // { v = x; x = expr; } 8671 // { v = x; x++; } 8672 // { v = x; x--; } 8673 // { v = x; ++x; } 8674 // { v = x; --x; } 8675 // { v = x; x binop= expr; } 8676 // { v = x; x = x binop expr; } 8677 // { v = x; x = expr binop x; } 8678 // { x++; v = x; } 8679 // { x--; v = x; } 8680 // { ++x; v = x; } 8681 // { --x; v = x; } 8682 // { x binop= expr; v = x; } 8683 // { x = x binop expr; v = x; } 8684 // { x = expr binop x; v = x; } 8685 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8686 // Check that this is { expr1; expr2; } 8687 if (CS->size() == 2) { 8688 Stmt *First = CS->body_front(); 8689 Stmt *Second = CS->body_back(); 8690 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8691 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8692 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8693 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8694 // Need to find what subexpression is 'v' and what is 'x'. 8695 OpenMPAtomicUpdateChecker Checker(*this); 8696 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8697 BinaryOperator *BinOp = nullptr; 8698 if (IsUpdateExprFound) { 8699 BinOp = dyn_cast<BinaryOperator>(First); 8700 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8701 } 8702 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8703 // { v = x; x++; } 8704 // { v = x; x--; } 8705 // { v = x; ++x; } 8706 // { v = x; --x; } 8707 // { v = x; x binop= expr; } 8708 // { v = x; x = x binop expr; } 8709 // { v = x; x = expr binop x; } 8710 // Check that the first expression has form v = x. 8711 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8712 llvm::FoldingSetNodeID XId, PossibleXId; 8713 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8714 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8715 IsUpdateExprFound = XId == PossibleXId; 8716 if (IsUpdateExprFound) { 8717 V = BinOp->getLHS(); 8718 X = Checker.getX(); 8719 E = Checker.getExpr(); 8720 UE = Checker.getUpdateExpr(); 8721 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8722 IsPostfixUpdate = true; 8723 } 8724 } 8725 if (!IsUpdateExprFound) { 8726 IsUpdateExprFound = !Checker.checkStatement(First); 8727 BinOp = nullptr; 8728 if (IsUpdateExprFound) { 8729 BinOp = dyn_cast<BinaryOperator>(Second); 8730 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8731 } 8732 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8733 // { x++; v = x; } 8734 // { x--; v = x; } 8735 // { ++x; v = x; } 8736 // { --x; v = x; } 8737 // { x binop= expr; v = x; } 8738 // { x = x binop expr; v = x; } 8739 // { x = expr binop x; v = x; } 8740 // Check that the second expression has form v = x. 8741 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8742 llvm::FoldingSetNodeID XId, PossibleXId; 8743 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8744 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8745 IsUpdateExprFound = XId == PossibleXId; 8746 if (IsUpdateExprFound) { 8747 V = BinOp->getLHS(); 8748 X = Checker.getX(); 8749 E = Checker.getExpr(); 8750 UE = Checker.getUpdateExpr(); 8751 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8752 IsPostfixUpdate = false; 8753 } 8754 } 8755 } 8756 if (!IsUpdateExprFound) { 8757 // { v = x; x = expr; } 8758 auto *FirstExpr = dyn_cast<Expr>(First); 8759 auto *SecondExpr = dyn_cast<Expr>(Second); 8760 if (!FirstExpr || !SecondExpr || 8761 !(FirstExpr->isInstantiationDependent() || 8762 SecondExpr->isInstantiationDependent())) { 8763 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8764 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8765 ErrorFound = NotAnAssignmentOp; 8766 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8767 : First->getBeginLoc(); 8768 NoteRange = ErrorRange = FirstBinOp 8769 ? FirstBinOp->getSourceRange() 8770 : SourceRange(ErrorLoc, ErrorLoc); 8771 } else { 8772 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8773 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8774 ErrorFound = NotAnAssignmentOp; 8775 NoteLoc = ErrorLoc = SecondBinOp 8776 ? SecondBinOp->getOperatorLoc() 8777 : Second->getBeginLoc(); 8778 NoteRange = ErrorRange = 8779 SecondBinOp ? SecondBinOp->getSourceRange() 8780 : SourceRange(ErrorLoc, ErrorLoc); 8781 } else { 8782 Expr *PossibleXRHSInFirst = 8783 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8784 Expr *PossibleXLHSInSecond = 8785 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8786 llvm::FoldingSetNodeID X1Id, X2Id; 8787 PossibleXRHSInFirst->Profile(X1Id, Context, 8788 /*Canonical=*/true); 8789 PossibleXLHSInSecond->Profile(X2Id, Context, 8790 /*Canonical=*/true); 8791 IsUpdateExprFound = X1Id == X2Id; 8792 if (IsUpdateExprFound) { 8793 V = FirstBinOp->getLHS(); 8794 X = SecondBinOp->getLHS(); 8795 E = SecondBinOp->getRHS(); 8796 UE = nullptr; 8797 IsXLHSInRHSPart = false; 8798 IsPostfixUpdate = true; 8799 } else { 8800 ErrorFound = NotASpecificExpression; 8801 ErrorLoc = FirstBinOp->getExprLoc(); 8802 ErrorRange = FirstBinOp->getSourceRange(); 8803 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8804 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8805 } 8806 } 8807 } 8808 } 8809 } 8810 } else { 8811 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8812 NoteRange = ErrorRange = 8813 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8814 ErrorFound = NotTwoSubstatements; 8815 } 8816 } else { 8817 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8818 NoteRange = ErrorRange = 8819 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8820 ErrorFound = NotACompoundStatement; 8821 } 8822 if (ErrorFound != NoError) { 8823 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8824 << ErrorRange; 8825 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8826 return StmtError(); 8827 } 8828 if (CurContext->isDependentContext()) 8829 UE = V = E = X = nullptr; 8830 } 8831 } 8832 8833 setFunctionHasBranchProtectedScope(); 8834 8835 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8836 X, V, E, UE, IsXLHSInRHSPart, 8837 IsPostfixUpdate); 8838 } 8839 8840 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8841 Stmt *AStmt, 8842 SourceLocation StartLoc, 8843 SourceLocation EndLoc) { 8844 if (!AStmt) 8845 return StmtError(); 8846 8847 auto *CS = cast<CapturedStmt>(AStmt); 8848 // 1.2.2 OpenMP Language Terminology 8849 // Structured block - An executable statement with a single entry at the 8850 // top and a single exit at the bottom. 8851 // The point of exit cannot be a branch out of the structured block. 8852 // longjmp() and throw() must not violate the entry/exit criteria. 8853 CS->getCapturedDecl()->setNothrow(); 8854 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8855 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8856 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8857 // 1.2.2 OpenMP Language Terminology 8858 // Structured block - An executable statement with a single entry at the 8859 // top and a single exit at the bottom. 8860 // The point of exit cannot be a branch out of the structured block. 8861 // longjmp() and throw() must not violate the entry/exit criteria. 8862 CS->getCapturedDecl()->setNothrow(); 8863 } 8864 8865 // OpenMP [2.16, Nesting of Regions] 8866 // If specified, a teams construct must be contained within a target 8867 // construct. That target construct must contain no statements or directives 8868 // outside of the teams construct. 8869 if (DSAStack->hasInnerTeamsRegion()) { 8870 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8871 bool OMPTeamsFound = true; 8872 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8873 auto I = CS->body_begin(); 8874 while (I != CS->body_end()) { 8875 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8876 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8877 OMPTeamsFound) { 8878 8879 OMPTeamsFound = false; 8880 break; 8881 } 8882 ++I; 8883 } 8884 assert(I != CS->body_end() && "Not found statement"); 8885 S = *I; 8886 } else { 8887 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8888 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8889 } 8890 if (!OMPTeamsFound) { 8891 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8892 Diag(DSAStack->getInnerTeamsRegionLoc(), 8893 diag::note_omp_nested_teams_construct_here); 8894 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8895 << isa<OMPExecutableDirective>(S); 8896 return StmtError(); 8897 } 8898 } 8899 8900 setFunctionHasBranchProtectedScope(); 8901 8902 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8903 } 8904 8905 StmtResult 8906 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8907 Stmt *AStmt, SourceLocation StartLoc, 8908 SourceLocation EndLoc) { 8909 if (!AStmt) 8910 return StmtError(); 8911 8912 auto *CS = cast<CapturedStmt>(AStmt); 8913 // 1.2.2 OpenMP Language Terminology 8914 // Structured block - An executable statement with a single entry at the 8915 // top and a single exit at the bottom. 8916 // The point of exit cannot be a branch out of the structured block. 8917 // longjmp() and throw() must not violate the entry/exit criteria. 8918 CS->getCapturedDecl()->setNothrow(); 8919 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8920 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8921 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8922 // 1.2.2 OpenMP Language Terminology 8923 // Structured block - An executable statement with a single entry at the 8924 // top and a single exit at the bottom. 8925 // The point of exit cannot be a branch out of the structured block. 8926 // longjmp() and throw() must not violate the entry/exit criteria. 8927 CS->getCapturedDecl()->setNothrow(); 8928 } 8929 8930 setFunctionHasBranchProtectedScope(); 8931 8932 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8933 AStmt); 8934 } 8935 8936 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8937 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8938 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8939 if (!AStmt) 8940 return StmtError(); 8941 8942 auto *CS = cast<CapturedStmt>(AStmt); 8943 // 1.2.2 OpenMP Language Terminology 8944 // Structured block - An executable statement with a single entry at the 8945 // top and a single exit at the bottom. 8946 // The point of exit cannot be a branch out of the structured block. 8947 // longjmp() and throw() must not violate the entry/exit criteria. 8948 CS->getCapturedDecl()->setNothrow(); 8949 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8950 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8951 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8952 // 1.2.2 OpenMP Language Terminology 8953 // Structured block - An executable statement with a single entry at the 8954 // top and a single exit at the bottom. 8955 // The point of exit cannot be a branch out of the structured block. 8956 // longjmp() and throw() must not violate the entry/exit criteria. 8957 CS->getCapturedDecl()->setNothrow(); 8958 } 8959 8960 OMPLoopDirective::HelperExprs B; 8961 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8962 // define the nested loops number. 8963 unsigned NestedLoopCount = 8964 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8965 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8966 VarsWithImplicitDSA, B); 8967 if (NestedLoopCount == 0) 8968 return StmtError(); 8969 8970 assert((CurContext->isDependentContext() || B.builtAll()) && 8971 "omp target parallel for loop exprs were not built"); 8972 8973 if (!CurContext->isDependentContext()) { 8974 // Finalize the clauses that need pre-built expressions for CodeGen. 8975 for (OMPClause *C : Clauses) { 8976 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8977 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8978 B.NumIterations, *this, CurScope, 8979 DSAStack)) 8980 return StmtError(); 8981 } 8982 } 8983 8984 setFunctionHasBranchProtectedScope(); 8985 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8986 NestedLoopCount, Clauses, AStmt, 8987 B, DSAStack->isCancelRegion()); 8988 } 8989 8990 /// Check for existence of a map clause in the list of clauses. 8991 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8992 const OpenMPClauseKind K) { 8993 return llvm::any_of( 8994 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8995 } 8996 8997 template <typename... Params> 8998 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8999 const Params... ClauseTypes) { 9000 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9001 } 9002 9003 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9004 Stmt *AStmt, 9005 SourceLocation StartLoc, 9006 SourceLocation EndLoc) { 9007 if (!AStmt) 9008 return StmtError(); 9009 9010 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9011 9012 // OpenMP [2.10.1, Restrictions, p. 97] 9013 // At least one map clause must appear on the directive. 9014 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9015 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9016 << "'map' or 'use_device_ptr'" 9017 << getOpenMPDirectiveName(OMPD_target_data); 9018 return StmtError(); 9019 } 9020 9021 setFunctionHasBranchProtectedScope(); 9022 9023 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9024 AStmt); 9025 } 9026 9027 StmtResult 9028 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9029 SourceLocation StartLoc, 9030 SourceLocation EndLoc, Stmt *AStmt) { 9031 if (!AStmt) 9032 return StmtError(); 9033 9034 auto *CS = cast<CapturedStmt>(AStmt); 9035 // 1.2.2 OpenMP Language Terminology 9036 // Structured block - An executable statement with a single entry at the 9037 // top and a single exit at the bottom. 9038 // The point of exit cannot be a branch out of the structured block. 9039 // longjmp() and throw() must not violate the entry/exit criteria. 9040 CS->getCapturedDecl()->setNothrow(); 9041 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9042 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9043 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9044 // 1.2.2 OpenMP Language Terminology 9045 // Structured block - An executable statement with a single entry at the 9046 // top and a single exit at the bottom. 9047 // The point of exit cannot be a branch out of the structured block. 9048 // longjmp() and throw() must not violate the entry/exit criteria. 9049 CS->getCapturedDecl()->setNothrow(); 9050 } 9051 9052 // OpenMP [2.10.2, Restrictions, p. 99] 9053 // At least one map clause must appear on the directive. 9054 if (!hasClauses(Clauses, OMPC_map)) { 9055 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9056 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9057 return StmtError(); 9058 } 9059 9060 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9061 AStmt); 9062 } 9063 9064 StmtResult 9065 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9066 SourceLocation StartLoc, 9067 SourceLocation EndLoc, Stmt *AStmt) { 9068 if (!AStmt) 9069 return StmtError(); 9070 9071 auto *CS = cast<CapturedStmt>(AStmt); 9072 // 1.2.2 OpenMP Language Terminology 9073 // Structured block - An executable statement with a single entry at the 9074 // top and a single exit at the bottom. 9075 // The point of exit cannot be a branch out of the structured block. 9076 // longjmp() and throw() must not violate the entry/exit criteria. 9077 CS->getCapturedDecl()->setNothrow(); 9078 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9079 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9080 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9081 // 1.2.2 OpenMP Language Terminology 9082 // Structured block - An executable statement with a single entry at the 9083 // top and a single exit at the bottom. 9084 // The point of exit cannot be a branch out of the structured block. 9085 // longjmp() and throw() must not violate the entry/exit criteria. 9086 CS->getCapturedDecl()->setNothrow(); 9087 } 9088 9089 // OpenMP [2.10.3, Restrictions, p. 102] 9090 // At least one map clause must appear on the directive. 9091 if (!hasClauses(Clauses, OMPC_map)) { 9092 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9093 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9094 return StmtError(); 9095 } 9096 9097 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9098 AStmt); 9099 } 9100 9101 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9102 SourceLocation StartLoc, 9103 SourceLocation EndLoc, 9104 Stmt *AStmt) { 9105 if (!AStmt) 9106 return StmtError(); 9107 9108 auto *CS = cast<CapturedStmt>(AStmt); 9109 // 1.2.2 OpenMP Language Terminology 9110 // Structured block - An executable statement with a single entry at the 9111 // top and a single exit at the bottom. 9112 // The point of exit cannot be a branch out of the structured block. 9113 // longjmp() and throw() must not violate the entry/exit criteria. 9114 CS->getCapturedDecl()->setNothrow(); 9115 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9116 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9117 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9118 // 1.2.2 OpenMP Language Terminology 9119 // Structured block - An executable statement with a single entry at the 9120 // top and a single exit at the bottom. 9121 // The point of exit cannot be a branch out of the structured block. 9122 // longjmp() and throw() must not violate the entry/exit criteria. 9123 CS->getCapturedDecl()->setNothrow(); 9124 } 9125 9126 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9127 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9128 return StmtError(); 9129 } 9130 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9131 AStmt); 9132 } 9133 9134 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9135 Stmt *AStmt, SourceLocation StartLoc, 9136 SourceLocation EndLoc) { 9137 if (!AStmt) 9138 return StmtError(); 9139 9140 auto *CS = cast<CapturedStmt>(AStmt); 9141 // 1.2.2 OpenMP Language Terminology 9142 // Structured block - An executable statement with a single entry at the 9143 // top and a single exit at the bottom. 9144 // The point of exit cannot be a branch out of the structured block. 9145 // longjmp() and throw() must not violate the entry/exit criteria. 9146 CS->getCapturedDecl()->setNothrow(); 9147 9148 setFunctionHasBranchProtectedScope(); 9149 9150 DSAStack->setParentTeamsRegionLoc(StartLoc); 9151 9152 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9153 } 9154 9155 StmtResult 9156 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9157 SourceLocation EndLoc, 9158 OpenMPDirectiveKind CancelRegion) { 9159 if (DSAStack->isParentNowaitRegion()) { 9160 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9161 return StmtError(); 9162 } 9163 if (DSAStack->isParentOrderedRegion()) { 9164 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9165 return StmtError(); 9166 } 9167 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9168 CancelRegion); 9169 } 9170 9171 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9172 SourceLocation StartLoc, 9173 SourceLocation EndLoc, 9174 OpenMPDirectiveKind CancelRegion) { 9175 if (DSAStack->isParentNowaitRegion()) { 9176 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9177 return StmtError(); 9178 } 9179 if (DSAStack->isParentOrderedRegion()) { 9180 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9181 return StmtError(); 9182 } 9183 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9184 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9185 CancelRegion); 9186 } 9187 9188 static bool checkGrainsizeNumTasksClauses(Sema &S, 9189 ArrayRef<OMPClause *> Clauses) { 9190 const OMPClause *PrevClause = nullptr; 9191 bool ErrorFound = false; 9192 for (const OMPClause *C : Clauses) { 9193 if (C->getClauseKind() == OMPC_grainsize || 9194 C->getClauseKind() == OMPC_num_tasks) { 9195 if (!PrevClause) 9196 PrevClause = C; 9197 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9198 S.Diag(C->getBeginLoc(), 9199 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9200 << getOpenMPClauseName(C->getClauseKind()) 9201 << getOpenMPClauseName(PrevClause->getClauseKind()); 9202 S.Diag(PrevClause->getBeginLoc(), 9203 diag::note_omp_previous_grainsize_num_tasks) 9204 << getOpenMPClauseName(PrevClause->getClauseKind()); 9205 ErrorFound = true; 9206 } 9207 } 9208 } 9209 return ErrorFound; 9210 } 9211 9212 static bool checkReductionClauseWithNogroup(Sema &S, 9213 ArrayRef<OMPClause *> Clauses) { 9214 const OMPClause *ReductionClause = nullptr; 9215 const OMPClause *NogroupClause = nullptr; 9216 for (const OMPClause *C : Clauses) { 9217 if (C->getClauseKind() == OMPC_reduction) { 9218 ReductionClause = C; 9219 if (NogroupClause) 9220 break; 9221 continue; 9222 } 9223 if (C->getClauseKind() == OMPC_nogroup) { 9224 NogroupClause = C; 9225 if (ReductionClause) 9226 break; 9227 continue; 9228 } 9229 } 9230 if (ReductionClause && NogroupClause) { 9231 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9232 << SourceRange(NogroupClause->getBeginLoc(), 9233 NogroupClause->getEndLoc()); 9234 return true; 9235 } 9236 return false; 9237 } 9238 9239 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9240 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9241 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9242 if (!AStmt) 9243 return StmtError(); 9244 9245 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9246 OMPLoopDirective::HelperExprs B; 9247 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9248 // define the nested loops number. 9249 unsigned NestedLoopCount = 9250 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9251 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9252 VarsWithImplicitDSA, B); 9253 if (NestedLoopCount == 0) 9254 return StmtError(); 9255 9256 assert((CurContext->isDependentContext() || B.builtAll()) && 9257 "omp for loop exprs were not built"); 9258 9259 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9260 // The grainsize clause and num_tasks clause are mutually exclusive and may 9261 // not appear on the same taskloop directive. 9262 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9263 return StmtError(); 9264 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9265 // If a reduction clause is present on the taskloop directive, the nogroup 9266 // clause must not be specified. 9267 if (checkReductionClauseWithNogroup(*this, Clauses)) 9268 return StmtError(); 9269 9270 setFunctionHasBranchProtectedScope(); 9271 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9272 NestedLoopCount, Clauses, AStmt, B); 9273 } 9274 9275 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9276 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9277 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9278 if (!AStmt) 9279 return StmtError(); 9280 9281 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9282 OMPLoopDirective::HelperExprs B; 9283 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9284 // define the nested loops number. 9285 unsigned NestedLoopCount = 9286 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9287 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9288 VarsWithImplicitDSA, B); 9289 if (NestedLoopCount == 0) 9290 return StmtError(); 9291 9292 assert((CurContext->isDependentContext() || B.builtAll()) && 9293 "omp for loop exprs were not built"); 9294 9295 if (!CurContext->isDependentContext()) { 9296 // Finalize the clauses that need pre-built expressions for CodeGen. 9297 for (OMPClause *C : Clauses) { 9298 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9299 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9300 B.NumIterations, *this, CurScope, 9301 DSAStack)) 9302 return StmtError(); 9303 } 9304 } 9305 9306 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9307 // The grainsize clause and num_tasks clause are mutually exclusive and may 9308 // not appear on the same taskloop directive. 9309 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9310 return StmtError(); 9311 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9312 // If a reduction clause is present on the taskloop directive, the nogroup 9313 // clause must not be specified. 9314 if (checkReductionClauseWithNogroup(*this, Clauses)) 9315 return StmtError(); 9316 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9317 return StmtError(); 9318 9319 setFunctionHasBranchProtectedScope(); 9320 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9321 NestedLoopCount, Clauses, AStmt, B); 9322 } 9323 9324 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9325 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9326 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9327 if (!AStmt) 9328 return StmtError(); 9329 9330 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9331 OMPLoopDirective::HelperExprs B; 9332 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9333 // define the nested loops number. 9334 unsigned NestedLoopCount = 9335 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9336 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9337 VarsWithImplicitDSA, B); 9338 if (NestedLoopCount == 0) 9339 return StmtError(); 9340 9341 assert((CurContext->isDependentContext() || B.builtAll()) && 9342 "omp for loop exprs were not built"); 9343 9344 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9345 // The grainsize clause and num_tasks clause are mutually exclusive and may 9346 // not appear on the same taskloop directive. 9347 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9348 return StmtError(); 9349 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9350 // If a reduction clause is present on the taskloop directive, the nogroup 9351 // clause must not be specified. 9352 if (checkReductionClauseWithNogroup(*this, Clauses)) 9353 return StmtError(); 9354 9355 setFunctionHasBranchProtectedScope(); 9356 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9357 NestedLoopCount, Clauses, AStmt, B); 9358 } 9359 9360 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9361 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9362 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9363 if (!AStmt) 9364 return StmtError(); 9365 9366 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9367 auto *CS = cast<CapturedStmt>(AStmt); 9368 // 1.2.2 OpenMP Language Terminology 9369 // Structured block - An executable statement with a single entry at the 9370 // top and a single exit at the bottom. 9371 // The point of exit cannot be a branch out of the structured block. 9372 // longjmp() and throw() must not violate the entry/exit criteria. 9373 CS->getCapturedDecl()->setNothrow(); 9374 for (int ThisCaptureLevel = 9375 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9376 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9377 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9378 // 1.2.2 OpenMP Language Terminology 9379 // Structured block - An executable statement with a single entry at the 9380 // top and a single exit at the bottom. 9381 // The point of exit cannot be a branch out of the structured block. 9382 // longjmp() and throw() must not violate the entry/exit criteria. 9383 CS->getCapturedDecl()->setNothrow(); 9384 } 9385 9386 OMPLoopDirective::HelperExprs B; 9387 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9388 // define the nested loops number. 9389 unsigned NestedLoopCount = checkOpenMPLoop( 9390 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9391 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9392 VarsWithImplicitDSA, B); 9393 if (NestedLoopCount == 0) 9394 return StmtError(); 9395 9396 assert((CurContext->isDependentContext() || B.builtAll()) && 9397 "omp for loop exprs were not built"); 9398 9399 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9400 // The grainsize clause and num_tasks clause are mutually exclusive and may 9401 // not appear on the same taskloop directive. 9402 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9403 return StmtError(); 9404 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9405 // If a reduction clause is present on the taskloop directive, the nogroup 9406 // clause must not be specified. 9407 if (checkReductionClauseWithNogroup(*this, Clauses)) 9408 return StmtError(); 9409 9410 setFunctionHasBranchProtectedScope(); 9411 return OMPParallelMasterTaskLoopDirective::Create( 9412 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9413 } 9414 9415 StmtResult Sema::ActOnOpenMPDistributeDirective( 9416 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9417 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9418 if (!AStmt) 9419 return StmtError(); 9420 9421 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9422 OMPLoopDirective::HelperExprs B; 9423 // In presence of clause 'collapse' with number of loops, it will 9424 // define the nested loops number. 9425 unsigned NestedLoopCount = 9426 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9427 nullptr /*ordered not a clause on distribute*/, AStmt, 9428 *this, *DSAStack, VarsWithImplicitDSA, B); 9429 if (NestedLoopCount == 0) 9430 return StmtError(); 9431 9432 assert((CurContext->isDependentContext() || B.builtAll()) && 9433 "omp for loop exprs were not built"); 9434 9435 setFunctionHasBranchProtectedScope(); 9436 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9437 NestedLoopCount, Clauses, AStmt, B); 9438 } 9439 9440 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9441 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9442 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9443 if (!AStmt) 9444 return StmtError(); 9445 9446 auto *CS = cast<CapturedStmt>(AStmt); 9447 // 1.2.2 OpenMP Language Terminology 9448 // Structured block - An executable statement with a single entry at the 9449 // top and a single exit at the bottom. 9450 // The point of exit cannot be a branch out of the structured block. 9451 // longjmp() and throw() must not violate the entry/exit criteria. 9452 CS->getCapturedDecl()->setNothrow(); 9453 for (int ThisCaptureLevel = 9454 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9455 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9456 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9457 // 1.2.2 OpenMP Language Terminology 9458 // Structured block - An executable statement with a single entry at the 9459 // top and a single exit at the bottom. 9460 // The point of exit cannot be a branch out of the structured block. 9461 // longjmp() and throw() must not violate the entry/exit criteria. 9462 CS->getCapturedDecl()->setNothrow(); 9463 } 9464 9465 OMPLoopDirective::HelperExprs B; 9466 // In presence of clause 'collapse' with number of loops, it will 9467 // define the nested loops number. 9468 unsigned NestedLoopCount = checkOpenMPLoop( 9469 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9470 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9471 VarsWithImplicitDSA, B); 9472 if (NestedLoopCount == 0) 9473 return StmtError(); 9474 9475 assert((CurContext->isDependentContext() || B.builtAll()) && 9476 "omp for loop exprs were not built"); 9477 9478 setFunctionHasBranchProtectedScope(); 9479 return OMPDistributeParallelForDirective::Create( 9480 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9481 DSAStack->isCancelRegion()); 9482 } 9483 9484 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9485 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9486 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9487 if (!AStmt) 9488 return StmtError(); 9489 9490 auto *CS = cast<CapturedStmt>(AStmt); 9491 // 1.2.2 OpenMP Language Terminology 9492 // Structured block - An executable statement with a single entry at the 9493 // top and a single exit at the bottom. 9494 // The point of exit cannot be a branch out of the structured block. 9495 // longjmp() and throw() must not violate the entry/exit criteria. 9496 CS->getCapturedDecl()->setNothrow(); 9497 for (int ThisCaptureLevel = 9498 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9499 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9500 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9501 // 1.2.2 OpenMP Language Terminology 9502 // Structured block - An executable statement with a single entry at the 9503 // top and a single exit at the bottom. 9504 // The point of exit cannot be a branch out of the structured block. 9505 // longjmp() and throw() must not violate the entry/exit criteria. 9506 CS->getCapturedDecl()->setNothrow(); 9507 } 9508 9509 OMPLoopDirective::HelperExprs B; 9510 // In presence of clause 'collapse' with number of loops, it will 9511 // define the nested loops number. 9512 unsigned NestedLoopCount = checkOpenMPLoop( 9513 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9514 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9515 VarsWithImplicitDSA, B); 9516 if (NestedLoopCount == 0) 9517 return StmtError(); 9518 9519 assert((CurContext->isDependentContext() || B.builtAll()) && 9520 "omp for loop exprs were not built"); 9521 9522 if (!CurContext->isDependentContext()) { 9523 // Finalize the clauses that need pre-built expressions for CodeGen. 9524 for (OMPClause *C : Clauses) { 9525 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9526 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9527 B.NumIterations, *this, CurScope, 9528 DSAStack)) 9529 return StmtError(); 9530 } 9531 } 9532 9533 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9534 return StmtError(); 9535 9536 setFunctionHasBranchProtectedScope(); 9537 return OMPDistributeParallelForSimdDirective::Create( 9538 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9539 } 9540 9541 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9542 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9543 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9544 if (!AStmt) 9545 return StmtError(); 9546 9547 auto *CS = cast<CapturedStmt>(AStmt); 9548 // 1.2.2 OpenMP Language Terminology 9549 // Structured block - An executable statement with a single entry at the 9550 // top and a single exit at the bottom. 9551 // The point of exit cannot be a branch out of the structured block. 9552 // longjmp() and throw() must not violate the entry/exit criteria. 9553 CS->getCapturedDecl()->setNothrow(); 9554 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9555 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9556 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9557 // 1.2.2 OpenMP Language Terminology 9558 // Structured block - An executable statement with a single entry at the 9559 // top and a single exit at the bottom. 9560 // The point of exit cannot be a branch out of the structured block. 9561 // longjmp() and throw() must not violate the entry/exit criteria. 9562 CS->getCapturedDecl()->setNothrow(); 9563 } 9564 9565 OMPLoopDirective::HelperExprs B; 9566 // In presence of clause 'collapse' with number of loops, it will 9567 // define the nested loops number. 9568 unsigned NestedLoopCount = 9569 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9570 nullptr /*ordered not a clause on distribute*/, CS, *this, 9571 *DSAStack, VarsWithImplicitDSA, B); 9572 if (NestedLoopCount == 0) 9573 return StmtError(); 9574 9575 assert((CurContext->isDependentContext() || B.builtAll()) && 9576 "omp for loop exprs were not built"); 9577 9578 if (!CurContext->isDependentContext()) { 9579 // Finalize the clauses that need pre-built expressions for CodeGen. 9580 for (OMPClause *C : Clauses) { 9581 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9582 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9583 B.NumIterations, *this, CurScope, 9584 DSAStack)) 9585 return StmtError(); 9586 } 9587 } 9588 9589 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9590 return StmtError(); 9591 9592 setFunctionHasBranchProtectedScope(); 9593 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9594 NestedLoopCount, Clauses, AStmt, B); 9595 } 9596 9597 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9598 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9599 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9600 if (!AStmt) 9601 return StmtError(); 9602 9603 auto *CS = cast<CapturedStmt>(AStmt); 9604 // 1.2.2 OpenMP Language Terminology 9605 // Structured block - An executable statement with a single entry at the 9606 // top and a single exit at the bottom. 9607 // The point of exit cannot be a branch out of the structured block. 9608 // longjmp() and throw() must not violate the entry/exit criteria. 9609 CS->getCapturedDecl()->setNothrow(); 9610 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9611 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9612 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9613 // 1.2.2 OpenMP Language Terminology 9614 // Structured block - An executable statement with a single entry at the 9615 // top and a single exit at the bottom. 9616 // The point of exit cannot be a branch out of the structured block. 9617 // longjmp() and throw() must not violate the entry/exit criteria. 9618 CS->getCapturedDecl()->setNothrow(); 9619 } 9620 9621 OMPLoopDirective::HelperExprs B; 9622 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9623 // define the nested loops number. 9624 unsigned NestedLoopCount = checkOpenMPLoop( 9625 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9626 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9627 VarsWithImplicitDSA, B); 9628 if (NestedLoopCount == 0) 9629 return StmtError(); 9630 9631 assert((CurContext->isDependentContext() || B.builtAll()) && 9632 "omp target parallel for simd loop exprs were not built"); 9633 9634 if (!CurContext->isDependentContext()) { 9635 // Finalize the clauses that need pre-built expressions for CodeGen. 9636 for (OMPClause *C : Clauses) { 9637 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9638 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9639 B.NumIterations, *this, CurScope, 9640 DSAStack)) 9641 return StmtError(); 9642 } 9643 } 9644 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9645 return StmtError(); 9646 9647 setFunctionHasBranchProtectedScope(); 9648 return OMPTargetParallelForSimdDirective::Create( 9649 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9650 } 9651 9652 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9653 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9654 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9655 if (!AStmt) 9656 return StmtError(); 9657 9658 auto *CS = cast<CapturedStmt>(AStmt); 9659 // 1.2.2 OpenMP Language Terminology 9660 // Structured block - An executable statement with a single entry at the 9661 // top and a single exit at the bottom. 9662 // The point of exit cannot be a branch out of the structured block. 9663 // longjmp() and throw() must not violate the entry/exit criteria. 9664 CS->getCapturedDecl()->setNothrow(); 9665 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9666 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9667 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9668 // 1.2.2 OpenMP Language Terminology 9669 // Structured block - An executable statement with a single entry at the 9670 // top and a single exit at the bottom. 9671 // The point of exit cannot be a branch out of the structured block. 9672 // longjmp() and throw() must not violate the entry/exit criteria. 9673 CS->getCapturedDecl()->setNothrow(); 9674 } 9675 9676 OMPLoopDirective::HelperExprs B; 9677 // In presence of clause 'collapse' with number of loops, it will define the 9678 // nested loops number. 9679 unsigned NestedLoopCount = 9680 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9681 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9682 VarsWithImplicitDSA, B); 9683 if (NestedLoopCount == 0) 9684 return StmtError(); 9685 9686 assert((CurContext->isDependentContext() || B.builtAll()) && 9687 "omp target simd loop exprs were not built"); 9688 9689 if (!CurContext->isDependentContext()) { 9690 // Finalize the clauses that need pre-built expressions for CodeGen. 9691 for (OMPClause *C : Clauses) { 9692 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9693 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9694 B.NumIterations, *this, CurScope, 9695 DSAStack)) 9696 return StmtError(); 9697 } 9698 } 9699 9700 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9701 return StmtError(); 9702 9703 setFunctionHasBranchProtectedScope(); 9704 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9705 NestedLoopCount, Clauses, AStmt, B); 9706 } 9707 9708 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9709 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9710 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9711 if (!AStmt) 9712 return StmtError(); 9713 9714 auto *CS = cast<CapturedStmt>(AStmt); 9715 // 1.2.2 OpenMP Language Terminology 9716 // Structured block - An executable statement with a single entry at the 9717 // top and a single exit at the bottom. 9718 // The point of exit cannot be a branch out of the structured block. 9719 // longjmp() and throw() must not violate the entry/exit criteria. 9720 CS->getCapturedDecl()->setNothrow(); 9721 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9722 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9723 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9724 // 1.2.2 OpenMP Language Terminology 9725 // Structured block - An executable statement with a single entry at the 9726 // top and a single exit at the bottom. 9727 // The point of exit cannot be a branch out of the structured block. 9728 // longjmp() and throw() must not violate the entry/exit criteria. 9729 CS->getCapturedDecl()->setNothrow(); 9730 } 9731 9732 OMPLoopDirective::HelperExprs B; 9733 // In presence of clause 'collapse' with number of loops, it will 9734 // define the nested loops number. 9735 unsigned NestedLoopCount = 9736 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9737 nullptr /*ordered not a clause on distribute*/, CS, *this, 9738 *DSAStack, VarsWithImplicitDSA, B); 9739 if (NestedLoopCount == 0) 9740 return StmtError(); 9741 9742 assert((CurContext->isDependentContext() || B.builtAll()) && 9743 "omp teams distribute loop exprs were not built"); 9744 9745 setFunctionHasBranchProtectedScope(); 9746 9747 DSAStack->setParentTeamsRegionLoc(StartLoc); 9748 9749 return OMPTeamsDistributeDirective::Create( 9750 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9751 } 9752 9753 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9754 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9755 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9756 if (!AStmt) 9757 return StmtError(); 9758 9759 auto *CS = cast<CapturedStmt>(AStmt); 9760 // 1.2.2 OpenMP Language Terminology 9761 // Structured block - An executable statement with a single entry at the 9762 // top and a single exit at the bottom. 9763 // The point of exit cannot be a branch out of the structured block. 9764 // longjmp() and throw() must not violate the entry/exit criteria. 9765 CS->getCapturedDecl()->setNothrow(); 9766 for (int ThisCaptureLevel = 9767 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9768 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9769 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9770 // 1.2.2 OpenMP Language Terminology 9771 // Structured block - An executable statement with a single entry at the 9772 // top and a single exit at the bottom. 9773 // The point of exit cannot be a branch out of the structured block. 9774 // longjmp() and throw() must not violate the entry/exit criteria. 9775 CS->getCapturedDecl()->setNothrow(); 9776 } 9777 9778 9779 OMPLoopDirective::HelperExprs B; 9780 // In presence of clause 'collapse' with number of loops, it will 9781 // define the nested loops number. 9782 unsigned NestedLoopCount = checkOpenMPLoop( 9783 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9784 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9785 VarsWithImplicitDSA, B); 9786 9787 if (NestedLoopCount == 0) 9788 return StmtError(); 9789 9790 assert((CurContext->isDependentContext() || B.builtAll()) && 9791 "omp teams distribute simd loop exprs were not built"); 9792 9793 if (!CurContext->isDependentContext()) { 9794 // Finalize the clauses that need pre-built expressions for CodeGen. 9795 for (OMPClause *C : Clauses) { 9796 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9797 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9798 B.NumIterations, *this, CurScope, 9799 DSAStack)) 9800 return StmtError(); 9801 } 9802 } 9803 9804 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9805 return StmtError(); 9806 9807 setFunctionHasBranchProtectedScope(); 9808 9809 DSAStack->setParentTeamsRegionLoc(StartLoc); 9810 9811 return OMPTeamsDistributeSimdDirective::Create( 9812 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9813 } 9814 9815 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9816 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9817 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9818 if (!AStmt) 9819 return StmtError(); 9820 9821 auto *CS = cast<CapturedStmt>(AStmt); 9822 // 1.2.2 OpenMP Language Terminology 9823 // Structured block - An executable statement with a single entry at the 9824 // top and a single exit at the bottom. 9825 // The point of exit cannot be a branch out of the structured block. 9826 // longjmp() and throw() must not violate the entry/exit criteria. 9827 CS->getCapturedDecl()->setNothrow(); 9828 9829 for (int ThisCaptureLevel = 9830 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9831 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9832 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9833 // 1.2.2 OpenMP Language Terminology 9834 // Structured block - An executable statement with a single entry at the 9835 // top and a single exit at the bottom. 9836 // The point of exit cannot be a branch out of the structured block. 9837 // longjmp() and throw() must not violate the entry/exit criteria. 9838 CS->getCapturedDecl()->setNothrow(); 9839 } 9840 9841 OMPLoopDirective::HelperExprs B; 9842 // In presence of clause 'collapse' with number of loops, it will 9843 // define the nested loops number. 9844 unsigned NestedLoopCount = checkOpenMPLoop( 9845 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9846 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9847 VarsWithImplicitDSA, B); 9848 9849 if (NestedLoopCount == 0) 9850 return StmtError(); 9851 9852 assert((CurContext->isDependentContext() || B.builtAll()) && 9853 "omp for loop exprs were not built"); 9854 9855 if (!CurContext->isDependentContext()) { 9856 // Finalize the clauses that need pre-built expressions for CodeGen. 9857 for (OMPClause *C : Clauses) { 9858 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9859 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9860 B.NumIterations, *this, CurScope, 9861 DSAStack)) 9862 return StmtError(); 9863 } 9864 } 9865 9866 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9867 return StmtError(); 9868 9869 setFunctionHasBranchProtectedScope(); 9870 9871 DSAStack->setParentTeamsRegionLoc(StartLoc); 9872 9873 return OMPTeamsDistributeParallelForSimdDirective::Create( 9874 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9875 } 9876 9877 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9878 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9879 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9880 if (!AStmt) 9881 return StmtError(); 9882 9883 auto *CS = cast<CapturedStmt>(AStmt); 9884 // 1.2.2 OpenMP Language Terminology 9885 // Structured block - An executable statement with a single entry at the 9886 // top and a single exit at the bottom. 9887 // The point of exit cannot be a branch out of the structured block. 9888 // longjmp() and throw() must not violate the entry/exit criteria. 9889 CS->getCapturedDecl()->setNothrow(); 9890 9891 for (int ThisCaptureLevel = 9892 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9893 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9894 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9895 // 1.2.2 OpenMP Language Terminology 9896 // Structured block - An executable statement with a single entry at the 9897 // top and a single exit at the bottom. 9898 // The point of exit cannot be a branch out of the structured block. 9899 // longjmp() and throw() must not violate the entry/exit criteria. 9900 CS->getCapturedDecl()->setNothrow(); 9901 } 9902 9903 OMPLoopDirective::HelperExprs B; 9904 // In presence of clause 'collapse' with number of loops, it will 9905 // define the nested loops number. 9906 unsigned NestedLoopCount = checkOpenMPLoop( 9907 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9908 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9909 VarsWithImplicitDSA, B); 9910 9911 if (NestedLoopCount == 0) 9912 return StmtError(); 9913 9914 assert((CurContext->isDependentContext() || B.builtAll()) && 9915 "omp for loop exprs were not built"); 9916 9917 setFunctionHasBranchProtectedScope(); 9918 9919 DSAStack->setParentTeamsRegionLoc(StartLoc); 9920 9921 return OMPTeamsDistributeParallelForDirective::Create( 9922 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9923 DSAStack->isCancelRegion()); 9924 } 9925 9926 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9927 Stmt *AStmt, 9928 SourceLocation StartLoc, 9929 SourceLocation EndLoc) { 9930 if (!AStmt) 9931 return StmtError(); 9932 9933 auto *CS = cast<CapturedStmt>(AStmt); 9934 // 1.2.2 OpenMP Language Terminology 9935 // Structured block - An executable statement with a single entry at the 9936 // top and a single exit at the bottom. 9937 // The point of exit cannot be a branch out of the structured block. 9938 // longjmp() and throw() must not violate the entry/exit criteria. 9939 CS->getCapturedDecl()->setNothrow(); 9940 9941 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9942 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9943 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9944 // 1.2.2 OpenMP Language Terminology 9945 // Structured block - An executable statement with a single entry at the 9946 // top and a single exit at the bottom. 9947 // The point of exit cannot be a branch out of the structured block. 9948 // longjmp() and throw() must not violate the entry/exit criteria. 9949 CS->getCapturedDecl()->setNothrow(); 9950 } 9951 setFunctionHasBranchProtectedScope(); 9952 9953 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9954 AStmt); 9955 } 9956 9957 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9958 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9959 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9960 if (!AStmt) 9961 return StmtError(); 9962 9963 auto *CS = cast<CapturedStmt>(AStmt); 9964 // 1.2.2 OpenMP Language Terminology 9965 // Structured block - An executable statement with a single entry at the 9966 // top and a single exit at the bottom. 9967 // The point of exit cannot be a branch out of the structured block. 9968 // longjmp() and throw() must not violate the entry/exit criteria. 9969 CS->getCapturedDecl()->setNothrow(); 9970 for (int ThisCaptureLevel = 9971 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9972 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9973 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9974 // 1.2.2 OpenMP Language Terminology 9975 // Structured block - An executable statement with a single entry at the 9976 // top and a single exit at the bottom. 9977 // The point of exit cannot be a branch out of the structured block. 9978 // longjmp() and throw() must not violate the entry/exit criteria. 9979 CS->getCapturedDecl()->setNothrow(); 9980 } 9981 9982 OMPLoopDirective::HelperExprs B; 9983 // In presence of clause 'collapse' with number of loops, it will 9984 // define the nested loops number. 9985 unsigned NestedLoopCount = checkOpenMPLoop( 9986 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9987 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9988 VarsWithImplicitDSA, B); 9989 if (NestedLoopCount == 0) 9990 return StmtError(); 9991 9992 assert((CurContext->isDependentContext() || B.builtAll()) && 9993 "omp target teams distribute loop exprs were not built"); 9994 9995 setFunctionHasBranchProtectedScope(); 9996 return OMPTargetTeamsDistributeDirective::Create( 9997 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9998 } 9999 10000 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10001 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10002 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10003 if (!AStmt) 10004 return StmtError(); 10005 10006 auto *CS = cast<CapturedStmt>(AStmt); 10007 // 1.2.2 OpenMP Language Terminology 10008 // Structured block - An executable statement with a single entry at the 10009 // top and a single exit at the bottom. 10010 // The point of exit cannot be a branch out of the structured block. 10011 // longjmp() and throw() must not violate the entry/exit criteria. 10012 CS->getCapturedDecl()->setNothrow(); 10013 for (int ThisCaptureLevel = 10014 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10015 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10016 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10017 // 1.2.2 OpenMP Language Terminology 10018 // Structured block - An executable statement with a single entry at the 10019 // top and a single exit at the bottom. 10020 // The point of exit cannot be a branch out of the structured block. 10021 // longjmp() and throw() must not violate the entry/exit criteria. 10022 CS->getCapturedDecl()->setNothrow(); 10023 } 10024 10025 OMPLoopDirective::HelperExprs B; 10026 // In presence of clause 'collapse' with number of loops, it will 10027 // define the nested loops number. 10028 unsigned NestedLoopCount = checkOpenMPLoop( 10029 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10030 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10031 VarsWithImplicitDSA, B); 10032 if (NestedLoopCount == 0) 10033 return StmtError(); 10034 10035 assert((CurContext->isDependentContext() || B.builtAll()) && 10036 "omp target teams distribute parallel for loop exprs were not built"); 10037 10038 if (!CurContext->isDependentContext()) { 10039 // Finalize the clauses that need pre-built expressions for CodeGen. 10040 for (OMPClause *C : Clauses) { 10041 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10042 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10043 B.NumIterations, *this, CurScope, 10044 DSAStack)) 10045 return StmtError(); 10046 } 10047 } 10048 10049 setFunctionHasBranchProtectedScope(); 10050 return OMPTargetTeamsDistributeParallelForDirective::Create( 10051 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10052 DSAStack->isCancelRegion()); 10053 } 10054 10055 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10056 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10057 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10058 if (!AStmt) 10059 return StmtError(); 10060 10061 auto *CS = cast<CapturedStmt>(AStmt); 10062 // 1.2.2 OpenMP Language Terminology 10063 // Structured block - An executable statement with a single entry at the 10064 // top and a single exit at the bottom. 10065 // The point of exit cannot be a branch out of the structured block. 10066 // longjmp() and throw() must not violate the entry/exit criteria. 10067 CS->getCapturedDecl()->setNothrow(); 10068 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10069 OMPD_target_teams_distribute_parallel_for_simd); 10070 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10071 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10072 // 1.2.2 OpenMP Language Terminology 10073 // Structured block - An executable statement with a single entry at the 10074 // top and a single exit at the bottom. 10075 // The point of exit cannot be a branch out of the structured block. 10076 // longjmp() and throw() must not violate the entry/exit criteria. 10077 CS->getCapturedDecl()->setNothrow(); 10078 } 10079 10080 OMPLoopDirective::HelperExprs B; 10081 // In presence of clause 'collapse' with number of loops, it will 10082 // define the nested loops number. 10083 unsigned NestedLoopCount = 10084 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10085 getCollapseNumberExpr(Clauses), 10086 nullptr /*ordered not a clause on distribute*/, CS, *this, 10087 *DSAStack, VarsWithImplicitDSA, B); 10088 if (NestedLoopCount == 0) 10089 return StmtError(); 10090 10091 assert((CurContext->isDependentContext() || B.builtAll()) && 10092 "omp target teams distribute parallel for simd loop exprs were not " 10093 "built"); 10094 10095 if (!CurContext->isDependentContext()) { 10096 // Finalize the clauses that need pre-built expressions for CodeGen. 10097 for (OMPClause *C : Clauses) { 10098 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10099 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10100 B.NumIterations, *this, CurScope, 10101 DSAStack)) 10102 return StmtError(); 10103 } 10104 } 10105 10106 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10107 return StmtError(); 10108 10109 setFunctionHasBranchProtectedScope(); 10110 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10111 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10112 } 10113 10114 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10115 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10116 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10117 if (!AStmt) 10118 return StmtError(); 10119 10120 auto *CS = cast<CapturedStmt>(AStmt); 10121 // 1.2.2 OpenMP Language Terminology 10122 // Structured block - An executable statement with a single entry at the 10123 // top and a single exit at the bottom. 10124 // The point of exit cannot be a branch out of the structured block. 10125 // longjmp() and throw() must not violate the entry/exit criteria. 10126 CS->getCapturedDecl()->setNothrow(); 10127 for (int ThisCaptureLevel = 10128 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10129 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10130 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10131 // 1.2.2 OpenMP Language Terminology 10132 // Structured block - An executable statement with a single entry at the 10133 // top and a single exit at the bottom. 10134 // The point of exit cannot be a branch out of the structured block. 10135 // longjmp() and throw() must not violate the entry/exit criteria. 10136 CS->getCapturedDecl()->setNothrow(); 10137 } 10138 10139 OMPLoopDirective::HelperExprs B; 10140 // In presence of clause 'collapse' with number of loops, it will 10141 // define the nested loops number. 10142 unsigned NestedLoopCount = checkOpenMPLoop( 10143 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10144 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10145 VarsWithImplicitDSA, B); 10146 if (NestedLoopCount == 0) 10147 return StmtError(); 10148 10149 assert((CurContext->isDependentContext() || B.builtAll()) && 10150 "omp target teams distribute simd loop exprs were not built"); 10151 10152 if (!CurContext->isDependentContext()) { 10153 // Finalize the clauses that need pre-built expressions for CodeGen. 10154 for (OMPClause *C : Clauses) { 10155 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10156 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10157 B.NumIterations, *this, CurScope, 10158 DSAStack)) 10159 return StmtError(); 10160 } 10161 } 10162 10163 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10164 return StmtError(); 10165 10166 setFunctionHasBranchProtectedScope(); 10167 return OMPTargetTeamsDistributeSimdDirective::Create( 10168 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10169 } 10170 10171 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10172 SourceLocation StartLoc, 10173 SourceLocation LParenLoc, 10174 SourceLocation EndLoc) { 10175 OMPClause *Res = nullptr; 10176 switch (Kind) { 10177 case OMPC_final: 10178 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10179 break; 10180 case OMPC_num_threads: 10181 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10182 break; 10183 case OMPC_safelen: 10184 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10185 break; 10186 case OMPC_simdlen: 10187 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10188 break; 10189 case OMPC_allocator: 10190 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10191 break; 10192 case OMPC_collapse: 10193 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10194 break; 10195 case OMPC_ordered: 10196 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10197 break; 10198 case OMPC_device: 10199 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10200 break; 10201 case OMPC_num_teams: 10202 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10203 break; 10204 case OMPC_thread_limit: 10205 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10206 break; 10207 case OMPC_priority: 10208 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10209 break; 10210 case OMPC_grainsize: 10211 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10212 break; 10213 case OMPC_num_tasks: 10214 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10215 break; 10216 case OMPC_hint: 10217 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10218 break; 10219 case OMPC_if: 10220 case OMPC_default: 10221 case OMPC_proc_bind: 10222 case OMPC_schedule: 10223 case OMPC_private: 10224 case OMPC_firstprivate: 10225 case OMPC_lastprivate: 10226 case OMPC_shared: 10227 case OMPC_reduction: 10228 case OMPC_task_reduction: 10229 case OMPC_in_reduction: 10230 case OMPC_linear: 10231 case OMPC_aligned: 10232 case OMPC_copyin: 10233 case OMPC_copyprivate: 10234 case OMPC_nowait: 10235 case OMPC_untied: 10236 case OMPC_mergeable: 10237 case OMPC_threadprivate: 10238 case OMPC_allocate: 10239 case OMPC_flush: 10240 case OMPC_read: 10241 case OMPC_write: 10242 case OMPC_update: 10243 case OMPC_capture: 10244 case OMPC_seq_cst: 10245 case OMPC_depend: 10246 case OMPC_threads: 10247 case OMPC_simd: 10248 case OMPC_map: 10249 case OMPC_nogroup: 10250 case OMPC_dist_schedule: 10251 case OMPC_defaultmap: 10252 case OMPC_unknown: 10253 case OMPC_uniform: 10254 case OMPC_to: 10255 case OMPC_from: 10256 case OMPC_use_device_ptr: 10257 case OMPC_is_device_ptr: 10258 case OMPC_unified_address: 10259 case OMPC_unified_shared_memory: 10260 case OMPC_reverse_offload: 10261 case OMPC_dynamic_allocators: 10262 case OMPC_atomic_default_mem_order: 10263 case OMPC_device_type: 10264 case OMPC_match: 10265 llvm_unreachable("Clause is not allowed."); 10266 } 10267 return Res; 10268 } 10269 10270 // An OpenMP directive such as 'target parallel' has two captured regions: 10271 // for the 'target' and 'parallel' respectively. This function returns 10272 // the region in which to capture expressions associated with a clause. 10273 // A return value of OMPD_unknown signifies that the expression should not 10274 // be captured. 10275 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10276 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10277 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10278 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10279 switch (CKind) { 10280 case OMPC_if: 10281 switch (DKind) { 10282 case OMPD_target_parallel: 10283 case OMPD_target_parallel_for: 10284 case OMPD_target_parallel_for_simd: 10285 // If this clause applies to the nested 'parallel' region, capture within 10286 // the 'target' region, otherwise do not capture. 10287 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10288 CaptureRegion = OMPD_target; 10289 break; 10290 case OMPD_target_teams_distribute_parallel_for: 10291 case OMPD_target_teams_distribute_parallel_for_simd: 10292 // If this clause applies to the nested 'parallel' region, capture within 10293 // the 'teams' region, otherwise do not capture. 10294 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10295 CaptureRegion = OMPD_teams; 10296 break; 10297 case OMPD_teams_distribute_parallel_for: 10298 case OMPD_teams_distribute_parallel_for_simd: 10299 CaptureRegion = OMPD_teams; 10300 break; 10301 case OMPD_target_update: 10302 case OMPD_target_enter_data: 10303 case OMPD_target_exit_data: 10304 CaptureRegion = OMPD_task; 10305 break; 10306 case OMPD_parallel_master_taskloop: 10307 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10308 CaptureRegion = OMPD_parallel; 10309 break; 10310 case OMPD_cancel: 10311 case OMPD_parallel: 10312 case OMPD_parallel_sections: 10313 case OMPD_parallel_for: 10314 case OMPD_parallel_for_simd: 10315 case OMPD_target: 10316 case OMPD_target_simd: 10317 case OMPD_target_teams: 10318 case OMPD_target_teams_distribute: 10319 case OMPD_target_teams_distribute_simd: 10320 case OMPD_distribute_parallel_for: 10321 case OMPD_distribute_parallel_for_simd: 10322 case OMPD_task: 10323 case OMPD_taskloop: 10324 case OMPD_taskloop_simd: 10325 case OMPD_master_taskloop: 10326 case OMPD_target_data: 10327 // Do not capture if-clause expressions. 10328 break; 10329 case OMPD_threadprivate: 10330 case OMPD_allocate: 10331 case OMPD_taskyield: 10332 case OMPD_barrier: 10333 case OMPD_taskwait: 10334 case OMPD_cancellation_point: 10335 case OMPD_flush: 10336 case OMPD_declare_reduction: 10337 case OMPD_declare_mapper: 10338 case OMPD_declare_simd: 10339 case OMPD_declare_variant: 10340 case OMPD_declare_target: 10341 case OMPD_end_declare_target: 10342 case OMPD_teams: 10343 case OMPD_simd: 10344 case OMPD_for: 10345 case OMPD_for_simd: 10346 case OMPD_sections: 10347 case OMPD_section: 10348 case OMPD_single: 10349 case OMPD_master: 10350 case OMPD_critical: 10351 case OMPD_taskgroup: 10352 case OMPD_distribute: 10353 case OMPD_ordered: 10354 case OMPD_atomic: 10355 case OMPD_distribute_simd: 10356 case OMPD_teams_distribute: 10357 case OMPD_teams_distribute_simd: 10358 case OMPD_requires: 10359 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10360 case OMPD_unknown: 10361 llvm_unreachable("Unknown OpenMP directive"); 10362 } 10363 break; 10364 case OMPC_num_threads: 10365 switch (DKind) { 10366 case OMPD_target_parallel: 10367 case OMPD_target_parallel_for: 10368 case OMPD_target_parallel_for_simd: 10369 CaptureRegion = OMPD_target; 10370 break; 10371 case OMPD_teams_distribute_parallel_for: 10372 case OMPD_teams_distribute_parallel_for_simd: 10373 case OMPD_target_teams_distribute_parallel_for: 10374 case OMPD_target_teams_distribute_parallel_for_simd: 10375 CaptureRegion = OMPD_teams; 10376 break; 10377 case OMPD_parallel: 10378 case OMPD_parallel_sections: 10379 case OMPD_parallel_for: 10380 case OMPD_parallel_for_simd: 10381 case OMPD_distribute_parallel_for: 10382 case OMPD_distribute_parallel_for_simd: 10383 case OMPD_parallel_master_taskloop: 10384 // Do not capture num_threads-clause expressions. 10385 break; 10386 case OMPD_target_data: 10387 case OMPD_target_enter_data: 10388 case OMPD_target_exit_data: 10389 case OMPD_target_update: 10390 case OMPD_target: 10391 case OMPD_target_simd: 10392 case OMPD_target_teams: 10393 case OMPD_target_teams_distribute: 10394 case OMPD_target_teams_distribute_simd: 10395 case OMPD_cancel: 10396 case OMPD_task: 10397 case OMPD_taskloop: 10398 case OMPD_taskloop_simd: 10399 case OMPD_master_taskloop: 10400 case OMPD_threadprivate: 10401 case OMPD_allocate: 10402 case OMPD_taskyield: 10403 case OMPD_barrier: 10404 case OMPD_taskwait: 10405 case OMPD_cancellation_point: 10406 case OMPD_flush: 10407 case OMPD_declare_reduction: 10408 case OMPD_declare_mapper: 10409 case OMPD_declare_simd: 10410 case OMPD_declare_variant: 10411 case OMPD_declare_target: 10412 case OMPD_end_declare_target: 10413 case OMPD_teams: 10414 case OMPD_simd: 10415 case OMPD_for: 10416 case OMPD_for_simd: 10417 case OMPD_sections: 10418 case OMPD_section: 10419 case OMPD_single: 10420 case OMPD_master: 10421 case OMPD_critical: 10422 case OMPD_taskgroup: 10423 case OMPD_distribute: 10424 case OMPD_ordered: 10425 case OMPD_atomic: 10426 case OMPD_distribute_simd: 10427 case OMPD_teams_distribute: 10428 case OMPD_teams_distribute_simd: 10429 case OMPD_requires: 10430 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10431 case OMPD_unknown: 10432 llvm_unreachable("Unknown OpenMP directive"); 10433 } 10434 break; 10435 case OMPC_num_teams: 10436 switch (DKind) { 10437 case OMPD_target_teams: 10438 case OMPD_target_teams_distribute: 10439 case OMPD_target_teams_distribute_simd: 10440 case OMPD_target_teams_distribute_parallel_for: 10441 case OMPD_target_teams_distribute_parallel_for_simd: 10442 CaptureRegion = OMPD_target; 10443 break; 10444 case OMPD_teams_distribute_parallel_for: 10445 case OMPD_teams_distribute_parallel_for_simd: 10446 case OMPD_teams: 10447 case OMPD_teams_distribute: 10448 case OMPD_teams_distribute_simd: 10449 // Do not capture num_teams-clause expressions. 10450 break; 10451 case OMPD_distribute_parallel_for: 10452 case OMPD_distribute_parallel_for_simd: 10453 case OMPD_task: 10454 case OMPD_taskloop: 10455 case OMPD_taskloop_simd: 10456 case OMPD_master_taskloop: 10457 case OMPD_parallel_master_taskloop: 10458 case OMPD_target_data: 10459 case OMPD_target_enter_data: 10460 case OMPD_target_exit_data: 10461 case OMPD_target_update: 10462 case OMPD_cancel: 10463 case OMPD_parallel: 10464 case OMPD_parallel_sections: 10465 case OMPD_parallel_for: 10466 case OMPD_parallel_for_simd: 10467 case OMPD_target: 10468 case OMPD_target_simd: 10469 case OMPD_target_parallel: 10470 case OMPD_target_parallel_for: 10471 case OMPD_target_parallel_for_simd: 10472 case OMPD_threadprivate: 10473 case OMPD_allocate: 10474 case OMPD_taskyield: 10475 case OMPD_barrier: 10476 case OMPD_taskwait: 10477 case OMPD_cancellation_point: 10478 case OMPD_flush: 10479 case OMPD_declare_reduction: 10480 case OMPD_declare_mapper: 10481 case OMPD_declare_simd: 10482 case OMPD_declare_variant: 10483 case OMPD_declare_target: 10484 case OMPD_end_declare_target: 10485 case OMPD_simd: 10486 case OMPD_for: 10487 case OMPD_for_simd: 10488 case OMPD_sections: 10489 case OMPD_section: 10490 case OMPD_single: 10491 case OMPD_master: 10492 case OMPD_critical: 10493 case OMPD_taskgroup: 10494 case OMPD_distribute: 10495 case OMPD_ordered: 10496 case OMPD_atomic: 10497 case OMPD_distribute_simd: 10498 case OMPD_requires: 10499 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10500 case OMPD_unknown: 10501 llvm_unreachable("Unknown OpenMP directive"); 10502 } 10503 break; 10504 case OMPC_thread_limit: 10505 switch (DKind) { 10506 case OMPD_target_teams: 10507 case OMPD_target_teams_distribute: 10508 case OMPD_target_teams_distribute_simd: 10509 case OMPD_target_teams_distribute_parallel_for: 10510 case OMPD_target_teams_distribute_parallel_for_simd: 10511 CaptureRegion = OMPD_target; 10512 break; 10513 case OMPD_teams_distribute_parallel_for: 10514 case OMPD_teams_distribute_parallel_for_simd: 10515 case OMPD_teams: 10516 case OMPD_teams_distribute: 10517 case OMPD_teams_distribute_simd: 10518 // Do not capture thread_limit-clause expressions. 10519 break; 10520 case OMPD_distribute_parallel_for: 10521 case OMPD_distribute_parallel_for_simd: 10522 case OMPD_task: 10523 case OMPD_taskloop: 10524 case OMPD_taskloop_simd: 10525 case OMPD_master_taskloop: 10526 case OMPD_parallel_master_taskloop: 10527 case OMPD_target_data: 10528 case OMPD_target_enter_data: 10529 case OMPD_target_exit_data: 10530 case OMPD_target_update: 10531 case OMPD_cancel: 10532 case OMPD_parallel: 10533 case OMPD_parallel_sections: 10534 case OMPD_parallel_for: 10535 case OMPD_parallel_for_simd: 10536 case OMPD_target: 10537 case OMPD_target_simd: 10538 case OMPD_target_parallel: 10539 case OMPD_target_parallel_for: 10540 case OMPD_target_parallel_for_simd: 10541 case OMPD_threadprivate: 10542 case OMPD_allocate: 10543 case OMPD_taskyield: 10544 case OMPD_barrier: 10545 case OMPD_taskwait: 10546 case OMPD_cancellation_point: 10547 case OMPD_flush: 10548 case OMPD_declare_reduction: 10549 case OMPD_declare_mapper: 10550 case OMPD_declare_simd: 10551 case OMPD_declare_variant: 10552 case OMPD_declare_target: 10553 case OMPD_end_declare_target: 10554 case OMPD_simd: 10555 case OMPD_for: 10556 case OMPD_for_simd: 10557 case OMPD_sections: 10558 case OMPD_section: 10559 case OMPD_single: 10560 case OMPD_master: 10561 case OMPD_critical: 10562 case OMPD_taskgroup: 10563 case OMPD_distribute: 10564 case OMPD_ordered: 10565 case OMPD_atomic: 10566 case OMPD_distribute_simd: 10567 case OMPD_requires: 10568 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10569 case OMPD_unknown: 10570 llvm_unreachable("Unknown OpenMP directive"); 10571 } 10572 break; 10573 case OMPC_schedule: 10574 switch (DKind) { 10575 case OMPD_parallel_for: 10576 case OMPD_parallel_for_simd: 10577 case OMPD_distribute_parallel_for: 10578 case OMPD_distribute_parallel_for_simd: 10579 case OMPD_teams_distribute_parallel_for: 10580 case OMPD_teams_distribute_parallel_for_simd: 10581 case OMPD_target_parallel_for: 10582 case OMPD_target_parallel_for_simd: 10583 case OMPD_target_teams_distribute_parallel_for: 10584 case OMPD_target_teams_distribute_parallel_for_simd: 10585 CaptureRegion = OMPD_parallel; 10586 break; 10587 case OMPD_for: 10588 case OMPD_for_simd: 10589 // Do not capture schedule-clause expressions. 10590 break; 10591 case OMPD_task: 10592 case OMPD_taskloop: 10593 case OMPD_taskloop_simd: 10594 case OMPD_master_taskloop: 10595 case OMPD_parallel_master_taskloop: 10596 case OMPD_target_data: 10597 case OMPD_target_enter_data: 10598 case OMPD_target_exit_data: 10599 case OMPD_target_update: 10600 case OMPD_teams: 10601 case OMPD_teams_distribute: 10602 case OMPD_teams_distribute_simd: 10603 case OMPD_target_teams_distribute: 10604 case OMPD_target_teams_distribute_simd: 10605 case OMPD_target: 10606 case OMPD_target_simd: 10607 case OMPD_target_parallel: 10608 case OMPD_cancel: 10609 case OMPD_parallel: 10610 case OMPD_parallel_sections: 10611 case OMPD_threadprivate: 10612 case OMPD_allocate: 10613 case OMPD_taskyield: 10614 case OMPD_barrier: 10615 case OMPD_taskwait: 10616 case OMPD_cancellation_point: 10617 case OMPD_flush: 10618 case OMPD_declare_reduction: 10619 case OMPD_declare_mapper: 10620 case OMPD_declare_simd: 10621 case OMPD_declare_variant: 10622 case OMPD_declare_target: 10623 case OMPD_end_declare_target: 10624 case OMPD_simd: 10625 case OMPD_sections: 10626 case OMPD_section: 10627 case OMPD_single: 10628 case OMPD_master: 10629 case OMPD_critical: 10630 case OMPD_taskgroup: 10631 case OMPD_distribute: 10632 case OMPD_ordered: 10633 case OMPD_atomic: 10634 case OMPD_distribute_simd: 10635 case OMPD_target_teams: 10636 case OMPD_requires: 10637 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10638 case OMPD_unknown: 10639 llvm_unreachable("Unknown OpenMP directive"); 10640 } 10641 break; 10642 case OMPC_dist_schedule: 10643 switch (DKind) { 10644 case OMPD_teams_distribute_parallel_for: 10645 case OMPD_teams_distribute_parallel_for_simd: 10646 case OMPD_teams_distribute: 10647 case OMPD_teams_distribute_simd: 10648 case OMPD_target_teams_distribute_parallel_for: 10649 case OMPD_target_teams_distribute_parallel_for_simd: 10650 case OMPD_target_teams_distribute: 10651 case OMPD_target_teams_distribute_simd: 10652 CaptureRegion = OMPD_teams; 10653 break; 10654 case OMPD_distribute_parallel_for: 10655 case OMPD_distribute_parallel_for_simd: 10656 case OMPD_distribute: 10657 case OMPD_distribute_simd: 10658 // Do not capture thread_limit-clause expressions. 10659 break; 10660 case OMPD_parallel_for: 10661 case OMPD_parallel_for_simd: 10662 case OMPD_target_parallel_for_simd: 10663 case OMPD_target_parallel_for: 10664 case OMPD_task: 10665 case OMPD_taskloop: 10666 case OMPD_taskloop_simd: 10667 case OMPD_master_taskloop: 10668 case OMPD_parallel_master_taskloop: 10669 case OMPD_target_data: 10670 case OMPD_target_enter_data: 10671 case OMPD_target_exit_data: 10672 case OMPD_target_update: 10673 case OMPD_teams: 10674 case OMPD_target: 10675 case OMPD_target_simd: 10676 case OMPD_target_parallel: 10677 case OMPD_cancel: 10678 case OMPD_parallel: 10679 case OMPD_parallel_sections: 10680 case OMPD_threadprivate: 10681 case OMPD_allocate: 10682 case OMPD_taskyield: 10683 case OMPD_barrier: 10684 case OMPD_taskwait: 10685 case OMPD_cancellation_point: 10686 case OMPD_flush: 10687 case OMPD_declare_reduction: 10688 case OMPD_declare_mapper: 10689 case OMPD_declare_simd: 10690 case OMPD_declare_variant: 10691 case OMPD_declare_target: 10692 case OMPD_end_declare_target: 10693 case OMPD_simd: 10694 case OMPD_for: 10695 case OMPD_for_simd: 10696 case OMPD_sections: 10697 case OMPD_section: 10698 case OMPD_single: 10699 case OMPD_master: 10700 case OMPD_critical: 10701 case OMPD_taskgroup: 10702 case OMPD_ordered: 10703 case OMPD_atomic: 10704 case OMPD_target_teams: 10705 case OMPD_requires: 10706 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10707 case OMPD_unknown: 10708 llvm_unreachable("Unknown OpenMP directive"); 10709 } 10710 break; 10711 case OMPC_device: 10712 switch (DKind) { 10713 case OMPD_target_update: 10714 case OMPD_target_enter_data: 10715 case OMPD_target_exit_data: 10716 case OMPD_target: 10717 case OMPD_target_simd: 10718 case OMPD_target_teams: 10719 case OMPD_target_parallel: 10720 case OMPD_target_teams_distribute: 10721 case OMPD_target_teams_distribute_simd: 10722 case OMPD_target_parallel_for: 10723 case OMPD_target_parallel_for_simd: 10724 case OMPD_target_teams_distribute_parallel_for: 10725 case OMPD_target_teams_distribute_parallel_for_simd: 10726 CaptureRegion = OMPD_task; 10727 break; 10728 case OMPD_target_data: 10729 // Do not capture device-clause expressions. 10730 break; 10731 case OMPD_teams_distribute_parallel_for: 10732 case OMPD_teams_distribute_parallel_for_simd: 10733 case OMPD_teams: 10734 case OMPD_teams_distribute: 10735 case OMPD_teams_distribute_simd: 10736 case OMPD_distribute_parallel_for: 10737 case OMPD_distribute_parallel_for_simd: 10738 case OMPD_task: 10739 case OMPD_taskloop: 10740 case OMPD_taskloop_simd: 10741 case OMPD_master_taskloop: 10742 case OMPD_parallel_master_taskloop: 10743 case OMPD_cancel: 10744 case OMPD_parallel: 10745 case OMPD_parallel_sections: 10746 case OMPD_parallel_for: 10747 case OMPD_parallel_for_simd: 10748 case OMPD_threadprivate: 10749 case OMPD_allocate: 10750 case OMPD_taskyield: 10751 case OMPD_barrier: 10752 case OMPD_taskwait: 10753 case OMPD_cancellation_point: 10754 case OMPD_flush: 10755 case OMPD_declare_reduction: 10756 case OMPD_declare_mapper: 10757 case OMPD_declare_simd: 10758 case OMPD_declare_variant: 10759 case OMPD_declare_target: 10760 case OMPD_end_declare_target: 10761 case OMPD_simd: 10762 case OMPD_for: 10763 case OMPD_for_simd: 10764 case OMPD_sections: 10765 case OMPD_section: 10766 case OMPD_single: 10767 case OMPD_master: 10768 case OMPD_critical: 10769 case OMPD_taskgroup: 10770 case OMPD_distribute: 10771 case OMPD_ordered: 10772 case OMPD_atomic: 10773 case OMPD_distribute_simd: 10774 case OMPD_requires: 10775 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10776 case OMPD_unknown: 10777 llvm_unreachable("Unknown OpenMP directive"); 10778 } 10779 break; 10780 case OMPC_grainsize: 10781 case OMPC_num_tasks: 10782 case OMPC_final: 10783 case OMPC_priority: 10784 switch (DKind) { 10785 case OMPD_task: 10786 case OMPD_taskloop: 10787 case OMPD_taskloop_simd: 10788 case OMPD_master_taskloop: 10789 break; 10790 case OMPD_parallel_master_taskloop: 10791 CaptureRegion = OMPD_parallel; 10792 break; 10793 case OMPD_target_update: 10794 case OMPD_target_enter_data: 10795 case OMPD_target_exit_data: 10796 case OMPD_target: 10797 case OMPD_target_simd: 10798 case OMPD_target_teams: 10799 case OMPD_target_parallel: 10800 case OMPD_target_teams_distribute: 10801 case OMPD_target_teams_distribute_simd: 10802 case OMPD_target_parallel_for: 10803 case OMPD_target_parallel_for_simd: 10804 case OMPD_target_teams_distribute_parallel_for: 10805 case OMPD_target_teams_distribute_parallel_for_simd: 10806 case OMPD_target_data: 10807 case OMPD_teams_distribute_parallel_for: 10808 case OMPD_teams_distribute_parallel_for_simd: 10809 case OMPD_teams: 10810 case OMPD_teams_distribute: 10811 case OMPD_teams_distribute_simd: 10812 case OMPD_distribute_parallel_for: 10813 case OMPD_distribute_parallel_for_simd: 10814 case OMPD_cancel: 10815 case OMPD_parallel: 10816 case OMPD_parallel_sections: 10817 case OMPD_parallel_for: 10818 case OMPD_parallel_for_simd: 10819 case OMPD_threadprivate: 10820 case OMPD_allocate: 10821 case OMPD_taskyield: 10822 case OMPD_barrier: 10823 case OMPD_taskwait: 10824 case OMPD_cancellation_point: 10825 case OMPD_flush: 10826 case OMPD_declare_reduction: 10827 case OMPD_declare_mapper: 10828 case OMPD_declare_simd: 10829 case OMPD_declare_variant: 10830 case OMPD_declare_target: 10831 case OMPD_end_declare_target: 10832 case OMPD_simd: 10833 case OMPD_for: 10834 case OMPD_for_simd: 10835 case OMPD_sections: 10836 case OMPD_section: 10837 case OMPD_single: 10838 case OMPD_master: 10839 case OMPD_critical: 10840 case OMPD_taskgroup: 10841 case OMPD_distribute: 10842 case OMPD_ordered: 10843 case OMPD_atomic: 10844 case OMPD_distribute_simd: 10845 case OMPD_requires: 10846 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 10847 case OMPD_unknown: 10848 llvm_unreachable("Unknown OpenMP directive"); 10849 } 10850 break; 10851 case OMPC_firstprivate: 10852 case OMPC_lastprivate: 10853 case OMPC_reduction: 10854 case OMPC_task_reduction: 10855 case OMPC_in_reduction: 10856 case OMPC_linear: 10857 case OMPC_default: 10858 case OMPC_proc_bind: 10859 case OMPC_safelen: 10860 case OMPC_simdlen: 10861 case OMPC_allocator: 10862 case OMPC_collapse: 10863 case OMPC_private: 10864 case OMPC_shared: 10865 case OMPC_aligned: 10866 case OMPC_copyin: 10867 case OMPC_copyprivate: 10868 case OMPC_ordered: 10869 case OMPC_nowait: 10870 case OMPC_untied: 10871 case OMPC_mergeable: 10872 case OMPC_threadprivate: 10873 case OMPC_allocate: 10874 case OMPC_flush: 10875 case OMPC_read: 10876 case OMPC_write: 10877 case OMPC_update: 10878 case OMPC_capture: 10879 case OMPC_seq_cst: 10880 case OMPC_depend: 10881 case OMPC_threads: 10882 case OMPC_simd: 10883 case OMPC_map: 10884 case OMPC_nogroup: 10885 case OMPC_hint: 10886 case OMPC_defaultmap: 10887 case OMPC_unknown: 10888 case OMPC_uniform: 10889 case OMPC_to: 10890 case OMPC_from: 10891 case OMPC_use_device_ptr: 10892 case OMPC_is_device_ptr: 10893 case OMPC_unified_address: 10894 case OMPC_unified_shared_memory: 10895 case OMPC_reverse_offload: 10896 case OMPC_dynamic_allocators: 10897 case OMPC_atomic_default_mem_order: 10898 case OMPC_device_type: 10899 case OMPC_match: 10900 llvm_unreachable("Unexpected OpenMP clause."); 10901 } 10902 return CaptureRegion; 10903 } 10904 10905 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10906 Expr *Condition, SourceLocation StartLoc, 10907 SourceLocation LParenLoc, 10908 SourceLocation NameModifierLoc, 10909 SourceLocation ColonLoc, 10910 SourceLocation EndLoc) { 10911 Expr *ValExpr = Condition; 10912 Stmt *HelperValStmt = nullptr; 10913 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10914 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10915 !Condition->isInstantiationDependent() && 10916 !Condition->containsUnexpandedParameterPack()) { 10917 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10918 if (Val.isInvalid()) 10919 return nullptr; 10920 10921 ValExpr = Val.get(); 10922 10923 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10924 CaptureRegion = 10925 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10926 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10927 ValExpr = MakeFullExpr(ValExpr).get(); 10928 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10929 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10930 HelperValStmt = buildPreInits(Context, Captures); 10931 } 10932 } 10933 10934 return new (Context) 10935 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10936 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10937 } 10938 10939 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10940 SourceLocation StartLoc, 10941 SourceLocation LParenLoc, 10942 SourceLocation EndLoc) { 10943 Expr *ValExpr = Condition; 10944 Stmt *HelperValStmt = nullptr; 10945 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10946 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10947 !Condition->isInstantiationDependent() && 10948 !Condition->containsUnexpandedParameterPack()) { 10949 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10950 if (Val.isInvalid()) 10951 return nullptr; 10952 10953 ValExpr = MakeFullExpr(Val.get()).get(); 10954 10955 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10956 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final); 10957 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10958 ValExpr = MakeFullExpr(ValExpr).get(); 10959 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10960 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10961 HelperValStmt = buildPreInits(Context, Captures); 10962 } 10963 } 10964 10965 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 10966 StartLoc, LParenLoc, EndLoc); 10967 } 10968 10969 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10970 Expr *Op) { 10971 if (!Op) 10972 return ExprError(); 10973 10974 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10975 public: 10976 IntConvertDiagnoser() 10977 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10978 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10979 QualType T) override { 10980 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10981 } 10982 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10983 QualType T) override { 10984 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10985 } 10986 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10987 QualType T, 10988 QualType ConvTy) override { 10989 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10990 } 10991 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 10992 QualType ConvTy) override { 10993 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10994 << ConvTy->isEnumeralType() << ConvTy; 10995 } 10996 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 10997 QualType T) override { 10998 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 10999 } 11000 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11001 QualType ConvTy) override { 11002 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11003 << ConvTy->isEnumeralType() << ConvTy; 11004 } 11005 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11006 QualType) override { 11007 llvm_unreachable("conversion functions are permitted"); 11008 } 11009 } ConvertDiagnoser; 11010 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11011 } 11012 11013 static bool 11014 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11015 bool StrictlyPositive, bool BuildCapture = false, 11016 OpenMPDirectiveKind DKind = OMPD_unknown, 11017 OpenMPDirectiveKind *CaptureRegion = nullptr, 11018 Stmt **HelperValStmt = nullptr) { 11019 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11020 !ValExpr->isInstantiationDependent()) { 11021 SourceLocation Loc = ValExpr->getExprLoc(); 11022 ExprResult Value = 11023 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11024 if (Value.isInvalid()) 11025 return false; 11026 11027 ValExpr = Value.get(); 11028 // The expression must evaluate to a non-negative integer value. 11029 llvm::APSInt Result; 11030 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11031 Result.isSigned() && 11032 !((!StrictlyPositive && Result.isNonNegative()) || 11033 (StrictlyPositive && Result.isStrictlyPositive()))) { 11034 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11035 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11036 << ValExpr->getSourceRange(); 11037 return false; 11038 } 11039 if (!BuildCapture) 11040 return true; 11041 *CaptureRegion = getOpenMPCaptureRegionForClause(DKind, CKind); 11042 if (*CaptureRegion != OMPD_unknown && 11043 !SemaRef.CurContext->isDependentContext()) { 11044 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11045 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11046 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11047 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11048 } 11049 } 11050 return true; 11051 } 11052 11053 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11054 SourceLocation StartLoc, 11055 SourceLocation LParenLoc, 11056 SourceLocation EndLoc) { 11057 Expr *ValExpr = NumThreads; 11058 Stmt *HelperValStmt = nullptr; 11059 11060 // OpenMP [2.5, Restrictions] 11061 // The num_threads expression must evaluate to a positive integer value. 11062 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11063 /*StrictlyPositive=*/true)) 11064 return nullptr; 11065 11066 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11067 OpenMPDirectiveKind CaptureRegion = 11068 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 11069 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11070 ValExpr = MakeFullExpr(ValExpr).get(); 11071 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11072 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11073 HelperValStmt = buildPreInits(Context, Captures); 11074 } 11075 11076 return new (Context) OMPNumThreadsClause( 11077 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11078 } 11079 11080 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11081 OpenMPClauseKind CKind, 11082 bool StrictlyPositive) { 11083 if (!E) 11084 return ExprError(); 11085 if (E->isValueDependent() || E->isTypeDependent() || 11086 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11087 return E; 11088 llvm::APSInt Result; 11089 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11090 if (ICE.isInvalid()) 11091 return ExprError(); 11092 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11093 (!StrictlyPositive && !Result.isNonNegative())) { 11094 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11095 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11096 << E->getSourceRange(); 11097 return ExprError(); 11098 } 11099 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11100 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11101 << E->getSourceRange(); 11102 return ExprError(); 11103 } 11104 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11105 DSAStack->setAssociatedLoops(Result.getExtValue()); 11106 else if (CKind == OMPC_ordered) 11107 DSAStack->setAssociatedLoops(Result.getExtValue()); 11108 return ICE; 11109 } 11110 11111 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11112 SourceLocation LParenLoc, 11113 SourceLocation EndLoc) { 11114 // OpenMP [2.8.1, simd construct, Description] 11115 // The parameter of the safelen clause must be a constant 11116 // positive integer expression. 11117 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11118 if (Safelen.isInvalid()) 11119 return nullptr; 11120 return new (Context) 11121 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11122 } 11123 11124 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11125 SourceLocation LParenLoc, 11126 SourceLocation EndLoc) { 11127 // OpenMP [2.8.1, simd construct, Description] 11128 // The parameter of the simdlen clause must be a constant 11129 // positive integer expression. 11130 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11131 if (Simdlen.isInvalid()) 11132 return nullptr; 11133 return new (Context) 11134 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11135 } 11136 11137 /// Tries to find omp_allocator_handle_t type. 11138 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11139 DSAStackTy *Stack) { 11140 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11141 if (!OMPAllocatorHandleT.isNull()) 11142 return true; 11143 // Build the predefined allocator expressions. 11144 bool ErrorFound = false; 11145 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11146 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11147 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11148 StringRef Allocator = 11149 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11150 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11151 auto *VD = dyn_cast_or_null<ValueDecl>( 11152 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11153 if (!VD) { 11154 ErrorFound = true; 11155 break; 11156 } 11157 QualType AllocatorType = 11158 VD->getType().getNonLValueExprType(S.getASTContext()); 11159 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11160 if (!Res.isUsable()) { 11161 ErrorFound = true; 11162 break; 11163 } 11164 if (OMPAllocatorHandleT.isNull()) 11165 OMPAllocatorHandleT = AllocatorType; 11166 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11167 ErrorFound = true; 11168 break; 11169 } 11170 Stack->setAllocator(AllocatorKind, Res.get()); 11171 } 11172 if (ErrorFound) { 11173 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11174 return false; 11175 } 11176 OMPAllocatorHandleT.addConst(); 11177 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11178 return true; 11179 } 11180 11181 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11182 SourceLocation LParenLoc, 11183 SourceLocation EndLoc) { 11184 // OpenMP [2.11.3, allocate Directive, Description] 11185 // allocator is an expression of omp_allocator_handle_t type. 11186 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11187 return nullptr; 11188 11189 ExprResult Allocator = DefaultLvalueConversion(A); 11190 if (Allocator.isInvalid()) 11191 return nullptr; 11192 Allocator = PerformImplicitConversion(Allocator.get(), 11193 DSAStack->getOMPAllocatorHandleT(), 11194 Sema::AA_Initializing, 11195 /*AllowExplicit=*/true); 11196 if (Allocator.isInvalid()) 11197 return nullptr; 11198 return new (Context) 11199 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11200 } 11201 11202 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11203 SourceLocation StartLoc, 11204 SourceLocation LParenLoc, 11205 SourceLocation EndLoc) { 11206 // OpenMP [2.7.1, loop construct, Description] 11207 // OpenMP [2.8.1, simd construct, Description] 11208 // OpenMP [2.9.6, distribute construct, Description] 11209 // The parameter of the collapse clause must be a constant 11210 // positive integer expression. 11211 ExprResult NumForLoopsResult = 11212 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11213 if (NumForLoopsResult.isInvalid()) 11214 return nullptr; 11215 return new (Context) 11216 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11217 } 11218 11219 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11220 SourceLocation EndLoc, 11221 SourceLocation LParenLoc, 11222 Expr *NumForLoops) { 11223 // OpenMP [2.7.1, loop construct, Description] 11224 // OpenMP [2.8.1, simd construct, Description] 11225 // OpenMP [2.9.6, distribute construct, Description] 11226 // The parameter of the ordered clause must be a constant 11227 // positive integer expression if any. 11228 if (NumForLoops && LParenLoc.isValid()) { 11229 ExprResult NumForLoopsResult = 11230 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11231 if (NumForLoopsResult.isInvalid()) 11232 return nullptr; 11233 NumForLoops = NumForLoopsResult.get(); 11234 } else { 11235 NumForLoops = nullptr; 11236 } 11237 auto *Clause = OMPOrderedClause::Create( 11238 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11239 StartLoc, LParenLoc, EndLoc); 11240 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11241 return Clause; 11242 } 11243 11244 OMPClause *Sema::ActOnOpenMPSimpleClause( 11245 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11246 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11247 OMPClause *Res = nullptr; 11248 switch (Kind) { 11249 case OMPC_default: 11250 Res = 11251 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11252 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11253 break; 11254 case OMPC_proc_bind: 11255 Res = ActOnOpenMPProcBindClause( 11256 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11257 LParenLoc, EndLoc); 11258 break; 11259 case OMPC_atomic_default_mem_order: 11260 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11261 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11262 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11263 break; 11264 case OMPC_if: 11265 case OMPC_final: 11266 case OMPC_num_threads: 11267 case OMPC_safelen: 11268 case OMPC_simdlen: 11269 case OMPC_allocator: 11270 case OMPC_collapse: 11271 case OMPC_schedule: 11272 case OMPC_private: 11273 case OMPC_firstprivate: 11274 case OMPC_lastprivate: 11275 case OMPC_shared: 11276 case OMPC_reduction: 11277 case OMPC_task_reduction: 11278 case OMPC_in_reduction: 11279 case OMPC_linear: 11280 case OMPC_aligned: 11281 case OMPC_copyin: 11282 case OMPC_copyprivate: 11283 case OMPC_ordered: 11284 case OMPC_nowait: 11285 case OMPC_untied: 11286 case OMPC_mergeable: 11287 case OMPC_threadprivate: 11288 case OMPC_allocate: 11289 case OMPC_flush: 11290 case OMPC_read: 11291 case OMPC_write: 11292 case OMPC_update: 11293 case OMPC_capture: 11294 case OMPC_seq_cst: 11295 case OMPC_depend: 11296 case OMPC_device: 11297 case OMPC_threads: 11298 case OMPC_simd: 11299 case OMPC_map: 11300 case OMPC_num_teams: 11301 case OMPC_thread_limit: 11302 case OMPC_priority: 11303 case OMPC_grainsize: 11304 case OMPC_nogroup: 11305 case OMPC_num_tasks: 11306 case OMPC_hint: 11307 case OMPC_dist_schedule: 11308 case OMPC_defaultmap: 11309 case OMPC_unknown: 11310 case OMPC_uniform: 11311 case OMPC_to: 11312 case OMPC_from: 11313 case OMPC_use_device_ptr: 11314 case OMPC_is_device_ptr: 11315 case OMPC_unified_address: 11316 case OMPC_unified_shared_memory: 11317 case OMPC_reverse_offload: 11318 case OMPC_dynamic_allocators: 11319 case OMPC_device_type: 11320 case OMPC_match: 11321 llvm_unreachable("Clause is not allowed."); 11322 } 11323 return Res; 11324 } 11325 11326 static std::string 11327 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11328 ArrayRef<unsigned> Exclude = llvm::None) { 11329 SmallString<256> Buffer; 11330 llvm::raw_svector_ostream Out(Buffer); 11331 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11332 unsigned Skipped = Exclude.size(); 11333 auto S = Exclude.begin(), E = Exclude.end(); 11334 for (unsigned I = First; I < Last; ++I) { 11335 if (std::find(S, E, I) != E) { 11336 --Skipped; 11337 continue; 11338 } 11339 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11340 if (I == Bound - Skipped) 11341 Out << " or "; 11342 else if (I != Bound + 1 - Skipped) 11343 Out << ", "; 11344 } 11345 return Out.str(); 11346 } 11347 11348 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11349 SourceLocation KindKwLoc, 11350 SourceLocation StartLoc, 11351 SourceLocation LParenLoc, 11352 SourceLocation EndLoc) { 11353 if (Kind == OMPC_DEFAULT_unknown) { 11354 static_assert(OMPC_DEFAULT_unknown > 0, 11355 "OMPC_DEFAULT_unknown not greater than 0"); 11356 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11357 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11358 /*Last=*/OMPC_DEFAULT_unknown) 11359 << getOpenMPClauseName(OMPC_default); 11360 return nullptr; 11361 } 11362 switch (Kind) { 11363 case OMPC_DEFAULT_none: 11364 DSAStack->setDefaultDSANone(KindKwLoc); 11365 break; 11366 case OMPC_DEFAULT_shared: 11367 DSAStack->setDefaultDSAShared(KindKwLoc); 11368 break; 11369 case OMPC_DEFAULT_unknown: 11370 llvm_unreachable("Clause kind is not allowed."); 11371 break; 11372 } 11373 return new (Context) 11374 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11375 } 11376 11377 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11378 SourceLocation KindKwLoc, 11379 SourceLocation StartLoc, 11380 SourceLocation LParenLoc, 11381 SourceLocation EndLoc) { 11382 if (Kind == OMPC_PROC_BIND_unknown) { 11383 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11384 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11385 /*Last=*/OMPC_PROC_BIND_unknown) 11386 << getOpenMPClauseName(OMPC_proc_bind); 11387 return nullptr; 11388 } 11389 return new (Context) 11390 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11391 } 11392 11393 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11394 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11395 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11396 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11397 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11398 << getListOfPossibleValues( 11399 OMPC_atomic_default_mem_order, /*First=*/0, 11400 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11401 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11402 return nullptr; 11403 } 11404 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11405 LParenLoc, EndLoc); 11406 } 11407 11408 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11409 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11410 SourceLocation StartLoc, SourceLocation LParenLoc, 11411 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11412 SourceLocation EndLoc) { 11413 OMPClause *Res = nullptr; 11414 switch (Kind) { 11415 case OMPC_schedule: 11416 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11417 assert(Argument.size() == NumberOfElements && 11418 ArgumentLoc.size() == NumberOfElements); 11419 Res = ActOnOpenMPScheduleClause( 11420 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11421 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11422 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11423 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11424 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11425 break; 11426 case OMPC_if: 11427 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11428 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11429 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11430 DelimLoc, EndLoc); 11431 break; 11432 case OMPC_dist_schedule: 11433 Res = ActOnOpenMPDistScheduleClause( 11434 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11435 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11436 break; 11437 case OMPC_defaultmap: 11438 enum { Modifier, DefaultmapKind }; 11439 Res = ActOnOpenMPDefaultmapClause( 11440 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11441 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11442 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11443 EndLoc); 11444 break; 11445 case OMPC_final: 11446 case OMPC_num_threads: 11447 case OMPC_safelen: 11448 case OMPC_simdlen: 11449 case OMPC_allocator: 11450 case OMPC_collapse: 11451 case OMPC_default: 11452 case OMPC_proc_bind: 11453 case OMPC_private: 11454 case OMPC_firstprivate: 11455 case OMPC_lastprivate: 11456 case OMPC_shared: 11457 case OMPC_reduction: 11458 case OMPC_task_reduction: 11459 case OMPC_in_reduction: 11460 case OMPC_linear: 11461 case OMPC_aligned: 11462 case OMPC_copyin: 11463 case OMPC_copyprivate: 11464 case OMPC_ordered: 11465 case OMPC_nowait: 11466 case OMPC_untied: 11467 case OMPC_mergeable: 11468 case OMPC_threadprivate: 11469 case OMPC_allocate: 11470 case OMPC_flush: 11471 case OMPC_read: 11472 case OMPC_write: 11473 case OMPC_update: 11474 case OMPC_capture: 11475 case OMPC_seq_cst: 11476 case OMPC_depend: 11477 case OMPC_device: 11478 case OMPC_threads: 11479 case OMPC_simd: 11480 case OMPC_map: 11481 case OMPC_num_teams: 11482 case OMPC_thread_limit: 11483 case OMPC_priority: 11484 case OMPC_grainsize: 11485 case OMPC_nogroup: 11486 case OMPC_num_tasks: 11487 case OMPC_hint: 11488 case OMPC_unknown: 11489 case OMPC_uniform: 11490 case OMPC_to: 11491 case OMPC_from: 11492 case OMPC_use_device_ptr: 11493 case OMPC_is_device_ptr: 11494 case OMPC_unified_address: 11495 case OMPC_unified_shared_memory: 11496 case OMPC_reverse_offload: 11497 case OMPC_dynamic_allocators: 11498 case OMPC_atomic_default_mem_order: 11499 case OMPC_device_type: 11500 case OMPC_match: 11501 llvm_unreachable("Clause is not allowed."); 11502 } 11503 return Res; 11504 } 11505 11506 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11507 OpenMPScheduleClauseModifier M2, 11508 SourceLocation M1Loc, SourceLocation M2Loc) { 11509 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11510 SmallVector<unsigned, 2> Excluded; 11511 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11512 Excluded.push_back(M2); 11513 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11514 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11515 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11516 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11517 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11518 << getListOfPossibleValues(OMPC_schedule, 11519 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11520 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11521 Excluded) 11522 << getOpenMPClauseName(OMPC_schedule); 11523 return true; 11524 } 11525 return false; 11526 } 11527 11528 OMPClause *Sema::ActOnOpenMPScheduleClause( 11529 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11530 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11531 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11532 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11533 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11534 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11535 return nullptr; 11536 // OpenMP, 2.7.1, Loop Construct, Restrictions 11537 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11538 // but not both. 11539 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11540 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11541 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11542 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11543 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11544 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11545 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11546 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11547 return nullptr; 11548 } 11549 if (Kind == OMPC_SCHEDULE_unknown) { 11550 std::string Values; 11551 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11552 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11553 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11554 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11555 Exclude); 11556 } else { 11557 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11558 /*Last=*/OMPC_SCHEDULE_unknown); 11559 } 11560 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11561 << Values << getOpenMPClauseName(OMPC_schedule); 11562 return nullptr; 11563 } 11564 // OpenMP, 2.7.1, Loop Construct, Restrictions 11565 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11566 // schedule(guided). 11567 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11568 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11569 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11570 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11571 diag::err_omp_schedule_nonmonotonic_static); 11572 return nullptr; 11573 } 11574 Expr *ValExpr = ChunkSize; 11575 Stmt *HelperValStmt = nullptr; 11576 if (ChunkSize) { 11577 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11578 !ChunkSize->isInstantiationDependent() && 11579 !ChunkSize->containsUnexpandedParameterPack()) { 11580 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11581 ExprResult Val = 11582 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11583 if (Val.isInvalid()) 11584 return nullptr; 11585 11586 ValExpr = Val.get(); 11587 11588 // OpenMP [2.7.1, Restrictions] 11589 // chunk_size must be a loop invariant integer expression with a positive 11590 // value. 11591 llvm::APSInt Result; 11592 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11593 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11594 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11595 << "schedule" << 1 << ChunkSize->getSourceRange(); 11596 return nullptr; 11597 } 11598 } else if (getOpenMPCaptureRegionForClause( 11599 DSAStack->getCurrentDirective(), OMPC_schedule) != 11600 OMPD_unknown && 11601 !CurContext->isDependentContext()) { 11602 ValExpr = MakeFullExpr(ValExpr).get(); 11603 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11604 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11605 HelperValStmt = buildPreInits(Context, Captures); 11606 } 11607 } 11608 } 11609 11610 return new (Context) 11611 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11612 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11613 } 11614 11615 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11616 SourceLocation StartLoc, 11617 SourceLocation EndLoc) { 11618 OMPClause *Res = nullptr; 11619 switch (Kind) { 11620 case OMPC_ordered: 11621 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11622 break; 11623 case OMPC_nowait: 11624 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11625 break; 11626 case OMPC_untied: 11627 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11628 break; 11629 case OMPC_mergeable: 11630 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11631 break; 11632 case OMPC_read: 11633 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11634 break; 11635 case OMPC_write: 11636 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11637 break; 11638 case OMPC_update: 11639 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11640 break; 11641 case OMPC_capture: 11642 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11643 break; 11644 case OMPC_seq_cst: 11645 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11646 break; 11647 case OMPC_threads: 11648 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11649 break; 11650 case OMPC_simd: 11651 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11652 break; 11653 case OMPC_nogroup: 11654 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11655 break; 11656 case OMPC_unified_address: 11657 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11658 break; 11659 case OMPC_unified_shared_memory: 11660 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11661 break; 11662 case OMPC_reverse_offload: 11663 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11664 break; 11665 case OMPC_dynamic_allocators: 11666 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11667 break; 11668 case OMPC_if: 11669 case OMPC_final: 11670 case OMPC_num_threads: 11671 case OMPC_safelen: 11672 case OMPC_simdlen: 11673 case OMPC_allocator: 11674 case OMPC_collapse: 11675 case OMPC_schedule: 11676 case OMPC_private: 11677 case OMPC_firstprivate: 11678 case OMPC_lastprivate: 11679 case OMPC_shared: 11680 case OMPC_reduction: 11681 case OMPC_task_reduction: 11682 case OMPC_in_reduction: 11683 case OMPC_linear: 11684 case OMPC_aligned: 11685 case OMPC_copyin: 11686 case OMPC_copyprivate: 11687 case OMPC_default: 11688 case OMPC_proc_bind: 11689 case OMPC_threadprivate: 11690 case OMPC_allocate: 11691 case OMPC_flush: 11692 case OMPC_depend: 11693 case OMPC_device: 11694 case OMPC_map: 11695 case OMPC_num_teams: 11696 case OMPC_thread_limit: 11697 case OMPC_priority: 11698 case OMPC_grainsize: 11699 case OMPC_num_tasks: 11700 case OMPC_hint: 11701 case OMPC_dist_schedule: 11702 case OMPC_defaultmap: 11703 case OMPC_unknown: 11704 case OMPC_uniform: 11705 case OMPC_to: 11706 case OMPC_from: 11707 case OMPC_use_device_ptr: 11708 case OMPC_is_device_ptr: 11709 case OMPC_atomic_default_mem_order: 11710 case OMPC_device_type: 11711 case OMPC_match: 11712 llvm_unreachable("Clause is not allowed."); 11713 } 11714 return Res; 11715 } 11716 11717 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11718 SourceLocation EndLoc) { 11719 DSAStack->setNowaitRegion(); 11720 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11721 } 11722 11723 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11724 SourceLocation EndLoc) { 11725 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11726 } 11727 11728 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11729 SourceLocation EndLoc) { 11730 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11731 } 11732 11733 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11734 SourceLocation EndLoc) { 11735 return new (Context) OMPReadClause(StartLoc, EndLoc); 11736 } 11737 11738 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11739 SourceLocation EndLoc) { 11740 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11741 } 11742 11743 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11744 SourceLocation EndLoc) { 11745 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11746 } 11747 11748 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11749 SourceLocation EndLoc) { 11750 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11751 } 11752 11753 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11754 SourceLocation EndLoc) { 11755 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11756 } 11757 11758 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11759 SourceLocation EndLoc) { 11760 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11761 } 11762 11763 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11764 SourceLocation EndLoc) { 11765 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11766 } 11767 11768 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11769 SourceLocation EndLoc) { 11770 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11771 } 11772 11773 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11774 SourceLocation EndLoc) { 11775 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11776 } 11777 11778 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11779 SourceLocation EndLoc) { 11780 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11781 } 11782 11783 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11784 SourceLocation EndLoc) { 11785 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11786 } 11787 11788 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11789 SourceLocation EndLoc) { 11790 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11791 } 11792 11793 OMPClause *Sema::ActOnOpenMPVarListClause( 11794 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11795 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11796 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11797 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11798 OpenMPLinearClauseKind LinKind, 11799 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11800 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11801 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11802 SourceLocation StartLoc = Locs.StartLoc; 11803 SourceLocation LParenLoc = Locs.LParenLoc; 11804 SourceLocation EndLoc = Locs.EndLoc; 11805 OMPClause *Res = nullptr; 11806 switch (Kind) { 11807 case OMPC_private: 11808 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11809 break; 11810 case OMPC_firstprivate: 11811 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11812 break; 11813 case OMPC_lastprivate: 11814 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11815 break; 11816 case OMPC_shared: 11817 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11818 break; 11819 case OMPC_reduction: 11820 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11821 EndLoc, ReductionOrMapperIdScopeSpec, 11822 ReductionOrMapperId); 11823 break; 11824 case OMPC_task_reduction: 11825 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11826 EndLoc, ReductionOrMapperIdScopeSpec, 11827 ReductionOrMapperId); 11828 break; 11829 case OMPC_in_reduction: 11830 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11831 EndLoc, ReductionOrMapperIdScopeSpec, 11832 ReductionOrMapperId); 11833 break; 11834 case OMPC_linear: 11835 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11836 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11837 break; 11838 case OMPC_aligned: 11839 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11840 ColonLoc, EndLoc); 11841 break; 11842 case OMPC_copyin: 11843 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11844 break; 11845 case OMPC_copyprivate: 11846 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11847 break; 11848 case OMPC_flush: 11849 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11850 break; 11851 case OMPC_depend: 11852 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11853 StartLoc, LParenLoc, EndLoc); 11854 break; 11855 case OMPC_map: 11856 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11857 ReductionOrMapperIdScopeSpec, 11858 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11859 DepLinMapLoc, ColonLoc, VarList, Locs); 11860 break; 11861 case OMPC_to: 11862 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11863 ReductionOrMapperId, Locs); 11864 break; 11865 case OMPC_from: 11866 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11867 ReductionOrMapperId, Locs); 11868 break; 11869 case OMPC_use_device_ptr: 11870 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11871 break; 11872 case OMPC_is_device_ptr: 11873 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11874 break; 11875 case OMPC_allocate: 11876 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11877 ColonLoc, EndLoc); 11878 break; 11879 case OMPC_if: 11880 case OMPC_final: 11881 case OMPC_num_threads: 11882 case OMPC_safelen: 11883 case OMPC_simdlen: 11884 case OMPC_allocator: 11885 case OMPC_collapse: 11886 case OMPC_default: 11887 case OMPC_proc_bind: 11888 case OMPC_schedule: 11889 case OMPC_ordered: 11890 case OMPC_nowait: 11891 case OMPC_untied: 11892 case OMPC_mergeable: 11893 case OMPC_threadprivate: 11894 case OMPC_read: 11895 case OMPC_write: 11896 case OMPC_update: 11897 case OMPC_capture: 11898 case OMPC_seq_cst: 11899 case OMPC_device: 11900 case OMPC_threads: 11901 case OMPC_simd: 11902 case OMPC_num_teams: 11903 case OMPC_thread_limit: 11904 case OMPC_priority: 11905 case OMPC_grainsize: 11906 case OMPC_nogroup: 11907 case OMPC_num_tasks: 11908 case OMPC_hint: 11909 case OMPC_dist_schedule: 11910 case OMPC_defaultmap: 11911 case OMPC_unknown: 11912 case OMPC_uniform: 11913 case OMPC_unified_address: 11914 case OMPC_unified_shared_memory: 11915 case OMPC_reverse_offload: 11916 case OMPC_dynamic_allocators: 11917 case OMPC_atomic_default_mem_order: 11918 case OMPC_device_type: 11919 case OMPC_match: 11920 llvm_unreachable("Clause is not allowed."); 11921 } 11922 return Res; 11923 } 11924 11925 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11926 ExprObjectKind OK, SourceLocation Loc) { 11927 ExprResult Res = BuildDeclRefExpr( 11928 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11929 if (!Res.isUsable()) 11930 return ExprError(); 11931 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11932 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11933 if (!Res.isUsable()) 11934 return ExprError(); 11935 } 11936 if (VK != VK_LValue && Res.get()->isGLValue()) { 11937 Res = DefaultLvalueConversion(Res.get()); 11938 if (!Res.isUsable()) 11939 return ExprError(); 11940 } 11941 return Res; 11942 } 11943 11944 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11945 SourceLocation StartLoc, 11946 SourceLocation LParenLoc, 11947 SourceLocation EndLoc) { 11948 SmallVector<Expr *, 8> Vars; 11949 SmallVector<Expr *, 8> PrivateCopies; 11950 for (Expr *RefExpr : VarList) { 11951 assert(RefExpr && "NULL expr in OpenMP private clause."); 11952 SourceLocation ELoc; 11953 SourceRange ERange; 11954 Expr *SimpleRefExpr = RefExpr; 11955 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11956 if (Res.second) { 11957 // It will be analyzed later. 11958 Vars.push_back(RefExpr); 11959 PrivateCopies.push_back(nullptr); 11960 } 11961 ValueDecl *D = Res.first; 11962 if (!D) 11963 continue; 11964 11965 QualType Type = D->getType(); 11966 auto *VD = dyn_cast<VarDecl>(D); 11967 11968 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11969 // A variable that appears in a private clause must not have an incomplete 11970 // type or a reference type. 11971 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11972 continue; 11973 Type = Type.getNonReferenceType(); 11974 11975 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11976 // A variable that is privatized must not have a const-qualified type 11977 // unless it is of class type with a mutable member. This restriction does 11978 // not apply to the firstprivate clause. 11979 // 11980 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11981 // A variable that appears in a private clause must not have a 11982 // const-qualified type unless it is of class type with a mutable member. 11983 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11984 continue; 11985 11986 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11987 // in a Construct] 11988 // Variables with the predetermined data-sharing attributes may not be 11989 // listed in data-sharing attributes clauses, except for the cases 11990 // listed below. For these exceptions only, listing a predetermined 11991 // variable in a data-sharing attribute clause is allowed and overrides 11992 // the variable's predetermined data-sharing attributes. 11993 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11994 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 11995 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11996 << getOpenMPClauseName(OMPC_private); 11997 reportOriginalDsa(*this, DSAStack, D, DVar); 11998 continue; 11999 } 12000 12001 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12002 // Variably modified types are not supported for tasks. 12003 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12004 isOpenMPTaskingDirective(CurrDir)) { 12005 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12006 << getOpenMPClauseName(OMPC_private) << Type 12007 << getOpenMPDirectiveName(CurrDir); 12008 bool IsDecl = 12009 !VD || 12010 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12011 Diag(D->getLocation(), 12012 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12013 << D; 12014 continue; 12015 } 12016 12017 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12018 // A list item cannot appear in both a map clause and a data-sharing 12019 // attribute clause on the same construct 12020 // 12021 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12022 // A list item cannot appear in both a map clause and a data-sharing 12023 // attribute clause on the same construct unless the construct is a 12024 // combined construct. 12025 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12026 CurrDir == OMPD_target) { 12027 OpenMPClauseKind ConflictKind; 12028 if (DSAStack->checkMappableExprComponentListsForDecl( 12029 VD, /*CurrentRegionOnly=*/true, 12030 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12031 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12032 ConflictKind = WhereFoundClauseKind; 12033 return true; 12034 })) { 12035 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12036 << getOpenMPClauseName(OMPC_private) 12037 << getOpenMPClauseName(ConflictKind) 12038 << getOpenMPDirectiveName(CurrDir); 12039 reportOriginalDsa(*this, DSAStack, D, DVar); 12040 continue; 12041 } 12042 } 12043 12044 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12045 // A variable of class type (or array thereof) that appears in a private 12046 // clause requires an accessible, unambiguous default constructor for the 12047 // class type. 12048 // Generate helper private variable and initialize it with the default 12049 // value. The address of the original variable is replaced by the address of 12050 // the new private variable in CodeGen. This new variable is not added to 12051 // IdResolver, so the code in the OpenMP region uses original variable for 12052 // proper diagnostics. 12053 Type = Type.getUnqualifiedType(); 12054 VarDecl *VDPrivate = 12055 buildVarDecl(*this, ELoc, Type, D->getName(), 12056 D->hasAttrs() ? &D->getAttrs() : nullptr, 12057 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12058 ActOnUninitializedDecl(VDPrivate); 12059 if (VDPrivate->isInvalidDecl()) 12060 continue; 12061 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12062 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12063 12064 DeclRefExpr *Ref = nullptr; 12065 if (!VD && !CurContext->isDependentContext()) 12066 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12067 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12068 Vars.push_back((VD || CurContext->isDependentContext()) 12069 ? RefExpr->IgnoreParens() 12070 : Ref); 12071 PrivateCopies.push_back(VDPrivateRefExpr); 12072 } 12073 12074 if (Vars.empty()) 12075 return nullptr; 12076 12077 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12078 PrivateCopies); 12079 } 12080 12081 namespace { 12082 class DiagsUninitializedSeveretyRAII { 12083 private: 12084 DiagnosticsEngine &Diags; 12085 SourceLocation SavedLoc; 12086 bool IsIgnored = false; 12087 12088 public: 12089 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12090 bool IsIgnored) 12091 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12092 if (!IsIgnored) { 12093 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12094 /*Map*/ diag::Severity::Ignored, Loc); 12095 } 12096 } 12097 ~DiagsUninitializedSeveretyRAII() { 12098 if (!IsIgnored) 12099 Diags.popMappings(SavedLoc); 12100 } 12101 }; 12102 } 12103 12104 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12105 SourceLocation StartLoc, 12106 SourceLocation LParenLoc, 12107 SourceLocation EndLoc) { 12108 SmallVector<Expr *, 8> Vars; 12109 SmallVector<Expr *, 8> PrivateCopies; 12110 SmallVector<Expr *, 8> Inits; 12111 SmallVector<Decl *, 4> ExprCaptures; 12112 bool IsImplicitClause = 12113 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12114 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12115 12116 for (Expr *RefExpr : VarList) { 12117 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12118 SourceLocation ELoc; 12119 SourceRange ERange; 12120 Expr *SimpleRefExpr = RefExpr; 12121 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12122 if (Res.second) { 12123 // It will be analyzed later. 12124 Vars.push_back(RefExpr); 12125 PrivateCopies.push_back(nullptr); 12126 Inits.push_back(nullptr); 12127 } 12128 ValueDecl *D = Res.first; 12129 if (!D) 12130 continue; 12131 12132 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12133 QualType Type = D->getType(); 12134 auto *VD = dyn_cast<VarDecl>(D); 12135 12136 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12137 // A variable that appears in a private clause must not have an incomplete 12138 // type or a reference type. 12139 if (RequireCompleteType(ELoc, Type, 12140 diag::err_omp_firstprivate_incomplete_type)) 12141 continue; 12142 Type = Type.getNonReferenceType(); 12143 12144 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12145 // A variable of class type (or array thereof) that appears in a private 12146 // clause requires an accessible, unambiguous copy constructor for the 12147 // class type. 12148 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12149 12150 // If an implicit firstprivate variable found it was checked already. 12151 DSAStackTy::DSAVarData TopDVar; 12152 if (!IsImplicitClause) { 12153 DSAStackTy::DSAVarData DVar = 12154 DSAStack->getTopDSA(D, /*FromParent=*/false); 12155 TopDVar = DVar; 12156 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12157 bool IsConstant = ElemType.isConstant(Context); 12158 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12159 // A list item that specifies a given variable may not appear in more 12160 // than one clause on the same directive, except that a variable may be 12161 // specified in both firstprivate and lastprivate clauses. 12162 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12163 // A list item may appear in a firstprivate or lastprivate clause but not 12164 // both. 12165 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12166 (isOpenMPDistributeDirective(CurrDir) || 12167 DVar.CKind != OMPC_lastprivate) && 12168 DVar.RefExpr) { 12169 Diag(ELoc, diag::err_omp_wrong_dsa) 12170 << getOpenMPClauseName(DVar.CKind) 12171 << getOpenMPClauseName(OMPC_firstprivate); 12172 reportOriginalDsa(*this, DSAStack, D, DVar); 12173 continue; 12174 } 12175 12176 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12177 // in a Construct] 12178 // Variables with the predetermined data-sharing attributes may not be 12179 // listed in data-sharing attributes clauses, except for the cases 12180 // listed below. For these exceptions only, listing a predetermined 12181 // variable in a data-sharing attribute clause is allowed and overrides 12182 // the variable's predetermined data-sharing attributes. 12183 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12184 // in a Construct, C/C++, p.2] 12185 // Variables with const-qualified type having no mutable member may be 12186 // listed in a firstprivate clause, even if they are static data members. 12187 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12188 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12189 Diag(ELoc, diag::err_omp_wrong_dsa) 12190 << getOpenMPClauseName(DVar.CKind) 12191 << getOpenMPClauseName(OMPC_firstprivate); 12192 reportOriginalDsa(*this, DSAStack, D, DVar); 12193 continue; 12194 } 12195 12196 // OpenMP [2.9.3.4, Restrictions, p.2] 12197 // A list item that is private within a parallel region must not appear 12198 // in a firstprivate clause on a worksharing construct if any of the 12199 // worksharing regions arising from the worksharing construct ever bind 12200 // to any of the parallel regions arising from the parallel construct. 12201 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12202 // A list item that is private within a teams region must not appear in a 12203 // firstprivate clause on a distribute construct if any of the distribute 12204 // regions arising from the distribute construct ever bind to any of the 12205 // teams regions arising from the teams construct. 12206 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12207 // A list item that appears in a reduction clause of a teams construct 12208 // must not appear in a firstprivate clause on a distribute construct if 12209 // any of the distribute regions arising from the distribute construct 12210 // ever bind to any of the teams regions arising from the teams construct. 12211 if ((isOpenMPWorksharingDirective(CurrDir) || 12212 isOpenMPDistributeDirective(CurrDir)) && 12213 !isOpenMPParallelDirective(CurrDir) && 12214 !isOpenMPTeamsDirective(CurrDir)) { 12215 DVar = DSAStack->getImplicitDSA(D, true); 12216 if (DVar.CKind != OMPC_shared && 12217 (isOpenMPParallelDirective(DVar.DKind) || 12218 isOpenMPTeamsDirective(DVar.DKind) || 12219 DVar.DKind == OMPD_unknown)) { 12220 Diag(ELoc, diag::err_omp_required_access) 12221 << getOpenMPClauseName(OMPC_firstprivate) 12222 << getOpenMPClauseName(OMPC_shared); 12223 reportOriginalDsa(*this, DSAStack, D, DVar); 12224 continue; 12225 } 12226 } 12227 // OpenMP [2.9.3.4, Restrictions, p.3] 12228 // A list item that appears in a reduction clause of a parallel construct 12229 // must not appear in a firstprivate clause on a worksharing or task 12230 // construct if any of the worksharing or task regions arising from the 12231 // worksharing or task construct ever bind to any of the parallel regions 12232 // arising from the parallel construct. 12233 // OpenMP [2.9.3.4, Restrictions, p.4] 12234 // A list item that appears in a reduction clause in worksharing 12235 // construct must not appear in a firstprivate clause in a task construct 12236 // encountered during execution of any of the worksharing regions arising 12237 // from the worksharing construct. 12238 if (isOpenMPTaskingDirective(CurrDir)) { 12239 DVar = DSAStack->hasInnermostDSA( 12240 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12241 [](OpenMPDirectiveKind K) { 12242 return isOpenMPParallelDirective(K) || 12243 isOpenMPWorksharingDirective(K) || 12244 isOpenMPTeamsDirective(K); 12245 }, 12246 /*FromParent=*/true); 12247 if (DVar.CKind == OMPC_reduction && 12248 (isOpenMPParallelDirective(DVar.DKind) || 12249 isOpenMPWorksharingDirective(DVar.DKind) || 12250 isOpenMPTeamsDirective(DVar.DKind))) { 12251 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12252 << getOpenMPDirectiveName(DVar.DKind); 12253 reportOriginalDsa(*this, DSAStack, D, DVar); 12254 continue; 12255 } 12256 } 12257 12258 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12259 // A list item cannot appear in both a map clause and a data-sharing 12260 // attribute clause on the same construct 12261 // 12262 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12263 // A list item cannot appear in both a map clause and a data-sharing 12264 // attribute clause on the same construct unless the construct is a 12265 // combined construct. 12266 if ((LangOpts.OpenMP <= 45 && 12267 isOpenMPTargetExecutionDirective(CurrDir)) || 12268 CurrDir == OMPD_target) { 12269 OpenMPClauseKind ConflictKind; 12270 if (DSAStack->checkMappableExprComponentListsForDecl( 12271 VD, /*CurrentRegionOnly=*/true, 12272 [&ConflictKind]( 12273 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12274 OpenMPClauseKind WhereFoundClauseKind) { 12275 ConflictKind = WhereFoundClauseKind; 12276 return true; 12277 })) { 12278 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12279 << getOpenMPClauseName(OMPC_firstprivate) 12280 << getOpenMPClauseName(ConflictKind) 12281 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12282 reportOriginalDsa(*this, DSAStack, D, DVar); 12283 continue; 12284 } 12285 } 12286 } 12287 12288 // Variably modified types are not supported for tasks. 12289 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12290 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12291 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12292 << getOpenMPClauseName(OMPC_firstprivate) << Type 12293 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12294 bool IsDecl = 12295 !VD || 12296 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12297 Diag(D->getLocation(), 12298 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12299 << D; 12300 continue; 12301 } 12302 12303 Type = Type.getUnqualifiedType(); 12304 VarDecl *VDPrivate = 12305 buildVarDecl(*this, ELoc, Type, D->getName(), 12306 D->hasAttrs() ? &D->getAttrs() : nullptr, 12307 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12308 // Generate helper private variable and initialize it with the value of the 12309 // original variable. The address of the original variable is replaced by 12310 // the address of the new private variable in the CodeGen. This new variable 12311 // is not added to IdResolver, so the code in the OpenMP region uses 12312 // original variable for proper diagnostics and variable capturing. 12313 Expr *VDInitRefExpr = nullptr; 12314 // For arrays generate initializer for single element and replace it by the 12315 // original array element in CodeGen. 12316 if (Type->isArrayType()) { 12317 VarDecl *VDInit = 12318 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12319 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12320 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12321 ElemType = ElemType.getUnqualifiedType(); 12322 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12323 ".firstprivate.temp"); 12324 InitializedEntity Entity = 12325 InitializedEntity::InitializeVariable(VDInitTemp); 12326 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12327 12328 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12329 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12330 if (Result.isInvalid()) 12331 VDPrivate->setInvalidDecl(); 12332 else 12333 VDPrivate->setInit(Result.getAs<Expr>()); 12334 // Remove temp variable declaration. 12335 Context.Deallocate(VDInitTemp); 12336 } else { 12337 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12338 ".firstprivate.temp"); 12339 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12340 RefExpr->getExprLoc()); 12341 AddInitializerToDecl(VDPrivate, 12342 DefaultLvalueConversion(VDInitRefExpr).get(), 12343 /*DirectInit=*/false); 12344 } 12345 if (VDPrivate->isInvalidDecl()) { 12346 if (IsImplicitClause) { 12347 Diag(RefExpr->getExprLoc(), 12348 diag::note_omp_task_predetermined_firstprivate_here); 12349 } 12350 continue; 12351 } 12352 CurContext->addDecl(VDPrivate); 12353 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12354 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12355 RefExpr->getExprLoc()); 12356 DeclRefExpr *Ref = nullptr; 12357 if (!VD && !CurContext->isDependentContext()) { 12358 if (TopDVar.CKind == OMPC_lastprivate) { 12359 Ref = TopDVar.PrivateCopy; 12360 } else { 12361 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12362 if (!isOpenMPCapturedDecl(D)) 12363 ExprCaptures.push_back(Ref->getDecl()); 12364 } 12365 } 12366 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12367 Vars.push_back((VD || CurContext->isDependentContext()) 12368 ? RefExpr->IgnoreParens() 12369 : Ref); 12370 PrivateCopies.push_back(VDPrivateRefExpr); 12371 Inits.push_back(VDInitRefExpr); 12372 } 12373 12374 if (Vars.empty()) 12375 return nullptr; 12376 12377 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12378 Vars, PrivateCopies, Inits, 12379 buildPreInits(Context, ExprCaptures)); 12380 } 12381 12382 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12383 SourceLocation StartLoc, 12384 SourceLocation LParenLoc, 12385 SourceLocation EndLoc) { 12386 SmallVector<Expr *, 8> Vars; 12387 SmallVector<Expr *, 8> SrcExprs; 12388 SmallVector<Expr *, 8> DstExprs; 12389 SmallVector<Expr *, 8> AssignmentOps; 12390 SmallVector<Decl *, 4> ExprCaptures; 12391 SmallVector<Expr *, 4> ExprPostUpdates; 12392 for (Expr *RefExpr : VarList) { 12393 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12394 SourceLocation ELoc; 12395 SourceRange ERange; 12396 Expr *SimpleRefExpr = RefExpr; 12397 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12398 if (Res.second) { 12399 // It will be analyzed later. 12400 Vars.push_back(RefExpr); 12401 SrcExprs.push_back(nullptr); 12402 DstExprs.push_back(nullptr); 12403 AssignmentOps.push_back(nullptr); 12404 } 12405 ValueDecl *D = Res.first; 12406 if (!D) 12407 continue; 12408 12409 QualType Type = D->getType(); 12410 auto *VD = dyn_cast<VarDecl>(D); 12411 12412 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12413 // A variable that appears in a lastprivate clause must not have an 12414 // incomplete type or a reference type. 12415 if (RequireCompleteType(ELoc, Type, 12416 diag::err_omp_lastprivate_incomplete_type)) 12417 continue; 12418 Type = Type.getNonReferenceType(); 12419 12420 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12421 // A variable that is privatized must not have a const-qualified type 12422 // unless it is of class type with a mutable member. This restriction does 12423 // not apply to the firstprivate clause. 12424 // 12425 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12426 // A variable that appears in a lastprivate clause must not have a 12427 // const-qualified type unless it is of class type with a mutable member. 12428 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12429 continue; 12430 12431 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12432 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12433 // in a Construct] 12434 // Variables with the predetermined data-sharing attributes may not be 12435 // listed in data-sharing attributes clauses, except for the cases 12436 // listed below. 12437 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12438 // A list item may appear in a firstprivate or lastprivate clause but not 12439 // both. 12440 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12441 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12442 (isOpenMPDistributeDirective(CurrDir) || 12443 DVar.CKind != OMPC_firstprivate) && 12444 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12445 Diag(ELoc, diag::err_omp_wrong_dsa) 12446 << getOpenMPClauseName(DVar.CKind) 12447 << getOpenMPClauseName(OMPC_lastprivate); 12448 reportOriginalDsa(*this, DSAStack, D, DVar); 12449 continue; 12450 } 12451 12452 // OpenMP [2.14.3.5, Restrictions, p.2] 12453 // A list item that is private within a parallel region, or that appears in 12454 // the reduction clause of a parallel construct, must not appear in a 12455 // lastprivate clause on a worksharing construct if any of the corresponding 12456 // worksharing regions ever binds to any of the corresponding parallel 12457 // regions. 12458 DSAStackTy::DSAVarData TopDVar = DVar; 12459 if (isOpenMPWorksharingDirective(CurrDir) && 12460 !isOpenMPParallelDirective(CurrDir) && 12461 !isOpenMPTeamsDirective(CurrDir)) { 12462 DVar = DSAStack->getImplicitDSA(D, true); 12463 if (DVar.CKind != OMPC_shared) { 12464 Diag(ELoc, diag::err_omp_required_access) 12465 << getOpenMPClauseName(OMPC_lastprivate) 12466 << getOpenMPClauseName(OMPC_shared); 12467 reportOriginalDsa(*this, DSAStack, D, DVar); 12468 continue; 12469 } 12470 } 12471 12472 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12473 // A variable of class type (or array thereof) that appears in a 12474 // lastprivate clause requires an accessible, unambiguous default 12475 // constructor for the class type, unless the list item is also specified 12476 // in a firstprivate clause. 12477 // A variable of class type (or array thereof) that appears in a 12478 // lastprivate clause requires an accessible, unambiguous copy assignment 12479 // operator for the class type. 12480 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12481 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12482 Type.getUnqualifiedType(), ".lastprivate.src", 12483 D->hasAttrs() ? &D->getAttrs() : nullptr); 12484 DeclRefExpr *PseudoSrcExpr = 12485 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12486 VarDecl *DstVD = 12487 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12488 D->hasAttrs() ? &D->getAttrs() : nullptr); 12489 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12490 // For arrays generate assignment operation for single element and replace 12491 // it by the original array element in CodeGen. 12492 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12493 PseudoDstExpr, PseudoSrcExpr); 12494 if (AssignmentOp.isInvalid()) 12495 continue; 12496 AssignmentOp = 12497 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12498 if (AssignmentOp.isInvalid()) 12499 continue; 12500 12501 DeclRefExpr *Ref = nullptr; 12502 if (!VD && !CurContext->isDependentContext()) { 12503 if (TopDVar.CKind == OMPC_firstprivate) { 12504 Ref = TopDVar.PrivateCopy; 12505 } else { 12506 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12507 if (!isOpenMPCapturedDecl(D)) 12508 ExprCaptures.push_back(Ref->getDecl()); 12509 } 12510 if (TopDVar.CKind == OMPC_firstprivate || 12511 (!isOpenMPCapturedDecl(D) && 12512 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12513 ExprResult RefRes = DefaultLvalueConversion(Ref); 12514 if (!RefRes.isUsable()) 12515 continue; 12516 ExprResult PostUpdateRes = 12517 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12518 RefRes.get()); 12519 if (!PostUpdateRes.isUsable()) 12520 continue; 12521 ExprPostUpdates.push_back( 12522 IgnoredValueConversions(PostUpdateRes.get()).get()); 12523 } 12524 } 12525 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12526 Vars.push_back((VD || CurContext->isDependentContext()) 12527 ? RefExpr->IgnoreParens() 12528 : Ref); 12529 SrcExprs.push_back(PseudoSrcExpr); 12530 DstExprs.push_back(PseudoDstExpr); 12531 AssignmentOps.push_back(AssignmentOp.get()); 12532 } 12533 12534 if (Vars.empty()) 12535 return nullptr; 12536 12537 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12538 Vars, SrcExprs, DstExprs, AssignmentOps, 12539 buildPreInits(Context, ExprCaptures), 12540 buildPostUpdate(*this, ExprPostUpdates)); 12541 } 12542 12543 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12544 SourceLocation StartLoc, 12545 SourceLocation LParenLoc, 12546 SourceLocation EndLoc) { 12547 SmallVector<Expr *, 8> Vars; 12548 for (Expr *RefExpr : VarList) { 12549 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12550 SourceLocation ELoc; 12551 SourceRange ERange; 12552 Expr *SimpleRefExpr = RefExpr; 12553 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12554 if (Res.second) { 12555 // It will be analyzed later. 12556 Vars.push_back(RefExpr); 12557 } 12558 ValueDecl *D = Res.first; 12559 if (!D) 12560 continue; 12561 12562 auto *VD = dyn_cast<VarDecl>(D); 12563 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12564 // in a Construct] 12565 // Variables with the predetermined data-sharing attributes may not be 12566 // listed in data-sharing attributes clauses, except for the cases 12567 // listed below. For these exceptions only, listing a predetermined 12568 // variable in a data-sharing attribute clause is allowed and overrides 12569 // the variable's predetermined data-sharing attributes. 12570 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12571 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12572 DVar.RefExpr) { 12573 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12574 << getOpenMPClauseName(OMPC_shared); 12575 reportOriginalDsa(*this, DSAStack, D, DVar); 12576 continue; 12577 } 12578 12579 DeclRefExpr *Ref = nullptr; 12580 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12581 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12582 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12583 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12584 ? RefExpr->IgnoreParens() 12585 : Ref); 12586 } 12587 12588 if (Vars.empty()) 12589 return nullptr; 12590 12591 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12592 } 12593 12594 namespace { 12595 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12596 DSAStackTy *Stack; 12597 12598 public: 12599 bool VisitDeclRefExpr(DeclRefExpr *E) { 12600 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12601 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12602 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12603 return false; 12604 if (DVar.CKind != OMPC_unknown) 12605 return true; 12606 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12607 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12608 /*FromParent=*/true); 12609 return DVarPrivate.CKind != OMPC_unknown; 12610 } 12611 return false; 12612 } 12613 bool VisitStmt(Stmt *S) { 12614 for (Stmt *Child : S->children()) { 12615 if (Child && Visit(Child)) 12616 return true; 12617 } 12618 return false; 12619 } 12620 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12621 }; 12622 } // namespace 12623 12624 namespace { 12625 // Transform MemberExpression for specified FieldDecl of current class to 12626 // DeclRefExpr to specified OMPCapturedExprDecl. 12627 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12628 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12629 ValueDecl *Field = nullptr; 12630 DeclRefExpr *CapturedExpr = nullptr; 12631 12632 public: 12633 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12634 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12635 12636 ExprResult TransformMemberExpr(MemberExpr *E) { 12637 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12638 E->getMemberDecl() == Field) { 12639 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12640 return CapturedExpr; 12641 } 12642 return BaseTransform::TransformMemberExpr(E); 12643 } 12644 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12645 }; 12646 } // namespace 12647 12648 template <typename T, typename U> 12649 static T filterLookupForUDReductionAndMapper( 12650 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12651 for (U &Set : Lookups) { 12652 for (auto *D : Set) { 12653 if (T Res = Gen(cast<ValueDecl>(D))) 12654 return Res; 12655 } 12656 } 12657 return T(); 12658 } 12659 12660 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12661 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12662 12663 for (auto RD : D->redecls()) { 12664 // Don't bother with extra checks if we already know this one isn't visible. 12665 if (RD == D) 12666 continue; 12667 12668 auto ND = cast<NamedDecl>(RD); 12669 if (LookupResult::isVisible(SemaRef, ND)) 12670 return ND; 12671 } 12672 12673 return nullptr; 12674 } 12675 12676 static void 12677 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12678 SourceLocation Loc, QualType Ty, 12679 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12680 // Find all of the associated namespaces and classes based on the 12681 // arguments we have. 12682 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12683 Sema::AssociatedClassSet AssociatedClasses; 12684 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12685 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12686 AssociatedClasses); 12687 12688 // C++ [basic.lookup.argdep]p3: 12689 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12690 // and let Y be the lookup set produced by argument dependent 12691 // lookup (defined as follows). If X contains [...] then Y is 12692 // empty. Otherwise Y is the set of declarations found in the 12693 // namespaces associated with the argument types as described 12694 // below. The set of declarations found by the lookup of the name 12695 // is the union of X and Y. 12696 // 12697 // Here, we compute Y and add its members to the overloaded 12698 // candidate set. 12699 for (auto *NS : AssociatedNamespaces) { 12700 // When considering an associated namespace, the lookup is the 12701 // same as the lookup performed when the associated namespace is 12702 // used as a qualifier (3.4.3.2) except that: 12703 // 12704 // -- Any using-directives in the associated namespace are 12705 // ignored. 12706 // 12707 // -- Any namespace-scope friend functions declared in 12708 // associated classes are visible within their respective 12709 // namespaces even if they are not visible during an ordinary 12710 // lookup (11.4). 12711 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12712 for (auto *D : R) { 12713 auto *Underlying = D; 12714 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12715 Underlying = USD->getTargetDecl(); 12716 12717 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12718 !isa<OMPDeclareMapperDecl>(Underlying)) 12719 continue; 12720 12721 if (!SemaRef.isVisible(D)) { 12722 D = findAcceptableDecl(SemaRef, D); 12723 if (!D) 12724 continue; 12725 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12726 Underlying = USD->getTargetDecl(); 12727 } 12728 Lookups.emplace_back(); 12729 Lookups.back().addDecl(Underlying); 12730 } 12731 } 12732 } 12733 12734 static ExprResult 12735 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12736 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12737 const DeclarationNameInfo &ReductionId, QualType Ty, 12738 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12739 if (ReductionIdScopeSpec.isInvalid()) 12740 return ExprError(); 12741 SmallVector<UnresolvedSet<8>, 4> Lookups; 12742 if (S) { 12743 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12744 Lookup.suppressDiagnostics(); 12745 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12746 NamedDecl *D = Lookup.getRepresentativeDecl(); 12747 do { 12748 S = S->getParent(); 12749 } while (S && !S->isDeclScope(D)); 12750 if (S) 12751 S = S->getParent(); 12752 Lookups.emplace_back(); 12753 Lookups.back().append(Lookup.begin(), Lookup.end()); 12754 Lookup.clear(); 12755 } 12756 } else if (auto *ULE = 12757 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12758 Lookups.push_back(UnresolvedSet<8>()); 12759 Decl *PrevD = nullptr; 12760 for (NamedDecl *D : ULE->decls()) { 12761 if (D == PrevD) 12762 Lookups.push_back(UnresolvedSet<8>()); 12763 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12764 Lookups.back().addDecl(DRD); 12765 PrevD = D; 12766 } 12767 } 12768 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12769 Ty->isInstantiationDependentType() || 12770 Ty->containsUnexpandedParameterPack() || 12771 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12772 return !D->isInvalidDecl() && 12773 (D->getType()->isDependentType() || 12774 D->getType()->isInstantiationDependentType() || 12775 D->getType()->containsUnexpandedParameterPack()); 12776 })) { 12777 UnresolvedSet<8> ResSet; 12778 for (const UnresolvedSet<8> &Set : Lookups) { 12779 if (Set.empty()) 12780 continue; 12781 ResSet.append(Set.begin(), Set.end()); 12782 // The last item marks the end of all declarations at the specified scope. 12783 ResSet.addDecl(Set[Set.size() - 1]); 12784 } 12785 return UnresolvedLookupExpr::Create( 12786 SemaRef.Context, /*NamingClass=*/nullptr, 12787 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12788 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12789 } 12790 // Lookup inside the classes. 12791 // C++ [over.match.oper]p3: 12792 // For a unary operator @ with an operand of a type whose 12793 // cv-unqualified version is T1, and for a binary operator @ with 12794 // a left operand of a type whose cv-unqualified version is T1 and 12795 // a right operand of a type whose cv-unqualified version is T2, 12796 // three sets of candidate functions, designated member 12797 // candidates, non-member candidates and built-in candidates, are 12798 // constructed as follows: 12799 // -- If T1 is a complete class type or a class currently being 12800 // defined, the set of member candidates is the result of the 12801 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12802 // the set of member candidates is empty. 12803 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12804 Lookup.suppressDiagnostics(); 12805 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12806 // Complete the type if it can be completed. 12807 // If the type is neither complete nor being defined, bail out now. 12808 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12809 TyRec->getDecl()->getDefinition()) { 12810 Lookup.clear(); 12811 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12812 if (Lookup.empty()) { 12813 Lookups.emplace_back(); 12814 Lookups.back().append(Lookup.begin(), Lookup.end()); 12815 } 12816 } 12817 } 12818 // Perform ADL. 12819 if (SemaRef.getLangOpts().CPlusPlus) 12820 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12821 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12822 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12823 if (!D->isInvalidDecl() && 12824 SemaRef.Context.hasSameType(D->getType(), Ty)) 12825 return D; 12826 return nullptr; 12827 })) 12828 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12829 VK_LValue, Loc); 12830 if (SemaRef.getLangOpts().CPlusPlus) { 12831 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12832 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12833 if (!D->isInvalidDecl() && 12834 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12835 !Ty.isMoreQualifiedThan(D->getType())) 12836 return D; 12837 return nullptr; 12838 })) { 12839 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12840 /*DetectVirtual=*/false); 12841 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12842 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12843 VD->getType().getUnqualifiedType()))) { 12844 if (SemaRef.CheckBaseClassAccess( 12845 Loc, VD->getType(), Ty, Paths.front(), 12846 /*DiagID=*/0) != Sema::AR_inaccessible) { 12847 SemaRef.BuildBasePathArray(Paths, BasePath); 12848 return SemaRef.BuildDeclRefExpr( 12849 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12850 } 12851 } 12852 } 12853 } 12854 } 12855 if (ReductionIdScopeSpec.isSet()) { 12856 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12857 return ExprError(); 12858 } 12859 return ExprEmpty(); 12860 } 12861 12862 namespace { 12863 /// Data for the reduction-based clauses. 12864 struct ReductionData { 12865 /// List of original reduction items. 12866 SmallVector<Expr *, 8> Vars; 12867 /// List of private copies of the reduction items. 12868 SmallVector<Expr *, 8> Privates; 12869 /// LHS expressions for the reduction_op expressions. 12870 SmallVector<Expr *, 8> LHSs; 12871 /// RHS expressions for the reduction_op expressions. 12872 SmallVector<Expr *, 8> RHSs; 12873 /// Reduction operation expression. 12874 SmallVector<Expr *, 8> ReductionOps; 12875 /// Taskgroup descriptors for the corresponding reduction items in 12876 /// in_reduction clauses. 12877 SmallVector<Expr *, 8> TaskgroupDescriptors; 12878 /// List of captures for clause. 12879 SmallVector<Decl *, 4> ExprCaptures; 12880 /// List of postupdate expressions. 12881 SmallVector<Expr *, 4> ExprPostUpdates; 12882 ReductionData() = delete; 12883 /// Reserves required memory for the reduction data. 12884 ReductionData(unsigned Size) { 12885 Vars.reserve(Size); 12886 Privates.reserve(Size); 12887 LHSs.reserve(Size); 12888 RHSs.reserve(Size); 12889 ReductionOps.reserve(Size); 12890 TaskgroupDescriptors.reserve(Size); 12891 ExprCaptures.reserve(Size); 12892 ExprPostUpdates.reserve(Size); 12893 } 12894 /// Stores reduction item and reduction operation only (required for dependent 12895 /// reduction item). 12896 void push(Expr *Item, Expr *ReductionOp) { 12897 Vars.emplace_back(Item); 12898 Privates.emplace_back(nullptr); 12899 LHSs.emplace_back(nullptr); 12900 RHSs.emplace_back(nullptr); 12901 ReductionOps.emplace_back(ReductionOp); 12902 TaskgroupDescriptors.emplace_back(nullptr); 12903 } 12904 /// Stores reduction data. 12905 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12906 Expr *TaskgroupDescriptor) { 12907 Vars.emplace_back(Item); 12908 Privates.emplace_back(Private); 12909 LHSs.emplace_back(LHS); 12910 RHSs.emplace_back(RHS); 12911 ReductionOps.emplace_back(ReductionOp); 12912 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12913 } 12914 }; 12915 } // namespace 12916 12917 static bool checkOMPArraySectionConstantForReduction( 12918 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12919 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12920 const Expr *Length = OASE->getLength(); 12921 if (Length == nullptr) { 12922 // For array sections of the form [1:] or [:], we would need to analyze 12923 // the lower bound... 12924 if (OASE->getColonLoc().isValid()) 12925 return false; 12926 12927 // This is an array subscript which has implicit length 1! 12928 SingleElement = true; 12929 ArraySizes.push_back(llvm::APSInt::get(1)); 12930 } else { 12931 Expr::EvalResult Result; 12932 if (!Length->EvaluateAsInt(Result, Context)) 12933 return false; 12934 12935 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12936 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12937 ArraySizes.push_back(ConstantLengthValue); 12938 } 12939 12940 // Get the base of this array section and walk up from there. 12941 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12942 12943 // We require length = 1 for all array sections except the right-most to 12944 // guarantee that the memory region is contiguous and has no holes in it. 12945 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12946 Length = TempOASE->getLength(); 12947 if (Length == nullptr) { 12948 // For array sections of the form [1:] or [:], we would need to analyze 12949 // the lower bound... 12950 if (OASE->getColonLoc().isValid()) 12951 return false; 12952 12953 // This is an array subscript which has implicit length 1! 12954 ArraySizes.push_back(llvm::APSInt::get(1)); 12955 } else { 12956 Expr::EvalResult Result; 12957 if (!Length->EvaluateAsInt(Result, Context)) 12958 return false; 12959 12960 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12961 if (ConstantLengthValue.getSExtValue() != 1) 12962 return false; 12963 12964 ArraySizes.push_back(ConstantLengthValue); 12965 } 12966 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12967 } 12968 12969 // If we have a single element, we don't need to add the implicit lengths. 12970 if (!SingleElement) { 12971 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12972 // Has implicit length 1! 12973 ArraySizes.push_back(llvm::APSInt::get(1)); 12974 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12975 } 12976 } 12977 12978 // This array section can be privatized as a single value or as a constant 12979 // sized array. 12980 return true; 12981 } 12982 12983 static bool actOnOMPReductionKindClause( 12984 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12985 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12986 SourceLocation ColonLoc, SourceLocation EndLoc, 12987 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12988 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12989 DeclarationName DN = ReductionId.getName(); 12990 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12991 BinaryOperatorKind BOK = BO_Comma; 12992 12993 ASTContext &Context = S.Context; 12994 // OpenMP [2.14.3.6, reduction clause] 12995 // C 12996 // reduction-identifier is either an identifier or one of the following 12997 // operators: +, -, *, &, |, ^, && and || 12998 // C++ 12999 // reduction-identifier is either an id-expression or one of the following 13000 // operators: +, -, *, &, |, ^, && and || 13001 switch (OOK) { 13002 case OO_Plus: 13003 case OO_Minus: 13004 BOK = BO_Add; 13005 break; 13006 case OO_Star: 13007 BOK = BO_Mul; 13008 break; 13009 case OO_Amp: 13010 BOK = BO_And; 13011 break; 13012 case OO_Pipe: 13013 BOK = BO_Or; 13014 break; 13015 case OO_Caret: 13016 BOK = BO_Xor; 13017 break; 13018 case OO_AmpAmp: 13019 BOK = BO_LAnd; 13020 break; 13021 case OO_PipePipe: 13022 BOK = BO_LOr; 13023 break; 13024 case OO_New: 13025 case OO_Delete: 13026 case OO_Array_New: 13027 case OO_Array_Delete: 13028 case OO_Slash: 13029 case OO_Percent: 13030 case OO_Tilde: 13031 case OO_Exclaim: 13032 case OO_Equal: 13033 case OO_Less: 13034 case OO_Greater: 13035 case OO_LessEqual: 13036 case OO_GreaterEqual: 13037 case OO_PlusEqual: 13038 case OO_MinusEqual: 13039 case OO_StarEqual: 13040 case OO_SlashEqual: 13041 case OO_PercentEqual: 13042 case OO_CaretEqual: 13043 case OO_AmpEqual: 13044 case OO_PipeEqual: 13045 case OO_LessLess: 13046 case OO_GreaterGreater: 13047 case OO_LessLessEqual: 13048 case OO_GreaterGreaterEqual: 13049 case OO_EqualEqual: 13050 case OO_ExclaimEqual: 13051 case OO_Spaceship: 13052 case OO_PlusPlus: 13053 case OO_MinusMinus: 13054 case OO_Comma: 13055 case OO_ArrowStar: 13056 case OO_Arrow: 13057 case OO_Call: 13058 case OO_Subscript: 13059 case OO_Conditional: 13060 case OO_Coawait: 13061 case NUM_OVERLOADED_OPERATORS: 13062 llvm_unreachable("Unexpected reduction identifier"); 13063 case OO_None: 13064 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13065 if (II->isStr("max")) 13066 BOK = BO_GT; 13067 else if (II->isStr("min")) 13068 BOK = BO_LT; 13069 } 13070 break; 13071 } 13072 SourceRange ReductionIdRange; 13073 if (ReductionIdScopeSpec.isValid()) 13074 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13075 else 13076 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13077 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13078 13079 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13080 bool FirstIter = true; 13081 for (Expr *RefExpr : VarList) { 13082 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13083 // OpenMP [2.1, C/C++] 13084 // A list item is a variable or array section, subject to the restrictions 13085 // specified in Section 2.4 on page 42 and in each of the sections 13086 // describing clauses and directives for which a list appears. 13087 // OpenMP [2.14.3.3, Restrictions, p.1] 13088 // A variable that is part of another variable (as an array or 13089 // structure element) cannot appear in a private clause. 13090 if (!FirstIter && IR != ER) 13091 ++IR; 13092 FirstIter = false; 13093 SourceLocation ELoc; 13094 SourceRange ERange; 13095 Expr *SimpleRefExpr = RefExpr; 13096 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13097 /*AllowArraySection=*/true); 13098 if (Res.second) { 13099 // Try to find 'declare reduction' corresponding construct before using 13100 // builtin/overloaded operators. 13101 QualType Type = Context.DependentTy; 13102 CXXCastPath BasePath; 13103 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13104 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13105 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13106 Expr *ReductionOp = nullptr; 13107 if (S.CurContext->isDependentContext() && 13108 (DeclareReductionRef.isUnset() || 13109 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13110 ReductionOp = DeclareReductionRef.get(); 13111 // It will be analyzed later. 13112 RD.push(RefExpr, ReductionOp); 13113 } 13114 ValueDecl *D = Res.first; 13115 if (!D) 13116 continue; 13117 13118 Expr *TaskgroupDescriptor = nullptr; 13119 QualType Type; 13120 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13121 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13122 if (ASE) { 13123 Type = ASE->getType().getNonReferenceType(); 13124 } else if (OASE) { 13125 QualType BaseType = 13126 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13127 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13128 Type = ATy->getElementType(); 13129 else 13130 Type = BaseType->getPointeeType(); 13131 Type = Type.getNonReferenceType(); 13132 } else { 13133 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13134 } 13135 auto *VD = dyn_cast<VarDecl>(D); 13136 13137 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13138 // A variable that appears in a private clause must not have an incomplete 13139 // type or a reference type. 13140 if (S.RequireCompleteType(ELoc, D->getType(), 13141 diag::err_omp_reduction_incomplete_type)) 13142 continue; 13143 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13144 // A list item that appears in a reduction clause must not be 13145 // const-qualified. 13146 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13147 /*AcceptIfMutable*/ false, ASE || OASE)) 13148 continue; 13149 13150 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13151 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13152 // If a list-item is a reference type then it must bind to the same object 13153 // for all threads of the team. 13154 if (!ASE && !OASE) { 13155 if (VD) { 13156 VarDecl *VDDef = VD->getDefinition(); 13157 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13158 DSARefChecker Check(Stack); 13159 if (Check.Visit(VDDef->getInit())) { 13160 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13161 << getOpenMPClauseName(ClauseKind) << ERange; 13162 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13163 continue; 13164 } 13165 } 13166 } 13167 13168 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13169 // in a Construct] 13170 // Variables with the predetermined data-sharing attributes may not be 13171 // listed in data-sharing attributes clauses, except for the cases 13172 // listed below. For these exceptions only, listing a predetermined 13173 // variable in a data-sharing attribute clause is allowed and overrides 13174 // the variable's predetermined data-sharing attributes. 13175 // OpenMP [2.14.3.6, Restrictions, p.3] 13176 // Any number of reduction clauses can be specified on the directive, 13177 // but a list item can appear only once in the reduction clauses for that 13178 // directive. 13179 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13180 if (DVar.CKind == OMPC_reduction) { 13181 S.Diag(ELoc, diag::err_omp_once_referenced) 13182 << getOpenMPClauseName(ClauseKind); 13183 if (DVar.RefExpr) 13184 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13185 continue; 13186 } 13187 if (DVar.CKind != OMPC_unknown) { 13188 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13189 << getOpenMPClauseName(DVar.CKind) 13190 << getOpenMPClauseName(OMPC_reduction); 13191 reportOriginalDsa(S, Stack, D, DVar); 13192 continue; 13193 } 13194 13195 // OpenMP [2.14.3.6, Restrictions, p.1] 13196 // A list item that appears in a reduction clause of a worksharing 13197 // construct must be shared in the parallel regions to which any of the 13198 // worksharing regions arising from the worksharing construct bind. 13199 if (isOpenMPWorksharingDirective(CurrDir) && 13200 !isOpenMPParallelDirective(CurrDir) && 13201 !isOpenMPTeamsDirective(CurrDir)) { 13202 DVar = Stack->getImplicitDSA(D, true); 13203 if (DVar.CKind != OMPC_shared) { 13204 S.Diag(ELoc, diag::err_omp_required_access) 13205 << getOpenMPClauseName(OMPC_reduction) 13206 << getOpenMPClauseName(OMPC_shared); 13207 reportOriginalDsa(S, Stack, D, DVar); 13208 continue; 13209 } 13210 } 13211 } 13212 13213 // Try to find 'declare reduction' corresponding construct before using 13214 // builtin/overloaded operators. 13215 CXXCastPath BasePath; 13216 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13217 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13218 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13219 if (DeclareReductionRef.isInvalid()) 13220 continue; 13221 if (S.CurContext->isDependentContext() && 13222 (DeclareReductionRef.isUnset() || 13223 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13224 RD.push(RefExpr, DeclareReductionRef.get()); 13225 continue; 13226 } 13227 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13228 // Not allowed reduction identifier is found. 13229 S.Diag(ReductionId.getBeginLoc(), 13230 diag::err_omp_unknown_reduction_identifier) 13231 << Type << ReductionIdRange; 13232 continue; 13233 } 13234 13235 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13236 // The type of a list item that appears in a reduction clause must be valid 13237 // for the reduction-identifier. For a max or min reduction in C, the type 13238 // of the list item must be an allowed arithmetic data type: char, int, 13239 // float, double, or _Bool, possibly modified with long, short, signed, or 13240 // unsigned. For a max or min reduction in C++, the type of the list item 13241 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13242 // double, or bool, possibly modified with long, short, signed, or unsigned. 13243 if (DeclareReductionRef.isUnset()) { 13244 if ((BOK == BO_GT || BOK == BO_LT) && 13245 !(Type->isScalarType() || 13246 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13247 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13248 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13249 if (!ASE && !OASE) { 13250 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13251 VarDecl::DeclarationOnly; 13252 S.Diag(D->getLocation(), 13253 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13254 << D; 13255 } 13256 continue; 13257 } 13258 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13259 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13260 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13261 << getOpenMPClauseName(ClauseKind); 13262 if (!ASE && !OASE) { 13263 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13264 VarDecl::DeclarationOnly; 13265 S.Diag(D->getLocation(), 13266 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13267 << D; 13268 } 13269 continue; 13270 } 13271 } 13272 13273 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13274 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13275 D->hasAttrs() ? &D->getAttrs() : nullptr); 13276 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13277 D->hasAttrs() ? &D->getAttrs() : nullptr); 13278 QualType PrivateTy = Type; 13279 13280 // Try if we can determine constant lengths for all array sections and avoid 13281 // the VLA. 13282 bool ConstantLengthOASE = false; 13283 if (OASE) { 13284 bool SingleElement; 13285 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13286 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13287 Context, OASE, SingleElement, ArraySizes); 13288 13289 // If we don't have a single element, we must emit a constant array type. 13290 if (ConstantLengthOASE && !SingleElement) { 13291 for (llvm::APSInt &Size : ArraySizes) 13292 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13293 ArrayType::Normal, 13294 /*IndexTypeQuals=*/0); 13295 } 13296 } 13297 13298 if ((OASE && !ConstantLengthOASE) || 13299 (!OASE && !ASE && 13300 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13301 if (!Context.getTargetInfo().isVLASupported()) { 13302 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13303 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13304 S.Diag(ELoc, diag::note_vla_unsupported); 13305 } else { 13306 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13307 S.targetDiag(ELoc, diag::note_vla_unsupported); 13308 } 13309 continue; 13310 } 13311 // For arrays/array sections only: 13312 // Create pseudo array type for private copy. The size for this array will 13313 // be generated during codegen. 13314 // For array subscripts or single variables Private Ty is the same as Type 13315 // (type of the variable or single array element). 13316 PrivateTy = Context.getVariableArrayType( 13317 Type, 13318 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13319 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13320 } else if (!ASE && !OASE && 13321 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13322 PrivateTy = D->getType().getNonReferenceType(); 13323 } 13324 // Private copy. 13325 VarDecl *PrivateVD = 13326 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13327 D->hasAttrs() ? &D->getAttrs() : nullptr, 13328 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13329 // Add initializer for private variable. 13330 Expr *Init = nullptr; 13331 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13332 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13333 if (DeclareReductionRef.isUsable()) { 13334 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13335 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13336 if (DRD->getInitializer()) { 13337 Init = DRDRef; 13338 RHSVD->setInit(DRDRef); 13339 RHSVD->setInitStyle(VarDecl::CallInit); 13340 } 13341 } else { 13342 switch (BOK) { 13343 case BO_Add: 13344 case BO_Xor: 13345 case BO_Or: 13346 case BO_LOr: 13347 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13348 if (Type->isScalarType() || Type->isAnyComplexType()) 13349 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13350 break; 13351 case BO_Mul: 13352 case BO_LAnd: 13353 if (Type->isScalarType() || Type->isAnyComplexType()) { 13354 // '*' and '&&' reduction ops - initializer is '1'. 13355 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13356 } 13357 break; 13358 case BO_And: { 13359 // '&' reduction op - initializer is '~0'. 13360 QualType OrigType = Type; 13361 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13362 Type = ComplexTy->getElementType(); 13363 if (Type->isRealFloatingType()) { 13364 llvm::APFloat InitValue = 13365 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13366 /*isIEEE=*/true); 13367 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13368 Type, ELoc); 13369 } else if (Type->isScalarType()) { 13370 uint64_t Size = Context.getTypeSize(Type); 13371 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13372 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13373 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13374 } 13375 if (Init && OrigType->isAnyComplexType()) { 13376 // Init = 0xFFFF + 0xFFFFi; 13377 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13378 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13379 } 13380 Type = OrigType; 13381 break; 13382 } 13383 case BO_LT: 13384 case BO_GT: { 13385 // 'min' reduction op - initializer is 'Largest representable number in 13386 // the reduction list item type'. 13387 // 'max' reduction op - initializer is 'Least representable number in 13388 // the reduction list item type'. 13389 if (Type->isIntegerType() || Type->isPointerType()) { 13390 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13391 uint64_t Size = Context.getTypeSize(Type); 13392 QualType IntTy = 13393 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13394 llvm::APInt InitValue = 13395 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13396 : llvm::APInt::getMinValue(Size) 13397 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13398 : llvm::APInt::getMaxValue(Size); 13399 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13400 if (Type->isPointerType()) { 13401 // Cast to pointer type. 13402 ExprResult CastExpr = S.BuildCStyleCastExpr( 13403 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13404 if (CastExpr.isInvalid()) 13405 continue; 13406 Init = CastExpr.get(); 13407 } 13408 } else if (Type->isRealFloatingType()) { 13409 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13410 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13411 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13412 Type, ELoc); 13413 } 13414 break; 13415 } 13416 case BO_PtrMemD: 13417 case BO_PtrMemI: 13418 case BO_MulAssign: 13419 case BO_Div: 13420 case BO_Rem: 13421 case BO_Sub: 13422 case BO_Shl: 13423 case BO_Shr: 13424 case BO_LE: 13425 case BO_GE: 13426 case BO_EQ: 13427 case BO_NE: 13428 case BO_Cmp: 13429 case BO_AndAssign: 13430 case BO_XorAssign: 13431 case BO_OrAssign: 13432 case BO_Assign: 13433 case BO_AddAssign: 13434 case BO_SubAssign: 13435 case BO_DivAssign: 13436 case BO_RemAssign: 13437 case BO_ShlAssign: 13438 case BO_ShrAssign: 13439 case BO_Comma: 13440 llvm_unreachable("Unexpected reduction operation"); 13441 } 13442 } 13443 if (Init && DeclareReductionRef.isUnset()) 13444 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13445 else if (!Init) 13446 S.ActOnUninitializedDecl(RHSVD); 13447 if (RHSVD->isInvalidDecl()) 13448 continue; 13449 if (!RHSVD->hasInit() && 13450 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13451 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13452 << Type << ReductionIdRange; 13453 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13454 VarDecl::DeclarationOnly; 13455 S.Diag(D->getLocation(), 13456 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13457 << D; 13458 continue; 13459 } 13460 // Store initializer for single element in private copy. Will be used during 13461 // codegen. 13462 PrivateVD->setInit(RHSVD->getInit()); 13463 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13464 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13465 ExprResult ReductionOp; 13466 if (DeclareReductionRef.isUsable()) { 13467 QualType RedTy = DeclareReductionRef.get()->getType(); 13468 QualType PtrRedTy = Context.getPointerType(RedTy); 13469 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13470 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13471 if (!BasePath.empty()) { 13472 LHS = S.DefaultLvalueConversion(LHS.get()); 13473 RHS = S.DefaultLvalueConversion(RHS.get()); 13474 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13475 CK_UncheckedDerivedToBase, LHS.get(), 13476 &BasePath, LHS.get()->getValueKind()); 13477 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13478 CK_UncheckedDerivedToBase, RHS.get(), 13479 &BasePath, RHS.get()->getValueKind()); 13480 } 13481 FunctionProtoType::ExtProtoInfo EPI; 13482 QualType Params[] = {PtrRedTy, PtrRedTy}; 13483 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13484 auto *OVE = new (Context) OpaqueValueExpr( 13485 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13486 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13487 Expr *Args[] = {LHS.get(), RHS.get()}; 13488 ReductionOp = 13489 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13490 } else { 13491 ReductionOp = S.BuildBinOp( 13492 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13493 if (ReductionOp.isUsable()) { 13494 if (BOK != BO_LT && BOK != BO_GT) { 13495 ReductionOp = 13496 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13497 BO_Assign, LHSDRE, ReductionOp.get()); 13498 } else { 13499 auto *ConditionalOp = new (Context) 13500 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13501 Type, VK_LValue, OK_Ordinary); 13502 ReductionOp = 13503 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13504 BO_Assign, LHSDRE, ConditionalOp); 13505 } 13506 if (ReductionOp.isUsable()) 13507 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13508 /*DiscardedValue*/ false); 13509 } 13510 if (!ReductionOp.isUsable()) 13511 continue; 13512 } 13513 13514 // OpenMP [2.15.4.6, Restrictions, p.2] 13515 // A list item that appears in an in_reduction clause of a task construct 13516 // must appear in a task_reduction clause of a construct associated with a 13517 // taskgroup region that includes the participating task in its taskgroup 13518 // set. The construct associated with the innermost region that meets this 13519 // condition must specify the same reduction-identifier as the in_reduction 13520 // clause. 13521 if (ClauseKind == OMPC_in_reduction) { 13522 SourceRange ParentSR; 13523 BinaryOperatorKind ParentBOK; 13524 const Expr *ParentReductionOp; 13525 Expr *ParentBOKTD, *ParentReductionOpTD; 13526 DSAStackTy::DSAVarData ParentBOKDSA = 13527 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13528 ParentBOKTD); 13529 DSAStackTy::DSAVarData ParentReductionOpDSA = 13530 Stack->getTopMostTaskgroupReductionData( 13531 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13532 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13533 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13534 if (!IsParentBOK && !IsParentReductionOp) { 13535 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13536 continue; 13537 } 13538 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13539 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13540 IsParentReductionOp) { 13541 bool EmitError = true; 13542 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13543 llvm::FoldingSetNodeID RedId, ParentRedId; 13544 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13545 DeclareReductionRef.get()->Profile(RedId, Context, 13546 /*Canonical=*/true); 13547 EmitError = RedId != ParentRedId; 13548 } 13549 if (EmitError) { 13550 S.Diag(ReductionId.getBeginLoc(), 13551 diag::err_omp_reduction_identifier_mismatch) 13552 << ReductionIdRange << RefExpr->getSourceRange(); 13553 S.Diag(ParentSR.getBegin(), 13554 diag::note_omp_previous_reduction_identifier) 13555 << ParentSR 13556 << (IsParentBOK ? ParentBOKDSA.RefExpr 13557 : ParentReductionOpDSA.RefExpr) 13558 ->getSourceRange(); 13559 continue; 13560 } 13561 } 13562 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13563 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13564 } 13565 13566 DeclRefExpr *Ref = nullptr; 13567 Expr *VarsExpr = RefExpr->IgnoreParens(); 13568 if (!VD && !S.CurContext->isDependentContext()) { 13569 if (ASE || OASE) { 13570 TransformExprToCaptures RebuildToCapture(S, D); 13571 VarsExpr = 13572 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13573 Ref = RebuildToCapture.getCapturedExpr(); 13574 } else { 13575 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13576 } 13577 if (!S.isOpenMPCapturedDecl(D)) { 13578 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13579 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13580 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13581 if (!RefRes.isUsable()) 13582 continue; 13583 ExprResult PostUpdateRes = 13584 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13585 RefRes.get()); 13586 if (!PostUpdateRes.isUsable()) 13587 continue; 13588 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13589 Stack->getCurrentDirective() == OMPD_taskgroup) { 13590 S.Diag(RefExpr->getExprLoc(), 13591 diag::err_omp_reduction_non_addressable_expression) 13592 << RefExpr->getSourceRange(); 13593 continue; 13594 } 13595 RD.ExprPostUpdates.emplace_back( 13596 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13597 } 13598 } 13599 } 13600 // All reduction items are still marked as reduction (to do not increase 13601 // code base size). 13602 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13603 if (CurrDir == OMPD_taskgroup) { 13604 if (DeclareReductionRef.isUsable()) 13605 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13606 DeclareReductionRef.get()); 13607 else 13608 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13609 } 13610 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13611 TaskgroupDescriptor); 13612 } 13613 return RD.Vars.empty(); 13614 } 13615 13616 OMPClause *Sema::ActOnOpenMPReductionClause( 13617 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13618 SourceLocation ColonLoc, SourceLocation EndLoc, 13619 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13620 ArrayRef<Expr *> UnresolvedReductions) { 13621 ReductionData RD(VarList.size()); 13622 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13623 StartLoc, LParenLoc, ColonLoc, EndLoc, 13624 ReductionIdScopeSpec, ReductionId, 13625 UnresolvedReductions, RD)) 13626 return nullptr; 13627 13628 return OMPReductionClause::Create( 13629 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13630 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13631 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13632 buildPreInits(Context, RD.ExprCaptures), 13633 buildPostUpdate(*this, RD.ExprPostUpdates)); 13634 } 13635 13636 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13637 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13638 SourceLocation ColonLoc, SourceLocation EndLoc, 13639 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13640 ArrayRef<Expr *> UnresolvedReductions) { 13641 ReductionData RD(VarList.size()); 13642 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13643 StartLoc, LParenLoc, ColonLoc, EndLoc, 13644 ReductionIdScopeSpec, ReductionId, 13645 UnresolvedReductions, RD)) 13646 return nullptr; 13647 13648 return OMPTaskReductionClause::Create( 13649 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13650 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13651 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13652 buildPreInits(Context, RD.ExprCaptures), 13653 buildPostUpdate(*this, RD.ExprPostUpdates)); 13654 } 13655 13656 OMPClause *Sema::ActOnOpenMPInReductionClause( 13657 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13658 SourceLocation ColonLoc, SourceLocation EndLoc, 13659 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13660 ArrayRef<Expr *> UnresolvedReductions) { 13661 ReductionData RD(VarList.size()); 13662 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13663 StartLoc, LParenLoc, ColonLoc, EndLoc, 13664 ReductionIdScopeSpec, ReductionId, 13665 UnresolvedReductions, RD)) 13666 return nullptr; 13667 13668 return OMPInReductionClause::Create( 13669 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13670 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13671 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13672 buildPreInits(Context, RD.ExprCaptures), 13673 buildPostUpdate(*this, RD.ExprPostUpdates)); 13674 } 13675 13676 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13677 SourceLocation LinLoc) { 13678 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13679 LinKind == OMPC_LINEAR_unknown) { 13680 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13681 return true; 13682 } 13683 return false; 13684 } 13685 13686 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13687 OpenMPLinearClauseKind LinKind, 13688 QualType Type) { 13689 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13690 // A variable must not have an incomplete type or a reference type. 13691 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13692 return true; 13693 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13694 !Type->isReferenceType()) { 13695 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13696 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13697 return true; 13698 } 13699 Type = Type.getNonReferenceType(); 13700 13701 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13702 // A variable that is privatized must not have a const-qualified type 13703 // unless it is of class type with a mutable member. This restriction does 13704 // not apply to the firstprivate clause. 13705 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13706 return true; 13707 13708 // A list item must be of integral or pointer type. 13709 Type = Type.getUnqualifiedType().getCanonicalType(); 13710 const auto *Ty = Type.getTypePtrOrNull(); 13711 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13712 !Ty->isPointerType())) { 13713 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13714 if (D) { 13715 bool IsDecl = 13716 !VD || 13717 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13718 Diag(D->getLocation(), 13719 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13720 << D; 13721 } 13722 return true; 13723 } 13724 return false; 13725 } 13726 13727 OMPClause *Sema::ActOnOpenMPLinearClause( 13728 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13729 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13730 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13731 SmallVector<Expr *, 8> Vars; 13732 SmallVector<Expr *, 8> Privates; 13733 SmallVector<Expr *, 8> Inits; 13734 SmallVector<Decl *, 4> ExprCaptures; 13735 SmallVector<Expr *, 4> ExprPostUpdates; 13736 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13737 LinKind = OMPC_LINEAR_val; 13738 for (Expr *RefExpr : VarList) { 13739 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13740 SourceLocation ELoc; 13741 SourceRange ERange; 13742 Expr *SimpleRefExpr = RefExpr; 13743 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13744 if (Res.second) { 13745 // It will be analyzed later. 13746 Vars.push_back(RefExpr); 13747 Privates.push_back(nullptr); 13748 Inits.push_back(nullptr); 13749 } 13750 ValueDecl *D = Res.first; 13751 if (!D) 13752 continue; 13753 13754 QualType Type = D->getType(); 13755 auto *VD = dyn_cast<VarDecl>(D); 13756 13757 // OpenMP [2.14.3.7, linear clause] 13758 // A list-item cannot appear in more than one linear clause. 13759 // A list-item that appears in a linear clause cannot appear in any 13760 // other data-sharing attribute clause. 13761 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13762 if (DVar.RefExpr) { 13763 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13764 << getOpenMPClauseName(OMPC_linear); 13765 reportOriginalDsa(*this, DSAStack, D, DVar); 13766 continue; 13767 } 13768 13769 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13770 continue; 13771 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13772 13773 // Build private copy of original var. 13774 VarDecl *Private = 13775 buildVarDecl(*this, ELoc, Type, D->getName(), 13776 D->hasAttrs() ? &D->getAttrs() : nullptr, 13777 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13778 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13779 // Build var to save initial value. 13780 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13781 Expr *InitExpr; 13782 DeclRefExpr *Ref = nullptr; 13783 if (!VD && !CurContext->isDependentContext()) { 13784 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13785 if (!isOpenMPCapturedDecl(D)) { 13786 ExprCaptures.push_back(Ref->getDecl()); 13787 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13788 ExprResult RefRes = DefaultLvalueConversion(Ref); 13789 if (!RefRes.isUsable()) 13790 continue; 13791 ExprResult PostUpdateRes = 13792 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13793 SimpleRefExpr, RefRes.get()); 13794 if (!PostUpdateRes.isUsable()) 13795 continue; 13796 ExprPostUpdates.push_back( 13797 IgnoredValueConversions(PostUpdateRes.get()).get()); 13798 } 13799 } 13800 } 13801 if (LinKind == OMPC_LINEAR_uval) 13802 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13803 else 13804 InitExpr = VD ? SimpleRefExpr : Ref; 13805 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13806 /*DirectInit=*/false); 13807 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13808 13809 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13810 Vars.push_back((VD || CurContext->isDependentContext()) 13811 ? RefExpr->IgnoreParens() 13812 : Ref); 13813 Privates.push_back(PrivateRef); 13814 Inits.push_back(InitRef); 13815 } 13816 13817 if (Vars.empty()) 13818 return nullptr; 13819 13820 Expr *StepExpr = Step; 13821 Expr *CalcStepExpr = nullptr; 13822 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13823 !Step->isInstantiationDependent() && 13824 !Step->containsUnexpandedParameterPack()) { 13825 SourceLocation StepLoc = Step->getBeginLoc(); 13826 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13827 if (Val.isInvalid()) 13828 return nullptr; 13829 StepExpr = Val.get(); 13830 13831 // Build var to save the step value. 13832 VarDecl *SaveVar = 13833 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13834 ExprResult SaveRef = 13835 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13836 ExprResult CalcStep = 13837 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13838 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13839 13840 // Warn about zero linear step (it would be probably better specified as 13841 // making corresponding variables 'const'). 13842 llvm::APSInt Result; 13843 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13844 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13845 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13846 << (Vars.size() > 1); 13847 if (!IsConstant && CalcStep.isUsable()) { 13848 // Calculate the step beforehand instead of doing this on each iteration. 13849 // (This is not used if the number of iterations may be kfold-ed). 13850 CalcStepExpr = CalcStep.get(); 13851 } 13852 } 13853 13854 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13855 ColonLoc, EndLoc, Vars, Privates, Inits, 13856 StepExpr, CalcStepExpr, 13857 buildPreInits(Context, ExprCaptures), 13858 buildPostUpdate(*this, ExprPostUpdates)); 13859 } 13860 13861 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13862 Expr *NumIterations, Sema &SemaRef, 13863 Scope *S, DSAStackTy *Stack) { 13864 // Walk the vars and build update/final expressions for the CodeGen. 13865 SmallVector<Expr *, 8> Updates; 13866 SmallVector<Expr *, 8> Finals; 13867 SmallVector<Expr *, 8> UsedExprs; 13868 Expr *Step = Clause.getStep(); 13869 Expr *CalcStep = Clause.getCalcStep(); 13870 // OpenMP [2.14.3.7, linear clause] 13871 // If linear-step is not specified it is assumed to be 1. 13872 if (!Step) 13873 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13874 else if (CalcStep) 13875 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13876 bool HasErrors = false; 13877 auto CurInit = Clause.inits().begin(); 13878 auto CurPrivate = Clause.privates().begin(); 13879 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13880 for (Expr *RefExpr : Clause.varlists()) { 13881 SourceLocation ELoc; 13882 SourceRange ERange; 13883 Expr *SimpleRefExpr = RefExpr; 13884 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13885 ValueDecl *D = Res.first; 13886 if (Res.second || !D) { 13887 Updates.push_back(nullptr); 13888 Finals.push_back(nullptr); 13889 HasErrors = true; 13890 continue; 13891 } 13892 auto &&Info = Stack->isLoopControlVariable(D); 13893 // OpenMP [2.15.11, distribute simd Construct] 13894 // A list item may not appear in a linear clause, unless it is the loop 13895 // iteration variable. 13896 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13897 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13898 SemaRef.Diag(ELoc, 13899 diag::err_omp_linear_distribute_var_non_loop_iteration); 13900 Updates.push_back(nullptr); 13901 Finals.push_back(nullptr); 13902 HasErrors = true; 13903 continue; 13904 } 13905 Expr *InitExpr = *CurInit; 13906 13907 // Build privatized reference to the current linear var. 13908 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13909 Expr *CapturedRef; 13910 if (LinKind == OMPC_LINEAR_uval) 13911 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13912 else 13913 CapturedRef = 13914 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13915 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13916 /*RefersToCapture=*/true); 13917 13918 // Build update: Var = InitExpr + IV * Step 13919 ExprResult Update; 13920 if (!Info.first) 13921 Update = buildCounterUpdate( 13922 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13923 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13924 else 13925 Update = *CurPrivate; 13926 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13927 /*DiscardedValue*/ false); 13928 13929 // Build final: Var = InitExpr + NumIterations * Step 13930 ExprResult Final; 13931 if (!Info.first) 13932 Final = 13933 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13934 InitExpr, NumIterations, Step, /*Subtract=*/false, 13935 /*IsNonRectangularLB=*/false); 13936 else 13937 Final = *CurPrivate; 13938 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13939 /*DiscardedValue*/ false); 13940 13941 if (!Update.isUsable() || !Final.isUsable()) { 13942 Updates.push_back(nullptr); 13943 Finals.push_back(nullptr); 13944 UsedExprs.push_back(nullptr); 13945 HasErrors = true; 13946 } else { 13947 Updates.push_back(Update.get()); 13948 Finals.push_back(Final.get()); 13949 if (!Info.first) 13950 UsedExprs.push_back(SimpleRefExpr); 13951 } 13952 ++CurInit; 13953 ++CurPrivate; 13954 } 13955 if (Expr *S = Clause.getStep()) 13956 UsedExprs.push_back(S); 13957 // Fill the remaining part with the nullptr. 13958 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13959 Clause.setUpdates(Updates); 13960 Clause.setFinals(Finals); 13961 Clause.setUsedExprs(UsedExprs); 13962 return HasErrors; 13963 } 13964 13965 OMPClause *Sema::ActOnOpenMPAlignedClause( 13966 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13967 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13968 SmallVector<Expr *, 8> Vars; 13969 for (Expr *RefExpr : VarList) { 13970 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13971 SourceLocation ELoc; 13972 SourceRange ERange; 13973 Expr *SimpleRefExpr = RefExpr; 13974 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13975 if (Res.second) { 13976 // It will be analyzed later. 13977 Vars.push_back(RefExpr); 13978 } 13979 ValueDecl *D = Res.first; 13980 if (!D) 13981 continue; 13982 13983 QualType QType = D->getType(); 13984 auto *VD = dyn_cast<VarDecl>(D); 13985 13986 // OpenMP [2.8.1, simd construct, Restrictions] 13987 // The type of list items appearing in the aligned clause must be 13988 // array, pointer, reference to array, or reference to pointer. 13989 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13990 const Type *Ty = QType.getTypePtrOrNull(); 13991 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 13992 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 13993 << QType << getLangOpts().CPlusPlus << ERange; 13994 bool IsDecl = 13995 !VD || 13996 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13997 Diag(D->getLocation(), 13998 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13999 << D; 14000 continue; 14001 } 14002 14003 // OpenMP [2.8.1, simd construct, Restrictions] 14004 // A list-item cannot appear in more than one aligned clause. 14005 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14006 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 14007 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14008 << getOpenMPClauseName(OMPC_aligned); 14009 continue; 14010 } 14011 14012 DeclRefExpr *Ref = nullptr; 14013 if (!VD && isOpenMPCapturedDecl(D)) 14014 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14015 Vars.push_back(DefaultFunctionArrayConversion( 14016 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14017 .get()); 14018 } 14019 14020 // OpenMP [2.8.1, simd construct, Description] 14021 // The parameter of the aligned clause, alignment, must be a constant 14022 // positive integer expression. 14023 // If no optional parameter is specified, implementation-defined default 14024 // alignments for SIMD instructions on the target platforms are assumed. 14025 if (Alignment != nullptr) { 14026 ExprResult AlignResult = 14027 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14028 if (AlignResult.isInvalid()) 14029 return nullptr; 14030 Alignment = AlignResult.get(); 14031 } 14032 if (Vars.empty()) 14033 return nullptr; 14034 14035 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14036 EndLoc, Vars, Alignment); 14037 } 14038 14039 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14040 SourceLocation StartLoc, 14041 SourceLocation LParenLoc, 14042 SourceLocation EndLoc) { 14043 SmallVector<Expr *, 8> Vars; 14044 SmallVector<Expr *, 8> SrcExprs; 14045 SmallVector<Expr *, 8> DstExprs; 14046 SmallVector<Expr *, 8> AssignmentOps; 14047 for (Expr *RefExpr : VarList) { 14048 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14049 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14050 // It will be analyzed later. 14051 Vars.push_back(RefExpr); 14052 SrcExprs.push_back(nullptr); 14053 DstExprs.push_back(nullptr); 14054 AssignmentOps.push_back(nullptr); 14055 continue; 14056 } 14057 14058 SourceLocation ELoc = RefExpr->getExprLoc(); 14059 // OpenMP [2.1, C/C++] 14060 // A list item is a variable name. 14061 // OpenMP [2.14.4.1, Restrictions, p.1] 14062 // A list item that appears in a copyin clause must be threadprivate. 14063 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14064 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14065 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14066 << 0 << RefExpr->getSourceRange(); 14067 continue; 14068 } 14069 14070 Decl *D = DE->getDecl(); 14071 auto *VD = cast<VarDecl>(D); 14072 14073 QualType Type = VD->getType(); 14074 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14075 // It will be analyzed later. 14076 Vars.push_back(DE); 14077 SrcExprs.push_back(nullptr); 14078 DstExprs.push_back(nullptr); 14079 AssignmentOps.push_back(nullptr); 14080 continue; 14081 } 14082 14083 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14084 // A list item that appears in a copyin clause must be threadprivate. 14085 if (!DSAStack->isThreadPrivate(VD)) { 14086 Diag(ELoc, diag::err_omp_required_access) 14087 << getOpenMPClauseName(OMPC_copyin) 14088 << getOpenMPDirectiveName(OMPD_threadprivate); 14089 continue; 14090 } 14091 14092 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14093 // A variable of class type (or array thereof) that appears in a 14094 // copyin clause requires an accessible, unambiguous copy assignment 14095 // operator for the class type. 14096 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14097 VarDecl *SrcVD = 14098 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14099 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14100 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14101 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14102 VarDecl *DstVD = 14103 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14104 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14105 DeclRefExpr *PseudoDstExpr = 14106 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14107 // For arrays generate assignment operation for single element and replace 14108 // it by the original array element in CodeGen. 14109 ExprResult AssignmentOp = 14110 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14111 PseudoSrcExpr); 14112 if (AssignmentOp.isInvalid()) 14113 continue; 14114 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14115 /*DiscardedValue*/ false); 14116 if (AssignmentOp.isInvalid()) 14117 continue; 14118 14119 DSAStack->addDSA(VD, DE, OMPC_copyin); 14120 Vars.push_back(DE); 14121 SrcExprs.push_back(PseudoSrcExpr); 14122 DstExprs.push_back(PseudoDstExpr); 14123 AssignmentOps.push_back(AssignmentOp.get()); 14124 } 14125 14126 if (Vars.empty()) 14127 return nullptr; 14128 14129 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14130 SrcExprs, DstExprs, AssignmentOps); 14131 } 14132 14133 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14134 SourceLocation StartLoc, 14135 SourceLocation LParenLoc, 14136 SourceLocation EndLoc) { 14137 SmallVector<Expr *, 8> Vars; 14138 SmallVector<Expr *, 8> SrcExprs; 14139 SmallVector<Expr *, 8> DstExprs; 14140 SmallVector<Expr *, 8> AssignmentOps; 14141 for (Expr *RefExpr : VarList) { 14142 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14143 SourceLocation ELoc; 14144 SourceRange ERange; 14145 Expr *SimpleRefExpr = RefExpr; 14146 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14147 if (Res.second) { 14148 // It will be analyzed later. 14149 Vars.push_back(RefExpr); 14150 SrcExprs.push_back(nullptr); 14151 DstExprs.push_back(nullptr); 14152 AssignmentOps.push_back(nullptr); 14153 } 14154 ValueDecl *D = Res.first; 14155 if (!D) 14156 continue; 14157 14158 QualType Type = D->getType(); 14159 auto *VD = dyn_cast<VarDecl>(D); 14160 14161 // OpenMP [2.14.4.2, Restrictions, p.2] 14162 // A list item that appears in a copyprivate clause may not appear in a 14163 // private or firstprivate clause on the single construct. 14164 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14165 DSAStackTy::DSAVarData DVar = 14166 DSAStack->getTopDSA(D, /*FromParent=*/false); 14167 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14168 DVar.RefExpr) { 14169 Diag(ELoc, diag::err_omp_wrong_dsa) 14170 << getOpenMPClauseName(DVar.CKind) 14171 << getOpenMPClauseName(OMPC_copyprivate); 14172 reportOriginalDsa(*this, DSAStack, D, DVar); 14173 continue; 14174 } 14175 14176 // OpenMP [2.11.4.2, Restrictions, p.1] 14177 // All list items that appear in a copyprivate clause must be either 14178 // threadprivate or private in the enclosing context. 14179 if (DVar.CKind == OMPC_unknown) { 14180 DVar = DSAStack->getImplicitDSA(D, false); 14181 if (DVar.CKind == OMPC_shared) { 14182 Diag(ELoc, diag::err_omp_required_access) 14183 << getOpenMPClauseName(OMPC_copyprivate) 14184 << "threadprivate or private in the enclosing context"; 14185 reportOriginalDsa(*this, DSAStack, D, DVar); 14186 continue; 14187 } 14188 } 14189 } 14190 14191 // Variably modified types are not supported. 14192 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14193 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14194 << getOpenMPClauseName(OMPC_copyprivate) << Type 14195 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14196 bool IsDecl = 14197 !VD || 14198 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14199 Diag(D->getLocation(), 14200 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14201 << D; 14202 continue; 14203 } 14204 14205 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14206 // A variable of class type (or array thereof) that appears in a 14207 // copyin clause requires an accessible, unambiguous copy assignment 14208 // operator for the class type. 14209 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14210 .getUnqualifiedType(); 14211 VarDecl *SrcVD = 14212 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14213 D->hasAttrs() ? &D->getAttrs() : nullptr); 14214 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14215 VarDecl *DstVD = 14216 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14217 D->hasAttrs() ? &D->getAttrs() : nullptr); 14218 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14219 ExprResult AssignmentOp = BuildBinOp( 14220 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14221 if (AssignmentOp.isInvalid()) 14222 continue; 14223 AssignmentOp = 14224 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14225 if (AssignmentOp.isInvalid()) 14226 continue; 14227 14228 // No need to mark vars as copyprivate, they are already threadprivate or 14229 // implicitly private. 14230 assert(VD || isOpenMPCapturedDecl(D)); 14231 Vars.push_back( 14232 VD ? RefExpr->IgnoreParens() 14233 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14234 SrcExprs.push_back(PseudoSrcExpr); 14235 DstExprs.push_back(PseudoDstExpr); 14236 AssignmentOps.push_back(AssignmentOp.get()); 14237 } 14238 14239 if (Vars.empty()) 14240 return nullptr; 14241 14242 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14243 Vars, SrcExprs, DstExprs, AssignmentOps); 14244 } 14245 14246 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14247 SourceLocation StartLoc, 14248 SourceLocation LParenLoc, 14249 SourceLocation EndLoc) { 14250 if (VarList.empty()) 14251 return nullptr; 14252 14253 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14254 } 14255 14256 OMPClause * 14257 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14258 SourceLocation DepLoc, SourceLocation ColonLoc, 14259 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14260 SourceLocation LParenLoc, SourceLocation EndLoc) { 14261 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14262 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14263 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14264 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14265 return nullptr; 14266 } 14267 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14268 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14269 DepKind == OMPC_DEPEND_sink)) { 14270 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14271 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14272 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14273 /*Last=*/OMPC_DEPEND_unknown, Except) 14274 << getOpenMPClauseName(OMPC_depend); 14275 return nullptr; 14276 } 14277 SmallVector<Expr *, 8> Vars; 14278 DSAStackTy::OperatorOffsetTy OpsOffs; 14279 llvm::APSInt DepCounter(/*BitWidth=*/32); 14280 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14281 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14282 if (const Expr *OrderedCountExpr = 14283 DSAStack->getParentOrderedRegionParam().first) { 14284 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14285 TotalDepCount.setIsUnsigned(/*Val=*/true); 14286 } 14287 } 14288 for (Expr *RefExpr : VarList) { 14289 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14290 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14291 // It will be analyzed later. 14292 Vars.push_back(RefExpr); 14293 continue; 14294 } 14295 14296 SourceLocation ELoc = RefExpr->getExprLoc(); 14297 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14298 if (DepKind == OMPC_DEPEND_sink) { 14299 if (DSAStack->getParentOrderedRegionParam().first && 14300 DepCounter >= TotalDepCount) { 14301 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14302 continue; 14303 } 14304 ++DepCounter; 14305 // OpenMP [2.13.9, Summary] 14306 // depend(dependence-type : vec), where dependence-type is: 14307 // 'sink' and where vec is the iteration vector, which has the form: 14308 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14309 // where n is the value specified by the ordered clause in the loop 14310 // directive, xi denotes the loop iteration variable of the i-th nested 14311 // loop associated with the loop directive, and di is a constant 14312 // non-negative integer. 14313 if (CurContext->isDependentContext()) { 14314 // It will be analyzed later. 14315 Vars.push_back(RefExpr); 14316 continue; 14317 } 14318 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14319 OverloadedOperatorKind OOK = OO_None; 14320 SourceLocation OOLoc; 14321 Expr *LHS = SimpleExpr; 14322 Expr *RHS = nullptr; 14323 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14324 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14325 OOLoc = BO->getOperatorLoc(); 14326 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14327 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14328 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14329 OOK = OCE->getOperator(); 14330 OOLoc = OCE->getOperatorLoc(); 14331 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14332 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14333 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14334 OOK = MCE->getMethodDecl() 14335 ->getNameInfo() 14336 .getName() 14337 .getCXXOverloadedOperator(); 14338 OOLoc = MCE->getCallee()->getExprLoc(); 14339 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14340 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14341 } 14342 SourceLocation ELoc; 14343 SourceRange ERange; 14344 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14345 if (Res.second) { 14346 // It will be analyzed later. 14347 Vars.push_back(RefExpr); 14348 } 14349 ValueDecl *D = Res.first; 14350 if (!D) 14351 continue; 14352 14353 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14354 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14355 continue; 14356 } 14357 if (RHS) { 14358 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14359 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14360 if (RHSRes.isInvalid()) 14361 continue; 14362 } 14363 if (!CurContext->isDependentContext() && 14364 DSAStack->getParentOrderedRegionParam().first && 14365 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14366 const ValueDecl *VD = 14367 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14368 if (VD) 14369 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14370 << 1 << VD; 14371 else 14372 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14373 continue; 14374 } 14375 OpsOffs.emplace_back(RHS, OOK); 14376 } else { 14377 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14378 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14379 (ASE && 14380 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14381 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14382 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14383 << RefExpr->getSourceRange(); 14384 continue; 14385 } 14386 14387 ExprResult Res; 14388 { 14389 Sema::TentativeAnalysisScope Trap(*this); 14390 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14391 RefExpr->IgnoreParenImpCasts()); 14392 } 14393 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14394 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14395 << RefExpr->getSourceRange(); 14396 continue; 14397 } 14398 } 14399 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14400 } 14401 14402 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14403 TotalDepCount > VarList.size() && 14404 DSAStack->getParentOrderedRegionParam().first && 14405 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14406 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14407 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14408 } 14409 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14410 Vars.empty()) 14411 return nullptr; 14412 14413 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14414 DepKind, DepLoc, ColonLoc, Vars, 14415 TotalDepCount.getZExtValue()); 14416 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14417 DSAStack->isParentOrderedRegion()) 14418 DSAStack->addDoacrossDependClause(C, OpsOffs); 14419 return C; 14420 } 14421 14422 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14423 SourceLocation LParenLoc, 14424 SourceLocation EndLoc) { 14425 Expr *ValExpr = Device; 14426 Stmt *HelperValStmt = nullptr; 14427 14428 // OpenMP [2.9.1, Restrictions] 14429 // The device expression must evaluate to a non-negative integer value. 14430 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14431 /*StrictlyPositive=*/false)) 14432 return nullptr; 14433 14434 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14435 OpenMPDirectiveKind CaptureRegion = 14436 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14437 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14438 ValExpr = MakeFullExpr(ValExpr).get(); 14439 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14440 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14441 HelperValStmt = buildPreInits(Context, Captures); 14442 } 14443 14444 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14445 StartLoc, LParenLoc, EndLoc); 14446 } 14447 14448 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14449 DSAStackTy *Stack, QualType QTy, 14450 bool FullCheck = true) { 14451 NamedDecl *ND; 14452 if (QTy->isIncompleteType(&ND)) { 14453 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14454 return false; 14455 } 14456 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14457 !QTy.isTrivialType(SemaRef.Context)) 14458 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14459 return true; 14460 } 14461 14462 /// Return true if it can be proven that the provided array expression 14463 /// (array section or array subscript) does NOT specify the whole size of the 14464 /// array whose base type is \a BaseQTy. 14465 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14466 const Expr *E, 14467 QualType BaseQTy) { 14468 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14469 14470 // If this is an array subscript, it refers to the whole size if the size of 14471 // the dimension is constant and equals 1. Also, an array section assumes the 14472 // format of an array subscript if no colon is used. 14473 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14474 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14475 return ATy->getSize().getSExtValue() != 1; 14476 // Size can't be evaluated statically. 14477 return false; 14478 } 14479 14480 assert(OASE && "Expecting array section if not an array subscript."); 14481 const Expr *LowerBound = OASE->getLowerBound(); 14482 const Expr *Length = OASE->getLength(); 14483 14484 // If there is a lower bound that does not evaluates to zero, we are not 14485 // covering the whole dimension. 14486 if (LowerBound) { 14487 Expr::EvalResult Result; 14488 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14489 return false; // Can't get the integer value as a constant. 14490 14491 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14492 if (ConstLowerBound.getSExtValue()) 14493 return true; 14494 } 14495 14496 // If we don't have a length we covering the whole dimension. 14497 if (!Length) 14498 return false; 14499 14500 // If the base is a pointer, we don't have a way to get the size of the 14501 // pointee. 14502 if (BaseQTy->isPointerType()) 14503 return false; 14504 14505 // We can only check if the length is the same as the size of the dimension 14506 // if we have a constant array. 14507 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14508 if (!CATy) 14509 return false; 14510 14511 Expr::EvalResult Result; 14512 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14513 return false; // Can't get the integer value as a constant. 14514 14515 llvm::APSInt ConstLength = Result.Val.getInt(); 14516 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14517 } 14518 14519 // Return true if it can be proven that the provided array expression (array 14520 // section or array subscript) does NOT specify a single element of the array 14521 // whose base type is \a BaseQTy. 14522 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14523 const Expr *E, 14524 QualType BaseQTy) { 14525 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14526 14527 // An array subscript always refer to a single element. Also, an array section 14528 // assumes the format of an array subscript if no colon is used. 14529 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14530 return false; 14531 14532 assert(OASE && "Expecting array section if not an array subscript."); 14533 const Expr *Length = OASE->getLength(); 14534 14535 // If we don't have a length we have to check if the array has unitary size 14536 // for this dimension. Also, we should always expect a length if the base type 14537 // is pointer. 14538 if (!Length) { 14539 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14540 return ATy->getSize().getSExtValue() != 1; 14541 // We cannot assume anything. 14542 return false; 14543 } 14544 14545 // Check if the length evaluates to 1. 14546 Expr::EvalResult Result; 14547 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14548 return false; // Can't get the integer value as a constant. 14549 14550 llvm::APSInt ConstLength = Result.Val.getInt(); 14551 return ConstLength.getSExtValue() != 1; 14552 } 14553 14554 // Return the expression of the base of the mappable expression or null if it 14555 // cannot be determined and do all the necessary checks to see if the expression 14556 // is valid as a standalone mappable expression. In the process, record all the 14557 // components of the expression. 14558 static const Expr *checkMapClauseExpressionBase( 14559 Sema &SemaRef, Expr *E, 14560 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14561 OpenMPClauseKind CKind, bool NoDiagnose) { 14562 SourceLocation ELoc = E->getExprLoc(); 14563 SourceRange ERange = E->getSourceRange(); 14564 14565 // The base of elements of list in a map clause have to be either: 14566 // - a reference to variable or field. 14567 // - a member expression. 14568 // - an array expression. 14569 // 14570 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14571 // reference to 'r'. 14572 // 14573 // If we have: 14574 // 14575 // struct SS { 14576 // Bla S; 14577 // foo() { 14578 // #pragma omp target map (S.Arr[:12]); 14579 // } 14580 // } 14581 // 14582 // We want to retrieve the member expression 'this->S'; 14583 14584 const Expr *RelevantExpr = nullptr; 14585 14586 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14587 // If a list item is an array section, it must specify contiguous storage. 14588 // 14589 // For this restriction it is sufficient that we make sure only references 14590 // to variables or fields and array expressions, and that no array sections 14591 // exist except in the rightmost expression (unless they cover the whole 14592 // dimension of the array). E.g. these would be invalid: 14593 // 14594 // r.ArrS[3:5].Arr[6:7] 14595 // 14596 // r.ArrS[3:5].x 14597 // 14598 // but these would be valid: 14599 // r.ArrS[3].Arr[6:7] 14600 // 14601 // r.ArrS[3].x 14602 14603 bool AllowUnitySizeArraySection = true; 14604 bool AllowWholeSizeArraySection = true; 14605 14606 while (!RelevantExpr) { 14607 E = E->IgnoreParenImpCasts(); 14608 14609 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14610 if (!isa<VarDecl>(CurE->getDecl())) 14611 return nullptr; 14612 14613 RelevantExpr = CurE; 14614 14615 // If we got a reference to a declaration, we should not expect any array 14616 // section before that. 14617 AllowUnitySizeArraySection = false; 14618 AllowWholeSizeArraySection = false; 14619 14620 // Record the component. 14621 CurComponents.emplace_back(CurE, CurE->getDecl()); 14622 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14623 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14624 14625 if (isa<CXXThisExpr>(BaseE)) 14626 // We found a base expression: this->Val. 14627 RelevantExpr = CurE; 14628 else 14629 E = BaseE; 14630 14631 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14632 if (!NoDiagnose) { 14633 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14634 << CurE->getSourceRange(); 14635 return nullptr; 14636 } 14637 if (RelevantExpr) 14638 return nullptr; 14639 continue; 14640 } 14641 14642 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14643 14644 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14645 // A bit-field cannot appear in a map clause. 14646 // 14647 if (FD->isBitField()) { 14648 if (!NoDiagnose) { 14649 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14650 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14651 return nullptr; 14652 } 14653 if (RelevantExpr) 14654 return nullptr; 14655 continue; 14656 } 14657 14658 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14659 // If the type of a list item is a reference to a type T then the type 14660 // will be considered to be T for all purposes of this clause. 14661 QualType CurType = BaseE->getType().getNonReferenceType(); 14662 14663 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14664 // A list item cannot be a variable that is a member of a structure with 14665 // a union type. 14666 // 14667 if (CurType->isUnionType()) { 14668 if (!NoDiagnose) { 14669 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14670 << CurE->getSourceRange(); 14671 return nullptr; 14672 } 14673 continue; 14674 } 14675 14676 // If we got a member expression, we should not expect any array section 14677 // before that: 14678 // 14679 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14680 // If a list item is an element of a structure, only the rightmost symbol 14681 // of the variable reference can be an array section. 14682 // 14683 AllowUnitySizeArraySection = false; 14684 AllowWholeSizeArraySection = false; 14685 14686 // Record the component. 14687 CurComponents.emplace_back(CurE, FD); 14688 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14689 E = CurE->getBase()->IgnoreParenImpCasts(); 14690 14691 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14692 if (!NoDiagnose) { 14693 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14694 << 0 << CurE->getSourceRange(); 14695 return nullptr; 14696 } 14697 continue; 14698 } 14699 14700 // If we got an array subscript that express the whole dimension we 14701 // can have any array expressions before. If it only expressing part of 14702 // the dimension, we can only have unitary-size array expressions. 14703 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14704 E->getType())) 14705 AllowWholeSizeArraySection = false; 14706 14707 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14708 Expr::EvalResult Result; 14709 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14710 if (!Result.Val.getInt().isNullValue()) { 14711 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14712 diag::err_omp_invalid_map_this_expr); 14713 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14714 diag::note_omp_invalid_subscript_on_this_ptr_map); 14715 } 14716 } 14717 RelevantExpr = TE; 14718 } 14719 14720 // Record the component - we don't have any declaration associated. 14721 CurComponents.emplace_back(CurE, nullptr); 14722 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14723 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14724 E = CurE->getBase()->IgnoreParenImpCasts(); 14725 14726 QualType CurType = 14727 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14728 14729 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14730 // If the type of a list item is a reference to a type T then the type 14731 // will be considered to be T for all purposes of this clause. 14732 if (CurType->isReferenceType()) 14733 CurType = CurType->getPointeeType(); 14734 14735 bool IsPointer = CurType->isAnyPointerType(); 14736 14737 if (!IsPointer && !CurType->isArrayType()) { 14738 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14739 << 0 << CurE->getSourceRange(); 14740 return nullptr; 14741 } 14742 14743 bool NotWhole = 14744 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14745 bool NotUnity = 14746 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14747 14748 if (AllowWholeSizeArraySection) { 14749 // Any array section is currently allowed. Allowing a whole size array 14750 // section implies allowing a unity array section as well. 14751 // 14752 // If this array section refers to the whole dimension we can still 14753 // accept other array sections before this one, except if the base is a 14754 // pointer. Otherwise, only unitary sections are accepted. 14755 if (NotWhole || IsPointer) 14756 AllowWholeSizeArraySection = false; 14757 } else if (AllowUnitySizeArraySection && NotUnity) { 14758 // A unity or whole array section is not allowed and that is not 14759 // compatible with the properties of the current array section. 14760 SemaRef.Diag( 14761 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14762 << CurE->getSourceRange(); 14763 return nullptr; 14764 } 14765 14766 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14767 Expr::EvalResult ResultR; 14768 Expr::EvalResult ResultL; 14769 if (CurE->getLength()->EvaluateAsInt(ResultR, 14770 SemaRef.getASTContext())) { 14771 if (!ResultR.Val.getInt().isOneValue()) { 14772 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14773 diag::err_omp_invalid_map_this_expr); 14774 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14775 diag::note_omp_invalid_length_on_this_ptr_mapping); 14776 } 14777 } 14778 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14779 ResultL, SemaRef.getASTContext())) { 14780 if (!ResultL.Val.getInt().isNullValue()) { 14781 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14782 diag::err_omp_invalid_map_this_expr); 14783 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14784 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14785 } 14786 } 14787 RelevantExpr = TE; 14788 } 14789 14790 // Record the component - we don't have any declaration associated. 14791 CurComponents.emplace_back(CurE, nullptr); 14792 } else { 14793 if (!NoDiagnose) { 14794 // If nothing else worked, this is not a valid map clause expression. 14795 SemaRef.Diag( 14796 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14797 << ERange; 14798 } 14799 return nullptr; 14800 } 14801 } 14802 14803 return RelevantExpr; 14804 } 14805 14806 // Return true if expression E associated with value VD has conflicts with other 14807 // map information. 14808 static bool checkMapConflicts( 14809 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14810 bool CurrentRegionOnly, 14811 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14812 OpenMPClauseKind CKind) { 14813 assert(VD && E); 14814 SourceLocation ELoc = E->getExprLoc(); 14815 SourceRange ERange = E->getSourceRange(); 14816 14817 // In order to easily check the conflicts we need to match each component of 14818 // the expression under test with the components of the expressions that are 14819 // already in the stack. 14820 14821 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14822 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14823 "Map clause expression with unexpected base!"); 14824 14825 // Variables to help detecting enclosing problems in data environment nests. 14826 bool IsEnclosedByDataEnvironmentExpr = false; 14827 const Expr *EnclosingExpr = nullptr; 14828 14829 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14830 VD, CurrentRegionOnly, 14831 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14832 ERange, CKind, &EnclosingExpr, 14833 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14834 StackComponents, 14835 OpenMPClauseKind) { 14836 assert(!StackComponents.empty() && 14837 "Map clause expression with no components!"); 14838 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14839 "Map clause expression with unexpected base!"); 14840 (void)VD; 14841 14842 // The whole expression in the stack. 14843 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14844 14845 // Expressions must start from the same base. Here we detect at which 14846 // point both expressions diverge from each other and see if we can 14847 // detect if the memory referred to both expressions is contiguous and 14848 // do not overlap. 14849 auto CI = CurComponents.rbegin(); 14850 auto CE = CurComponents.rend(); 14851 auto SI = StackComponents.rbegin(); 14852 auto SE = StackComponents.rend(); 14853 for (; CI != CE && SI != SE; ++CI, ++SI) { 14854 14855 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14856 // At most one list item can be an array item derived from a given 14857 // variable in map clauses of the same construct. 14858 if (CurrentRegionOnly && 14859 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14860 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14861 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14862 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14863 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14864 diag::err_omp_multiple_array_items_in_map_clause) 14865 << CI->getAssociatedExpression()->getSourceRange(); 14866 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14867 diag::note_used_here) 14868 << SI->getAssociatedExpression()->getSourceRange(); 14869 return true; 14870 } 14871 14872 // Do both expressions have the same kind? 14873 if (CI->getAssociatedExpression()->getStmtClass() != 14874 SI->getAssociatedExpression()->getStmtClass()) 14875 break; 14876 14877 // Are we dealing with different variables/fields? 14878 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14879 break; 14880 } 14881 // Check if the extra components of the expressions in the enclosing 14882 // data environment are redundant for the current base declaration. 14883 // If they are, the maps completely overlap, which is legal. 14884 for (; SI != SE; ++SI) { 14885 QualType Type; 14886 if (const auto *ASE = 14887 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14888 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14889 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14890 SI->getAssociatedExpression())) { 14891 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14892 Type = 14893 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14894 } 14895 if (Type.isNull() || Type->isAnyPointerType() || 14896 checkArrayExpressionDoesNotReferToWholeSize( 14897 SemaRef, SI->getAssociatedExpression(), Type)) 14898 break; 14899 } 14900 14901 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14902 // List items of map clauses in the same construct must not share 14903 // original storage. 14904 // 14905 // If the expressions are exactly the same or one is a subset of the 14906 // other, it means they are sharing storage. 14907 if (CI == CE && SI == SE) { 14908 if (CurrentRegionOnly) { 14909 if (CKind == OMPC_map) { 14910 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14911 } else { 14912 assert(CKind == OMPC_to || CKind == OMPC_from); 14913 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14914 << ERange; 14915 } 14916 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14917 << RE->getSourceRange(); 14918 return true; 14919 } 14920 // If we find the same expression in the enclosing data environment, 14921 // that is legal. 14922 IsEnclosedByDataEnvironmentExpr = true; 14923 return false; 14924 } 14925 14926 QualType DerivedType = 14927 std::prev(CI)->getAssociatedDeclaration()->getType(); 14928 SourceLocation DerivedLoc = 14929 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14930 14931 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14932 // If the type of a list item is a reference to a type T then the type 14933 // will be considered to be T for all purposes of this clause. 14934 DerivedType = DerivedType.getNonReferenceType(); 14935 14936 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14937 // A variable for which the type is pointer and an array section 14938 // derived from that variable must not appear as list items of map 14939 // clauses of the same construct. 14940 // 14941 // Also, cover one of the cases in: 14942 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14943 // If any part of the original storage of a list item has corresponding 14944 // storage in the device data environment, all of the original storage 14945 // must have corresponding storage in the device data environment. 14946 // 14947 if (DerivedType->isAnyPointerType()) { 14948 if (CI == CE || SI == SE) { 14949 SemaRef.Diag( 14950 DerivedLoc, 14951 diag::err_omp_pointer_mapped_along_with_derived_section) 14952 << DerivedLoc; 14953 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14954 << RE->getSourceRange(); 14955 return true; 14956 } 14957 if (CI->getAssociatedExpression()->getStmtClass() != 14958 SI->getAssociatedExpression()->getStmtClass() || 14959 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14960 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14961 assert(CI != CE && SI != SE); 14962 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14963 << DerivedLoc; 14964 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14965 << RE->getSourceRange(); 14966 return true; 14967 } 14968 } 14969 14970 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14971 // List items of map clauses in the same construct must not share 14972 // original storage. 14973 // 14974 // An expression is a subset of the other. 14975 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14976 if (CKind == OMPC_map) { 14977 if (CI != CE || SI != SE) { 14978 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14979 // a pointer. 14980 auto Begin = 14981 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14982 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14983 auto It = Begin; 14984 while (It != End && !It->getAssociatedDeclaration()) 14985 std::advance(It, 1); 14986 assert(It != End && 14987 "Expected at least one component with the declaration."); 14988 if (It != Begin && It->getAssociatedDeclaration() 14989 ->getType() 14990 .getCanonicalType() 14991 ->isAnyPointerType()) { 14992 IsEnclosedByDataEnvironmentExpr = false; 14993 EnclosingExpr = nullptr; 14994 return false; 14995 } 14996 } 14997 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14998 } else { 14999 assert(CKind == OMPC_to || CKind == OMPC_from); 15000 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15001 << ERange; 15002 } 15003 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15004 << RE->getSourceRange(); 15005 return true; 15006 } 15007 15008 // The current expression uses the same base as other expression in the 15009 // data environment but does not contain it completely. 15010 if (!CurrentRegionOnly && SI != SE) 15011 EnclosingExpr = RE; 15012 15013 // The current expression is a subset of the expression in the data 15014 // environment. 15015 IsEnclosedByDataEnvironmentExpr |= 15016 (!CurrentRegionOnly && CI != CE && SI == SE); 15017 15018 return false; 15019 }); 15020 15021 if (CurrentRegionOnly) 15022 return FoundError; 15023 15024 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15025 // If any part of the original storage of a list item has corresponding 15026 // storage in the device data environment, all of the original storage must 15027 // have corresponding storage in the device data environment. 15028 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15029 // If a list item is an element of a structure, and a different element of 15030 // the structure has a corresponding list item in the device data environment 15031 // prior to a task encountering the construct associated with the map clause, 15032 // then the list item must also have a corresponding list item in the device 15033 // data environment prior to the task encountering the construct. 15034 // 15035 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15036 SemaRef.Diag(ELoc, 15037 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15038 << ERange; 15039 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15040 << EnclosingExpr->getSourceRange(); 15041 return true; 15042 } 15043 15044 return FoundError; 15045 } 15046 15047 // Look up the user-defined mapper given the mapper name and mapped type, and 15048 // build a reference to it. 15049 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15050 CXXScopeSpec &MapperIdScopeSpec, 15051 const DeclarationNameInfo &MapperId, 15052 QualType Type, 15053 Expr *UnresolvedMapper) { 15054 if (MapperIdScopeSpec.isInvalid()) 15055 return ExprError(); 15056 // Get the actual type for the array type. 15057 if (Type->isArrayType()) { 15058 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15059 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15060 } 15061 // Find all user-defined mappers with the given MapperId. 15062 SmallVector<UnresolvedSet<8>, 4> Lookups; 15063 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15064 Lookup.suppressDiagnostics(); 15065 if (S) { 15066 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15067 NamedDecl *D = Lookup.getRepresentativeDecl(); 15068 while (S && !S->isDeclScope(D)) 15069 S = S->getParent(); 15070 if (S) 15071 S = S->getParent(); 15072 Lookups.emplace_back(); 15073 Lookups.back().append(Lookup.begin(), Lookup.end()); 15074 Lookup.clear(); 15075 } 15076 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15077 // Extract the user-defined mappers with the given MapperId. 15078 Lookups.push_back(UnresolvedSet<8>()); 15079 for (NamedDecl *D : ULE->decls()) { 15080 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15081 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15082 Lookups.back().addDecl(DMD); 15083 } 15084 } 15085 // Defer the lookup for dependent types. The results will be passed through 15086 // UnresolvedMapper on instantiation. 15087 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15088 Type->isInstantiationDependentType() || 15089 Type->containsUnexpandedParameterPack() || 15090 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15091 return !D->isInvalidDecl() && 15092 (D->getType()->isDependentType() || 15093 D->getType()->isInstantiationDependentType() || 15094 D->getType()->containsUnexpandedParameterPack()); 15095 })) { 15096 UnresolvedSet<8> URS; 15097 for (const UnresolvedSet<8> &Set : Lookups) { 15098 if (Set.empty()) 15099 continue; 15100 URS.append(Set.begin(), Set.end()); 15101 } 15102 return UnresolvedLookupExpr::Create( 15103 SemaRef.Context, /*NamingClass=*/nullptr, 15104 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15105 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15106 } 15107 SourceLocation Loc = MapperId.getLoc(); 15108 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15109 // The type must be of struct, union or class type in C and C++ 15110 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15111 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15112 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15113 return ExprError(); 15114 } 15115 // Perform argument dependent lookup. 15116 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15117 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15118 // Return the first user-defined mapper with the desired type. 15119 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15120 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15121 if (!D->isInvalidDecl() && 15122 SemaRef.Context.hasSameType(D->getType(), Type)) 15123 return D; 15124 return nullptr; 15125 })) 15126 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15127 // Find the first user-defined mapper with a type derived from the desired 15128 // type. 15129 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15130 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15131 if (!D->isInvalidDecl() && 15132 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15133 !Type.isMoreQualifiedThan(D->getType())) 15134 return D; 15135 return nullptr; 15136 })) { 15137 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15138 /*DetectVirtual=*/false); 15139 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15140 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15141 VD->getType().getUnqualifiedType()))) { 15142 if (SemaRef.CheckBaseClassAccess( 15143 Loc, VD->getType(), Type, Paths.front(), 15144 /*DiagID=*/0) != Sema::AR_inaccessible) { 15145 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15146 } 15147 } 15148 } 15149 } 15150 // Report error if a mapper is specified, but cannot be found. 15151 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15152 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15153 << Type << MapperId.getName(); 15154 return ExprError(); 15155 } 15156 return ExprEmpty(); 15157 } 15158 15159 namespace { 15160 // Utility struct that gathers all the related lists associated with a mappable 15161 // expression. 15162 struct MappableVarListInfo { 15163 // The list of expressions. 15164 ArrayRef<Expr *> VarList; 15165 // The list of processed expressions. 15166 SmallVector<Expr *, 16> ProcessedVarList; 15167 // The mappble components for each expression. 15168 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15169 // The base declaration of the variable. 15170 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15171 // The reference to the user-defined mapper associated with every expression. 15172 SmallVector<Expr *, 16> UDMapperList; 15173 15174 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15175 // We have a list of components and base declarations for each entry in the 15176 // variable list. 15177 VarComponents.reserve(VarList.size()); 15178 VarBaseDeclarations.reserve(VarList.size()); 15179 } 15180 }; 15181 } 15182 15183 // Check the validity of the provided variable list for the provided clause kind 15184 // \a CKind. In the check process the valid expressions, mappable expression 15185 // components, variables, and user-defined mappers are extracted and used to 15186 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15187 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15188 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15189 static void checkMappableExpressionList( 15190 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15191 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15192 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15193 ArrayRef<Expr *> UnresolvedMappers, 15194 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15195 bool IsMapTypeImplicit = false) { 15196 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15197 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15198 "Unexpected clause kind with mappable expressions!"); 15199 15200 // If the identifier of user-defined mapper is not specified, it is "default". 15201 // We do not change the actual name in this clause to distinguish whether a 15202 // mapper is specified explicitly, i.e., it is not explicitly specified when 15203 // MapperId.getName() is empty. 15204 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15205 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15206 MapperId.setName(DeclNames.getIdentifier( 15207 &SemaRef.getASTContext().Idents.get("default"))); 15208 } 15209 15210 // Iterators to find the current unresolved mapper expression. 15211 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15212 bool UpdateUMIt = false; 15213 Expr *UnresolvedMapper = nullptr; 15214 15215 // Keep track of the mappable components and base declarations in this clause. 15216 // Each entry in the list is going to have a list of components associated. We 15217 // record each set of the components so that we can build the clause later on. 15218 // In the end we should have the same amount of declarations and component 15219 // lists. 15220 15221 for (Expr *RE : MVLI.VarList) { 15222 assert(RE && "Null expr in omp to/from/map clause"); 15223 SourceLocation ELoc = RE->getExprLoc(); 15224 15225 // Find the current unresolved mapper expression. 15226 if (UpdateUMIt && UMIt != UMEnd) { 15227 UMIt++; 15228 assert( 15229 UMIt != UMEnd && 15230 "Expect the size of UnresolvedMappers to match with that of VarList"); 15231 } 15232 UpdateUMIt = true; 15233 if (UMIt != UMEnd) 15234 UnresolvedMapper = *UMIt; 15235 15236 const Expr *VE = RE->IgnoreParenLValueCasts(); 15237 15238 if (VE->isValueDependent() || VE->isTypeDependent() || 15239 VE->isInstantiationDependent() || 15240 VE->containsUnexpandedParameterPack()) { 15241 // Try to find the associated user-defined mapper. 15242 ExprResult ER = buildUserDefinedMapperRef( 15243 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15244 VE->getType().getCanonicalType(), UnresolvedMapper); 15245 if (ER.isInvalid()) 15246 continue; 15247 MVLI.UDMapperList.push_back(ER.get()); 15248 // We can only analyze this information once the missing information is 15249 // resolved. 15250 MVLI.ProcessedVarList.push_back(RE); 15251 continue; 15252 } 15253 15254 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15255 15256 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15257 SemaRef.Diag(ELoc, 15258 diag::err_omp_expected_named_var_member_or_array_expression) 15259 << RE->getSourceRange(); 15260 continue; 15261 } 15262 15263 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15264 ValueDecl *CurDeclaration = nullptr; 15265 15266 // Obtain the array or member expression bases if required. Also, fill the 15267 // components array with all the components identified in the process. 15268 const Expr *BE = checkMapClauseExpressionBase( 15269 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15270 if (!BE) 15271 continue; 15272 15273 assert(!CurComponents.empty() && 15274 "Invalid mappable expression information."); 15275 15276 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15277 // Add store "this" pointer to class in DSAStackTy for future checking 15278 DSAS->addMappedClassesQualTypes(TE->getType()); 15279 // Try to find the associated user-defined mapper. 15280 ExprResult ER = buildUserDefinedMapperRef( 15281 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15282 VE->getType().getCanonicalType(), UnresolvedMapper); 15283 if (ER.isInvalid()) 15284 continue; 15285 MVLI.UDMapperList.push_back(ER.get()); 15286 // Skip restriction checking for variable or field declarations 15287 MVLI.ProcessedVarList.push_back(RE); 15288 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15289 MVLI.VarComponents.back().append(CurComponents.begin(), 15290 CurComponents.end()); 15291 MVLI.VarBaseDeclarations.push_back(nullptr); 15292 continue; 15293 } 15294 15295 // For the following checks, we rely on the base declaration which is 15296 // expected to be associated with the last component. The declaration is 15297 // expected to be a variable or a field (if 'this' is being mapped). 15298 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15299 assert(CurDeclaration && "Null decl on map clause."); 15300 assert( 15301 CurDeclaration->isCanonicalDecl() && 15302 "Expecting components to have associated only canonical declarations."); 15303 15304 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15305 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15306 15307 assert((VD || FD) && "Only variables or fields are expected here!"); 15308 (void)FD; 15309 15310 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15311 // threadprivate variables cannot appear in a map clause. 15312 // OpenMP 4.5 [2.10.5, target update Construct] 15313 // threadprivate variables cannot appear in a from clause. 15314 if (VD && DSAS->isThreadPrivate(VD)) { 15315 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15316 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15317 << getOpenMPClauseName(CKind); 15318 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15319 continue; 15320 } 15321 15322 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15323 // A list item cannot appear in both a map clause and a data-sharing 15324 // attribute clause on the same construct. 15325 15326 // Check conflicts with other map clause expressions. We check the conflicts 15327 // with the current construct separately from the enclosing data 15328 // environment, because the restrictions are different. We only have to 15329 // check conflicts across regions for the map clauses. 15330 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15331 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15332 break; 15333 if (CKind == OMPC_map && 15334 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15335 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15336 break; 15337 15338 // OpenMP 4.5 [2.10.5, target update Construct] 15339 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15340 // If the type of a list item is a reference to a type T then the type will 15341 // be considered to be T for all purposes of this clause. 15342 auto I = llvm::find_if( 15343 CurComponents, 15344 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15345 return MC.getAssociatedDeclaration(); 15346 }); 15347 assert(I != CurComponents.end() && "Null decl on map clause."); 15348 QualType Type = 15349 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15350 15351 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15352 // A list item in a to or from clause must have a mappable type. 15353 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15354 // A list item must have a mappable type. 15355 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15356 DSAS, Type)) 15357 continue; 15358 15359 if (CKind == OMPC_map) { 15360 // target enter data 15361 // OpenMP [2.10.2, Restrictions, p. 99] 15362 // A map-type must be specified in all map clauses and must be either 15363 // to or alloc. 15364 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15365 if (DKind == OMPD_target_enter_data && 15366 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15367 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15368 << (IsMapTypeImplicit ? 1 : 0) 15369 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15370 << getOpenMPDirectiveName(DKind); 15371 continue; 15372 } 15373 15374 // target exit_data 15375 // OpenMP [2.10.3, Restrictions, p. 102] 15376 // A map-type must be specified in all map clauses and must be either 15377 // from, release, or delete. 15378 if (DKind == OMPD_target_exit_data && 15379 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15380 MapType == OMPC_MAP_delete)) { 15381 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15382 << (IsMapTypeImplicit ? 1 : 0) 15383 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15384 << getOpenMPDirectiveName(DKind); 15385 continue; 15386 } 15387 15388 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15389 // A list item cannot appear in both a map clause and a data-sharing 15390 // attribute clause on the same construct 15391 // 15392 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15393 // A list item cannot appear in both a map clause and a data-sharing 15394 // attribute clause on the same construct unless the construct is a 15395 // combined construct. 15396 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15397 isOpenMPTargetExecutionDirective(DKind)) || 15398 DKind == OMPD_target)) { 15399 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15400 if (isOpenMPPrivate(DVar.CKind)) { 15401 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15402 << getOpenMPClauseName(DVar.CKind) 15403 << getOpenMPClauseName(OMPC_map) 15404 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15405 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15406 continue; 15407 } 15408 } 15409 } 15410 15411 // Try to find the associated user-defined mapper. 15412 ExprResult ER = buildUserDefinedMapperRef( 15413 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15414 Type.getCanonicalType(), UnresolvedMapper); 15415 if (ER.isInvalid()) 15416 continue; 15417 MVLI.UDMapperList.push_back(ER.get()); 15418 15419 // Save the current expression. 15420 MVLI.ProcessedVarList.push_back(RE); 15421 15422 // Store the components in the stack so that they can be used to check 15423 // against other clauses later on. 15424 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15425 /*WhereFoundClauseKind=*/OMPC_map); 15426 15427 // Save the components and declaration to create the clause. For purposes of 15428 // the clause creation, any component list that has has base 'this' uses 15429 // null as base declaration. 15430 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15431 MVLI.VarComponents.back().append(CurComponents.begin(), 15432 CurComponents.end()); 15433 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15434 : CurDeclaration); 15435 } 15436 } 15437 15438 OMPClause *Sema::ActOnOpenMPMapClause( 15439 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15440 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15441 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15442 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15443 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15444 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15445 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15446 OMPC_MAP_MODIFIER_unknown, 15447 OMPC_MAP_MODIFIER_unknown}; 15448 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15449 15450 // Process map-type-modifiers, flag errors for duplicate modifiers. 15451 unsigned Count = 0; 15452 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15453 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15454 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15455 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15456 continue; 15457 } 15458 assert(Count < OMPMapClause::NumberOfModifiers && 15459 "Modifiers exceed the allowed number of map type modifiers"); 15460 Modifiers[Count] = MapTypeModifiers[I]; 15461 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15462 ++Count; 15463 } 15464 15465 MappableVarListInfo MVLI(VarList); 15466 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15467 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15468 MapType, IsMapTypeImplicit); 15469 15470 // We need to produce a map clause even if we don't have variables so that 15471 // other diagnostics related with non-existing map clauses are accurate. 15472 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15473 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15474 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15475 MapperIdScopeSpec.getWithLocInContext(Context), 15476 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15477 } 15478 15479 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15480 TypeResult ParsedType) { 15481 assert(ParsedType.isUsable()); 15482 15483 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15484 if (ReductionType.isNull()) 15485 return QualType(); 15486 15487 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15488 // A type name in a declare reduction directive cannot be a function type, an 15489 // array type, a reference type, or a type qualified with const, volatile or 15490 // restrict. 15491 if (ReductionType.hasQualifiers()) { 15492 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15493 return QualType(); 15494 } 15495 15496 if (ReductionType->isFunctionType()) { 15497 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15498 return QualType(); 15499 } 15500 if (ReductionType->isReferenceType()) { 15501 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15502 return QualType(); 15503 } 15504 if (ReductionType->isArrayType()) { 15505 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15506 return QualType(); 15507 } 15508 return ReductionType; 15509 } 15510 15511 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15512 Scope *S, DeclContext *DC, DeclarationName Name, 15513 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15514 AccessSpecifier AS, Decl *PrevDeclInScope) { 15515 SmallVector<Decl *, 8> Decls; 15516 Decls.reserve(ReductionTypes.size()); 15517 15518 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15519 forRedeclarationInCurContext()); 15520 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15521 // A reduction-identifier may not be re-declared in the current scope for the 15522 // same type or for a type that is compatible according to the base language 15523 // rules. 15524 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15525 OMPDeclareReductionDecl *PrevDRD = nullptr; 15526 bool InCompoundScope = true; 15527 if (S != nullptr) { 15528 // Find previous declaration with the same name not referenced in other 15529 // declarations. 15530 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15531 InCompoundScope = 15532 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15533 LookupName(Lookup, S); 15534 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15535 /*AllowInlineNamespace=*/false); 15536 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15537 LookupResult::Filter Filter = Lookup.makeFilter(); 15538 while (Filter.hasNext()) { 15539 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15540 if (InCompoundScope) { 15541 auto I = UsedAsPrevious.find(PrevDecl); 15542 if (I == UsedAsPrevious.end()) 15543 UsedAsPrevious[PrevDecl] = false; 15544 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15545 UsedAsPrevious[D] = true; 15546 } 15547 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15548 PrevDecl->getLocation(); 15549 } 15550 Filter.done(); 15551 if (InCompoundScope) { 15552 for (const auto &PrevData : UsedAsPrevious) { 15553 if (!PrevData.second) { 15554 PrevDRD = PrevData.first; 15555 break; 15556 } 15557 } 15558 } 15559 } else if (PrevDeclInScope != nullptr) { 15560 auto *PrevDRDInScope = PrevDRD = 15561 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15562 do { 15563 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15564 PrevDRDInScope->getLocation(); 15565 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15566 } while (PrevDRDInScope != nullptr); 15567 } 15568 for (const auto &TyData : ReductionTypes) { 15569 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15570 bool Invalid = false; 15571 if (I != PreviousRedeclTypes.end()) { 15572 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15573 << TyData.first; 15574 Diag(I->second, diag::note_previous_definition); 15575 Invalid = true; 15576 } 15577 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15578 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15579 Name, TyData.first, PrevDRD); 15580 DC->addDecl(DRD); 15581 DRD->setAccess(AS); 15582 Decls.push_back(DRD); 15583 if (Invalid) 15584 DRD->setInvalidDecl(); 15585 else 15586 PrevDRD = DRD; 15587 } 15588 15589 return DeclGroupPtrTy::make( 15590 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15591 } 15592 15593 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15594 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15595 15596 // Enter new function scope. 15597 PushFunctionScope(); 15598 setFunctionHasBranchProtectedScope(); 15599 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15600 15601 if (S != nullptr) 15602 PushDeclContext(S, DRD); 15603 else 15604 CurContext = DRD; 15605 15606 PushExpressionEvaluationContext( 15607 ExpressionEvaluationContext::PotentiallyEvaluated); 15608 15609 QualType ReductionType = DRD->getType(); 15610 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15611 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15612 // uses semantics of argument handles by value, but it should be passed by 15613 // reference. C lang does not support references, so pass all parameters as 15614 // pointers. 15615 // Create 'T omp_in;' variable. 15616 VarDecl *OmpInParm = 15617 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15618 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15619 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 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_out;' variable. 15624 VarDecl *OmpOutParm = 15625 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15626 if (S != nullptr) { 15627 PushOnScopeChains(OmpInParm, S); 15628 PushOnScopeChains(OmpOutParm, S); 15629 } else { 15630 DRD->addDecl(OmpInParm); 15631 DRD->addDecl(OmpOutParm); 15632 } 15633 Expr *InE = 15634 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15635 Expr *OutE = 15636 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15637 DRD->setCombinerData(InE, OutE); 15638 } 15639 15640 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15641 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15642 DiscardCleanupsInEvaluationContext(); 15643 PopExpressionEvaluationContext(); 15644 15645 PopDeclContext(); 15646 PopFunctionScopeInfo(); 15647 15648 if (Combiner != nullptr) 15649 DRD->setCombiner(Combiner); 15650 else 15651 DRD->setInvalidDecl(); 15652 } 15653 15654 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15655 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15656 15657 // Enter new function scope. 15658 PushFunctionScope(); 15659 setFunctionHasBranchProtectedScope(); 15660 15661 if (S != nullptr) 15662 PushDeclContext(S, DRD); 15663 else 15664 CurContext = DRD; 15665 15666 PushExpressionEvaluationContext( 15667 ExpressionEvaluationContext::PotentiallyEvaluated); 15668 15669 QualType ReductionType = DRD->getType(); 15670 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15671 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15672 // uses semantics of argument handles by value, but it should be passed by 15673 // reference. C lang does not support references, so pass all parameters as 15674 // pointers. 15675 // Create 'T omp_priv;' variable. 15676 VarDecl *OmpPrivParm = 15677 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15678 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15679 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 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_orig;' variable. 15684 VarDecl *OmpOrigParm = 15685 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15686 if (S != nullptr) { 15687 PushOnScopeChains(OmpPrivParm, S); 15688 PushOnScopeChains(OmpOrigParm, S); 15689 } else { 15690 DRD->addDecl(OmpPrivParm); 15691 DRD->addDecl(OmpOrigParm); 15692 } 15693 Expr *OrigE = 15694 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15695 Expr *PrivE = 15696 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15697 DRD->setInitializerData(OrigE, PrivE); 15698 return OmpPrivParm; 15699 } 15700 15701 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15702 VarDecl *OmpPrivParm) { 15703 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15704 DiscardCleanupsInEvaluationContext(); 15705 PopExpressionEvaluationContext(); 15706 15707 PopDeclContext(); 15708 PopFunctionScopeInfo(); 15709 15710 if (Initializer != nullptr) { 15711 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15712 } else if (OmpPrivParm->hasInit()) { 15713 DRD->setInitializer(OmpPrivParm->getInit(), 15714 OmpPrivParm->isDirectInit() 15715 ? OMPDeclareReductionDecl::DirectInit 15716 : OMPDeclareReductionDecl::CopyInit); 15717 } else { 15718 DRD->setInvalidDecl(); 15719 } 15720 } 15721 15722 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15723 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15724 for (Decl *D : DeclReductions.get()) { 15725 if (IsValid) { 15726 if (S) 15727 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15728 /*AddToContext=*/false); 15729 } else { 15730 D->setInvalidDecl(); 15731 } 15732 } 15733 return DeclReductions; 15734 } 15735 15736 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15737 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15738 QualType T = TInfo->getType(); 15739 if (D.isInvalidType()) 15740 return true; 15741 15742 if (getLangOpts().CPlusPlus) { 15743 // Check that there are no default arguments (C++ only). 15744 CheckExtraCXXDefaultArguments(D); 15745 } 15746 15747 return CreateParsedType(T, TInfo); 15748 } 15749 15750 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15751 TypeResult ParsedType) { 15752 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15753 15754 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15755 assert(!MapperType.isNull() && "Expect valid mapper type"); 15756 15757 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15758 // The type must be of struct, union or class type in C and C++ 15759 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15760 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15761 return QualType(); 15762 } 15763 return MapperType; 15764 } 15765 15766 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15767 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15768 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15769 Decl *PrevDeclInScope) { 15770 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15771 forRedeclarationInCurContext()); 15772 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15773 // A mapper-identifier may not be redeclared in the current scope for the 15774 // same type or for a type that is compatible according to the base language 15775 // rules. 15776 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15777 OMPDeclareMapperDecl *PrevDMD = nullptr; 15778 bool InCompoundScope = true; 15779 if (S != nullptr) { 15780 // Find previous declaration with the same name not referenced in other 15781 // declarations. 15782 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15783 InCompoundScope = 15784 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15785 LookupName(Lookup, S); 15786 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15787 /*AllowInlineNamespace=*/false); 15788 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15789 LookupResult::Filter Filter = Lookup.makeFilter(); 15790 while (Filter.hasNext()) { 15791 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15792 if (InCompoundScope) { 15793 auto I = UsedAsPrevious.find(PrevDecl); 15794 if (I == UsedAsPrevious.end()) 15795 UsedAsPrevious[PrevDecl] = false; 15796 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15797 UsedAsPrevious[D] = true; 15798 } 15799 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15800 PrevDecl->getLocation(); 15801 } 15802 Filter.done(); 15803 if (InCompoundScope) { 15804 for (const auto &PrevData : UsedAsPrevious) { 15805 if (!PrevData.second) { 15806 PrevDMD = PrevData.first; 15807 break; 15808 } 15809 } 15810 } 15811 } else if (PrevDeclInScope) { 15812 auto *PrevDMDInScope = PrevDMD = 15813 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15814 do { 15815 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15816 PrevDMDInScope->getLocation(); 15817 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15818 } while (PrevDMDInScope != nullptr); 15819 } 15820 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15821 bool Invalid = false; 15822 if (I != PreviousRedeclTypes.end()) { 15823 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15824 << MapperType << Name; 15825 Diag(I->second, diag::note_previous_definition); 15826 Invalid = true; 15827 } 15828 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15829 MapperType, VN, PrevDMD); 15830 DC->addDecl(DMD); 15831 DMD->setAccess(AS); 15832 if (Invalid) 15833 DMD->setInvalidDecl(); 15834 15835 // Enter new function scope. 15836 PushFunctionScope(); 15837 setFunctionHasBranchProtectedScope(); 15838 15839 CurContext = DMD; 15840 15841 return DMD; 15842 } 15843 15844 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15845 Scope *S, 15846 QualType MapperType, 15847 SourceLocation StartLoc, 15848 DeclarationName VN) { 15849 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15850 if (S) 15851 PushOnScopeChains(VD, S); 15852 else 15853 DMD->addDecl(VD); 15854 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15855 DMD->setMapperVarRef(MapperVarRefExpr); 15856 } 15857 15858 Sema::DeclGroupPtrTy 15859 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15860 ArrayRef<OMPClause *> ClauseList) { 15861 PopDeclContext(); 15862 PopFunctionScopeInfo(); 15863 15864 if (D) { 15865 if (S) 15866 PushOnScopeChains(D, S, /*AddToContext=*/false); 15867 D->CreateClauses(Context, ClauseList); 15868 } 15869 15870 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15871 } 15872 15873 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15874 SourceLocation StartLoc, 15875 SourceLocation LParenLoc, 15876 SourceLocation EndLoc) { 15877 Expr *ValExpr = NumTeams; 15878 Stmt *HelperValStmt = nullptr; 15879 15880 // OpenMP [teams Constrcut, Restrictions] 15881 // The num_teams expression must evaluate to a positive integer value. 15882 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15883 /*StrictlyPositive=*/true)) 15884 return nullptr; 15885 15886 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15887 OpenMPDirectiveKind CaptureRegion = 15888 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15889 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15890 ValExpr = MakeFullExpr(ValExpr).get(); 15891 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15892 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15893 HelperValStmt = buildPreInits(Context, Captures); 15894 } 15895 15896 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15897 StartLoc, LParenLoc, EndLoc); 15898 } 15899 15900 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15901 SourceLocation StartLoc, 15902 SourceLocation LParenLoc, 15903 SourceLocation EndLoc) { 15904 Expr *ValExpr = ThreadLimit; 15905 Stmt *HelperValStmt = nullptr; 15906 15907 // OpenMP [teams Constrcut, Restrictions] 15908 // The thread_limit expression must evaluate to a positive integer value. 15909 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15910 /*StrictlyPositive=*/true)) 15911 return nullptr; 15912 15913 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15914 OpenMPDirectiveKind CaptureRegion = 15915 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15916 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15917 ValExpr = MakeFullExpr(ValExpr).get(); 15918 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15919 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15920 HelperValStmt = buildPreInits(Context, Captures); 15921 } 15922 15923 return new (Context) OMPThreadLimitClause( 15924 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15925 } 15926 15927 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15928 SourceLocation StartLoc, 15929 SourceLocation LParenLoc, 15930 SourceLocation EndLoc) { 15931 Expr *ValExpr = Priority; 15932 Stmt *HelperValStmt = nullptr; 15933 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15934 15935 // OpenMP [2.9.1, task Constrcut] 15936 // The priority-value is a non-negative numerical scalar expression. 15937 if (!isNonNegativeIntegerValue( 15938 ValExpr, *this, OMPC_priority, 15939 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 15940 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 15941 return nullptr; 15942 15943 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 15944 StartLoc, LParenLoc, EndLoc); 15945 } 15946 15947 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15948 SourceLocation StartLoc, 15949 SourceLocation LParenLoc, 15950 SourceLocation EndLoc) { 15951 Expr *ValExpr = Grainsize; 15952 Stmt *HelperValStmt = nullptr; 15953 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15954 15955 // OpenMP [2.9.2, taskloop Constrcut] 15956 // The parameter of the grainsize clause must be a positive integer 15957 // expression. 15958 if (!isNonNegativeIntegerValue( 15959 ValExpr, *this, OMPC_grainsize, 15960 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 15961 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 15962 return nullptr; 15963 15964 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 15965 StartLoc, LParenLoc, EndLoc); 15966 } 15967 15968 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15969 SourceLocation StartLoc, 15970 SourceLocation LParenLoc, 15971 SourceLocation EndLoc) { 15972 Expr *ValExpr = NumTasks; 15973 Stmt *HelperValStmt = nullptr; 15974 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15975 15976 // OpenMP [2.9.2, taskloop Constrcut] 15977 // The parameter of the num_tasks clause must be a positive integer 15978 // expression. 15979 if (!isNonNegativeIntegerValue( 15980 ValExpr, *this, OMPC_num_tasks, 15981 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 15982 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 15983 return nullptr; 15984 15985 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 15986 StartLoc, LParenLoc, EndLoc); 15987 } 15988 15989 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15990 SourceLocation LParenLoc, 15991 SourceLocation EndLoc) { 15992 // OpenMP [2.13.2, critical construct, Description] 15993 // ... where hint-expression is an integer constant expression that evaluates 15994 // to a valid lock hint. 15995 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15996 if (HintExpr.isInvalid()) 15997 return nullptr; 15998 return new (Context) 15999 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16000 } 16001 16002 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16003 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16004 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16005 SourceLocation EndLoc) { 16006 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16007 std::string Values; 16008 Values += "'"; 16009 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16010 Values += "'"; 16011 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16012 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16013 return nullptr; 16014 } 16015 Expr *ValExpr = ChunkSize; 16016 Stmt *HelperValStmt = nullptr; 16017 if (ChunkSize) { 16018 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16019 !ChunkSize->isInstantiationDependent() && 16020 !ChunkSize->containsUnexpandedParameterPack()) { 16021 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16022 ExprResult Val = 16023 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16024 if (Val.isInvalid()) 16025 return nullptr; 16026 16027 ValExpr = Val.get(); 16028 16029 // OpenMP [2.7.1, Restrictions] 16030 // chunk_size must be a loop invariant integer expression with a positive 16031 // value. 16032 llvm::APSInt Result; 16033 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16034 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16035 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16036 << "dist_schedule" << ChunkSize->getSourceRange(); 16037 return nullptr; 16038 } 16039 } else if (getOpenMPCaptureRegionForClause( 16040 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 16041 OMPD_unknown && 16042 !CurContext->isDependentContext()) { 16043 ValExpr = MakeFullExpr(ValExpr).get(); 16044 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16045 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16046 HelperValStmt = buildPreInits(Context, Captures); 16047 } 16048 } 16049 } 16050 16051 return new (Context) 16052 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16053 Kind, ValExpr, HelperValStmt); 16054 } 16055 16056 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16057 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16058 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16059 SourceLocation KindLoc, SourceLocation EndLoc) { 16060 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 16061 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 16062 std::string Value; 16063 SourceLocation Loc; 16064 Value += "'"; 16065 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16066 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16067 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16068 Loc = MLoc; 16069 } else { 16070 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16071 OMPC_DEFAULTMAP_scalar); 16072 Loc = KindLoc; 16073 } 16074 Value += "'"; 16075 Diag(Loc, diag::err_omp_unexpected_clause_value) 16076 << Value << getOpenMPClauseName(OMPC_defaultmap); 16077 return nullptr; 16078 } 16079 DSAStack->setDefaultDMAToFromScalar(StartLoc); 16080 16081 return new (Context) 16082 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16083 } 16084 16085 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16086 DeclContext *CurLexicalContext = getCurLexicalContext(); 16087 if (!CurLexicalContext->isFileContext() && 16088 !CurLexicalContext->isExternCContext() && 16089 !CurLexicalContext->isExternCXXContext() && 16090 !isa<CXXRecordDecl>(CurLexicalContext) && 16091 !isa<ClassTemplateDecl>(CurLexicalContext) && 16092 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16093 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16094 Diag(Loc, diag::err_omp_region_not_file_context); 16095 return false; 16096 } 16097 ++DeclareTargetNestingLevel; 16098 return true; 16099 } 16100 16101 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16102 assert(DeclareTargetNestingLevel > 0 && 16103 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16104 --DeclareTargetNestingLevel; 16105 } 16106 16107 NamedDecl * 16108 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16109 const DeclarationNameInfo &Id, 16110 NamedDeclSetType &SameDirectiveDecls) { 16111 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16112 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16113 16114 if (Lookup.isAmbiguous()) 16115 return nullptr; 16116 Lookup.suppressDiagnostics(); 16117 16118 if (!Lookup.isSingleResult()) { 16119 VarOrFuncDeclFilterCCC CCC(*this); 16120 if (TypoCorrection Corrected = 16121 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16122 CTK_ErrorRecovery)) { 16123 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16124 << Id.getName()); 16125 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16126 return nullptr; 16127 } 16128 16129 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16130 return nullptr; 16131 } 16132 16133 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16134 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16135 !isa<FunctionTemplateDecl>(ND)) { 16136 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16137 return nullptr; 16138 } 16139 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16140 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16141 return ND; 16142 } 16143 16144 void Sema::ActOnOpenMPDeclareTargetName( 16145 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16146 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16147 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16148 isa<FunctionTemplateDecl>(ND)) && 16149 "Expected variable, function or function template."); 16150 16151 // Diagnose marking after use as it may lead to incorrect diagnosis and 16152 // codegen. 16153 if (LangOpts.OpenMP >= 50 && 16154 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16155 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16156 16157 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16158 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16159 if (DevTy.hasValue() && *DevTy != DT) { 16160 Diag(Loc, diag::err_omp_device_type_mismatch) 16161 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16162 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16163 return; 16164 } 16165 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16166 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16167 if (!Res) { 16168 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16169 SourceRange(Loc, Loc)); 16170 ND->addAttr(A); 16171 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16172 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16173 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16174 } else if (*Res != MT) { 16175 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16176 } 16177 } 16178 16179 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16180 Sema &SemaRef, Decl *D) { 16181 if (!D || !isa<VarDecl>(D)) 16182 return; 16183 auto *VD = cast<VarDecl>(D); 16184 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16185 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16186 if (SemaRef.LangOpts.OpenMP >= 50 && 16187 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16188 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16189 VD->hasGlobalStorage()) { 16190 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16191 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16192 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16193 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16194 // If a lambda declaration and definition appears between a 16195 // declare target directive and the matching end declare target 16196 // directive, all variables that are captured by the lambda 16197 // expression must also appear in a to clause. 16198 SemaRef.Diag(VD->getLocation(), 16199 diag::err_omp_lambda_capture_in_declare_target_not_to); 16200 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16201 << VD << 0 << SR; 16202 return; 16203 } 16204 } 16205 if (MapTy.hasValue()) 16206 return; 16207 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16208 SemaRef.Diag(SL, diag::note_used_here) << SR; 16209 } 16210 16211 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16212 Sema &SemaRef, DSAStackTy *Stack, 16213 ValueDecl *VD) { 16214 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16215 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16216 /*FullCheck=*/false); 16217 } 16218 16219 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16220 SourceLocation IdLoc) { 16221 if (!D || D->isInvalidDecl()) 16222 return; 16223 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16224 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16225 if (auto *VD = dyn_cast<VarDecl>(D)) { 16226 // Only global variables can be marked as declare target. 16227 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16228 !VD->isStaticDataMember()) 16229 return; 16230 // 2.10.6: threadprivate variable cannot appear in a declare target 16231 // directive. 16232 if (DSAStack->isThreadPrivate(VD)) { 16233 Diag(SL, diag::err_omp_threadprivate_in_target); 16234 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16235 return; 16236 } 16237 } 16238 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16239 D = FTD->getTemplatedDecl(); 16240 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16241 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16242 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16243 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16244 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16245 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16246 return; 16247 } 16248 // Mark the function as must be emitted for the device. 16249 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16250 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16251 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16252 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16253 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16254 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16255 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16256 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16257 } 16258 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16259 // Problem if any with var declared with incomplete type will be reported 16260 // as normal, so no need to check it here. 16261 if ((E || !VD->getType()->isIncompleteType()) && 16262 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16263 return; 16264 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16265 // Checking declaration inside declare target region. 16266 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16267 isa<FunctionTemplateDecl>(D)) { 16268 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16269 Context, OMPDeclareTargetDeclAttr::MT_To, 16270 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16271 D->addAttr(A); 16272 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16273 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16274 } 16275 return; 16276 } 16277 } 16278 if (!E) 16279 return; 16280 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16281 } 16282 16283 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16284 CXXScopeSpec &MapperIdScopeSpec, 16285 DeclarationNameInfo &MapperId, 16286 const OMPVarListLocTy &Locs, 16287 ArrayRef<Expr *> UnresolvedMappers) { 16288 MappableVarListInfo MVLI(VarList); 16289 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16290 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16291 if (MVLI.ProcessedVarList.empty()) 16292 return nullptr; 16293 16294 return OMPToClause::Create( 16295 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16296 MVLI.VarComponents, MVLI.UDMapperList, 16297 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16298 } 16299 16300 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16301 CXXScopeSpec &MapperIdScopeSpec, 16302 DeclarationNameInfo &MapperId, 16303 const OMPVarListLocTy &Locs, 16304 ArrayRef<Expr *> UnresolvedMappers) { 16305 MappableVarListInfo MVLI(VarList); 16306 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16307 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16308 if (MVLI.ProcessedVarList.empty()) 16309 return nullptr; 16310 16311 return OMPFromClause::Create( 16312 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16313 MVLI.VarComponents, MVLI.UDMapperList, 16314 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16315 } 16316 16317 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16318 const OMPVarListLocTy &Locs) { 16319 MappableVarListInfo MVLI(VarList); 16320 SmallVector<Expr *, 8> PrivateCopies; 16321 SmallVector<Expr *, 8> Inits; 16322 16323 for (Expr *RefExpr : VarList) { 16324 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16325 SourceLocation ELoc; 16326 SourceRange ERange; 16327 Expr *SimpleRefExpr = RefExpr; 16328 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16329 if (Res.second) { 16330 // It will be analyzed later. 16331 MVLI.ProcessedVarList.push_back(RefExpr); 16332 PrivateCopies.push_back(nullptr); 16333 Inits.push_back(nullptr); 16334 } 16335 ValueDecl *D = Res.first; 16336 if (!D) 16337 continue; 16338 16339 QualType Type = D->getType(); 16340 Type = Type.getNonReferenceType().getUnqualifiedType(); 16341 16342 auto *VD = dyn_cast<VarDecl>(D); 16343 16344 // Item should be a pointer or reference to pointer. 16345 if (!Type->isPointerType()) { 16346 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16347 << 0 << RefExpr->getSourceRange(); 16348 continue; 16349 } 16350 16351 // Build the private variable and the expression that refers to it. 16352 auto VDPrivate = 16353 buildVarDecl(*this, ELoc, Type, D->getName(), 16354 D->hasAttrs() ? &D->getAttrs() : nullptr, 16355 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16356 if (VDPrivate->isInvalidDecl()) 16357 continue; 16358 16359 CurContext->addDecl(VDPrivate); 16360 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16361 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16362 16363 // Add temporary variable to initialize the private copy of the pointer. 16364 VarDecl *VDInit = 16365 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16366 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16367 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16368 AddInitializerToDecl(VDPrivate, 16369 DefaultLvalueConversion(VDInitRefExpr).get(), 16370 /*DirectInit=*/false); 16371 16372 // If required, build a capture to implement the privatization initialized 16373 // with the current list item value. 16374 DeclRefExpr *Ref = nullptr; 16375 if (!VD) 16376 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16377 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16378 PrivateCopies.push_back(VDPrivateRefExpr); 16379 Inits.push_back(VDInitRefExpr); 16380 16381 // We need to add a data sharing attribute for this variable to make sure it 16382 // is correctly captured. A variable that shows up in a use_device_ptr has 16383 // similar properties of a first private variable. 16384 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16385 16386 // Create a mappable component for the list item. List items in this clause 16387 // only need a component. 16388 MVLI.VarBaseDeclarations.push_back(D); 16389 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16390 MVLI.VarComponents.back().push_back( 16391 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16392 } 16393 16394 if (MVLI.ProcessedVarList.empty()) 16395 return nullptr; 16396 16397 return OMPUseDevicePtrClause::Create( 16398 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16399 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16400 } 16401 16402 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16403 const OMPVarListLocTy &Locs) { 16404 MappableVarListInfo MVLI(VarList); 16405 for (Expr *RefExpr : VarList) { 16406 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16407 SourceLocation ELoc; 16408 SourceRange ERange; 16409 Expr *SimpleRefExpr = RefExpr; 16410 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16411 if (Res.second) { 16412 // It will be analyzed later. 16413 MVLI.ProcessedVarList.push_back(RefExpr); 16414 } 16415 ValueDecl *D = Res.first; 16416 if (!D) 16417 continue; 16418 16419 QualType Type = D->getType(); 16420 // item should be a pointer or array or reference to pointer or array 16421 if (!Type.getNonReferenceType()->isPointerType() && 16422 !Type.getNonReferenceType()->isArrayType()) { 16423 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16424 << 0 << RefExpr->getSourceRange(); 16425 continue; 16426 } 16427 16428 // Check if the declaration in the clause does not show up in any data 16429 // sharing attribute. 16430 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16431 if (isOpenMPPrivate(DVar.CKind)) { 16432 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16433 << getOpenMPClauseName(DVar.CKind) 16434 << getOpenMPClauseName(OMPC_is_device_ptr) 16435 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16436 reportOriginalDsa(*this, DSAStack, D, DVar); 16437 continue; 16438 } 16439 16440 const Expr *ConflictExpr; 16441 if (DSAStack->checkMappableExprComponentListsForDecl( 16442 D, /*CurrentRegionOnly=*/true, 16443 [&ConflictExpr]( 16444 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16445 OpenMPClauseKind) -> bool { 16446 ConflictExpr = R.front().getAssociatedExpression(); 16447 return true; 16448 })) { 16449 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16450 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16451 << ConflictExpr->getSourceRange(); 16452 continue; 16453 } 16454 16455 // Store the components in the stack so that they can be used to check 16456 // against other clauses later on. 16457 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16458 DSAStack->addMappableExpressionComponents( 16459 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16460 16461 // Record the expression we've just processed. 16462 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16463 16464 // Create a mappable component for the list item. List items in this clause 16465 // only need a component. We use a null declaration to signal fields in 16466 // 'this'. 16467 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16468 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16469 "Unexpected device pointer expression!"); 16470 MVLI.VarBaseDeclarations.push_back( 16471 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16472 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16473 MVLI.VarComponents.back().push_back(MC); 16474 } 16475 16476 if (MVLI.ProcessedVarList.empty()) 16477 return nullptr; 16478 16479 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16480 MVLI.VarBaseDeclarations, 16481 MVLI.VarComponents); 16482 } 16483 16484 OMPClause *Sema::ActOnOpenMPAllocateClause( 16485 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16486 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16487 if (Allocator) { 16488 // OpenMP [2.11.4 allocate Clause, Description] 16489 // allocator is an expression of omp_allocator_handle_t type. 16490 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16491 return nullptr; 16492 16493 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16494 if (AllocatorRes.isInvalid()) 16495 return nullptr; 16496 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16497 DSAStack->getOMPAllocatorHandleT(), 16498 Sema::AA_Initializing, 16499 /*AllowExplicit=*/true); 16500 if (AllocatorRes.isInvalid()) 16501 return nullptr; 16502 Allocator = AllocatorRes.get(); 16503 } else { 16504 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16505 // allocate clauses that appear on a target construct or on constructs in a 16506 // target region must specify an allocator expression unless a requires 16507 // directive with the dynamic_allocators clause is present in the same 16508 // compilation unit. 16509 if (LangOpts.OpenMPIsDevice && 16510 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16511 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16512 } 16513 // Analyze and build list of variables. 16514 SmallVector<Expr *, 8> Vars; 16515 for (Expr *RefExpr : VarList) { 16516 assert(RefExpr && "NULL expr in OpenMP private clause."); 16517 SourceLocation ELoc; 16518 SourceRange ERange; 16519 Expr *SimpleRefExpr = RefExpr; 16520 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16521 if (Res.second) { 16522 // It will be analyzed later. 16523 Vars.push_back(RefExpr); 16524 } 16525 ValueDecl *D = Res.first; 16526 if (!D) 16527 continue; 16528 16529 auto *VD = dyn_cast<VarDecl>(D); 16530 DeclRefExpr *Ref = nullptr; 16531 if (!VD && !CurContext->isDependentContext()) 16532 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16533 Vars.push_back((VD || CurContext->isDependentContext()) 16534 ? RefExpr->IgnoreParens() 16535 : Ref); 16536 } 16537 16538 if (Vars.empty()) 16539 return nullptr; 16540 16541 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16542 ColonLoc, EndLoc, Vars); 16543 } 16544