1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 bool HasMutipleLoops = false; 143 const Decl *PossiblyLoopCounter = nullptr; 144 bool NowaitRegion = false; 145 bool CancelRegion = false; 146 bool LoopStart = false; 147 bool BodyComplete = false; 148 SourceLocation InnerTeamsRegionLoc; 149 /// Reference to the taskgroup task_reduction reference expression. 150 Expr *TaskgroupReductionRef = nullptr; 151 llvm::DenseSet<QualType> MappedClassesQualTypes; 152 /// List of globals marked as declare target link in this target region 153 /// (isOpenMPTargetExecutionDirective(Directive) == true). 154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 156 Scope *CurScope, SourceLocation Loc) 157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 158 ConstructLoc(Loc) {} 159 SharingMapTy() = default; 160 }; 161 162 using StackTy = SmallVector<SharingMapTy, 4>; 163 164 /// Stack of used declaration and their data-sharing attributes. 165 DeclSAMapTy Threadprivates; 166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 168 /// true, if check for DSA must be from parent directive, false, if 169 /// from current directive. 170 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 171 Sema &SemaRef; 172 bool ForceCapturing = false; 173 /// true if all the vaiables in the target executable directives must be 174 /// captured by reference. 175 bool ForceCaptureByReferenceInTargetExecutable = false; 176 CriticalsWithHintsTy Criticals; 177 unsigned IgnoredStackElements = 0; 178 179 /// Iterators over the stack iterate in order from innermost to outermost 180 /// directive. 181 using const_iterator = StackTy::const_reverse_iterator; 182 const_iterator begin() const { 183 return Stack.empty() ? const_iterator() 184 : Stack.back().first.rbegin() + IgnoredStackElements; 185 } 186 const_iterator end() const { 187 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 188 } 189 using iterator = StackTy::reverse_iterator; 190 iterator begin() { 191 return Stack.empty() ? iterator() 192 : Stack.back().first.rbegin() + IgnoredStackElements; 193 } 194 iterator end() { 195 return Stack.empty() ? iterator() : Stack.back().first.rend(); 196 } 197 198 // Convenience operations to get at the elements of the stack. 199 200 bool isStackEmpty() const { 201 return Stack.empty() || 202 Stack.back().second != CurrentNonCapturingFunctionScope || 203 Stack.back().first.size() <= IgnoredStackElements; 204 } 205 size_t getStackSize() const { 206 return isStackEmpty() ? 0 207 : Stack.back().first.size() - IgnoredStackElements; 208 } 209 210 SharingMapTy *getTopOfStackOrNull() { 211 size_t Size = getStackSize(); 212 if (Size == 0) 213 return nullptr; 214 return &Stack.back().first[Size - 1]; 215 } 216 const SharingMapTy *getTopOfStackOrNull() const { 217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 218 } 219 SharingMapTy &getTopOfStack() { 220 assert(!isStackEmpty() && "no current directive"); 221 return *getTopOfStackOrNull(); 222 } 223 const SharingMapTy &getTopOfStack() const { 224 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 225 } 226 227 SharingMapTy *getSecondOnStackOrNull() { 228 size_t Size = getStackSize(); 229 if (Size <= 1) 230 return nullptr; 231 return &Stack.back().first[Size - 2]; 232 } 233 const SharingMapTy *getSecondOnStackOrNull() const { 234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 235 } 236 237 /// Get the stack element at a certain level (previously returned by 238 /// \c getNestingLevel). 239 /// 240 /// Note that nesting levels count from outermost to innermost, and this is 241 /// the reverse of our iteration order where new inner levels are pushed at 242 /// the front of the stack. 243 SharingMapTy &getStackElemAtLevel(unsigned Level) { 244 assert(Level < getStackSize() && "no such stack element"); 245 return Stack.back().first[Level]; 246 } 247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 249 } 250 251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 252 253 /// Checks if the variable is a local for OpenMP region. 254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 255 256 /// Vector of previously declared requires directives 257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 258 /// omp_allocator_handle_t type. 259 QualType OMPAllocatorHandleT; 260 /// Expression for the predefined allocators. 261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 262 nullptr}; 263 /// Vector of previously encountered target directives 264 SmallVector<SourceLocation, 2> TargetLocations; 265 266 public: 267 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 268 269 /// Sets omp_allocator_handle_t type. 270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 271 /// Gets omp_allocator_handle_t type. 272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 273 /// Sets the given default allocator. 274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 275 Expr *Allocator) { 276 OMPPredefinedAllocators[AllocatorKind] = Allocator; 277 } 278 /// Returns the specified default allocator. 279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 280 return OMPPredefinedAllocators[AllocatorKind]; 281 } 282 283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 284 OpenMPClauseKind getClauseParsingMode() const { 285 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 286 return ClauseKindMode; 287 } 288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 289 290 bool isBodyComplete() const { 291 const SharingMapTy *Top = getTopOfStackOrNull(); 292 return Top && Top->BodyComplete; 293 } 294 void setBodyComplete() { 295 getTopOfStack().BodyComplete = true; 296 } 297 298 bool isForceVarCapturing() const { return ForceCapturing; } 299 void setForceVarCapturing(bool V) { ForceCapturing = V; } 300 301 void setForceCaptureByReferenceInTargetExecutable(bool V) { 302 ForceCaptureByReferenceInTargetExecutable = V; 303 } 304 bool isForceCaptureByReferenceInTargetExecutable() const { 305 return ForceCaptureByReferenceInTargetExecutable; 306 } 307 308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 309 Scope *CurScope, SourceLocation Loc) { 310 assert(!IgnoredStackElements && 311 "cannot change stack while ignoring elements"); 312 if (Stack.empty() || 313 Stack.back().second != CurrentNonCapturingFunctionScope) 314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 316 Stack.back().first.back().DefaultAttrLoc = Loc; 317 } 318 319 void pop() { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 assert(!Stack.back().first.empty() && 323 "Data-sharing attributes stack is empty!"); 324 Stack.back().first.pop_back(); 325 } 326 327 /// RAII object to temporarily leave the scope of a directive when we want to 328 /// logically operate in its parent. 329 class ParentDirectiveScope { 330 DSAStackTy &Self; 331 bool Active; 332 public: 333 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 334 : Self(Self), Active(false) { 335 if (Activate) 336 enable(); 337 } 338 ~ParentDirectiveScope() { disable(); } 339 void disable() { 340 if (Active) { 341 --Self.IgnoredStackElements; 342 Active = false; 343 } 344 } 345 void enable() { 346 if (!Active) { 347 ++Self.IgnoredStackElements; 348 Active = true; 349 } 350 } 351 }; 352 353 /// Marks that we're started loop parsing. 354 void loopInit() { 355 assert(isOpenMPLoopDirective(getCurrentDirective()) && 356 "Expected loop-based directive."); 357 getTopOfStack().LoopStart = true; 358 } 359 /// Start capturing of the variables in the loop context. 360 void loopStart() { 361 assert(isOpenMPLoopDirective(getCurrentDirective()) && 362 "Expected loop-based directive."); 363 getTopOfStack().LoopStart = false; 364 } 365 /// true, if variables are captured, false otherwise. 366 bool isLoopStarted() const { 367 assert(isOpenMPLoopDirective(getCurrentDirective()) && 368 "Expected loop-based directive."); 369 return !getTopOfStack().LoopStart; 370 } 371 /// Marks (or clears) declaration as possibly loop counter. 372 void resetPossibleLoopCounter(const Decl *D = nullptr) { 373 getTopOfStack().PossiblyLoopCounter = 374 D ? D->getCanonicalDecl() : D; 375 } 376 /// Gets the possible loop counter decl. 377 const Decl *getPossiblyLoopCunter() const { 378 return getTopOfStack().PossiblyLoopCounter; 379 } 380 /// Start new OpenMP region stack in new non-capturing function. 381 void pushFunction() { 382 assert(!IgnoredStackElements && 383 "cannot change stack while ignoring elements"); 384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 385 assert(!isa<CapturingScopeInfo>(CurFnScope)); 386 CurrentNonCapturingFunctionScope = CurFnScope; 387 } 388 /// Pop region stack for non-capturing function. 389 void popFunction(const FunctionScopeInfo *OldFSI) { 390 assert(!IgnoredStackElements && 391 "cannot change stack while ignoring elements"); 392 if (!Stack.empty() && Stack.back().second == OldFSI) { 393 assert(Stack.back().first.empty()); 394 Stack.pop_back(); 395 } 396 CurrentNonCapturingFunctionScope = nullptr; 397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 398 if (!isa<CapturingScopeInfo>(FSI)) { 399 CurrentNonCapturingFunctionScope = FSI; 400 break; 401 } 402 } 403 } 404 405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 407 } 408 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 409 getCriticalWithHint(const DeclarationNameInfo &Name) const { 410 auto I = Criticals.find(Name.getAsString()); 411 if (I != Criticals.end()) 412 return I->second; 413 return std::make_pair(nullptr, llvm::APSInt()); 414 } 415 /// If 'aligned' declaration for given variable \a D was not seen yet, 416 /// add it and return NULL; otherwise return previous occurrence's expression 417 /// for diagnostics. 418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 419 420 /// Register specified variable as loop control variable. 421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 422 /// Check if the specified variable is a loop control variable for 423 /// current region. 424 /// \return The index of the loop control variable in the list of associated 425 /// for-loops (from outer to inner). 426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 427 /// Check if the specified variable is a loop control variable for 428 /// parent region. 429 /// \return The index of the loop control variable in the list of associated 430 /// for-loops (from outer to inner). 431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 432 /// Get the loop control variable for the I-th loop (or nullptr) in 433 /// parent directive. 434 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 435 436 /// Adds explicit data sharing attribute to the specified declaration. 437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 438 DeclRefExpr *PrivateCopy = nullptr); 439 440 /// Adds additional information for the reduction items with the reduction id 441 /// represented as an operator. 442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 443 BinaryOperatorKind BOK); 444 /// Adds additional information for the reduction items with the reduction id 445 /// represented as reduction identifier. 446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 447 const Expr *ReductionRef); 448 /// Returns the location and reduction operation from the innermost parent 449 /// region for the given \p D. 450 const DSAVarData 451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 452 BinaryOperatorKind &BOK, 453 Expr *&TaskgroupDescriptor) const; 454 /// Returns the location and reduction operation from the innermost parent 455 /// region for the given \p D. 456 const DSAVarData 457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 458 const Expr *&ReductionRef, 459 Expr *&TaskgroupDescriptor) const; 460 /// Return reduction reference expression for the current taskgroup. 461 Expr *getTaskgroupReductionRef() const { 462 assert(getTopOfStack().Directive == OMPD_taskgroup && 463 "taskgroup reference expression requested for non taskgroup " 464 "directive."); 465 return getTopOfStack().TaskgroupReductionRef; 466 } 467 /// Checks if the given \p VD declaration is actually a taskgroup reduction 468 /// descriptor variable at the \p Level of OpenMP regions. 469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 470 return getStackElemAtLevel(Level).TaskgroupReductionRef && 471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 472 ->getDecl() == VD; 473 } 474 475 /// Returns data sharing attributes from top of the stack for the 476 /// specified declaration. 477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 478 /// Returns data-sharing attributes for the specified declaration. 479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 480 /// Checks if the specified variables has data-sharing attributes which 481 /// match specified \a CPred predicate in any directive which matches \a DPred 482 /// predicate. 483 const DSAVarData 484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 486 bool FromParent) const; 487 /// Checks if the specified variables has data-sharing attributes which 488 /// match specified \a CPred predicate in any innermost directive which 489 /// matches \a DPred predicate. 490 const DSAVarData 491 hasInnermostDSA(ValueDecl *D, 492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 494 bool FromParent) const; 495 /// Checks if the specified variables has explicit data-sharing 496 /// attributes which match specified \a CPred predicate at the specified 497 /// OpenMP region. 498 bool hasExplicitDSA(const ValueDecl *D, 499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 500 unsigned Level, bool NotLastprivate = false) const; 501 502 /// Returns true if the directive at level \Level matches in the 503 /// specified \a DPred predicate. 504 bool hasExplicitDirective( 505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 506 unsigned Level) const; 507 508 /// Finds a directive which matches specified \a DPred predicate. 509 bool hasDirective( 510 const llvm::function_ref<bool( 511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 512 DPred, 513 bool FromParent) const; 514 515 /// Returns currently analyzed directive. 516 OpenMPDirectiveKind getCurrentDirective() const { 517 const SharingMapTy *Top = getTopOfStackOrNull(); 518 return Top ? Top->Directive : OMPD_unknown; 519 } 520 /// Returns directive kind at specified level. 521 OpenMPDirectiveKind getDirective(unsigned Level) const { 522 assert(!isStackEmpty() && "No directive at specified level."); 523 return getStackElemAtLevel(Level).Directive; 524 } 525 /// Returns the capture region at the specified level. 526 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 527 unsigned OpenMPCaptureLevel) const { 528 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 529 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 530 return CaptureRegions[OpenMPCaptureLevel]; 531 } 532 /// Returns parent directive. 533 OpenMPDirectiveKind getParentDirective() const { 534 const SharingMapTy *Parent = getSecondOnStackOrNull(); 535 return Parent ? Parent->Directive : OMPD_unknown; 536 } 537 538 /// Add requires decl to internal vector 539 void addRequiresDecl(OMPRequiresDecl *RD) { 540 RequiresDecls.push_back(RD); 541 } 542 543 /// Checks if the defined 'requires' directive has specified type of clause. 544 template <typename ClauseType> 545 bool hasRequiresDeclWithClause() { 546 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 547 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 548 return isa<ClauseType>(C); 549 }); 550 }); 551 } 552 553 /// Checks for a duplicate clause amongst previously declared requires 554 /// directives 555 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 556 bool IsDuplicate = false; 557 for (OMPClause *CNew : ClauseList) { 558 for (const OMPRequiresDecl *D : RequiresDecls) { 559 for (const OMPClause *CPrev : D->clauselists()) { 560 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 561 SemaRef.Diag(CNew->getBeginLoc(), 562 diag::err_omp_requires_clause_redeclaration) 563 << getOpenMPClauseName(CNew->getClauseKind()); 564 SemaRef.Diag(CPrev->getBeginLoc(), 565 diag::note_omp_requires_previous_clause) 566 << getOpenMPClauseName(CPrev->getClauseKind()); 567 IsDuplicate = true; 568 } 569 } 570 } 571 } 572 return IsDuplicate; 573 } 574 575 /// Add location of previously encountered target to internal vector 576 void addTargetDirLocation(SourceLocation LocStart) { 577 TargetLocations.push_back(LocStart); 578 } 579 580 // Return previously encountered target region locations. 581 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 582 return TargetLocations; 583 } 584 585 /// Set default data sharing attribute to none. 586 void setDefaultDSANone(SourceLocation Loc) { 587 getTopOfStack().DefaultAttr = DSA_none; 588 getTopOfStack().DefaultAttrLoc = Loc; 589 } 590 /// Set default data sharing attribute to shared. 591 void setDefaultDSAShared(SourceLocation Loc) { 592 getTopOfStack().DefaultAttr = DSA_shared; 593 getTopOfStack().DefaultAttrLoc = Loc; 594 } 595 /// Set default data mapping attribute to 'tofrom:scalar'. 596 void setDefaultDMAToFromScalar(SourceLocation Loc) { 597 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 598 getTopOfStack().DefaultMapAttrLoc = Loc; 599 } 600 601 DefaultDataSharingAttributes getDefaultDSA() const { 602 return isStackEmpty() ? DSA_unspecified 603 : getTopOfStack().DefaultAttr; 604 } 605 SourceLocation getDefaultDSALocation() const { 606 return isStackEmpty() ? SourceLocation() 607 : getTopOfStack().DefaultAttrLoc; 608 } 609 DefaultMapAttributes getDefaultDMA() const { 610 return isStackEmpty() ? DMA_unspecified 611 : getTopOfStack().DefaultMapAttr; 612 } 613 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 614 return getStackElemAtLevel(Level).DefaultMapAttr; 615 } 616 SourceLocation getDefaultDMALocation() const { 617 return isStackEmpty() ? SourceLocation() 618 : getTopOfStack().DefaultMapAttrLoc; 619 } 620 621 /// Checks if the specified variable is a threadprivate. 622 bool isThreadPrivate(VarDecl *D) { 623 const DSAVarData DVar = getTopDSA(D, false); 624 return isOpenMPThreadPrivate(DVar.CKind); 625 } 626 627 /// Marks current region as ordered (it has an 'ordered' clause). 628 void setOrderedRegion(bool IsOrdered, const Expr *Param, 629 OMPOrderedClause *Clause) { 630 if (IsOrdered) 631 getTopOfStack().OrderedRegion.emplace(Param, Clause); 632 else 633 getTopOfStack().OrderedRegion.reset(); 634 } 635 /// Returns true, if region is ordered (has associated 'ordered' clause), 636 /// false - otherwise. 637 bool isOrderedRegion() const { 638 if (const SharingMapTy *Top = getTopOfStackOrNull()) 639 return Top->OrderedRegion.hasValue(); 640 return false; 641 } 642 /// Returns optional parameter for the ordered region. 643 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 644 if (const SharingMapTy *Top = getTopOfStackOrNull()) 645 if (Top->OrderedRegion.hasValue()) 646 return Top->OrderedRegion.getValue(); 647 return std::make_pair(nullptr, nullptr); 648 } 649 /// Returns true, if parent region is ordered (has associated 650 /// 'ordered' clause), false - otherwise. 651 bool isParentOrderedRegion() const { 652 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 653 return Parent->OrderedRegion.hasValue(); 654 return false; 655 } 656 /// Returns optional parameter for the ordered region. 657 std::pair<const Expr *, OMPOrderedClause *> 658 getParentOrderedRegionParam() const { 659 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 660 if (Parent->OrderedRegion.hasValue()) 661 return Parent->OrderedRegion.getValue(); 662 return std::make_pair(nullptr, nullptr); 663 } 664 /// Marks current region as nowait (it has a 'nowait' clause). 665 void setNowaitRegion(bool IsNowait = true) { 666 getTopOfStack().NowaitRegion = IsNowait; 667 } 668 /// Returns true, if parent region is nowait (has associated 669 /// 'nowait' clause), false - otherwise. 670 bool isParentNowaitRegion() const { 671 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 672 return Parent->NowaitRegion; 673 return false; 674 } 675 /// Marks parent region as cancel region. 676 void setParentCancelRegion(bool Cancel = true) { 677 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 678 Parent->CancelRegion |= Cancel; 679 } 680 /// Return true if current region has inner cancel construct. 681 bool isCancelRegion() const { 682 const SharingMapTy *Top = getTopOfStackOrNull(); 683 return Top ? Top->CancelRegion : false; 684 } 685 686 /// Set collapse value for the region. 687 void setAssociatedLoops(unsigned Val) { 688 getTopOfStack().AssociatedLoops = Val; 689 if (Val > 1) 690 getTopOfStack().HasMutipleLoops = true; 691 } 692 /// Return collapse value for region. 693 unsigned getAssociatedLoops() const { 694 const SharingMapTy *Top = getTopOfStackOrNull(); 695 return Top ? Top->AssociatedLoops : 0; 696 } 697 /// Returns true if the construct is associated with multiple loops. 698 bool hasMutipleLoops() const { 699 const SharingMapTy *Top = getTopOfStackOrNull(); 700 return Top ? Top->HasMutipleLoops : false; 701 } 702 703 /// Marks current target region as one with closely nested teams 704 /// region. 705 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 706 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 707 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 708 } 709 /// Returns true, if current region has closely nested teams region. 710 bool hasInnerTeamsRegion() const { 711 return getInnerTeamsRegionLoc().isValid(); 712 } 713 /// Returns location of the nested teams region (if any). 714 SourceLocation getInnerTeamsRegionLoc() const { 715 const SharingMapTy *Top = getTopOfStackOrNull(); 716 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 717 } 718 719 Scope *getCurScope() const { 720 const SharingMapTy *Top = getTopOfStackOrNull(); 721 return Top ? Top->CurScope : nullptr; 722 } 723 SourceLocation getConstructLoc() const { 724 const SharingMapTy *Top = getTopOfStackOrNull(); 725 return Top ? Top->ConstructLoc : SourceLocation(); 726 } 727 728 /// Do the check specified in \a Check to all component lists and return true 729 /// if any issue is found. 730 bool checkMappableExprComponentListsForDecl( 731 const ValueDecl *VD, bool CurrentRegionOnly, 732 const llvm::function_ref< 733 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 734 OpenMPClauseKind)> 735 Check) const { 736 if (isStackEmpty()) 737 return false; 738 auto SI = begin(); 739 auto SE = end(); 740 741 if (SI == SE) 742 return false; 743 744 if (CurrentRegionOnly) 745 SE = std::next(SI); 746 else 747 std::advance(SI, 1); 748 749 for (; SI != SE; ++SI) { 750 auto MI = SI->MappedExprComponents.find(VD); 751 if (MI != SI->MappedExprComponents.end()) 752 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 753 MI->second.Components) 754 if (Check(L, MI->second.Kind)) 755 return true; 756 } 757 return false; 758 } 759 760 /// Do the check specified in \a Check to all component lists at a given level 761 /// and return true if any issue is found. 762 bool checkMappableExprComponentListsForDeclAtLevel( 763 const ValueDecl *VD, unsigned Level, 764 const llvm::function_ref< 765 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 766 OpenMPClauseKind)> 767 Check) const { 768 if (getStackSize() <= Level) 769 return false; 770 771 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 772 auto MI = StackElem.MappedExprComponents.find(VD); 773 if (MI != StackElem.MappedExprComponents.end()) 774 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 775 MI->second.Components) 776 if (Check(L, MI->second.Kind)) 777 return true; 778 return false; 779 } 780 781 /// Create a new mappable expression component list associated with a given 782 /// declaration and initialize it with the provided list of components. 783 void addMappableExpressionComponents( 784 const ValueDecl *VD, 785 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 786 OpenMPClauseKind WhereFoundClauseKind) { 787 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 788 // Create new entry and append the new components there. 789 MEC.Components.resize(MEC.Components.size() + 1); 790 MEC.Components.back().append(Components.begin(), Components.end()); 791 MEC.Kind = WhereFoundClauseKind; 792 } 793 794 unsigned getNestingLevel() const { 795 assert(!isStackEmpty()); 796 return getStackSize() - 1; 797 } 798 void addDoacrossDependClause(OMPDependClause *C, 799 const OperatorOffsetTy &OpsOffs) { 800 SharingMapTy *Parent = getSecondOnStackOrNull(); 801 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 802 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 803 } 804 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 805 getDoacrossDependClauses() const { 806 const SharingMapTy &StackElem = getTopOfStack(); 807 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 808 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 809 return llvm::make_range(Ref.begin(), Ref.end()); 810 } 811 return llvm::make_range(StackElem.DoacrossDepends.end(), 812 StackElem.DoacrossDepends.end()); 813 } 814 815 // Store types of classes which have been explicitly mapped 816 void addMappedClassesQualTypes(QualType QT) { 817 SharingMapTy &StackElem = getTopOfStack(); 818 StackElem.MappedClassesQualTypes.insert(QT); 819 } 820 821 // Return set of mapped classes types 822 bool isClassPreviouslyMapped(QualType QT) const { 823 const SharingMapTy &StackElem = getTopOfStack(); 824 return StackElem.MappedClassesQualTypes.count(QT) != 0; 825 } 826 827 /// Adds global declare target to the parent target region. 828 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 829 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 830 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 831 "Expected declare target link global."); 832 for (auto &Elem : *this) { 833 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 834 Elem.DeclareTargetLinkVarDecls.push_back(E); 835 return; 836 } 837 } 838 } 839 840 /// Returns the list of globals with declare target link if current directive 841 /// is target. 842 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 843 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 844 "Expected target executable directive."); 845 return getTopOfStack().DeclareTargetLinkVarDecls; 846 } 847 }; 848 849 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 850 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 851 } 852 853 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 854 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 855 DKind == OMPD_unknown; 856 } 857 858 } // namespace 859 860 static const Expr *getExprAsWritten(const Expr *E) { 861 if (const auto *FE = dyn_cast<FullExpr>(E)) 862 E = FE->getSubExpr(); 863 864 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 865 E = MTE->GetTemporaryExpr(); 866 867 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 868 E = Binder->getSubExpr(); 869 870 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 871 E = ICE->getSubExprAsWritten(); 872 return E->IgnoreParens(); 873 } 874 875 static Expr *getExprAsWritten(Expr *E) { 876 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 877 } 878 879 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 880 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 881 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 882 D = ME->getMemberDecl(); 883 const auto *VD = dyn_cast<VarDecl>(D); 884 const auto *FD = dyn_cast<FieldDecl>(D); 885 if (VD != nullptr) { 886 VD = VD->getCanonicalDecl(); 887 D = VD; 888 } else { 889 assert(FD); 890 FD = FD->getCanonicalDecl(); 891 D = FD; 892 } 893 return D; 894 } 895 896 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 897 return const_cast<ValueDecl *>( 898 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 899 } 900 901 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 902 ValueDecl *D) const { 903 D = getCanonicalDecl(D); 904 auto *VD = dyn_cast<VarDecl>(D); 905 const auto *FD = dyn_cast<FieldDecl>(D); 906 DSAVarData DVar; 907 if (Iter == end()) { 908 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 909 // in a region but not in construct] 910 // File-scope or namespace-scope variables referenced in called routines 911 // in the region are shared unless they appear in a threadprivate 912 // directive. 913 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 914 DVar.CKind = OMPC_shared; 915 916 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 917 // in a region but not in construct] 918 // Variables with static storage duration that are declared in called 919 // routines in the region are shared. 920 if (VD && VD->hasGlobalStorage()) 921 DVar.CKind = OMPC_shared; 922 923 // Non-static data members are shared by default. 924 if (FD) 925 DVar.CKind = OMPC_shared; 926 927 return DVar; 928 } 929 930 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 931 // in a Construct, C/C++, predetermined, p.1] 932 // Variables with automatic storage duration that are declared in a scope 933 // inside the construct are private. 934 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 935 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 936 DVar.CKind = OMPC_private; 937 return DVar; 938 } 939 940 DVar.DKind = Iter->Directive; 941 // Explicitly specified attributes and local variables with predetermined 942 // attributes. 943 if (Iter->SharingMap.count(D)) { 944 const DSAInfo &Data = Iter->SharingMap.lookup(D); 945 DVar.RefExpr = Data.RefExpr.getPointer(); 946 DVar.PrivateCopy = Data.PrivateCopy; 947 DVar.CKind = Data.Attributes; 948 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 949 return DVar; 950 } 951 952 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 953 // in a Construct, C/C++, implicitly determined, p.1] 954 // In a parallel or task construct, the data-sharing attributes of these 955 // variables are determined by the default clause, if present. 956 switch (Iter->DefaultAttr) { 957 case DSA_shared: 958 DVar.CKind = OMPC_shared; 959 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 960 return DVar; 961 case DSA_none: 962 return DVar; 963 case DSA_unspecified: 964 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 965 // in a Construct, implicitly determined, p.2] 966 // In a parallel construct, if no default clause is present, these 967 // variables are shared. 968 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 969 if (isOpenMPParallelDirective(DVar.DKind) || 970 isOpenMPTeamsDirective(DVar.DKind)) { 971 DVar.CKind = OMPC_shared; 972 return DVar; 973 } 974 975 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 976 // in a Construct, implicitly determined, p.4] 977 // In a task construct, if no default clause is present, a variable that in 978 // the enclosing context is determined to be shared by all implicit tasks 979 // bound to the current team is shared. 980 if (isOpenMPTaskingDirective(DVar.DKind)) { 981 DSAVarData DVarTemp; 982 const_iterator I = Iter, E = end(); 983 do { 984 ++I; 985 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 986 // Referenced in a Construct, implicitly determined, p.6] 987 // In a task construct, if no default clause is present, a variable 988 // whose data-sharing attribute is not determined by the rules above is 989 // firstprivate. 990 DVarTemp = getDSA(I, D); 991 if (DVarTemp.CKind != OMPC_shared) { 992 DVar.RefExpr = nullptr; 993 DVar.CKind = OMPC_firstprivate; 994 return DVar; 995 } 996 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 997 DVar.CKind = 998 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 999 return DVar; 1000 } 1001 } 1002 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1003 // in a Construct, implicitly determined, p.3] 1004 // For constructs other than task, if no default clause is present, these 1005 // variables inherit their data-sharing attributes from the enclosing 1006 // context. 1007 return getDSA(++Iter, D); 1008 } 1009 1010 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1011 const Expr *NewDE) { 1012 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1013 D = getCanonicalDecl(D); 1014 SharingMapTy &StackElem = getTopOfStack(); 1015 auto It = StackElem.AlignedMap.find(D); 1016 if (It == StackElem.AlignedMap.end()) { 1017 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1018 StackElem.AlignedMap[D] = NewDE; 1019 return nullptr; 1020 } 1021 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1022 return It->second; 1023 } 1024 1025 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1026 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1027 D = getCanonicalDecl(D); 1028 SharingMapTy &StackElem = getTopOfStack(); 1029 StackElem.LCVMap.try_emplace( 1030 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1031 } 1032 1033 const DSAStackTy::LCDeclInfo 1034 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1035 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1036 D = getCanonicalDecl(D); 1037 const SharingMapTy &StackElem = getTopOfStack(); 1038 auto It = StackElem.LCVMap.find(D); 1039 if (It != StackElem.LCVMap.end()) 1040 return It->second; 1041 return {0, nullptr}; 1042 } 1043 1044 const DSAStackTy::LCDeclInfo 1045 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1046 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1047 assert(Parent && "Data-sharing attributes stack is empty"); 1048 D = getCanonicalDecl(D); 1049 auto It = Parent->LCVMap.find(D); 1050 if (It != Parent->LCVMap.end()) 1051 return It->second; 1052 return {0, nullptr}; 1053 } 1054 1055 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1056 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1057 assert(Parent && "Data-sharing attributes stack is empty"); 1058 if (Parent->LCVMap.size() < I) 1059 return nullptr; 1060 for (const auto &Pair : Parent->LCVMap) 1061 if (Pair.second.first == I) 1062 return Pair.first; 1063 return nullptr; 1064 } 1065 1066 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1067 DeclRefExpr *PrivateCopy) { 1068 D = getCanonicalDecl(D); 1069 if (A == OMPC_threadprivate) { 1070 DSAInfo &Data = Threadprivates[D]; 1071 Data.Attributes = A; 1072 Data.RefExpr.setPointer(E); 1073 Data.PrivateCopy = nullptr; 1074 } else { 1075 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1076 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1077 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1078 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1079 (isLoopControlVariable(D).first && A == OMPC_private)); 1080 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1081 Data.RefExpr.setInt(/*IntVal=*/true); 1082 return; 1083 } 1084 const bool IsLastprivate = 1085 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1086 Data.Attributes = A; 1087 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1088 Data.PrivateCopy = PrivateCopy; 1089 if (PrivateCopy) { 1090 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1091 Data.Attributes = A; 1092 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1093 Data.PrivateCopy = nullptr; 1094 } 1095 } 1096 } 1097 1098 /// Build a variable declaration for OpenMP loop iteration variable. 1099 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1100 StringRef Name, const AttrVec *Attrs = nullptr, 1101 DeclRefExpr *OrigRef = nullptr) { 1102 DeclContext *DC = SemaRef.CurContext; 1103 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1104 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1105 auto *Decl = 1106 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1107 if (Attrs) { 1108 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1109 I != E; ++I) 1110 Decl->addAttr(*I); 1111 } 1112 Decl->setImplicit(); 1113 if (OrigRef) { 1114 Decl->addAttr( 1115 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1116 } 1117 return Decl; 1118 } 1119 1120 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1121 SourceLocation Loc, 1122 bool RefersToCapture = false) { 1123 D->setReferenced(); 1124 D->markUsed(S.Context); 1125 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1126 SourceLocation(), D, RefersToCapture, Loc, Ty, 1127 VK_LValue); 1128 } 1129 1130 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1131 BinaryOperatorKind BOK) { 1132 D = getCanonicalDecl(D); 1133 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1134 assert( 1135 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1136 "Additional reduction info may be specified only for reduction items."); 1137 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1138 assert(ReductionData.ReductionRange.isInvalid() && 1139 getTopOfStack().Directive == OMPD_taskgroup && 1140 "Additional reduction info may be specified only once for reduction " 1141 "items."); 1142 ReductionData.set(BOK, SR); 1143 Expr *&TaskgroupReductionRef = 1144 getTopOfStack().TaskgroupReductionRef; 1145 if (!TaskgroupReductionRef) { 1146 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1147 SemaRef.Context.VoidPtrTy, ".task_red."); 1148 TaskgroupReductionRef = 1149 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1150 } 1151 } 1152 1153 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1154 const Expr *ReductionRef) { 1155 D = getCanonicalDecl(D); 1156 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1157 assert( 1158 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1159 "Additional reduction info may be specified only for reduction items."); 1160 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1161 assert(ReductionData.ReductionRange.isInvalid() && 1162 getTopOfStack().Directive == OMPD_taskgroup && 1163 "Additional reduction info may be specified only once for reduction " 1164 "items."); 1165 ReductionData.set(ReductionRef, SR); 1166 Expr *&TaskgroupReductionRef = 1167 getTopOfStack().TaskgroupReductionRef; 1168 if (!TaskgroupReductionRef) { 1169 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1170 SemaRef.Context.VoidPtrTy, ".task_red."); 1171 TaskgroupReductionRef = 1172 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1173 } 1174 } 1175 1176 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1177 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1178 Expr *&TaskgroupDescriptor) const { 1179 D = getCanonicalDecl(D); 1180 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1181 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1182 const DSAInfo &Data = I->SharingMap.lookup(D); 1183 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1184 continue; 1185 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1186 if (!ReductionData.ReductionOp || 1187 ReductionData.ReductionOp.is<const Expr *>()) 1188 return DSAVarData(); 1189 SR = ReductionData.ReductionRange; 1190 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1191 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1192 "expression for the descriptor is not " 1193 "set."); 1194 TaskgroupDescriptor = I->TaskgroupReductionRef; 1195 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1196 Data.PrivateCopy, I->DefaultAttrLoc); 1197 } 1198 return DSAVarData(); 1199 } 1200 1201 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1202 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1203 Expr *&TaskgroupDescriptor) const { 1204 D = getCanonicalDecl(D); 1205 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1206 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1207 const DSAInfo &Data = I->SharingMap.lookup(D); 1208 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1209 continue; 1210 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1211 if (!ReductionData.ReductionOp || 1212 !ReductionData.ReductionOp.is<const Expr *>()) 1213 return DSAVarData(); 1214 SR = ReductionData.ReductionRange; 1215 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1216 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1217 "expression for the descriptor is not " 1218 "set."); 1219 TaskgroupDescriptor = I->TaskgroupReductionRef; 1220 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1221 Data.PrivateCopy, I->DefaultAttrLoc); 1222 } 1223 return DSAVarData(); 1224 } 1225 1226 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1227 D = D->getCanonicalDecl(); 1228 for (const_iterator E = end(); I != E; ++I) { 1229 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1230 isOpenMPTargetExecutionDirective(I->Directive)) { 1231 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1232 Scope *CurScope = getCurScope(); 1233 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1234 CurScope = CurScope->getParent(); 1235 return CurScope != TopScope; 1236 } 1237 } 1238 return false; 1239 } 1240 1241 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1242 bool AcceptIfMutable = true, 1243 bool *IsClassType = nullptr) { 1244 ASTContext &Context = SemaRef.getASTContext(); 1245 Type = Type.getNonReferenceType().getCanonicalType(); 1246 bool IsConstant = Type.isConstant(Context); 1247 Type = Context.getBaseElementType(Type); 1248 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1249 ? Type->getAsCXXRecordDecl() 1250 : nullptr; 1251 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1252 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1253 RD = CTD->getTemplatedDecl(); 1254 if (IsClassType) 1255 *IsClassType = RD; 1256 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1257 RD->hasDefinition() && RD->hasMutableFields()); 1258 } 1259 1260 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1261 QualType Type, OpenMPClauseKind CKind, 1262 SourceLocation ELoc, 1263 bool AcceptIfMutable = true, 1264 bool ListItemNotVar = false) { 1265 ASTContext &Context = SemaRef.getASTContext(); 1266 bool IsClassType; 1267 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1268 unsigned Diag = ListItemNotVar 1269 ? diag::err_omp_const_list_item 1270 : IsClassType ? diag::err_omp_const_not_mutable_variable 1271 : diag::err_omp_const_variable; 1272 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1273 if (!ListItemNotVar && D) { 1274 const VarDecl *VD = dyn_cast<VarDecl>(D); 1275 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1276 VarDecl::DeclarationOnly; 1277 SemaRef.Diag(D->getLocation(), 1278 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1279 << D; 1280 } 1281 return true; 1282 } 1283 return false; 1284 } 1285 1286 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1287 bool FromParent) { 1288 D = getCanonicalDecl(D); 1289 DSAVarData DVar; 1290 1291 auto *VD = dyn_cast<VarDecl>(D); 1292 auto TI = Threadprivates.find(D); 1293 if (TI != Threadprivates.end()) { 1294 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1295 DVar.CKind = OMPC_threadprivate; 1296 return DVar; 1297 } 1298 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1299 DVar.RefExpr = buildDeclRefExpr( 1300 SemaRef, VD, D->getType().getNonReferenceType(), 1301 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1302 DVar.CKind = OMPC_threadprivate; 1303 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1304 return DVar; 1305 } 1306 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1307 // in a Construct, C/C++, predetermined, p.1] 1308 // Variables appearing in threadprivate directives are threadprivate. 1309 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1310 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1311 SemaRef.getLangOpts().OpenMPUseTLS && 1312 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1313 (VD && VD->getStorageClass() == SC_Register && 1314 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1315 DVar.RefExpr = buildDeclRefExpr( 1316 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1317 DVar.CKind = OMPC_threadprivate; 1318 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1319 return DVar; 1320 } 1321 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1322 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1323 !isLoopControlVariable(D).first) { 1324 const_iterator IterTarget = 1325 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1326 return isOpenMPTargetExecutionDirective(Data.Directive); 1327 }); 1328 if (IterTarget != end()) { 1329 const_iterator ParentIterTarget = IterTarget + 1; 1330 for (const_iterator Iter = begin(); 1331 Iter != ParentIterTarget; ++Iter) { 1332 if (isOpenMPLocal(VD, Iter)) { 1333 DVar.RefExpr = 1334 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1335 D->getLocation()); 1336 DVar.CKind = OMPC_threadprivate; 1337 return DVar; 1338 } 1339 } 1340 if (!isClauseParsingMode() || IterTarget != begin()) { 1341 auto DSAIter = IterTarget->SharingMap.find(D); 1342 if (DSAIter != IterTarget->SharingMap.end() && 1343 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1344 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1345 DVar.CKind = OMPC_threadprivate; 1346 return DVar; 1347 } 1348 const_iterator End = end(); 1349 if (!SemaRef.isOpenMPCapturedByRef( 1350 D, std::distance(ParentIterTarget, End), 1351 /*OpenMPCaptureLevel=*/0)) { 1352 DVar.RefExpr = 1353 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1354 IterTarget->ConstructLoc); 1355 DVar.CKind = OMPC_threadprivate; 1356 return DVar; 1357 } 1358 } 1359 } 1360 } 1361 1362 if (isStackEmpty()) 1363 // Not in OpenMP execution region and top scope was already checked. 1364 return DVar; 1365 1366 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1367 // in a Construct, C/C++, predetermined, p.4] 1368 // Static data members are shared. 1369 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1370 // in a Construct, C/C++, predetermined, p.7] 1371 // Variables with static storage duration that are declared in a scope 1372 // inside the construct are shared. 1373 if (VD && VD->isStaticDataMember()) { 1374 // Check for explicitly specified attributes. 1375 const_iterator I = begin(); 1376 const_iterator EndI = end(); 1377 if (FromParent && I != EndI) 1378 ++I; 1379 auto It = I->SharingMap.find(D); 1380 if (It != I->SharingMap.end()) { 1381 const DSAInfo &Data = It->getSecond(); 1382 DVar.RefExpr = Data.RefExpr.getPointer(); 1383 DVar.PrivateCopy = Data.PrivateCopy; 1384 DVar.CKind = Data.Attributes; 1385 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1386 DVar.DKind = I->Directive; 1387 return DVar; 1388 } 1389 1390 DVar.CKind = OMPC_shared; 1391 return DVar; 1392 } 1393 1394 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1395 // The predetermined shared attribute for const-qualified types having no 1396 // mutable members was removed after OpenMP 3.1. 1397 if (SemaRef.LangOpts.OpenMP <= 31) { 1398 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1399 // in a Construct, C/C++, predetermined, p.6] 1400 // Variables with const qualified type having no mutable member are 1401 // shared. 1402 if (isConstNotMutableType(SemaRef, D->getType())) { 1403 // Variables with const-qualified type having no mutable member may be 1404 // listed in a firstprivate clause, even if they are static data members. 1405 DSAVarData DVarTemp = hasInnermostDSA( 1406 D, 1407 [](OpenMPClauseKind C) { 1408 return C == OMPC_firstprivate || C == OMPC_shared; 1409 }, 1410 MatchesAlways, FromParent); 1411 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1412 return DVarTemp; 1413 1414 DVar.CKind = OMPC_shared; 1415 return DVar; 1416 } 1417 } 1418 1419 // Explicitly specified attributes and local variables with predetermined 1420 // attributes. 1421 const_iterator I = begin(); 1422 const_iterator EndI = end(); 1423 if (FromParent && I != EndI) 1424 ++I; 1425 auto It = I->SharingMap.find(D); 1426 if (It != I->SharingMap.end()) { 1427 const DSAInfo &Data = It->getSecond(); 1428 DVar.RefExpr = Data.RefExpr.getPointer(); 1429 DVar.PrivateCopy = Data.PrivateCopy; 1430 DVar.CKind = Data.Attributes; 1431 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1432 DVar.DKind = I->Directive; 1433 } 1434 1435 return DVar; 1436 } 1437 1438 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1439 bool FromParent) const { 1440 if (isStackEmpty()) { 1441 const_iterator I; 1442 return getDSA(I, D); 1443 } 1444 D = getCanonicalDecl(D); 1445 const_iterator StartI = begin(); 1446 const_iterator EndI = end(); 1447 if (FromParent && StartI != EndI) 1448 ++StartI; 1449 return getDSA(StartI, D); 1450 } 1451 1452 const DSAStackTy::DSAVarData 1453 DSAStackTy::hasDSA(ValueDecl *D, 1454 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1455 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1456 bool FromParent) const { 1457 if (isStackEmpty()) 1458 return {}; 1459 D = getCanonicalDecl(D); 1460 const_iterator I = begin(); 1461 const_iterator EndI = end(); 1462 if (FromParent && I != EndI) 1463 ++I; 1464 for (; I != EndI; ++I) { 1465 if (!DPred(I->Directive) && 1466 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1467 continue; 1468 const_iterator NewI = I; 1469 DSAVarData DVar = getDSA(NewI, D); 1470 if (I == NewI && CPred(DVar.CKind)) 1471 return DVar; 1472 } 1473 return {}; 1474 } 1475 1476 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1477 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1478 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1479 bool FromParent) const { 1480 if (isStackEmpty()) 1481 return {}; 1482 D = getCanonicalDecl(D); 1483 const_iterator StartI = begin(); 1484 const_iterator EndI = end(); 1485 if (FromParent && StartI != EndI) 1486 ++StartI; 1487 if (StartI == EndI || !DPred(StartI->Directive)) 1488 return {}; 1489 const_iterator NewI = StartI; 1490 DSAVarData DVar = getDSA(NewI, D); 1491 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1492 } 1493 1494 bool DSAStackTy::hasExplicitDSA( 1495 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1496 unsigned Level, bool NotLastprivate) const { 1497 if (getStackSize() <= Level) 1498 return false; 1499 D = getCanonicalDecl(D); 1500 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1501 auto I = StackElem.SharingMap.find(D); 1502 if (I != StackElem.SharingMap.end() && 1503 I->getSecond().RefExpr.getPointer() && 1504 CPred(I->getSecond().Attributes) && 1505 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1506 return true; 1507 // Check predetermined rules for the loop control variables. 1508 auto LI = StackElem.LCVMap.find(D); 1509 if (LI != StackElem.LCVMap.end()) 1510 return CPred(OMPC_private); 1511 return false; 1512 } 1513 1514 bool DSAStackTy::hasExplicitDirective( 1515 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1516 unsigned Level) const { 1517 if (getStackSize() <= Level) 1518 return false; 1519 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1520 return DPred(StackElem.Directive); 1521 } 1522 1523 bool DSAStackTy::hasDirective( 1524 const llvm::function_ref<bool(OpenMPDirectiveKind, 1525 const DeclarationNameInfo &, SourceLocation)> 1526 DPred, 1527 bool FromParent) const { 1528 // We look only in the enclosing region. 1529 size_t Skip = FromParent ? 2 : 1; 1530 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1531 I != E; ++I) { 1532 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1533 return true; 1534 } 1535 return false; 1536 } 1537 1538 void Sema::InitDataSharingAttributesStack() { 1539 VarDataSharingAttributesStack = new DSAStackTy(*this); 1540 } 1541 1542 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1543 1544 void Sema::pushOpenMPFunctionRegion() { 1545 DSAStack->pushFunction(); 1546 } 1547 1548 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1549 DSAStack->popFunction(OldFSI); 1550 } 1551 1552 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1553 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1554 "Expected OpenMP device compilation."); 1555 return !S.isInOpenMPTargetExecutionDirective() && 1556 !S.isInOpenMPDeclareTargetContext(); 1557 } 1558 1559 namespace { 1560 /// Status of the function emission on the host/device. 1561 enum class FunctionEmissionStatus { 1562 Emitted, 1563 Discarded, 1564 Unknown, 1565 }; 1566 } // anonymous namespace 1567 1568 /// Do we know that we will eventually codegen the given function? 1569 static FunctionEmissionStatus isKnownDeviceEmitted(Sema &S, FunctionDecl *FD) { 1570 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1571 "Expected OpenMP device compilation."); 1572 // Templates are emitted when they're instantiated. 1573 if (FD->isDependentContext()) 1574 return FunctionEmissionStatus::Discarded; 1575 1576 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 1577 OMPDeclareTargetDeclAttr::getDeviceType(FD->getCanonicalDecl()); 1578 if (DevTy.hasValue()) 1579 return (*DevTy == OMPDeclareTargetDeclAttr::DT_Host) 1580 ? FunctionEmissionStatus::Discarded 1581 : FunctionEmissionStatus::Emitted; 1582 1583 // Otherwise, the function is known-emitted if it's in our set of 1584 // known-emitted functions. 1585 return (S.DeviceKnownEmittedFns.count(FD) > 0) 1586 ? FunctionEmissionStatus::Emitted 1587 : FunctionEmissionStatus::Unknown; 1588 } 1589 1590 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1591 unsigned DiagID) { 1592 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1593 "Expected OpenMP device compilation."); 1594 FunctionEmissionStatus FES = 1595 isKnownDeviceEmitted(*this, getCurFunctionDecl()); 1596 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1597 switch (FES) { 1598 case FunctionEmissionStatus::Emitted: 1599 Kind = DeviceDiagBuilder::K_Immediate; 1600 break; 1601 case FunctionEmissionStatus::Unknown: 1602 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1603 : DeviceDiagBuilder::K_Immediate; 1604 break; 1605 case FunctionEmissionStatus::Discarded: 1606 Kind = DeviceDiagBuilder::K_Nop; 1607 break; 1608 } 1609 1610 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1611 } 1612 1613 /// Do we know that we will eventually codegen the given function? 1614 static FunctionEmissionStatus isKnownHostEmitted(Sema &S, FunctionDecl *FD) { 1615 assert(S.LangOpts.OpenMP && !S.LangOpts.OpenMPIsDevice && 1616 "Expected OpenMP host compilation."); 1617 // In OpenMP 4.5 all the functions are host functions. 1618 if (S.LangOpts.OpenMP <= 45) 1619 return FunctionEmissionStatus::Emitted; 1620 1621 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 1622 OMPDeclareTargetDeclAttr::getDeviceType(FD->getCanonicalDecl()); 1623 if (DevTy.hasValue()) 1624 return (*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 1625 ? FunctionEmissionStatus::Discarded 1626 : FunctionEmissionStatus::Emitted; 1627 1628 // Otherwise, the function is known-emitted if it's in our set of 1629 // known-emitted functions. 1630 return (S.DeviceKnownEmittedFns.count(FD) > 0) 1631 ? FunctionEmissionStatus::Emitted 1632 : FunctionEmissionStatus::Unknown; 1633 } 1634 1635 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1636 unsigned DiagID) { 1637 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1638 "Expected OpenMP host compilation."); 1639 FunctionEmissionStatus FES = 1640 isKnownHostEmitted(*this, getCurFunctionDecl()); 1641 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1642 switch (FES) { 1643 case FunctionEmissionStatus::Emitted: 1644 Kind = DeviceDiagBuilder::K_Immediate; 1645 break; 1646 case FunctionEmissionStatus::Unknown: 1647 Kind = DeviceDiagBuilder::K_Deferred; 1648 break; 1649 case FunctionEmissionStatus::Discarded: 1650 Kind = DeviceDiagBuilder::K_Nop; 1651 break; 1652 } 1653 1654 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1655 } 1656 1657 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1658 bool CheckForDelayedContext) { 1659 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1660 "Expected OpenMP device compilation."); 1661 assert(Callee && "Callee may not be null."); 1662 Callee = Callee->getMostRecentDecl(); 1663 FunctionDecl *Caller = getCurFunctionDecl(); 1664 1665 // host only function are not available on the device. 1666 if (Caller && 1667 (isKnownDeviceEmitted(*this, Caller) == FunctionEmissionStatus::Emitted || 1668 (!isOpenMPDeviceDelayedContext(*this) && 1669 isKnownDeviceEmitted(*this, Caller) == 1670 FunctionEmissionStatus::Unknown)) && 1671 isKnownDeviceEmitted(*this, Callee) == 1672 FunctionEmissionStatus::Discarded) { 1673 StringRef HostDevTy = 1674 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 1675 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1676 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1677 diag::note_omp_marked_device_type_here) 1678 << HostDevTy; 1679 return; 1680 } 1681 // If the caller is known-emitted, mark the callee as known-emitted. 1682 // Otherwise, mark the call in our call graph so we can traverse it later. 1683 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1684 (!Caller && !CheckForDelayedContext) || 1685 (Caller && 1686 isKnownDeviceEmitted(*this, Caller) == FunctionEmissionStatus::Emitted)) 1687 markKnownEmitted(*this, Caller, Callee, Loc, 1688 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1689 return CheckForDelayedContext && 1690 isKnownDeviceEmitted(S, FD) == 1691 FunctionEmissionStatus::Emitted; 1692 }); 1693 else if (Caller) 1694 DeviceCallGraph[Caller].insert({Callee, Loc}); 1695 } 1696 1697 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1698 bool CheckCaller) { 1699 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1700 "Expected OpenMP host compilation."); 1701 assert(Callee && "Callee may not be null."); 1702 Callee = Callee->getMostRecentDecl(); 1703 FunctionDecl *Caller = getCurFunctionDecl(); 1704 1705 // device only function are not available on the host. 1706 if (Caller && 1707 isKnownHostEmitted(*this, Caller) == FunctionEmissionStatus::Emitted && 1708 isKnownHostEmitted(*this, Callee) == FunctionEmissionStatus::Discarded) { 1709 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1710 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1711 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1712 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1713 diag::note_omp_marked_device_type_here) 1714 << NoHostDevTy; 1715 return; 1716 } 1717 // If the caller is known-emitted, mark the callee as known-emitted. 1718 // Otherwise, mark the call in our call graph so we can traverse it later. 1719 if ((!CheckCaller && !Caller) || 1720 (Caller && 1721 isKnownHostEmitted(*this, Caller) == FunctionEmissionStatus::Emitted)) 1722 markKnownEmitted( 1723 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1724 return CheckCaller && 1725 isKnownHostEmitted(S, FD) == FunctionEmissionStatus::Emitted; 1726 }); 1727 else if (Caller) 1728 DeviceCallGraph[Caller].insert({Callee, Loc}); 1729 } 1730 1731 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1732 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1733 "OpenMP device compilation mode is expected."); 1734 QualType Ty = E->getType(); 1735 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1736 ((Ty->isFloat128Type() || 1737 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1738 !Context.getTargetInfo().hasFloat128Type()) || 1739 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1740 !Context.getTargetInfo().hasInt128Type())) 1741 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1742 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1743 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1744 } 1745 1746 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1747 unsigned OpenMPCaptureLevel) const { 1748 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1749 1750 ASTContext &Ctx = getASTContext(); 1751 bool IsByRef = true; 1752 1753 // Find the directive that is associated with the provided scope. 1754 D = cast<ValueDecl>(D->getCanonicalDecl()); 1755 QualType Ty = D->getType(); 1756 1757 bool IsVariableUsedInMapClause = false; 1758 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1759 // This table summarizes how a given variable should be passed to the device 1760 // given its type and the clauses where it appears. This table is based on 1761 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1762 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1763 // 1764 // ========================================================================= 1765 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1766 // | |(tofrom:scalar)| | pvt | | | | 1767 // ========================================================================= 1768 // | scl | | | | - | | bycopy| 1769 // | scl | | - | x | - | - | bycopy| 1770 // | scl | | x | - | - | - | null | 1771 // | scl | x | | | - | | byref | 1772 // | scl | x | - | x | - | - | bycopy| 1773 // | scl | x | x | - | - | - | null | 1774 // | scl | | - | - | - | x | byref | 1775 // | scl | x | - | - | - | x | byref | 1776 // 1777 // | agg | n.a. | | | - | | byref | 1778 // | agg | n.a. | - | x | - | - | byref | 1779 // | agg | n.a. | x | - | - | - | null | 1780 // | agg | n.a. | - | - | - | x | byref | 1781 // | agg | n.a. | - | - | - | x[] | byref | 1782 // 1783 // | ptr | n.a. | | | - | | bycopy| 1784 // | ptr | n.a. | - | x | - | - | bycopy| 1785 // | ptr | n.a. | x | - | - | - | null | 1786 // | ptr | n.a. | - | - | - | x | byref | 1787 // | ptr | n.a. | - | - | - | x[] | bycopy| 1788 // | ptr | n.a. | - | - | x | | bycopy| 1789 // | ptr | n.a. | - | - | x | x | bycopy| 1790 // | ptr | n.a. | - | - | x | x[] | bycopy| 1791 // ========================================================================= 1792 // Legend: 1793 // scl - scalar 1794 // ptr - pointer 1795 // agg - aggregate 1796 // x - applies 1797 // - - invalid in this combination 1798 // [] - mapped with an array section 1799 // byref - should be mapped by reference 1800 // byval - should be mapped by value 1801 // null - initialize a local variable to null on the device 1802 // 1803 // Observations: 1804 // - All scalar declarations that show up in a map clause have to be passed 1805 // by reference, because they may have been mapped in the enclosing data 1806 // environment. 1807 // - If the scalar value does not fit the size of uintptr, it has to be 1808 // passed by reference, regardless the result in the table above. 1809 // - For pointers mapped by value that have either an implicit map or an 1810 // array section, the runtime library may pass the NULL value to the 1811 // device instead of the value passed to it by the compiler. 1812 1813 if (Ty->isReferenceType()) 1814 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1815 1816 // Locate map clauses and see if the variable being captured is referred to 1817 // in any of those clauses. Here we only care about variables, not fields, 1818 // because fields are part of aggregates. 1819 bool IsVariableAssociatedWithSection = false; 1820 1821 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1822 D, Level, 1823 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1824 OMPClauseMappableExprCommon::MappableExprComponentListRef 1825 MapExprComponents, 1826 OpenMPClauseKind WhereFoundClauseKind) { 1827 // Only the map clause information influences how a variable is 1828 // captured. E.g. is_device_ptr does not require changing the default 1829 // behavior. 1830 if (WhereFoundClauseKind != OMPC_map) 1831 return false; 1832 1833 auto EI = MapExprComponents.rbegin(); 1834 auto EE = MapExprComponents.rend(); 1835 1836 assert(EI != EE && "Invalid map expression!"); 1837 1838 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1839 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1840 1841 ++EI; 1842 if (EI == EE) 1843 return false; 1844 1845 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1846 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1847 isa<MemberExpr>(EI->getAssociatedExpression())) { 1848 IsVariableAssociatedWithSection = true; 1849 // There is nothing more we need to know about this variable. 1850 return true; 1851 } 1852 1853 // Keep looking for more map info. 1854 return false; 1855 }); 1856 1857 if (IsVariableUsedInMapClause) { 1858 // If variable is identified in a map clause it is always captured by 1859 // reference except if it is a pointer that is dereferenced somehow. 1860 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1861 } else { 1862 // By default, all the data that has a scalar type is mapped by copy 1863 // (except for reduction variables). 1864 IsByRef = 1865 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1866 !Ty->isAnyPointerType()) || 1867 !Ty->isScalarType() || 1868 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1869 DSAStack->hasExplicitDSA( 1870 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1871 } 1872 } 1873 1874 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1875 IsByRef = 1876 ((IsVariableUsedInMapClause && 1877 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1878 OMPD_target) || 1879 !DSAStack->hasExplicitDSA( 1880 D, 1881 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1882 Level, /*NotLastprivate=*/true)) && 1883 // If the variable is artificial and must be captured by value - try to 1884 // capture by value. 1885 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1886 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1887 } 1888 1889 // When passing data by copy, we need to make sure it fits the uintptr size 1890 // and alignment, because the runtime library only deals with uintptr types. 1891 // If it does not fit the uintptr size, we need to pass the data by reference 1892 // instead. 1893 if (!IsByRef && 1894 (Ctx.getTypeSizeInChars(Ty) > 1895 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1896 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1897 IsByRef = true; 1898 } 1899 1900 return IsByRef; 1901 } 1902 1903 unsigned Sema::getOpenMPNestingLevel() const { 1904 assert(getLangOpts().OpenMP); 1905 return DSAStack->getNestingLevel(); 1906 } 1907 1908 bool Sema::isInOpenMPTargetExecutionDirective() const { 1909 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1910 !DSAStack->isClauseParsingMode()) || 1911 DSAStack->hasDirective( 1912 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1913 SourceLocation) -> bool { 1914 return isOpenMPTargetExecutionDirective(K); 1915 }, 1916 false); 1917 } 1918 1919 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1920 unsigned StopAt) { 1921 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1922 D = getCanonicalDecl(D); 1923 1924 // If we want to determine whether the variable should be captured from the 1925 // perspective of the current capturing scope, and we've already left all the 1926 // capturing scopes of the top directive on the stack, check from the 1927 // perspective of its parent directive (if any) instead. 1928 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1929 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1930 1931 // If we are attempting to capture a global variable in a directive with 1932 // 'target' we return true so that this global is also mapped to the device. 1933 // 1934 auto *VD = dyn_cast<VarDecl>(D); 1935 if (VD && !VD->hasLocalStorage() && 1936 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1937 if (isInOpenMPDeclareTargetContext()) { 1938 // Try to mark variable as declare target if it is used in capturing 1939 // regions. 1940 if (LangOpts.OpenMP <= 45 && 1941 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1942 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1943 return nullptr; 1944 } else if (isInOpenMPTargetExecutionDirective()) { 1945 // If the declaration is enclosed in a 'declare target' directive, 1946 // then it should not be captured. 1947 // 1948 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1949 return nullptr; 1950 return VD; 1951 } 1952 } 1953 1954 if (CheckScopeInfo) { 1955 bool OpenMPFound = false; 1956 for (unsigned I = StopAt + 1; I > 0; --I) { 1957 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1958 if(!isa<CapturingScopeInfo>(FSI)) 1959 return nullptr; 1960 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1961 if (RSI->CapRegionKind == CR_OpenMP) { 1962 OpenMPFound = true; 1963 break; 1964 } 1965 } 1966 if (!OpenMPFound) 1967 return nullptr; 1968 } 1969 1970 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1971 (!DSAStack->isClauseParsingMode() || 1972 DSAStack->getParentDirective() != OMPD_unknown)) { 1973 auto &&Info = DSAStack->isLoopControlVariable(D); 1974 if (Info.first || 1975 (VD && VD->hasLocalStorage() && 1976 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1977 (VD && DSAStack->isForceVarCapturing())) 1978 return VD ? VD : Info.second; 1979 DSAStackTy::DSAVarData DVarPrivate = 1980 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1981 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1982 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1983 // Threadprivate variables must not be captured. 1984 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1985 return nullptr; 1986 // The variable is not private or it is the variable in the directive with 1987 // default(none) clause and not used in any clause. 1988 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1989 [](OpenMPDirectiveKind) { return true; }, 1990 DSAStack->isClauseParsingMode()); 1991 if (DVarPrivate.CKind != OMPC_unknown || 1992 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1993 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1994 } 1995 return nullptr; 1996 } 1997 1998 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1999 unsigned Level) const { 2000 SmallVector<OpenMPDirectiveKind, 4> Regions; 2001 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2002 FunctionScopesIndex -= Regions.size(); 2003 } 2004 2005 void Sema::startOpenMPLoop() { 2006 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2007 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2008 DSAStack->loopInit(); 2009 } 2010 2011 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2012 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2013 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2014 if (DSAStack->getAssociatedLoops() > 0 && 2015 !DSAStack->isLoopStarted()) { 2016 DSAStack->resetPossibleLoopCounter(D); 2017 DSAStack->loopStart(); 2018 return true; 2019 } 2020 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2021 DSAStack->isLoopControlVariable(D).first) && 2022 !DSAStack->hasExplicitDSA( 2023 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2024 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2025 return true; 2026 } 2027 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2028 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2029 DSAStack->isForceVarCapturing() && 2030 !DSAStack->hasExplicitDSA( 2031 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2032 return true; 2033 } 2034 return DSAStack->hasExplicitDSA( 2035 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2036 (DSAStack->isClauseParsingMode() && 2037 DSAStack->getClauseParsingMode() == OMPC_private) || 2038 // Consider taskgroup reduction descriptor variable a private to avoid 2039 // possible capture in the region. 2040 (DSAStack->hasExplicitDirective( 2041 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2042 Level) && 2043 DSAStack->isTaskgroupReductionRef(D, Level)); 2044 } 2045 2046 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2047 unsigned Level) { 2048 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2049 D = getCanonicalDecl(D); 2050 OpenMPClauseKind OMPC = OMPC_unknown; 2051 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2052 const unsigned NewLevel = I - 1; 2053 if (DSAStack->hasExplicitDSA(D, 2054 [&OMPC](const OpenMPClauseKind K) { 2055 if (isOpenMPPrivate(K)) { 2056 OMPC = K; 2057 return true; 2058 } 2059 return false; 2060 }, 2061 NewLevel)) 2062 break; 2063 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2064 D, NewLevel, 2065 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2066 OpenMPClauseKind) { return true; })) { 2067 OMPC = OMPC_map; 2068 break; 2069 } 2070 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2071 NewLevel)) { 2072 OMPC = OMPC_map; 2073 if (D->getType()->isScalarType() && 2074 DSAStack->getDefaultDMAAtLevel(NewLevel) != 2075 DefaultMapAttributes::DMA_tofrom_scalar) 2076 OMPC = OMPC_firstprivate; 2077 break; 2078 } 2079 } 2080 if (OMPC != OMPC_unknown) 2081 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2082 } 2083 2084 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2085 unsigned Level) const { 2086 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2087 // Return true if the current level is no longer enclosed in a target region. 2088 2089 const auto *VD = dyn_cast<VarDecl>(D); 2090 return VD && !VD->hasLocalStorage() && 2091 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2092 Level); 2093 } 2094 2095 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2096 2097 void Sema::finalizeOpenMPDelayedAnalysis() { 2098 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2099 // Diagnose implicit declare target functions and their callees. 2100 for (const auto &CallerCallees : DeviceCallGraph) { 2101 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2102 OMPDeclareTargetDeclAttr::getDeviceType( 2103 CallerCallees.getFirst()->getMostRecentDecl()); 2104 // Ignore host functions during device analyzis. 2105 if (LangOpts.OpenMPIsDevice && DevTy && 2106 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2107 continue; 2108 // Ignore nohost functions during host analyzis. 2109 if (!LangOpts.OpenMPIsDevice && DevTy && 2110 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2111 continue; 2112 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2113 &Callee : CallerCallees.getSecond()) { 2114 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2115 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2116 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2117 if (LangOpts.OpenMPIsDevice && DevTy && 2118 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2119 // Diagnose host function called during device codegen. 2120 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2121 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2122 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2123 << HostDevTy << 0; 2124 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2125 diag::note_omp_marked_device_type_here) 2126 << HostDevTy; 2127 continue; 2128 } 2129 if (!LangOpts.OpenMPIsDevice && DevTy && 2130 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2131 // Diagnose nohost function called during host codegen. 2132 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2133 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2134 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2135 << NoHostDevTy << 1; 2136 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2137 diag::note_omp_marked_device_type_here) 2138 << NoHostDevTy; 2139 continue; 2140 } 2141 } 2142 } 2143 } 2144 2145 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2146 const DeclarationNameInfo &DirName, 2147 Scope *CurScope, SourceLocation Loc) { 2148 DSAStack->push(DKind, DirName, CurScope, Loc); 2149 PushExpressionEvaluationContext( 2150 ExpressionEvaluationContext::PotentiallyEvaluated); 2151 } 2152 2153 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2154 DSAStack->setClauseParsingMode(K); 2155 } 2156 2157 void Sema::EndOpenMPClause() { 2158 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2159 } 2160 2161 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2162 ArrayRef<OMPClause *> Clauses); 2163 2164 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2165 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2166 // A variable of class type (or array thereof) that appears in a lastprivate 2167 // clause requires an accessible, unambiguous default constructor for the 2168 // class type, unless the list item is also specified in a firstprivate 2169 // clause. 2170 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2171 for (OMPClause *C : D->clauses()) { 2172 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2173 SmallVector<Expr *, 8> PrivateCopies; 2174 for (Expr *DE : Clause->varlists()) { 2175 if (DE->isValueDependent() || DE->isTypeDependent()) { 2176 PrivateCopies.push_back(nullptr); 2177 continue; 2178 } 2179 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2180 auto *VD = cast<VarDecl>(DRE->getDecl()); 2181 QualType Type = VD->getType().getNonReferenceType(); 2182 const DSAStackTy::DSAVarData DVar = 2183 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2184 if (DVar.CKind == OMPC_lastprivate) { 2185 // Generate helper private variable and initialize it with the 2186 // default value. The address of the original variable is replaced 2187 // by the address of the new private variable in CodeGen. This new 2188 // variable is not added to IdResolver, so the code in the OpenMP 2189 // region uses original variable for proper diagnostics. 2190 VarDecl *VDPrivate = buildVarDecl( 2191 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2192 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2193 ActOnUninitializedDecl(VDPrivate); 2194 if (VDPrivate->isInvalidDecl()) { 2195 PrivateCopies.push_back(nullptr); 2196 continue; 2197 } 2198 PrivateCopies.push_back(buildDeclRefExpr( 2199 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2200 } else { 2201 // The variable is also a firstprivate, so initialization sequence 2202 // for private copy is generated already. 2203 PrivateCopies.push_back(nullptr); 2204 } 2205 } 2206 Clause->setPrivateCopies(PrivateCopies); 2207 } 2208 } 2209 // Check allocate clauses. 2210 if (!CurContext->isDependentContext()) 2211 checkAllocateClauses(*this, DSAStack, D->clauses()); 2212 } 2213 2214 DSAStack->pop(); 2215 DiscardCleanupsInEvaluationContext(); 2216 PopExpressionEvaluationContext(); 2217 } 2218 2219 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2220 Expr *NumIterations, Sema &SemaRef, 2221 Scope *S, DSAStackTy *Stack); 2222 2223 namespace { 2224 2225 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2226 private: 2227 Sema &SemaRef; 2228 2229 public: 2230 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2231 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2232 NamedDecl *ND = Candidate.getCorrectionDecl(); 2233 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2234 return VD->hasGlobalStorage() && 2235 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2236 SemaRef.getCurScope()); 2237 } 2238 return false; 2239 } 2240 2241 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2242 return std::make_unique<VarDeclFilterCCC>(*this); 2243 } 2244 2245 }; 2246 2247 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2248 private: 2249 Sema &SemaRef; 2250 2251 public: 2252 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2253 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2254 NamedDecl *ND = Candidate.getCorrectionDecl(); 2255 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2256 isa<FunctionDecl>(ND))) { 2257 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2258 SemaRef.getCurScope()); 2259 } 2260 return false; 2261 } 2262 2263 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2264 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2265 } 2266 }; 2267 2268 } // namespace 2269 2270 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2271 CXXScopeSpec &ScopeSpec, 2272 const DeclarationNameInfo &Id, 2273 OpenMPDirectiveKind Kind) { 2274 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2275 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2276 2277 if (Lookup.isAmbiguous()) 2278 return ExprError(); 2279 2280 VarDecl *VD; 2281 if (!Lookup.isSingleResult()) { 2282 VarDeclFilterCCC CCC(*this); 2283 if (TypoCorrection Corrected = 2284 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2285 CTK_ErrorRecovery)) { 2286 diagnoseTypo(Corrected, 2287 PDiag(Lookup.empty() 2288 ? diag::err_undeclared_var_use_suggest 2289 : diag::err_omp_expected_var_arg_suggest) 2290 << Id.getName()); 2291 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2292 } else { 2293 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2294 : diag::err_omp_expected_var_arg) 2295 << Id.getName(); 2296 return ExprError(); 2297 } 2298 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2299 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2300 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2301 return ExprError(); 2302 } 2303 Lookup.suppressDiagnostics(); 2304 2305 // OpenMP [2.9.2, Syntax, C/C++] 2306 // Variables must be file-scope, namespace-scope, or static block-scope. 2307 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2308 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2309 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2310 bool IsDecl = 2311 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2312 Diag(VD->getLocation(), 2313 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2314 << VD; 2315 return ExprError(); 2316 } 2317 2318 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2319 NamedDecl *ND = CanonicalVD; 2320 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2321 // A threadprivate directive for file-scope variables must appear outside 2322 // any definition or declaration. 2323 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2324 !getCurLexicalContext()->isTranslationUnit()) { 2325 Diag(Id.getLoc(), diag::err_omp_var_scope) 2326 << getOpenMPDirectiveName(Kind) << VD; 2327 bool IsDecl = 2328 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2329 Diag(VD->getLocation(), 2330 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2331 << VD; 2332 return ExprError(); 2333 } 2334 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2335 // A threadprivate directive for static class member variables must appear 2336 // in the class definition, in the same scope in which the member 2337 // variables are declared. 2338 if (CanonicalVD->isStaticDataMember() && 2339 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2340 Diag(Id.getLoc(), diag::err_omp_var_scope) 2341 << getOpenMPDirectiveName(Kind) << VD; 2342 bool IsDecl = 2343 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2344 Diag(VD->getLocation(), 2345 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2346 << VD; 2347 return ExprError(); 2348 } 2349 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2350 // A threadprivate directive for namespace-scope variables must appear 2351 // outside any definition or declaration other than the namespace 2352 // definition itself. 2353 if (CanonicalVD->getDeclContext()->isNamespace() && 2354 (!getCurLexicalContext()->isFileContext() || 2355 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2356 Diag(Id.getLoc(), diag::err_omp_var_scope) 2357 << getOpenMPDirectiveName(Kind) << VD; 2358 bool IsDecl = 2359 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2360 Diag(VD->getLocation(), 2361 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2362 << VD; 2363 return ExprError(); 2364 } 2365 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2366 // A threadprivate directive for static block-scope variables must appear 2367 // in the scope of the variable and not in a nested scope. 2368 if (CanonicalVD->isLocalVarDecl() && CurScope && 2369 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2370 Diag(Id.getLoc(), diag::err_omp_var_scope) 2371 << getOpenMPDirectiveName(Kind) << VD; 2372 bool IsDecl = 2373 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2374 Diag(VD->getLocation(), 2375 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2376 << VD; 2377 return ExprError(); 2378 } 2379 2380 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2381 // A threadprivate directive must lexically precede all references to any 2382 // of the variables in its list. 2383 if (Kind == OMPD_threadprivate && VD->isUsed() && 2384 !DSAStack->isThreadPrivate(VD)) { 2385 Diag(Id.getLoc(), diag::err_omp_var_used) 2386 << getOpenMPDirectiveName(Kind) << VD; 2387 return ExprError(); 2388 } 2389 2390 QualType ExprType = VD->getType().getNonReferenceType(); 2391 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2392 SourceLocation(), VD, 2393 /*RefersToEnclosingVariableOrCapture=*/false, 2394 Id.getLoc(), ExprType, VK_LValue); 2395 } 2396 2397 Sema::DeclGroupPtrTy 2398 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2399 ArrayRef<Expr *> VarList) { 2400 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2401 CurContext->addDecl(D); 2402 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2403 } 2404 return nullptr; 2405 } 2406 2407 namespace { 2408 class LocalVarRefChecker final 2409 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2410 Sema &SemaRef; 2411 2412 public: 2413 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2414 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2415 if (VD->hasLocalStorage()) { 2416 SemaRef.Diag(E->getBeginLoc(), 2417 diag::err_omp_local_var_in_threadprivate_init) 2418 << E->getSourceRange(); 2419 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2420 << VD << VD->getSourceRange(); 2421 return true; 2422 } 2423 } 2424 return false; 2425 } 2426 bool VisitStmt(const Stmt *S) { 2427 for (const Stmt *Child : S->children()) { 2428 if (Child && Visit(Child)) 2429 return true; 2430 } 2431 return false; 2432 } 2433 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2434 }; 2435 } // namespace 2436 2437 OMPThreadPrivateDecl * 2438 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2439 SmallVector<Expr *, 8> Vars; 2440 for (Expr *RefExpr : VarList) { 2441 auto *DE = cast<DeclRefExpr>(RefExpr); 2442 auto *VD = cast<VarDecl>(DE->getDecl()); 2443 SourceLocation ILoc = DE->getExprLoc(); 2444 2445 // Mark variable as used. 2446 VD->setReferenced(); 2447 VD->markUsed(Context); 2448 2449 QualType QType = VD->getType(); 2450 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2451 // It will be analyzed later. 2452 Vars.push_back(DE); 2453 continue; 2454 } 2455 2456 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2457 // A threadprivate variable must not have an incomplete type. 2458 if (RequireCompleteType(ILoc, VD->getType(), 2459 diag::err_omp_threadprivate_incomplete_type)) { 2460 continue; 2461 } 2462 2463 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2464 // A threadprivate variable must not have a reference type. 2465 if (VD->getType()->isReferenceType()) { 2466 Diag(ILoc, diag::err_omp_ref_type_arg) 2467 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2468 bool IsDecl = 2469 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2470 Diag(VD->getLocation(), 2471 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2472 << VD; 2473 continue; 2474 } 2475 2476 // Check if this is a TLS variable. If TLS is not being supported, produce 2477 // the corresponding diagnostic. 2478 if ((VD->getTLSKind() != VarDecl::TLS_None && 2479 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2480 getLangOpts().OpenMPUseTLS && 2481 getASTContext().getTargetInfo().isTLSSupported())) || 2482 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2483 !VD->isLocalVarDecl())) { 2484 Diag(ILoc, diag::err_omp_var_thread_local) 2485 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2486 bool IsDecl = 2487 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2488 Diag(VD->getLocation(), 2489 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2490 << VD; 2491 continue; 2492 } 2493 2494 // Check if initial value of threadprivate variable reference variable with 2495 // local storage (it is not supported by runtime). 2496 if (const Expr *Init = VD->getAnyInitializer()) { 2497 LocalVarRefChecker Checker(*this); 2498 if (Checker.Visit(Init)) 2499 continue; 2500 } 2501 2502 Vars.push_back(RefExpr); 2503 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2504 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2505 Context, SourceRange(Loc, Loc))); 2506 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2507 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2508 } 2509 OMPThreadPrivateDecl *D = nullptr; 2510 if (!Vars.empty()) { 2511 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2512 Vars); 2513 D->setAccess(AS_public); 2514 } 2515 return D; 2516 } 2517 2518 static OMPAllocateDeclAttr::AllocatorTypeTy 2519 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2520 if (!Allocator) 2521 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2522 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2523 Allocator->isInstantiationDependent() || 2524 Allocator->containsUnexpandedParameterPack()) 2525 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2526 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2527 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2528 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2529 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2530 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2531 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2532 llvm::FoldingSetNodeID AEId, DAEId; 2533 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2534 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2535 if (AEId == DAEId) { 2536 AllocatorKindRes = AllocatorKind; 2537 break; 2538 } 2539 } 2540 return AllocatorKindRes; 2541 } 2542 2543 static bool checkPreviousOMPAllocateAttribute( 2544 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2545 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2546 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2547 return false; 2548 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2549 Expr *PrevAllocator = A->getAllocator(); 2550 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2551 getAllocatorKind(S, Stack, PrevAllocator); 2552 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2553 if (AllocatorsMatch && 2554 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2555 Allocator && PrevAllocator) { 2556 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2557 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2558 llvm::FoldingSetNodeID AEId, PAEId; 2559 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2560 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2561 AllocatorsMatch = AEId == PAEId; 2562 } 2563 if (!AllocatorsMatch) { 2564 SmallString<256> AllocatorBuffer; 2565 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2566 if (Allocator) 2567 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2568 SmallString<256> PrevAllocatorBuffer; 2569 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2570 if (PrevAllocator) 2571 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2572 S.getPrintingPolicy()); 2573 2574 SourceLocation AllocatorLoc = 2575 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2576 SourceRange AllocatorRange = 2577 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2578 SourceLocation PrevAllocatorLoc = 2579 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2580 SourceRange PrevAllocatorRange = 2581 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2582 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2583 << (Allocator ? 1 : 0) << AllocatorStream.str() 2584 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2585 << AllocatorRange; 2586 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2587 << PrevAllocatorRange; 2588 return true; 2589 } 2590 return false; 2591 } 2592 2593 static void 2594 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2595 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2596 Expr *Allocator, SourceRange SR) { 2597 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2598 return; 2599 if (Allocator && 2600 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2601 Allocator->isInstantiationDependent() || 2602 Allocator->containsUnexpandedParameterPack())) 2603 return; 2604 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2605 Allocator, SR); 2606 VD->addAttr(A); 2607 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2608 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2609 } 2610 2611 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2612 SourceLocation Loc, ArrayRef<Expr *> VarList, 2613 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2614 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2615 Expr *Allocator = nullptr; 2616 if (Clauses.empty()) { 2617 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2618 // allocate directives that appear in a target region must specify an 2619 // allocator clause unless a requires directive with the dynamic_allocators 2620 // clause is present in the same compilation unit. 2621 if (LangOpts.OpenMPIsDevice && 2622 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2623 targetDiag(Loc, diag::err_expected_allocator_clause); 2624 } else { 2625 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2626 } 2627 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2628 getAllocatorKind(*this, DSAStack, Allocator); 2629 SmallVector<Expr *, 8> Vars; 2630 for (Expr *RefExpr : VarList) { 2631 auto *DE = cast<DeclRefExpr>(RefExpr); 2632 auto *VD = cast<VarDecl>(DE->getDecl()); 2633 2634 // Check if this is a TLS variable or global register. 2635 if (VD->getTLSKind() != VarDecl::TLS_None || 2636 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2637 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2638 !VD->isLocalVarDecl())) 2639 continue; 2640 2641 // If the used several times in the allocate directive, the same allocator 2642 // must be used. 2643 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2644 AllocatorKind, Allocator)) 2645 continue; 2646 2647 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2648 // If a list item has a static storage type, the allocator expression in the 2649 // allocator clause must be a constant expression that evaluates to one of 2650 // the predefined memory allocator values. 2651 if (Allocator && VD->hasGlobalStorage()) { 2652 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2653 Diag(Allocator->getExprLoc(), 2654 diag::err_omp_expected_predefined_allocator) 2655 << Allocator->getSourceRange(); 2656 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2657 VarDecl::DeclarationOnly; 2658 Diag(VD->getLocation(), 2659 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2660 << VD; 2661 continue; 2662 } 2663 } 2664 2665 Vars.push_back(RefExpr); 2666 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2667 DE->getSourceRange()); 2668 } 2669 if (Vars.empty()) 2670 return nullptr; 2671 if (!Owner) 2672 Owner = getCurLexicalContext(); 2673 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2674 D->setAccess(AS_public); 2675 Owner->addDecl(D); 2676 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2677 } 2678 2679 Sema::DeclGroupPtrTy 2680 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2681 ArrayRef<OMPClause *> ClauseList) { 2682 OMPRequiresDecl *D = nullptr; 2683 if (!CurContext->isFileContext()) { 2684 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2685 } else { 2686 D = CheckOMPRequiresDecl(Loc, ClauseList); 2687 if (D) { 2688 CurContext->addDecl(D); 2689 DSAStack->addRequiresDecl(D); 2690 } 2691 } 2692 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2693 } 2694 2695 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2696 ArrayRef<OMPClause *> ClauseList) { 2697 /// For target specific clauses, the requires directive cannot be 2698 /// specified after the handling of any of the target regions in the 2699 /// current compilation unit. 2700 ArrayRef<SourceLocation> TargetLocations = 2701 DSAStack->getEncounteredTargetLocs(); 2702 if (!TargetLocations.empty()) { 2703 for (const OMPClause *CNew : ClauseList) { 2704 // Check if any of the requires clauses affect target regions. 2705 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2706 isa<OMPUnifiedAddressClause>(CNew) || 2707 isa<OMPReverseOffloadClause>(CNew) || 2708 isa<OMPDynamicAllocatorsClause>(CNew)) { 2709 Diag(Loc, diag::err_omp_target_before_requires) 2710 << getOpenMPClauseName(CNew->getClauseKind()); 2711 for (SourceLocation TargetLoc : TargetLocations) { 2712 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2713 } 2714 } 2715 } 2716 } 2717 2718 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2719 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2720 ClauseList); 2721 return nullptr; 2722 } 2723 2724 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2725 const ValueDecl *D, 2726 const DSAStackTy::DSAVarData &DVar, 2727 bool IsLoopIterVar = false) { 2728 if (DVar.RefExpr) { 2729 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2730 << getOpenMPClauseName(DVar.CKind); 2731 return; 2732 } 2733 enum { 2734 PDSA_StaticMemberShared, 2735 PDSA_StaticLocalVarShared, 2736 PDSA_LoopIterVarPrivate, 2737 PDSA_LoopIterVarLinear, 2738 PDSA_LoopIterVarLastprivate, 2739 PDSA_ConstVarShared, 2740 PDSA_GlobalVarShared, 2741 PDSA_TaskVarFirstprivate, 2742 PDSA_LocalVarPrivate, 2743 PDSA_Implicit 2744 } Reason = PDSA_Implicit; 2745 bool ReportHint = false; 2746 auto ReportLoc = D->getLocation(); 2747 auto *VD = dyn_cast<VarDecl>(D); 2748 if (IsLoopIterVar) { 2749 if (DVar.CKind == OMPC_private) 2750 Reason = PDSA_LoopIterVarPrivate; 2751 else if (DVar.CKind == OMPC_lastprivate) 2752 Reason = PDSA_LoopIterVarLastprivate; 2753 else 2754 Reason = PDSA_LoopIterVarLinear; 2755 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2756 DVar.CKind == OMPC_firstprivate) { 2757 Reason = PDSA_TaskVarFirstprivate; 2758 ReportLoc = DVar.ImplicitDSALoc; 2759 } else if (VD && VD->isStaticLocal()) 2760 Reason = PDSA_StaticLocalVarShared; 2761 else if (VD && VD->isStaticDataMember()) 2762 Reason = PDSA_StaticMemberShared; 2763 else if (VD && VD->isFileVarDecl()) 2764 Reason = PDSA_GlobalVarShared; 2765 else if (D->getType().isConstant(SemaRef.getASTContext())) 2766 Reason = PDSA_ConstVarShared; 2767 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2768 ReportHint = true; 2769 Reason = PDSA_LocalVarPrivate; 2770 } 2771 if (Reason != PDSA_Implicit) { 2772 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2773 << Reason << ReportHint 2774 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2775 } else if (DVar.ImplicitDSALoc.isValid()) { 2776 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2777 << getOpenMPClauseName(DVar.CKind); 2778 } 2779 } 2780 2781 namespace { 2782 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2783 DSAStackTy *Stack; 2784 Sema &SemaRef; 2785 bool ErrorFound = false; 2786 CapturedStmt *CS = nullptr; 2787 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2788 llvm::SmallVector<Expr *, 4> ImplicitMap; 2789 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2790 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2791 2792 void VisitSubCaptures(OMPExecutableDirective *S) { 2793 // Check implicitly captured variables. 2794 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2795 return; 2796 visitSubCaptures(S->getInnermostCapturedStmt()); 2797 } 2798 2799 public: 2800 void VisitDeclRefExpr(DeclRefExpr *E) { 2801 if (E->isTypeDependent() || E->isValueDependent() || 2802 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2803 return; 2804 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2805 // Check the datasharing rules for the expressions in the clauses. 2806 if (!CS) { 2807 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2808 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2809 Visit(CED->getInit()); 2810 return; 2811 } 2812 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2813 // Do not analyze internal variables and do not enclose them into 2814 // implicit clauses. 2815 return; 2816 VD = VD->getCanonicalDecl(); 2817 // Skip internally declared variables. 2818 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2819 return; 2820 2821 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2822 // Check if the variable has explicit DSA set and stop analysis if it so. 2823 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2824 return; 2825 2826 // Skip internally declared static variables. 2827 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2828 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2829 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2830 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2831 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2832 return; 2833 2834 SourceLocation ELoc = E->getExprLoc(); 2835 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2836 // The default(none) clause requires that each variable that is referenced 2837 // in the construct, and does not have a predetermined data-sharing 2838 // attribute, must have its data-sharing attribute explicitly determined 2839 // by being listed in a data-sharing attribute clause. 2840 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2841 isImplicitOrExplicitTaskingRegion(DKind) && 2842 VarsWithInheritedDSA.count(VD) == 0) { 2843 VarsWithInheritedDSA[VD] = E; 2844 return; 2845 } 2846 2847 if (isOpenMPTargetExecutionDirective(DKind) && 2848 !Stack->isLoopControlVariable(VD).first) { 2849 if (!Stack->checkMappableExprComponentListsForDecl( 2850 VD, /*CurrentRegionOnly=*/true, 2851 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2852 StackComponents, 2853 OpenMPClauseKind) { 2854 // Variable is used if it has been marked as an array, array 2855 // section or the variable iself. 2856 return StackComponents.size() == 1 || 2857 std::all_of( 2858 std::next(StackComponents.rbegin()), 2859 StackComponents.rend(), 2860 [](const OMPClauseMappableExprCommon:: 2861 MappableComponent &MC) { 2862 return MC.getAssociatedDeclaration() == 2863 nullptr && 2864 (isa<OMPArraySectionExpr>( 2865 MC.getAssociatedExpression()) || 2866 isa<ArraySubscriptExpr>( 2867 MC.getAssociatedExpression())); 2868 }); 2869 })) { 2870 bool IsFirstprivate = false; 2871 // By default lambdas are captured as firstprivates. 2872 if (const auto *RD = 2873 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2874 IsFirstprivate = RD->isLambda(); 2875 IsFirstprivate = 2876 IsFirstprivate || 2877 (VD->getType().getNonReferenceType()->isScalarType() && 2878 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2879 if (IsFirstprivate) 2880 ImplicitFirstprivate.emplace_back(E); 2881 else 2882 ImplicitMap.emplace_back(E); 2883 return; 2884 } 2885 } 2886 2887 // OpenMP [2.9.3.6, Restrictions, p.2] 2888 // A list item that appears in a reduction clause of the innermost 2889 // enclosing worksharing or parallel construct may not be accessed in an 2890 // explicit task. 2891 DVar = Stack->hasInnermostDSA( 2892 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2893 [](OpenMPDirectiveKind K) { 2894 return isOpenMPParallelDirective(K) || 2895 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2896 }, 2897 /*FromParent=*/true); 2898 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2899 ErrorFound = true; 2900 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2901 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2902 return; 2903 } 2904 2905 // Define implicit data-sharing attributes for task. 2906 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2907 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2908 !Stack->isLoopControlVariable(VD).first) { 2909 ImplicitFirstprivate.push_back(E); 2910 return; 2911 } 2912 2913 // Store implicitly used globals with declare target link for parent 2914 // target. 2915 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2916 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2917 Stack->addToParentTargetRegionLinkGlobals(E); 2918 return; 2919 } 2920 } 2921 } 2922 void VisitMemberExpr(MemberExpr *E) { 2923 if (E->isTypeDependent() || E->isValueDependent() || 2924 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2925 return; 2926 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2927 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2928 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2929 if (!FD) 2930 return; 2931 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2932 // Check if the variable has explicit DSA set and stop analysis if it 2933 // so. 2934 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2935 return; 2936 2937 if (isOpenMPTargetExecutionDirective(DKind) && 2938 !Stack->isLoopControlVariable(FD).first && 2939 !Stack->checkMappableExprComponentListsForDecl( 2940 FD, /*CurrentRegionOnly=*/true, 2941 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2942 StackComponents, 2943 OpenMPClauseKind) { 2944 return isa<CXXThisExpr>( 2945 cast<MemberExpr>( 2946 StackComponents.back().getAssociatedExpression()) 2947 ->getBase() 2948 ->IgnoreParens()); 2949 })) { 2950 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2951 // A bit-field cannot appear in a map clause. 2952 // 2953 if (FD->isBitField()) 2954 return; 2955 2956 // Check to see if the member expression is referencing a class that 2957 // has already been explicitly mapped 2958 if (Stack->isClassPreviouslyMapped(TE->getType())) 2959 return; 2960 2961 ImplicitMap.emplace_back(E); 2962 return; 2963 } 2964 2965 SourceLocation ELoc = E->getExprLoc(); 2966 // OpenMP [2.9.3.6, Restrictions, p.2] 2967 // A list item that appears in a reduction clause of the innermost 2968 // enclosing worksharing or parallel construct may not be accessed in 2969 // an explicit task. 2970 DVar = Stack->hasInnermostDSA( 2971 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2972 [](OpenMPDirectiveKind K) { 2973 return isOpenMPParallelDirective(K) || 2974 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2975 }, 2976 /*FromParent=*/true); 2977 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2978 ErrorFound = true; 2979 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2980 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2981 return; 2982 } 2983 2984 // Define implicit data-sharing attributes for task. 2985 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2986 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2987 !Stack->isLoopControlVariable(FD).first) { 2988 // Check if there is a captured expression for the current field in the 2989 // region. Do not mark it as firstprivate unless there is no captured 2990 // expression. 2991 // TODO: try to make it firstprivate. 2992 if (DVar.CKind != OMPC_unknown) 2993 ImplicitFirstprivate.push_back(E); 2994 } 2995 return; 2996 } 2997 if (isOpenMPTargetExecutionDirective(DKind)) { 2998 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2999 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3000 /*NoDiagnose=*/true)) 3001 return; 3002 const auto *VD = cast<ValueDecl>( 3003 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3004 if (!Stack->checkMappableExprComponentListsForDecl( 3005 VD, /*CurrentRegionOnly=*/true, 3006 [&CurComponents]( 3007 OMPClauseMappableExprCommon::MappableExprComponentListRef 3008 StackComponents, 3009 OpenMPClauseKind) { 3010 auto CCI = CurComponents.rbegin(); 3011 auto CCE = CurComponents.rend(); 3012 for (const auto &SC : llvm::reverse(StackComponents)) { 3013 // Do both expressions have the same kind? 3014 if (CCI->getAssociatedExpression()->getStmtClass() != 3015 SC.getAssociatedExpression()->getStmtClass()) 3016 if (!(isa<OMPArraySectionExpr>( 3017 SC.getAssociatedExpression()) && 3018 isa<ArraySubscriptExpr>( 3019 CCI->getAssociatedExpression()))) 3020 return false; 3021 3022 const Decl *CCD = CCI->getAssociatedDeclaration(); 3023 const Decl *SCD = SC.getAssociatedDeclaration(); 3024 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3025 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3026 if (SCD != CCD) 3027 return false; 3028 std::advance(CCI, 1); 3029 if (CCI == CCE) 3030 break; 3031 } 3032 return true; 3033 })) { 3034 Visit(E->getBase()); 3035 } 3036 } else { 3037 Visit(E->getBase()); 3038 } 3039 } 3040 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3041 for (OMPClause *C : S->clauses()) { 3042 // Skip analysis of arguments of implicitly defined firstprivate clause 3043 // for task|target directives. 3044 // Skip analysis of arguments of implicitly defined map clause for target 3045 // directives. 3046 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3047 C->isImplicit())) { 3048 for (Stmt *CC : C->children()) { 3049 if (CC) 3050 Visit(CC); 3051 } 3052 } 3053 } 3054 // Check implicitly captured variables. 3055 VisitSubCaptures(S); 3056 } 3057 void VisitStmt(Stmt *S) { 3058 for (Stmt *C : S->children()) { 3059 if (C) { 3060 // Check implicitly captured variables in the task-based directives to 3061 // check if they must be firstprivatized. 3062 Visit(C); 3063 } 3064 } 3065 } 3066 3067 void visitSubCaptures(CapturedStmt *S) { 3068 for (const CapturedStmt::Capture &Cap : S->captures()) { 3069 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3070 continue; 3071 VarDecl *VD = Cap.getCapturedVar(); 3072 // Do not try to map the variable if it or its sub-component was mapped 3073 // already. 3074 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3075 Stack->checkMappableExprComponentListsForDecl( 3076 VD, /*CurrentRegionOnly=*/true, 3077 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3078 OpenMPClauseKind) { return true; })) 3079 continue; 3080 DeclRefExpr *DRE = buildDeclRefExpr( 3081 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3082 Cap.getLocation(), /*RefersToCapture=*/true); 3083 Visit(DRE); 3084 } 3085 } 3086 bool isErrorFound() const { return ErrorFound; } 3087 ArrayRef<Expr *> getImplicitFirstprivate() const { 3088 return ImplicitFirstprivate; 3089 } 3090 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 3091 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3092 return VarsWithInheritedDSA; 3093 } 3094 3095 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3096 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3097 // Process declare target link variables for the target directives. 3098 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3099 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3100 Visit(E); 3101 } 3102 } 3103 }; 3104 } // namespace 3105 3106 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3107 switch (DKind) { 3108 case OMPD_parallel: 3109 case OMPD_parallel_for: 3110 case OMPD_parallel_for_simd: 3111 case OMPD_parallel_sections: 3112 case OMPD_teams: 3113 case OMPD_teams_distribute: 3114 case OMPD_teams_distribute_simd: { 3115 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3116 QualType KmpInt32PtrTy = 3117 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3118 Sema::CapturedParamNameType Params[] = { 3119 std::make_pair(".global_tid.", KmpInt32PtrTy), 3120 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3121 std::make_pair(StringRef(), QualType()) // __context with shared vars 3122 }; 3123 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3124 Params); 3125 break; 3126 } 3127 case OMPD_target_teams: 3128 case OMPD_target_parallel: 3129 case OMPD_target_parallel_for: 3130 case OMPD_target_parallel_for_simd: 3131 case OMPD_target_teams_distribute: 3132 case OMPD_target_teams_distribute_simd: { 3133 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3134 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3135 QualType KmpInt32PtrTy = 3136 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3137 QualType Args[] = {VoidPtrTy}; 3138 FunctionProtoType::ExtProtoInfo EPI; 3139 EPI.Variadic = true; 3140 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3141 Sema::CapturedParamNameType Params[] = { 3142 std::make_pair(".global_tid.", KmpInt32Ty), 3143 std::make_pair(".part_id.", KmpInt32PtrTy), 3144 std::make_pair(".privates.", VoidPtrTy), 3145 std::make_pair( 3146 ".copy_fn.", 3147 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3148 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3149 std::make_pair(StringRef(), QualType()) // __context with shared vars 3150 }; 3151 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3152 Params, /*OpenMPCaptureLevel=*/0); 3153 // Mark this captured region as inlined, because we don't use outlined 3154 // function directly. 3155 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3156 AlwaysInlineAttr::CreateImplicit( 3157 Context, {}, AttributeCommonInfo::AS_Keyword, 3158 AlwaysInlineAttr::Keyword_forceinline)); 3159 Sema::CapturedParamNameType ParamsTarget[] = { 3160 std::make_pair(StringRef(), QualType()) // __context with shared vars 3161 }; 3162 // Start a captured region for 'target' with no implicit parameters. 3163 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3164 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3165 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3166 std::make_pair(".global_tid.", KmpInt32PtrTy), 3167 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3168 std::make_pair(StringRef(), QualType()) // __context with shared vars 3169 }; 3170 // Start a captured region for 'teams' or 'parallel'. Both regions have 3171 // the same implicit parameters. 3172 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3173 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3174 break; 3175 } 3176 case OMPD_target: 3177 case OMPD_target_simd: { 3178 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3179 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3180 QualType KmpInt32PtrTy = 3181 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3182 QualType Args[] = {VoidPtrTy}; 3183 FunctionProtoType::ExtProtoInfo EPI; 3184 EPI.Variadic = true; 3185 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3186 Sema::CapturedParamNameType Params[] = { 3187 std::make_pair(".global_tid.", KmpInt32Ty), 3188 std::make_pair(".part_id.", KmpInt32PtrTy), 3189 std::make_pair(".privates.", VoidPtrTy), 3190 std::make_pair( 3191 ".copy_fn.", 3192 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3193 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3194 std::make_pair(StringRef(), QualType()) // __context with shared vars 3195 }; 3196 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3197 Params, /*OpenMPCaptureLevel=*/0); 3198 // Mark this captured region as inlined, because we don't use outlined 3199 // function directly. 3200 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3201 AlwaysInlineAttr::CreateImplicit( 3202 Context, {}, AttributeCommonInfo::AS_Keyword, 3203 AlwaysInlineAttr::Keyword_forceinline)); 3204 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3205 std::make_pair(StringRef(), QualType()), 3206 /*OpenMPCaptureLevel=*/1); 3207 break; 3208 } 3209 case OMPD_simd: 3210 case OMPD_for: 3211 case OMPD_for_simd: 3212 case OMPD_sections: 3213 case OMPD_section: 3214 case OMPD_single: 3215 case OMPD_master: 3216 case OMPD_critical: 3217 case OMPD_taskgroup: 3218 case OMPD_distribute: 3219 case OMPD_distribute_simd: 3220 case OMPD_ordered: 3221 case OMPD_atomic: 3222 case OMPD_target_data: { 3223 Sema::CapturedParamNameType Params[] = { 3224 std::make_pair(StringRef(), QualType()) // __context with shared vars 3225 }; 3226 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3227 Params); 3228 break; 3229 } 3230 case OMPD_task: { 3231 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3232 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3233 QualType KmpInt32PtrTy = 3234 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3235 QualType Args[] = {VoidPtrTy}; 3236 FunctionProtoType::ExtProtoInfo EPI; 3237 EPI.Variadic = true; 3238 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3239 Sema::CapturedParamNameType Params[] = { 3240 std::make_pair(".global_tid.", KmpInt32Ty), 3241 std::make_pair(".part_id.", KmpInt32PtrTy), 3242 std::make_pair(".privates.", VoidPtrTy), 3243 std::make_pair( 3244 ".copy_fn.", 3245 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3246 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3247 std::make_pair(StringRef(), QualType()) // __context with shared vars 3248 }; 3249 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3250 Params); 3251 // Mark this captured region as inlined, because we don't use outlined 3252 // function directly. 3253 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3254 AlwaysInlineAttr::CreateImplicit( 3255 Context, {}, AttributeCommonInfo::AS_Keyword, 3256 AlwaysInlineAttr::Keyword_forceinline)); 3257 break; 3258 } 3259 case OMPD_taskloop: 3260 case OMPD_taskloop_simd: { 3261 QualType KmpInt32Ty = 3262 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3263 .withConst(); 3264 QualType KmpUInt64Ty = 3265 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3266 .withConst(); 3267 QualType KmpInt64Ty = 3268 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3269 .withConst(); 3270 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3271 QualType KmpInt32PtrTy = 3272 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3273 QualType Args[] = {VoidPtrTy}; 3274 FunctionProtoType::ExtProtoInfo EPI; 3275 EPI.Variadic = true; 3276 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3277 Sema::CapturedParamNameType Params[] = { 3278 std::make_pair(".global_tid.", KmpInt32Ty), 3279 std::make_pair(".part_id.", KmpInt32PtrTy), 3280 std::make_pair(".privates.", VoidPtrTy), 3281 std::make_pair( 3282 ".copy_fn.", 3283 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3284 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3285 std::make_pair(".lb.", KmpUInt64Ty), 3286 std::make_pair(".ub.", KmpUInt64Ty), 3287 std::make_pair(".st.", KmpInt64Ty), 3288 std::make_pair(".liter.", KmpInt32Ty), 3289 std::make_pair(".reductions.", VoidPtrTy), 3290 std::make_pair(StringRef(), QualType()) // __context with shared vars 3291 }; 3292 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3293 Params); 3294 // Mark this captured region as inlined, because we don't use outlined 3295 // function directly. 3296 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3297 AlwaysInlineAttr::CreateImplicit( 3298 Context, {}, AttributeCommonInfo::AS_Keyword, 3299 AlwaysInlineAttr::Keyword_forceinline)); 3300 break; 3301 } 3302 case OMPD_distribute_parallel_for_simd: 3303 case OMPD_distribute_parallel_for: { 3304 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3305 QualType KmpInt32PtrTy = 3306 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3307 Sema::CapturedParamNameType Params[] = { 3308 std::make_pair(".global_tid.", KmpInt32PtrTy), 3309 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3310 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3311 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3312 std::make_pair(StringRef(), QualType()) // __context with shared vars 3313 }; 3314 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3315 Params); 3316 break; 3317 } 3318 case OMPD_target_teams_distribute_parallel_for: 3319 case OMPD_target_teams_distribute_parallel_for_simd: { 3320 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3321 QualType KmpInt32PtrTy = 3322 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3323 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3324 3325 QualType Args[] = {VoidPtrTy}; 3326 FunctionProtoType::ExtProtoInfo EPI; 3327 EPI.Variadic = true; 3328 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3329 Sema::CapturedParamNameType Params[] = { 3330 std::make_pair(".global_tid.", KmpInt32Ty), 3331 std::make_pair(".part_id.", KmpInt32PtrTy), 3332 std::make_pair(".privates.", VoidPtrTy), 3333 std::make_pair( 3334 ".copy_fn.", 3335 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3336 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3337 std::make_pair(StringRef(), QualType()) // __context with shared vars 3338 }; 3339 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3340 Params, /*OpenMPCaptureLevel=*/0); 3341 // Mark this captured region as inlined, because we don't use outlined 3342 // function directly. 3343 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3344 AlwaysInlineAttr::CreateImplicit( 3345 Context, {}, AttributeCommonInfo::AS_Keyword, 3346 AlwaysInlineAttr::Keyword_forceinline)); 3347 Sema::CapturedParamNameType ParamsTarget[] = { 3348 std::make_pair(StringRef(), QualType()) // __context with shared vars 3349 }; 3350 // Start a captured region for 'target' with no implicit parameters. 3351 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3352 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3353 3354 Sema::CapturedParamNameType ParamsTeams[] = { 3355 std::make_pair(".global_tid.", KmpInt32PtrTy), 3356 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3357 std::make_pair(StringRef(), QualType()) // __context with shared vars 3358 }; 3359 // Start a captured region for 'target' with no implicit parameters. 3360 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3361 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3362 3363 Sema::CapturedParamNameType ParamsParallel[] = { 3364 std::make_pair(".global_tid.", KmpInt32PtrTy), 3365 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3366 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3367 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3368 std::make_pair(StringRef(), QualType()) // __context with shared vars 3369 }; 3370 // Start a captured region for 'teams' or 'parallel'. Both regions have 3371 // the same implicit parameters. 3372 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3373 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3374 break; 3375 } 3376 3377 case OMPD_teams_distribute_parallel_for: 3378 case OMPD_teams_distribute_parallel_for_simd: { 3379 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3380 QualType KmpInt32PtrTy = 3381 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3382 3383 Sema::CapturedParamNameType ParamsTeams[] = { 3384 std::make_pair(".global_tid.", KmpInt32PtrTy), 3385 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3386 std::make_pair(StringRef(), QualType()) // __context with shared vars 3387 }; 3388 // Start a captured region for 'target' with no implicit parameters. 3389 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3390 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3391 3392 Sema::CapturedParamNameType ParamsParallel[] = { 3393 std::make_pair(".global_tid.", KmpInt32PtrTy), 3394 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3395 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3396 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3397 std::make_pair(StringRef(), QualType()) // __context with shared vars 3398 }; 3399 // Start a captured region for 'teams' or 'parallel'. Both regions have 3400 // the same implicit parameters. 3401 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3402 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3403 break; 3404 } 3405 case OMPD_target_update: 3406 case OMPD_target_enter_data: 3407 case OMPD_target_exit_data: { 3408 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3409 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3410 QualType KmpInt32PtrTy = 3411 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3412 QualType Args[] = {VoidPtrTy}; 3413 FunctionProtoType::ExtProtoInfo EPI; 3414 EPI.Variadic = true; 3415 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3416 Sema::CapturedParamNameType Params[] = { 3417 std::make_pair(".global_tid.", KmpInt32Ty), 3418 std::make_pair(".part_id.", KmpInt32PtrTy), 3419 std::make_pair(".privates.", VoidPtrTy), 3420 std::make_pair( 3421 ".copy_fn.", 3422 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3423 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3424 std::make_pair(StringRef(), QualType()) // __context with shared vars 3425 }; 3426 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3427 Params); 3428 // Mark this captured region as inlined, because we don't use outlined 3429 // function directly. 3430 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3431 AlwaysInlineAttr::CreateImplicit( 3432 Context, {}, AttributeCommonInfo::AS_Keyword, 3433 AlwaysInlineAttr::Keyword_forceinline)); 3434 break; 3435 } 3436 case OMPD_threadprivate: 3437 case OMPD_allocate: 3438 case OMPD_taskyield: 3439 case OMPD_barrier: 3440 case OMPD_taskwait: 3441 case OMPD_cancellation_point: 3442 case OMPD_cancel: 3443 case OMPD_flush: 3444 case OMPD_declare_reduction: 3445 case OMPD_declare_mapper: 3446 case OMPD_declare_simd: 3447 case OMPD_declare_target: 3448 case OMPD_end_declare_target: 3449 case OMPD_requires: 3450 llvm_unreachable("OpenMP Directive is not allowed"); 3451 case OMPD_unknown: 3452 llvm_unreachable("Unknown OpenMP directive"); 3453 } 3454 } 3455 3456 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3457 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3458 getOpenMPCaptureRegions(CaptureRegions, DKind); 3459 return CaptureRegions.size(); 3460 } 3461 3462 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3463 Expr *CaptureExpr, bool WithInit, 3464 bool AsExpression) { 3465 assert(CaptureExpr); 3466 ASTContext &C = S.getASTContext(); 3467 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3468 QualType Ty = Init->getType(); 3469 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3470 if (S.getLangOpts().CPlusPlus) { 3471 Ty = C.getLValueReferenceType(Ty); 3472 } else { 3473 Ty = C.getPointerType(Ty); 3474 ExprResult Res = 3475 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3476 if (!Res.isUsable()) 3477 return nullptr; 3478 Init = Res.get(); 3479 } 3480 WithInit = true; 3481 } 3482 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3483 CaptureExpr->getBeginLoc()); 3484 if (!WithInit) 3485 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3486 S.CurContext->addHiddenDecl(CED); 3487 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3488 return CED; 3489 } 3490 3491 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3492 bool WithInit) { 3493 OMPCapturedExprDecl *CD; 3494 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3495 CD = cast<OMPCapturedExprDecl>(VD); 3496 else 3497 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3498 /*AsExpression=*/false); 3499 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3500 CaptureExpr->getExprLoc()); 3501 } 3502 3503 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3504 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3505 if (!Ref) { 3506 OMPCapturedExprDecl *CD = buildCaptureDecl( 3507 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3508 /*WithInit=*/true, /*AsExpression=*/true); 3509 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3510 CaptureExpr->getExprLoc()); 3511 } 3512 ExprResult Res = Ref; 3513 if (!S.getLangOpts().CPlusPlus && 3514 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3515 Ref->getType()->isPointerType()) { 3516 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3517 if (!Res.isUsable()) 3518 return ExprError(); 3519 } 3520 return S.DefaultLvalueConversion(Res.get()); 3521 } 3522 3523 namespace { 3524 // OpenMP directives parsed in this section are represented as a 3525 // CapturedStatement with an associated statement. If a syntax error 3526 // is detected during the parsing of the associated statement, the 3527 // compiler must abort processing and close the CapturedStatement. 3528 // 3529 // Combined directives such as 'target parallel' have more than one 3530 // nested CapturedStatements. This RAII ensures that we unwind out 3531 // of all the nested CapturedStatements when an error is found. 3532 class CaptureRegionUnwinderRAII { 3533 private: 3534 Sema &S; 3535 bool &ErrorFound; 3536 OpenMPDirectiveKind DKind = OMPD_unknown; 3537 3538 public: 3539 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3540 OpenMPDirectiveKind DKind) 3541 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3542 ~CaptureRegionUnwinderRAII() { 3543 if (ErrorFound) { 3544 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3545 while (--ThisCaptureLevel >= 0) 3546 S.ActOnCapturedRegionError(); 3547 } 3548 } 3549 }; 3550 } // namespace 3551 3552 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3553 // Capture variables captured by reference in lambdas for target-based 3554 // directives. 3555 if (!CurContext->isDependentContext() && 3556 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3557 isOpenMPTargetDataManagementDirective( 3558 DSAStack->getCurrentDirective()))) { 3559 QualType Type = V->getType(); 3560 if (const auto *RD = Type.getCanonicalType() 3561 .getNonReferenceType() 3562 ->getAsCXXRecordDecl()) { 3563 bool SavedForceCaptureByReferenceInTargetExecutable = 3564 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3565 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3566 /*V=*/true); 3567 if (RD->isLambda()) { 3568 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3569 FieldDecl *ThisCapture; 3570 RD->getCaptureFields(Captures, ThisCapture); 3571 for (const LambdaCapture &LC : RD->captures()) { 3572 if (LC.getCaptureKind() == LCK_ByRef) { 3573 VarDecl *VD = LC.getCapturedVar(); 3574 DeclContext *VDC = VD->getDeclContext(); 3575 if (!VDC->Encloses(CurContext)) 3576 continue; 3577 MarkVariableReferenced(LC.getLocation(), VD); 3578 } else if (LC.getCaptureKind() == LCK_This) { 3579 QualType ThisTy = getCurrentThisType(); 3580 if (!ThisTy.isNull() && 3581 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3582 CheckCXXThisCapture(LC.getLocation()); 3583 } 3584 } 3585 } 3586 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3587 SavedForceCaptureByReferenceInTargetExecutable); 3588 } 3589 } 3590 } 3591 3592 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3593 ArrayRef<OMPClause *> Clauses) { 3594 bool ErrorFound = false; 3595 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3596 *this, ErrorFound, DSAStack->getCurrentDirective()); 3597 if (!S.isUsable()) { 3598 ErrorFound = true; 3599 return StmtError(); 3600 } 3601 3602 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3603 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3604 OMPOrderedClause *OC = nullptr; 3605 OMPScheduleClause *SC = nullptr; 3606 SmallVector<const OMPLinearClause *, 4> LCs; 3607 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3608 // This is required for proper codegen. 3609 for (OMPClause *Clause : Clauses) { 3610 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3611 Clause->getClauseKind() == OMPC_in_reduction) { 3612 // Capture taskgroup task_reduction descriptors inside the tasking regions 3613 // with the corresponding in_reduction items. 3614 auto *IRC = cast<OMPInReductionClause>(Clause); 3615 for (Expr *E : IRC->taskgroup_descriptors()) 3616 if (E) 3617 MarkDeclarationsReferencedInExpr(E); 3618 } 3619 if (isOpenMPPrivate(Clause->getClauseKind()) || 3620 Clause->getClauseKind() == OMPC_copyprivate || 3621 (getLangOpts().OpenMPUseTLS && 3622 getASTContext().getTargetInfo().isTLSSupported() && 3623 Clause->getClauseKind() == OMPC_copyin)) { 3624 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3625 // Mark all variables in private list clauses as used in inner region. 3626 for (Stmt *VarRef : Clause->children()) { 3627 if (auto *E = cast_or_null<Expr>(VarRef)) { 3628 MarkDeclarationsReferencedInExpr(E); 3629 } 3630 } 3631 DSAStack->setForceVarCapturing(/*V=*/false); 3632 } else if (CaptureRegions.size() > 1 || 3633 CaptureRegions.back() != OMPD_unknown) { 3634 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3635 PICs.push_back(C); 3636 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3637 if (Expr *E = C->getPostUpdateExpr()) 3638 MarkDeclarationsReferencedInExpr(E); 3639 } 3640 } 3641 if (Clause->getClauseKind() == OMPC_schedule) 3642 SC = cast<OMPScheduleClause>(Clause); 3643 else if (Clause->getClauseKind() == OMPC_ordered) 3644 OC = cast<OMPOrderedClause>(Clause); 3645 else if (Clause->getClauseKind() == OMPC_linear) 3646 LCs.push_back(cast<OMPLinearClause>(Clause)); 3647 } 3648 // OpenMP, 2.7.1 Loop Construct, Restrictions 3649 // The nonmonotonic modifier cannot be specified if an ordered clause is 3650 // specified. 3651 if (SC && 3652 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3653 SC->getSecondScheduleModifier() == 3654 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3655 OC) { 3656 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3657 ? SC->getFirstScheduleModifierLoc() 3658 : SC->getSecondScheduleModifierLoc(), 3659 diag::err_omp_schedule_nonmonotonic_ordered) 3660 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3661 ErrorFound = true; 3662 } 3663 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3664 for (const OMPLinearClause *C : LCs) { 3665 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3666 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3667 } 3668 ErrorFound = true; 3669 } 3670 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3671 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3672 OC->getNumForLoops()) { 3673 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3674 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3675 ErrorFound = true; 3676 } 3677 if (ErrorFound) { 3678 return StmtError(); 3679 } 3680 StmtResult SR = S; 3681 unsigned CompletedRegions = 0; 3682 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3683 // Mark all variables in private list clauses as used in inner region. 3684 // Required for proper codegen of combined directives. 3685 // TODO: add processing for other clauses. 3686 if (ThisCaptureRegion != OMPD_unknown) { 3687 for (const clang::OMPClauseWithPreInit *C : PICs) { 3688 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3689 // Find the particular capture region for the clause if the 3690 // directive is a combined one with multiple capture regions. 3691 // If the directive is not a combined one, the capture region 3692 // associated with the clause is OMPD_unknown and is generated 3693 // only once. 3694 if (CaptureRegion == ThisCaptureRegion || 3695 CaptureRegion == OMPD_unknown) { 3696 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3697 for (Decl *D : DS->decls()) 3698 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3699 } 3700 } 3701 } 3702 } 3703 if (++CompletedRegions == CaptureRegions.size()) 3704 DSAStack->setBodyComplete(); 3705 SR = ActOnCapturedRegionEnd(SR.get()); 3706 } 3707 return SR; 3708 } 3709 3710 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3711 OpenMPDirectiveKind CancelRegion, 3712 SourceLocation StartLoc) { 3713 // CancelRegion is only needed for cancel and cancellation_point. 3714 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3715 return false; 3716 3717 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3718 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3719 return false; 3720 3721 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3722 << getOpenMPDirectiveName(CancelRegion); 3723 return true; 3724 } 3725 3726 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3727 OpenMPDirectiveKind CurrentRegion, 3728 const DeclarationNameInfo &CurrentName, 3729 OpenMPDirectiveKind CancelRegion, 3730 SourceLocation StartLoc) { 3731 if (Stack->getCurScope()) { 3732 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3733 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3734 bool NestingProhibited = false; 3735 bool CloseNesting = true; 3736 bool OrphanSeen = false; 3737 enum { 3738 NoRecommend, 3739 ShouldBeInParallelRegion, 3740 ShouldBeInOrderedRegion, 3741 ShouldBeInTargetRegion, 3742 ShouldBeInTeamsRegion 3743 } Recommend = NoRecommend; 3744 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3745 // OpenMP [2.16, Nesting of Regions] 3746 // OpenMP constructs may not be nested inside a simd region. 3747 // OpenMP [2.8.1,simd Construct, Restrictions] 3748 // An ordered construct with the simd clause is the only OpenMP 3749 // construct that can appear in the simd region. 3750 // Allowing a SIMD construct nested in another SIMD construct is an 3751 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3752 // message. 3753 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3754 ? diag::err_omp_prohibited_region_simd 3755 : diag::warn_omp_nesting_simd); 3756 return CurrentRegion != OMPD_simd; 3757 } 3758 if (ParentRegion == OMPD_atomic) { 3759 // OpenMP [2.16, Nesting of Regions] 3760 // OpenMP constructs may not be nested inside an atomic region. 3761 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3762 return true; 3763 } 3764 if (CurrentRegion == OMPD_section) { 3765 // OpenMP [2.7.2, sections Construct, Restrictions] 3766 // Orphaned section directives are prohibited. That is, the section 3767 // directives must appear within the sections construct and must not be 3768 // encountered elsewhere in the sections region. 3769 if (ParentRegion != OMPD_sections && 3770 ParentRegion != OMPD_parallel_sections) { 3771 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3772 << (ParentRegion != OMPD_unknown) 3773 << getOpenMPDirectiveName(ParentRegion); 3774 return true; 3775 } 3776 return false; 3777 } 3778 // Allow some constructs (except teams and cancellation constructs) to be 3779 // orphaned (they could be used in functions, called from OpenMP regions 3780 // with the required preconditions). 3781 if (ParentRegion == OMPD_unknown && 3782 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3783 CurrentRegion != OMPD_cancellation_point && 3784 CurrentRegion != OMPD_cancel) 3785 return false; 3786 if (CurrentRegion == OMPD_cancellation_point || 3787 CurrentRegion == OMPD_cancel) { 3788 // OpenMP [2.16, Nesting of Regions] 3789 // A cancellation point construct for which construct-type-clause is 3790 // taskgroup must be nested inside a task construct. A cancellation 3791 // point construct for which construct-type-clause is not taskgroup must 3792 // be closely nested inside an OpenMP construct that matches the type 3793 // specified in construct-type-clause. 3794 // A cancel construct for which construct-type-clause is taskgroup must be 3795 // nested inside a task construct. A cancel construct for which 3796 // construct-type-clause is not taskgroup must be closely nested inside an 3797 // OpenMP construct that matches the type specified in 3798 // construct-type-clause. 3799 NestingProhibited = 3800 !((CancelRegion == OMPD_parallel && 3801 (ParentRegion == OMPD_parallel || 3802 ParentRegion == OMPD_target_parallel)) || 3803 (CancelRegion == OMPD_for && 3804 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3805 ParentRegion == OMPD_target_parallel_for || 3806 ParentRegion == OMPD_distribute_parallel_for || 3807 ParentRegion == OMPD_teams_distribute_parallel_for || 3808 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3809 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3810 (CancelRegion == OMPD_sections && 3811 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3812 ParentRegion == OMPD_parallel_sections))); 3813 OrphanSeen = ParentRegion == OMPD_unknown; 3814 } else if (CurrentRegion == OMPD_master) { 3815 // OpenMP [2.16, Nesting of Regions] 3816 // A master region may not be closely nested inside a worksharing, 3817 // atomic, or explicit task region. 3818 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3819 isOpenMPTaskingDirective(ParentRegion); 3820 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3821 // OpenMP [2.16, Nesting of Regions] 3822 // A critical region may not be nested (closely or otherwise) inside a 3823 // critical region with the same name. Note that this restriction is not 3824 // sufficient to prevent deadlock. 3825 SourceLocation PreviousCriticalLoc; 3826 bool DeadLock = Stack->hasDirective( 3827 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3828 const DeclarationNameInfo &DNI, 3829 SourceLocation Loc) { 3830 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3831 PreviousCriticalLoc = Loc; 3832 return true; 3833 } 3834 return false; 3835 }, 3836 false /* skip top directive */); 3837 if (DeadLock) { 3838 SemaRef.Diag(StartLoc, 3839 diag::err_omp_prohibited_region_critical_same_name) 3840 << CurrentName.getName(); 3841 if (PreviousCriticalLoc.isValid()) 3842 SemaRef.Diag(PreviousCriticalLoc, 3843 diag::note_omp_previous_critical_region); 3844 return true; 3845 } 3846 } else if (CurrentRegion == OMPD_barrier) { 3847 // OpenMP [2.16, Nesting of Regions] 3848 // A barrier region may not be closely nested inside a worksharing, 3849 // explicit task, critical, ordered, atomic, or master region. 3850 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3851 isOpenMPTaskingDirective(ParentRegion) || 3852 ParentRegion == OMPD_master || 3853 ParentRegion == OMPD_critical || 3854 ParentRegion == OMPD_ordered; 3855 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3856 !isOpenMPParallelDirective(CurrentRegion) && 3857 !isOpenMPTeamsDirective(CurrentRegion)) { 3858 // OpenMP [2.16, Nesting of Regions] 3859 // A worksharing region may not be closely nested inside a worksharing, 3860 // explicit task, critical, ordered, atomic, or master region. 3861 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3862 isOpenMPTaskingDirective(ParentRegion) || 3863 ParentRegion == OMPD_master || 3864 ParentRegion == OMPD_critical || 3865 ParentRegion == OMPD_ordered; 3866 Recommend = ShouldBeInParallelRegion; 3867 } else if (CurrentRegion == OMPD_ordered) { 3868 // OpenMP [2.16, Nesting of Regions] 3869 // An ordered region may not be closely nested inside a critical, 3870 // atomic, or explicit task region. 3871 // An ordered region must be closely nested inside a loop region (or 3872 // parallel loop region) with an ordered clause. 3873 // OpenMP [2.8.1,simd Construct, Restrictions] 3874 // An ordered construct with the simd clause is the only OpenMP construct 3875 // that can appear in the simd region. 3876 NestingProhibited = ParentRegion == OMPD_critical || 3877 isOpenMPTaskingDirective(ParentRegion) || 3878 !(isOpenMPSimdDirective(ParentRegion) || 3879 Stack->isParentOrderedRegion()); 3880 Recommend = ShouldBeInOrderedRegion; 3881 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3882 // OpenMP [2.16, Nesting of Regions] 3883 // If specified, a teams construct must be contained within a target 3884 // construct. 3885 NestingProhibited = 3886 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 3887 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 3888 ParentRegion != OMPD_target); 3889 OrphanSeen = ParentRegion == OMPD_unknown; 3890 Recommend = ShouldBeInTargetRegion; 3891 } 3892 if (!NestingProhibited && 3893 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3894 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3895 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3896 // OpenMP [2.16, Nesting of Regions] 3897 // distribute, parallel, parallel sections, parallel workshare, and the 3898 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3899 // constructs that can be closely nested in the teams region. 3900 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3901 !isOpenMPDistributeDirective(CurrentRegion); 3902 Recommend = ShouldBeInParallelRegion; 3903 } 3904 if (!NestingProhibited && 3905 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3906 // OpenMP 4.5 [2.17 Nesting of Regions] 3907 // The region associated with the distribute construct must be strictly 3908 // nested inside a teams region 3909 NestingProhibited = 3910 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3911 Recommend = ShouldBeInTeamsRegion; 3912 } 3913 if (!NestingProhibited && 3914 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3915 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3916 // OpenMP 4.5 [2.17 Nesting of Regions] 3917 // If a target, target update, target data, target enter data, or 3918 // target exit data construct is encountered during execution of a 3919 // target region, the behavior is unspecified. 3920 NestingProhibited = Stack->hasDirective( 3921 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3922 SourceLocation) { 3923 if (isOpenMPTargetExecutionDirective(K)) { 3924 OffendingRegion = K; 3925 return true; 3926 } 3927 return false; 3928 }, 3929 false /* don't skip top directive */); 3930 CloseNesting = false; 3931 } 3932 if (NestingProhibited) { 3933 if (OrphanSeen) { 3934 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3935 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3936 } else { 3937 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3938 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3939 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3940 } 3941 return true; 3942 } 3943 } 3944 return false; 3945 } 3946 3947 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3948 ArrayRef<OMPClause *> Clauses, 3949 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3950 bool ErrorFound = false; 3951 unsigned NamedModifiersNumber = 0; 3952 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3953 OMPD_unknown + 1); 3954 SmallVector<SourceLocation, 4> NameModifierLoc; 3955 for (const OMPClause *C : Clauses) { 3956 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3957 // At most one if clause without a directive-name-modifier can appear on 3958 // the directive. 3959 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3960 if (FoundNameModifiers[CurNM]) { 3961 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3962 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3963 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3964 ErrorFound = true; 3965 } else if (CurNM != OMPD_unknown) { 3966 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3967 ++NamedModifiersNumber; 3968 } 3969 FoundNameModifiers[CurNM] = IC; 3970 if (CurNM == OMPD_unknown) 3971 continue; 3972 // Check if the specified name modifier is allowed for the current 3973 // directive. 3974 // At most one if clause with the particular directive-name-modifier can 3975 // appear on the directive. 3976 bool MatchFound = false; 3977 for (auto NM : AllowedNameModifiers) { 3978 if (CurNM == NM) { 3979 MatchFound = true; 3980 break; 3981 } 3982 } 3983 if (!MatchFound) { 3984 S.Diag(IC->getNameModifierLoc(), 3985 diag::err_omp_wrong_if_directive_name_modifier) 3986 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3987 ErrorFound = true; 3988 } 3989 } 3990 } 3991 // If any if clause on the directive includes a directive-name-modifier then 3992 // all if clauses on the directive must include a directive-name-modifier. 3993 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3994 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3995 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3996 diag::err_omp_no_more_if_clause); 3997 } else { 3998 std::string Values; 3999 std::string Sep(", "); 4000 unsigned AllowedCnt = 0; 4001 unsigned TotalAllowedNum = 4002 AllowedNameModifiers.size() - NamedModifiersNumber; 4003 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4004 ++Cnt) { 4005 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4006 if (!FoundNameModifiers[NM]) { 4007 Values += "'"; 4008 Values += getOpenMPDirectiveName(NM); 4009 Values += "'"; 4010 if (AllowedCnt + 2 == TotalAllowedNum) 4011 Values += " or "; 4012 else if (AllowedCnt + 1 != TotalAllowedNum) 4013 Values += Sep; 4014 ++AllowedCnt; 4015 } 4016 } 4017 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4018 diag::err_omp_unnamed_if_clause) 4019 << (TotalAllowedNum > 1) << Values; 4020 } 4021 for (SourceLocation Loc : NameModifierLoc) { 4022 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4023 } 4024 ErrorFound = true; 4025 } 4026 return ErrorFound; 4027 } 4028 4029 static std::pair<ValueDecl *, bool> 4030 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4031 SourceRange &ERange, bool AllowArraySection = false) { 4032 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4033 RefExpr->containsUnexpandedParameterPack()) 4034 return std::make_pair(nullptr, true); 4035 4036 // OpenMP [3.1, C/C++] 4037 // A list item is a variable name. 4038 // OpenMP [2.9.3.3, Restrictions, p.1] 4039 // A variable that is part of another variable (as an array or 4040 // structure element) cannot appear in a private clause. 4041 RefExpr = RefExpr->IgnoreParens(); 4042 enum { 4043 NoArrayExpr = -1, 4044 ArraySubscript = 0, 4045 OMPArraySection = 1 4046 } IsArrayExpr = NoArrayExpr; 4047 if (AllowArraySection) { 4048 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4049 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4050 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4051 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4052 RefExpr = Base; 4053 IsArrayExpr = ArraySubscript; 4054 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4055 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4056 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4057 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4058 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4059 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4060 RefExpr = Base; 4061 IsArrayExpr = OMPArraySection; 4062 } 4063 } 4064 ELoc = RefExpr->getExprLoc(); 4065 ERange = RefExpr->getSourceRange(); 4066 RefExpr = RefExpr->IgnoreParenImpCasts(); 4067 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4068 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4069 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4070 (S.getCurrentThisType().isNull() || !ME || 4071 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4072 !isa<FieldDecl>(ME->getMemberDecl()))) { 4073 if (IsArrayExpr != NoArrayExpr) { 4074 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4075 << ERange; 4076 } else { 4077 S.Diag(ELoc, 4078 AllowArraySection 4079 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4080 : diag::err_omp_expected_var_name_member_expr) 4081 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4082 } 4083 return std::make_pair(nullptr, false); 4084 } 4085 return std::make_pair( 4086 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4087 } 4088 4089 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4090 ArrayRef<OMPClause *> Clauses) { 4091 assert(!S.CurContext->isDependentContext() && 4092 "Expected non-dependent context."); 4093 auto AllocateRange = 4094 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4095 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4096 DeclToCopy; 4097 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4098 return isOpenMPPrivate(C->getClauseKind()); 4099 }); 4100 for (OMPClause *Cl : PrivateRange) { 4101 MutableArrayRef<Expr *>::iterator I, It, Et; 4102 if (Cl->getClauseKind() == OMPC_private) { 4103 auto *PC = cast<OMPPrivateClause>(Cl); 4104 I = PC->private_copies().begin(); 4105 It = PC->varlist_begin(); 4106 Et = PC->varlist_end(); 4107 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4108 auto *PC = cast<OMPFirstprivateClause>(Cl); 4109 I = PC->private_copies().begin(); 4110 It = PC->varlist_begin(); 4111 Et = PC->varlist_end(); 4112 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4113 auto *PC = cast<OMPLastprivateClause>(Cl); 4114 I = PC->private_copies().begin(); 4115 It = PC->varlist_begin(); 4116 Et = PC->varlist_end(); 4117 } else if (Cl->getClauseKind() == OMPC_linear) { 4118 auto *PC = cast<OMPLinearClause>(Cl); 4119 I = PC->privates().begin(); 4120 It = PC->varlist_begin(); 4121 Et = PC->varlist_end(); 4122 } else if (Cl->getClauseKind() == OMPC_reduction) { 4123 auto *PC = cast<OMPReductionClause>(Cl); 4124 I = PC->privates().begin(); 4125 It = PC->varlist_begin(); 4126 Et = PC->varlist_end(); 4127 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4128 auto *PC = cast<OMPTaskReductionClause>(Cl); 4129 I = PC->privates().begin(); 4130 It = PC->varlist_begin(); 4131 Et = PC->varlist_end(); 4132 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4133 auto *PC = cast<OMPInReductionClause>(Cl); 4134 I = PC->privates().begin(); 4135 It = PC->varlist_begin(); 4136 Et = PC->varlist_end(); 4137 } else { 4138 llvm_unreachable("Expected private clause."); 4139 } 4140 for (Expr *E : llvm::make_range(It, Et)) { 4141 if (!*I) { 4142 ++I; 4143 continue; 4144 } 4145 SourceLocation ELoc; 4146 SourceRange ERange; 4147 Expr *SimpleRefExpr = E; 4148 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4149 /*AllowArraySection=*/true); 4150 DeclToCopy.try_emplace(Res.first, 4151 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4152 ++I; 4153 } 4154 } 4155 for (OMPClause *C : AllocateRange) { 4156 auto *AC = cast<OMPAllocateClause>(C); 4157 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4158 getAllocatorKind(S, Stack, AC->getAllocator()); 4159 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4160 // For task, taskloop or target directives, allocation requests to memory 4161 // allocators with the trait access set to thread result in unspecified 4162 // behavior. 4163 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4164 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4165 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4166 S.Diag(AC->getAllocator()->getExprLoc(), 4167 diag::warn_omp_allocate_thread_on_task_target_directive) 4168 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4169 } 4170 for (Expr *E : AC->varlists()) { 4171 SourceLocation ELoc; 4172 SourceRange ERange; 4173 Expr *SimpleRefExpr = E; 4174 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4175 ValueDecl *VD = Res.first; 4176 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4177 if (!isOpenMPPrivate(Data.CKind)) { 4178 S.Diag(E->getExprLoc(), 4179 diag::err_omp_expected_private_copy_for_allocate); 4180 continue; 4181 } 4182 VarDecl *PrivateVD = DeclToCopy[VD]; 4183 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4184 AllocatorKind, AC->getAllocator())) 4185 continue; 4186 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4187 E->getSourceRange()); 4188 } 4189 } 4190 } 4191 4192 StmtResult Sema::ActOnOpenMPExecutableDirective( 4193 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4194 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4195 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4196 StmtResult Res = StmtError(); 4197 // First check CancelRegion which is then used in checkNestingOfRegions. 4198 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4199 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4200 StartLoc)) 4201 return StmtError(); 4202 4203 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4204 VarsWithInheritedDSAType VarsWithInheritedDSA; 4205 bool ErrorFound = false; 4206 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4207 if (AStmt && !CurContext->isDependentContext()) { 4208 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4209 4210 // Check default data sharing attributes for referenced variables. 4211 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4212 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4213 Stmt *S = AStmt; 4214 while (--ThisCaptureLevel >= 0) 4215 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4216 DSAChecker.Visit(S); 4217 if (!isOpenMPTargetDataManagementDirective(Kind) && 4218 !isOpenMPTaskingDirective(Kind)) { 4219 // Visit subcaptures to generate implicit clauses for captured vars. 4220 auto *CS = cast<CapturedStmt>(AStmt); 4221 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4222 getOpenMPCaptureRegions(CaptureRegions, Kind); 4223 // Ignore outer tasking regions for target directives. 4224 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4225 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4226 DSAChecker.visitSubCaptures(CS); 4227 } 4228 if (DSAChecker.isErrorFound()) 4229 return StmtError(); 4230 // Generate list of implicitly defined firstprivate variables. 4231 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4232 4233 SmallVector<Expr *, 4> ImplicitFirstprivates( 4234 DSAChecker.getImplicitFirstprivate().begin(), 4235 DSAChecker.getImplicitFirstprivate().end()); 4236 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4237 DSAChecker.getImplicitMap().end()); 4238 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4239 for (OMPClause *C : Clauses) { 4240 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4241 for (Expr *E : IRC->taskgroup_descriptors()) 4242 if (E) 4243 ImplicitFirstprivates.emplace_back(E); 4244 } 4245 } 4246 if (!ImplicitFirstprivates.empty()) { 4247 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4248 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4249 SourceLocation())) { 4250 ClausesWithImplicit.push_back(Implicit); 4251 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4252 ImplicitFirstprivates.size(); 4253 } else { 4254 ErrorFound = true; 4255 } 4256 } 4257 if (!ImplicitMaps.empty()) { 4258 CXXScopeSpec MapperIdScopeSpec; 4259 DeclarationNameInfo MapperId; 4260 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4261 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4262 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4263 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4264 ClausesWithImplicit.emplace_back(Implicit); 4265 ErrorFound |= 4266 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4267 } else { 4268 ErrorFound = true; 4269 } 4270 } 4271 } 4272 4273 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4274 switch (Kind) { 4275 case OMPD_parallel: 4276 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4277 EndLoc); 4278 AllowedNameModifiers.push_back(OMPD_parallel); 4279 break; 4280 case OMPD_simd: 4281 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4282 VarsWithInheritedDSA); 4283 break; 4284 case OMPD_for: 4285 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4286 VarsWithInheritedDSA); 4287 break; 4288 case OMPD_for_simd: 4289 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4290 EndLoc, VarsWithInheritedDSA); 4291 break; 4292 case OMPD_sections: 4293 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4294 EndLoc); 4295 break; 4296 case OMPD_section: 4297 assert(ClausesWithImplicit.empty() && 4298 "No clauses are allowed for 'omp section' directive"); 4299 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4300 break; 4301 case OMPD_single: 4302 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4303 EndLoc); 4304 break; 4305 case OMPD_master: 4306 assert(ClausesWithImplicit.empty() && 4307 "No clauses are allowed for 'omp master' directive"); 4308 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4309 break; 4310 case OMPD_critical: 4311 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4312 StartLoc, EndLoc); 4313 break; 4314 case OMPD_parallel_for: 4315 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4316 EndLoc, VarsWithInheritedDSA); 4317 AllowedNameModifiers.push_back(OMPD_parallel); 4318 break; 4319 case OMPD_parallel_for_simd: 4320 Res = ActOnOpenMPParallelForSimdDirective( 4321 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4322 AllowedNameModifiers.push_back(OMPD_parallel); 4323 break; 4324 case OMPD_parallel_sections: 4325 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4326 StartLoc, EndLoc); 4327 AllowedNameModifiers.push_back(OMPD_parallel); 4328 break; 4329 case OMPD_task: 4330 Res = 4331 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4332 AllowedNameModifiers.push_back(OMPD_task); 4333 break; 4334 case OMPD_taskyield: 4335 assert(ClausesWithImplicit.empty() && 4336 "No clauses are allowed for 'omp taskyield' directive"); 4337 assert(AStmt == nullptr && 4338 "No associated statement allowed for 'omp taskyield' directive"); 4339 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4340 break; 4341 case OMPD_barrier: 4342 assert(ClausesWithImplicit.empty() && 4343 "No clauses are allowed for 'omp barrier' directive"); 4344 assert(AStmt == nullptr && 4345 "No associated statement allowed for 'omp barrier' directive"); 4346 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4347 break; 4348 case OMPD_taskwait: 4349 assert(ClausesWithImplicit.empty() && 4350 "No clauses are allowed for 'omp taskwait' directive"); 4351 assert(AStmt == nullptr && 4352 "No associated statement allowed for 'omp taskwait' directive"); 4353 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4354 break; 4355 case OMPD_taskgroup: 4356 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4357 EndLoc); 4358 break; 4359 case OMPD_flush: 4360 assert(AStmt == nullptr && 4361 "No associated statement allowed for 'omp flush' directive"); 4362 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4363 break; 4364 case OMPD_ordered: 4365 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4366 EndLoc); 4367 break; 4368 case OMPD_atomic: 4369 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4370 EndLoc); 4371 break; 4372 case OMPD_teams: 4373 Res = 4374 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4375 break; 4376 case OMPD_target: 4377 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4378 EndLoc); 4379 AllowedNameModifiers.push_back(OMPD_target); 4380 break; 4381 case OMPD_target_parallel: 4382 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4383 StartLoc, EndLoc); 4384 AllowedNameModifiers.push_back(OMPD_target); 4385 AllowedNameModifiers.push_back(OMPD_parallel); 4386 break; 4387 case OMPD_target_parallel_for: 4388 Res = ActOnOpenMPTargetParallelForDirective( 4389 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4390 AllowedNameModifiers.push_back(OMPD_target); 4391 AllowedNameModifiers.push_back(OMPD_parallel); 4392 break; 4393 case OMPD_cancellation_point: 4394 assert(ClausesWithImplicit.empty() && 4395 "No clauses are allowed for 'omp cancellation point' directive"); 4396 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4397 "cancellation point' directive"); 4398 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4399 break; 4400 case OMPD_cancel: 4401 assert(AStmt == nullptr && 4402 "No associated statement allowed for 'omp cancel' directive"); 4403 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4404 CancelRegion); 4405 AllowedNameModifiers.push_back(OMPD_cancel); 4406 break; 4407 case OMPD_target_data: 4408 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4409 EndLoc); 4410 AllowedNameModifiers.push_back(OMPD_target_data); 4411 break; 4412 case OMPD_target_enter_data: 4413 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4414 EndLoc, AStmt); 4415 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4416 break; 4417 case OMPD_target_exit_data: 4418 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4419 EndLoc, AStmt); 4420 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4421 break; 4422 case OMPD_taskloop: 4423 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4424 EndLoc, VarsWithInheritedDSA); 4425 AllowedNameModifiers.push_back(OMPD_taskloop); 4426 break; 4427 case OMPD_taskloop_simd: 4428 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4429 EndLoc, VarsWithInheritedDSA); 4430 AllowedNameModifiers.push_back(OMPD_taskloop); 4431 break; 4432 case OMPD_distribute: 4433 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4434 EndLoc, VarsWithInheritedDSA); 4435 break; 4436 case OMPD_target_update: 4437 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4438 EndLoc, AStmt); 4439 AllowedNameModifiers.push_back(OMPD_target_update); 4440 break; 4441 case OMPD_distribute_parallel_for: 4442 Res = ActOnOpenMPDistributeParallelForDirective( 4443 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4444 AllowedNameModifiers.push_back(OMPD_parallel); 4445 break; 4446 case OMPD_distribute_parallel_for_simd: 4447 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4448 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4449 AllowedNameModifiers.push_back(OMPD_parallel); 4450 break; 4451 case OMPD_distribute_simd: 4452 Res = ActOnOpenMPDistributeSimdDirective( 4453 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4454 break; 4455 case OMPD_target_parallel_for_simd: 4456 Res = ActOnOpenMPTargetParallelForSimdDirective( 4457 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4458 AllowedNameModifiers.push_back(OMPD_target); 4459 AllowedNameModifiers.push_back(OMPD_parallel); 4460 break; 4461 case OMPD_target_simd: 4462 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4463 EndLoc, VarsWithInheritedDSA); 4464 AllowedNameModifiers.push_back(OMPD_target); 4465 break; 4466 case OMPD_teams_distribute: 4467 Res = ActOnOpenMPTeamsDistributeDirective( 4468 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4469 break; 4470 case OMPD_teams_distribute_simd: 4471 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4472 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4473 break; 4474 case OMPD_teams_distribute_parallel_for_simd: 4475 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4476 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4477 AllowedNameModifiers.push_back(OMPD_parallel); 4478 break; 4479 case OMPD_teams_distribute_parallel_for: 4480 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4481 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4482 AllowedNameModifiers.push_back(OMPD_parallel); 4483 break; 4484 case OMPD_target_teams: 4485 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4486 EndLoc); 4487 AllowedNameModifiers.push_back(OMPD_target); 4488 break; 4489 case OMPD_target_teams_distribute: 4490 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4491 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4492 AllowedNameModifiers.push_back(OMPD_target); 4493 break; 4494 case OMPD_target_teams_distribute_parallel_for: 4495 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4496 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4497 AllowedNameModifiers.push_back(OMPD_target); 4498 AllowedNameModifiers.push_back(OMPD_parallel); 4499 break; 4500 case OMPD_target_teams_distribute_parallel_for_simd: 4501 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4502 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4503 AllowedNameModifiers.push_back(OMPD_target); 4504 AllowedNameModifiers.push_back(OMPD_parallel); 4505 break; 4506 case OMPD_target_teams_distribute_simd: 4507 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4508 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4509 AllowedNameModifiers.push_back(OMPD_target); 4510 break; 4511 case OMPD_declare_target: 4512 case OMPD_end_declare_target: 4513 case OMPD_threadprivate: 4514 case OMPD_allocate: 4515 case OMPD_declare_reduction: 4516 case OMPD_declare_mapper: 4517 case OMPD_declare_simd: 4518 case OMPD_requires: 4519 llvm_unreachable("OpenMP Directive is not allowed"); 4520 case OMPD_unknown: 4521 llvm_unreachable("Unknown OpenMP directive"); 4522 } 4523 4524 ErrorFound = Res.isInvalid() || ErrorFound; 4525 4526 // Check variables in the clauses if default(none) was specified. 4527 if (DSAStack->getDefaultDSA() == DSA_none) { 4528 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4529 for (OMPClause *C : Clauses) { 4530 switch (C->getClauseKind()) { 4531 case OMPC_num_threads: 4532 case OMPC_dist_schedule: 4533 // Do not analyse if no parent teams directive. 4534 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4535 break; 4536 continue; 4537 case OMPC_if: 4538 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4539 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4540 break; 4541 continue; 4542 case OMPC_schedule: 4543 break; 4544 case OMPC_ordered: 4545 case OMPC_device: 4546 case OMPC_num_teams: 4547 case OMPC_thread_limit: 4548 case OMPC_priority: 4549 case OMPC_grainsize: 4550 case OMPC_num_tasks: 4551 case OMPC_hint: 4552 case OMPC_collapse: 4553 case OMPC_safelen: 4554 case OMPC_simdlen: 4555 case OMPC_final: 4556 case OMPC_default: 4557 case OMPC_proc_bind: 4558 case OMPC_private: 4559 case OMPC_firstprivate: 4560 case OMPC_lastprivate: 4561 case OMPC_shared: 4562 case OMPC_reduction: 4563 case OMPC_task_reduction: 4564 case OMPC_in_reduction: 4565 case OMPC_linear: 4566 case OMPC_aligned: 4567 case OMPC_copyin: 4568 case OMPC_copyprivate: 4569 case OMPC_nowait: 4570 case OMPC_untied: 4571 case OMPC_mergeable: 4572 case OMPC_allocate: 4573 case OMPC_read: 4574 case OMPC_write: 4575 case OMPC_update: 4576 case OMPC_capture: 4577 case OMPC_seq_cst: 4578 case OMPC_depend: 4579 case OMPC_threads: 4580 case OMPC_simd: 4581 case OMPC_map: 4582 case OMPC_nogroup: 4583 case OMPC_defaultmap: 4584 case OMPC_to: 4585 case OMPC_from: 4586 case OMPC_use_device_ptr: 4587 case OMPC_is_device_ptr: 4588 continue; 4589 case OMPC_allocator: 4590 case OMPC_flush: 4591 case OMPC_threadprivate: 4592 case OMPC_uniform: 4593 case OMPC_unknown: 4594 case OMPC_unified_address: 4595 case OMPC_unified_shared_memory: 4596 case OMPC_reverse_offload: 4597 case OMPC_dynamic_allocators: 4598 case OMPC_atomic_default_mem_order: 4599 case OMPC_device_type: 4600 llvm_unreachable("Unexpected clause"); 4601 } 4602 for (Stmt *CC : C->children()) { 4603 if (CC) 4604 DSAChecker.Visit(CC); 4605 } 4606 } 4607 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4608 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4609 } 4610 for (const auto &P : VarsWithInheritedDSA) { 4611 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4612 continue; 4613 ErrorFound = true; 4614 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4615 << P.first << P.second->getSourceRange(); 4616 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4617 } 4618 4619 if (!AllowedNameModifiers.empty()) 4620 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4621 ErrorFound; 4622 4623 if (ErrorFound) 4624 return StmtError(); 4625 4626 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4627 Res.getAs<OMPExecutableDirective>() 4628 ->getStructuredBlock() 4629 ->setIsOMPStructuredBlock(true); 4630 } 4631 4632 if (!CurContext->isDependentContext() && 4633 isOpenMPTargetExecutionDirective(Kind) && 4634 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4635 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4636 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4637 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4638 // Register target to DSA Stack. 4639 DSAStack->addTargetDirLocation(StartLoc); 4640 } 4641 4642 return Res; 4643 } 4644 4645 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4646 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4647 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4648 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4649 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4650 assert(Aligneds.size() == Alignments.size()); 4651 assert(Linears.size() == LinModifiers.size()); 4652 assert(Linears.size() == Steps.size()); 4653 if (!DG || DG.get().isNull()) 4654 return DeclGroupPtrTy(); 4655 4656 if (!DG.get().isSingleDecl()) { 4657 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4658 return DG; 4659 } 4660 Decl *ADecl = DG.get().getSingleDecl(); 4661 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4662 ADecl = FTD->getTemplatedDecl(); 4663 4664 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4665 if (!FD) { 4666 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4667 return DeclGroupPtrTy(); 4668 } 4669 4670 // OpenMP [2.8.2, declare simd construct, Description] 4671 // The parameter of the simdlen clause must be a constant positive integer 4672 // expression. 4673 ExprResult SL; 4674 if (Simdlen) 4675 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4676 // OpenMP [2.8.2, declare simd construct, Description] 4677 // The special this pointer can be used as if was one of the arguments to the 4678 // function in any of the linear, aligned, or uniform clauses. 4679 // The uniform clause declares one or more arguments to have an invariant 4680 // value for all concurrent invocations of the function in the execution of a 4681 // single SIMD loop. 4682 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4683 const Expr *UniformedLinearThis = nullptr; 4684 for (const Expr *E : Uniforms) { 4685 E = E->IgnoreParenImpCasts(); 4686 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4687 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4688 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4689 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4690 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4691 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4692 continue; 4693 } 4694 if (isa<CXXThisExpr>(E)) { 4695 UniformedLinearThis = E; 4696 continue; 4697 } 4698 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4699 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4700 } 4701 // OpenMP [2.8.2, declare simd construct, Description] 4702 // The aligned clause declares that the object to which each list item points 4703 // is aligned to the number of bytes expressed in the optional parameter of 4704 // the aligned clause. 4705 // The special this pointer can be used as if was one of the arguments to the 4706 // function in any of the linear, aligned, or uniform clauses. 4707 // The type of list items appearing in the aligned clause must be array, 4708 // pointer, reference to array, or reference to pointer. 4709 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4710 const Expr *AlignedThis = nullptr; 4711 for (const Expr *E : Aligneds) { 4712 E = E->IgnoreParenImpCasts(); 4713 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4714 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4715 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4716 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4717 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4718 ->getCanonicalDecl() == CanonPVD) { 4719 // OpenMP [2.8.1, simd construct, Restrictions] 4720 // A list-item cannot appear in more than one aligned clause. 4721 if (AlignedArgs.count(CanonPVD) > 0) { 4722 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4723 << 1 << E->getSourceRange(); 4724 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4725 diag::note_omp_explicit_dsa) 4726 << getOpenMPClauseName(OMPC_aligned); 4727 continue; 4728 } 4729 AlignedArgs[CanonPVD] = E; 4730 QualType QTy = PVD->getType() 4731 .getNonReferenceType() 4732 .getUnqualifiedType() 4733 .getCanonicalType(); 4734 const Type *Ty = QTy.getTypePtrOrNull(); 4735 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4736 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4737 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4738 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4739 } 4740 continue; 4741 } 4742 } 4743 if (isa<CXXThisExpr>(E)) { 4744 if (AlignedThis) { 4745 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4746 << 2 << E->getSourceRange(); 4747 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4748 << getOpenMPClauseName(OMPC_aligned); 4749 } 4750 AlignedThis = E; 4751 continue; 4752 } 4753 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4754 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4755 } 4756 // The optional parameter of the aligned clause, alignment, must be a constant 4757 // positive integer expression. If no optional parameter is specified, 4758 // implementation-defined default alignments for SIMD instructions on the 4759 // target platforms are assumed. 4760 SmallVector<const Expr *, 4> NewAligns; 4761 for (Expr *E : Alignments) { 4762 ExprResult Align; 4763 if (E) 4764 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4765 NewAligns.push_back(Align.get()); 4766 } 4767 // OpenMP [2.8.2, declare simd construct, Description] 4768 // The linear clause declares one or more list items to be private to a SIMD 4769 // lane and to have a linear relationship with respect to the iteration space 4770 // of a loop. 4771 // The special this pointer can be used as if was one of the arguments to the 4772 // function in any of the linear, aligned, or uniform clauses. 4773 // When a linear-step expression is specified in a linear clause it must be 4774 // either a constant integer expression or an integer-typed parameter that is 4775 // specified in a uniform clause on the directive. 4776 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4777 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4778 auto MI = LinModifiers.begin(); 4779 for (const Expr *E : Linears) { 4780 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4781 ++MI; 4782 E = E->IgnoreParenImpCasts(); 4783 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4784 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4785 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4786 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4787 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4788 ->getCanonicalDecl() == CanonPVD) { 4789 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4790 // A list-item cannot appear in more than one linear clause. 4791 if (LinearArgs.count(CanonPVD) > 0) { 4792 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4793 << getOpenMPClauseName(OMPC_linear) 4794 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4795 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4796 diag::note_omp_explicit_dsa) 4797 << getOpenMPClauseName(OMPC_linear); 4798 continue; 4799 } 4800 // Each argument can appear in at most one uniform or linear clause. 4801 if (UniformedArgs.count(CanonPVD) > 0) { 4802 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4803 << getOpenMPClauseName(OMPC_linear) 4804 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4805 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4806 diag::note_omp_explicit_dsa) 4807 << getOpenMPClauseName(OMPC_uniform); 4808 continue; 4809 } 4810 LinearArgs[CanonPVD] = E; 4811 if (E->isValueDependent() || E->isTypeDependent() || 4812 E->isInstantiationDependent() || 4813 E->containsUnexpandedParameterPack()) 4814 continue; 4815 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4816 PVD->getOriginalType()); 4817 continue; 4818 } 4819 } 4820 if (isa<CXXThisExpr>(E)) { 4821 if (UniformedLinearThis) { 4822 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4823 << getOpenMPClauseName(OMPC_linear) 4824 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4825 << E->getSourceRange(); 4826 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4827 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4828 : OMPC_linear); 4829 continue; 4830 } 4831 UniformedLinearThis = E; 4832 if (E->isValueDependent() || E->isTypeDependent() || 4833 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4834 continue; 4835 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4836 E->getType()); 4837 continue; 4838 } 4839 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4840 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4841 } 4842 Expr *Step = nullptr; 4843 Expr *NewStep = nullptr; 4844 SmallVector<Expr *, 4> NewSteps; 4845 for (Expr *E : Steps) { 4846 // Skip the same step expression, it was checked already. 4847 if (Step == E || !E) { 4848 NewSteps.push_back(E ? NewStep : nullptr); 4849 continue; 4850 } 4851 Step = E; 4852 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4853 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4854 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4855 if (UniformedArgs.count(CanonPVD) == 0) { 4856 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4857 << Step->getSourceRange(); 4858 } else if (E->isValueDependent() || E->isTypeDependent() || 4859 E->isInstantiationDependent() || 4860 E->containsUnexpandedParameterPack() || 4861 CanonPVD->getType()->hasIntegerRepresentation()) { 4862 NewSteps.push_back(Step); 4863 } else { 4864 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4865 << Step->getSourceRange(); 4866 } 4867 continue; 4868 } 4869 NewStep = Step; 4870 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4871 !Step->isInstantiationDependent() && 4872 !Step->containsUnexpandedParameterPack()) { 4873 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4874 .get(); 4875 if (NewStep) 4876 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4877 } 4878 NewSteps.push_back(NewStep); 4879 } 4880 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4881 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4882 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4883 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4884 const_cast<Expr **>(Linears.data()), Linears.size(), 4885 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4886 NewSteps.data(), NewSteps.size(), SR); 4887 ADecl->addAttr(NewAttr); 4888 return ConvertDeclToDeclGroup(ADecl); 4889 } 4890 4891 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4892 Stmt *AStmt, 4893 SourceLocation StartLoc, 4894 SourceLocation EndLoc) { 4895 if (!AStmt) 4896 return StmtError(); 4897 4898 auto *CS = cast<CapturedStmt>(AStmt); 4899 // 1.2.2 OpenMP Language Terminology 4900 // Structured block - An executable statement with a single entry at the 4901 // top and a single exit at the bottom. 4902 // The point of exit cannot be a branch out of the structured block. 4903 // longjmp() and throw() must not violate the entry/exit criteria. 4904 CS->getCapturedDecl()->setNothrow(); 4905 4906 setFunctionHasBranchProtectedScope(); 4907 4908 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4909 DSAStack->isCancelRegion()); 4910 } 4911 4912 namespace { 4913 /// Iteration space of a single for loop. 4914 struct LoopIterationSpace final { 4915 /// True if the condition operator is the strict compare operator (<, > or 4916 /// !=). 4917 bool IsStrictCompare = false; 4918 /// Condition of the loop. 4919 Expr *PreCond = nullptr; 4920 /// This expression calculates the number of iterations in the loop. 4921 /// It is always possible to calculate it before starting the loop. 4922 Expr *NumIterations = nullptr; 4923 /// The loop counter variable. 4924 Expr *CounterVar = nullptr; 4925 /// Private loop counter variable. 4926 Expr *PrivateCounterVar = nullptr; 4927 /// This is initializer for the initial value of #CounterVar. 4928 Expr *CounterInit = nullptr; 4929 /// This is step for the #CounterVar used to generate its update: 4930 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4931 Expr *CounterStep = nullptr; 4932 /// Should step be subtracted? 4933 bool Subtract = false; 4934 /// Source range of the loop init. 4935 SourceRange InitSrcRange; 4936 /// Source range of the loop condition. 4937 SourceRange CondSrcRange; 4938 /// Source range of the loop increment. 4939 SourceRange IncSrcRange; 4940 /// Minimum value that can have the loop control variable. Used to support 4941 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 4942 /// since only such variables can be used in non-loop invariant expressions. 4943 Expr *MinValue = nullptr; 4944 /// Maximum value that can have the loop control variable. Used to support 4945 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 4946 /// since only such variables can be used in non-loop invariant expressions. 4947 Expr *MaxValue = nullptr; 4948 /// true, if the lower bound depends on the outer loop control var. 4949 bool IsNonRectangularLB = false; 4950 /// true, if the upper bound depends on the outer loop control var. 4951 bool IsNonRectangularUB = false; 4952 /// Index of the loop this loop depends on and forms non-rectangular loop 4953 /// nest. 4954 unsigned LoopDependentIdx = 0; 4955 /// Final condition for the non-rectangular loop nest support. It is used to 4956 /// check that the number of iterations for this particular counter must be 4957 /// finished. 4958 Expr *FinalCondition = nullptr; 4959 }; 4960 4961 /// Helper class for checking canonical form of the OpenMP loops and 4962 /// extracting iteration space of each loop in the loop nest, that will be used 4963 /// for IR generation. 4964 class OpenMPIterationSpaceChecker { 4965 /// Reference to Sema. 4966 Sema &SemaRef; 4967 /// Data-sharing stack. 4968 DSAStackTy &Stack; 4969 /// A location for diagnostics (when there is no some better location). 4970 SourceLocation DefaultLoc; 4971 /// A location for diagnostics (when increment is not compatible). 4972 SourceLocation ConditionLoc; 4973 /// A source location for referring to loop init later. 4974 SourceRange InitSrcRange; 4975 /// A source location for referring to condition later. 4976 SourceRange ConditionSrcRange; 4977 /// A source location for referring to increment later. 4978 SourceRange IncrementSrcRange; 4979 /// Loop variable. 4980 ValueDecl *LCDecl = nullptr; 4981 /// Reference to loop variable. 4982 Expr *LCRef = nullptr; 4983 /// Lower bound (initializer for the var). 4984 Expr *LB = nullptr; 4985 /// Upper bound. 4986 Expr *UB = nullptr; 4987 /// Loop step (increment). 4988 Expr *Step = nullptr; 4989 /// This flag is true when condition is one of: 4990 /// Var < UB 4991 /// Var <= UB 4992 /// UB > Var 4993 /// UB >= Var 4994 /// This will have no value when the condition is != 4995 llvm::Optional<bool> TestIsLessOp; 4996 /// This flag is true when condition is strict ( < or > ). 4997 bool TestIsStrictOp = false; 4998 /// This flag is true when step is subtracted on each iteration. 4999 bool SubtractStep = false; 5000 /// The outer loop counter this loop depends on (if any). 5001 const ValueDecl *DepDecl = nullptr; 5002 /// Contains number of loop (starts from 1) on which loop counter init 5003 /// expression of this loop depends on. 5004 Optional<unsigned> InitDependOnLC; 5005 /// Contains number of loop (starts from 1) on which loop counter condition 5006 /// expression of this loop depends on. 5007 Optional<unsigned> CondDependOnLC; 5008 /// Checks if the provide statement depends on the loop counter. 5009 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5010 /// Original condition required for checking of the exit condition for 5011 /// non-rectangular loop. 5012 Expr *Condition = nullptr; 5013 5014 public: 5015 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5016 SourceLocation DefaultLoc) 5017 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5018 ConditionLoc(DefaultLoc) {} 5019 /// Check init-expr for canonical loop form and save loop counter 5020 /// variable - #Var and its initialization value - #LB. 5021 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5022 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5023 /// for less/greater and for strict/non-strict comparison. 5024 bool checkAndSetCond(Expr *S); 5025 /// Check incr-expr for canonical loop form and return true if it 5026 /// does not conform, otherwise save loop step (#Step). 5027 bool checkAndSetInc(Expr *S); 5028 /// Return the loop counter variable. 5029 ValueDecl *getLoopDecl() const { return LCDecl; } 5030 /// Return the reference expression to loop counter variable. 5031 Expr *getLoopDeclRefExpr() const { return LCRef; } 5032 /// Source range of the loop init. 5033 SourceRange getInitSrcRange() const { return InitSrcRange; } 5034 /// Source range of the loop condition. 5035 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5036 /// Source range of the loop increment. 5037 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5038 /// True if the step should be subtracted. 5039 bool shouldSubtractStep() const { return SubtractStep; } 5040 /// True, if the compare operator is strict (<, > or !=). 5041 bool isStrictTestOp() const { return TestIsStrictOp; } 5042 /// Build the expression to calculate the number of iterations. 5043 Expr *buildNumIterations( 5044 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5045 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5046 /// Build the precondition expression for the loops. 5047 Expr * 5048 buildPreCond(Scope *S, Expr *Cond, 5049 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5050 /// Build reference expression to the counter be used for codegen. 5051 DeclRefExpr * 5052 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5053 DSAStackTy &DSA) const; 5054 /// Build reference expression to the private counter be used for 5055 /// codegen. 5056 Expr *buildPrivateCounterVar() const; 5057 /// Build initialization of the counter be used for codegen. 5058 Expr *buildCounterInit() const; 5059 /// Build step of the counter be used for codegen. 5060 Expr *buildCounterStep() const; 5061 /// Build loop data with counter value for depend clauses in ordered 5062 /// directives. 5063 Expr * 5064 buildOrderedLoopData(Scope *S, Expr *Counter, 5065 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5066 SourceLocation Loc, Expr *Inc = nullptr, 5067 OverloadedOperatorKind OOK = OO_Amp); 5068 /// Builds the minimum value for the loop counter. 5069 std::pair<Expr *, Expr *> buildMinMaxValues( 5070 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5071 /// Builds final condition for the non-rectangular loops. 5072 Expr *buildFinalCondition(Scope *S) const; 5073 /// Return true if any expression is dependent. 5074 bool dependent() const; 5075 /// Returns true if the initializer forms non-rectangular loop. 5076 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5077 /// Returns true if the condition forms non-rectangular loop. 5078 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5079 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5080 unsigned getLoopDependentIdx() const { 5081 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5082 } 5083 5084 private: 5085 /// Check the right-hand side of an assignment in the increment 5086 /// expression. 5087 bool checkAndSetIncRHS(Expr *RHS); 5088 /// Helper to set loop counter variable and its initializer. 5089 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5090 bool EmitDiags); 5091 /// Helper to set upper bound. 5092 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5093 SourceRange SR, SourceLocation SL); 5094 /// Helper to set loop increment. 5095 bool setStep(Expr *NewStep, bool Subtract); 5096 }; 5097 5098 bool OpenMPIterationSpaceChecker::dependent() const { 5099 if (!LCDecl) { 5100 assert(!LB && !UB && !Step); 5101 return false; 5102 } 5103 return LCDecl->getType()->isDependentType() || 5104 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5105 (Step && Step->isValueDependent()); 5106 } 5107 5108 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5109 Expr *NewLCRefExpr, 5110 Expr *NewLB, bool EmitDiags) { 5111 // State consistency checking to ensure correct usage. 5112 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5113 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5114 if (!NewLCDecl || !NewLB) 5115 return true; 5116 LCDecl = getCanonicalDecl(NewLCDecl); 5117 LCRef = NewLCRefExpr; 5118 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5119 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5120 if ((Ctor->isCopyOrMoveConstructor() || 5121 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5122 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5123 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5124 LB = NewLB; 5125 if (EmitDiags) 5126 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5127 return false; 5128 } 5129 5130 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5131 llvm::Optional<bool> LessOp, 5132 bool StrictOp, SourceRange SR, 5133 SourceLocation SL) { 5134 // State consistency checking to ensure correct usage. 5135 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5136 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5137 if (!NewUB) 5138 return true; 5139 UB = NewUB; 5140 if (LessOp) 5141 TestIsLessOp = LessOp; 5142 TestIsStrictOp = StrictOp; 5143 ConditionSrcRange = SR; 5144 ConditionLoc = SL; 5145 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5146 return false; 5147 } 5148 5149 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5150 // State consistency checking to ensure correct usage. 5151 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5152 if (!NewStep) 5153 return true; 5154 if (!NewStep->isValueDependent()) { 5155 // Check that the step is integer expression. 5156 SourceLocation StepLoc = NewStep->getBeginLoc(); 5157 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5158 StepLoc, getExprAsWritten(NewStep)); 5159 if (Val.isInvalid()) 5160 return true; 5161 NewStep = Val.get(); 5162 5163 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5164 // If test-expr is of form var relational-op b and relational-op is < or 5165 // <= then incr-expr must cause var to increase on each iteration of the 5166 // loop. If test-expr is of form var relational-op b and relational-op is 5167 // > or >= then incr-expr must cause var to decrease on each iteration of 5168 // the loop. 5169 // If test-expr is of form b relational-op var and relational-op is < or 5170 // <= then incr-expr must cause var to decrease on each iteration of the 5171 // loop. If test-expr is of form b relational-op var and relational-op is 5172 // > or >= then incr-expr must cause var to increase on each iteration of 5173 // the loop. 5174 llvm::APSInt Result; 5175 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5176 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5177 bool IsConstNeg = 5178 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5179 bool IsConstPos = 5180 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5181 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5182 5183 // != with increment is treated as <; != with decrement is treated as > 5184 if (!TestIsLessOp.hasValue()) 5185 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5186 if (UB && (IsConstZero || 5187 (TestIsLessOp.getValue() ? 5188 (IsConstNeg || (IsUnsigned && Subtract)) : 5189 (IsConstPos || (IsUnsigned && !Subtract))))) { 5190 SemaRef.Diag(NewStep->getExprLoc(), 5191 diag::err_omp_loop_incr_not_compatible) 5192 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5193 SemaRef.Diag(ConditionLoc, 5194 diag::note_omp_loop_cond_requres_compatible_incr) 5195 << TestIsLessOp.getValue() << ConditionSrcRange; 5196 return true; 5197 } 5198 if (TestIsLessOp.getValue() == Subtract) { 5199 NewStep = 5200 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5201 .get(); 5202 Subtract = !Subtract; 5203 } 5204 } 5205 5206 Step = NewStep; 5207 SubtractStep = Subtract; 5208 return false; 5209 } 5210 5211 namespace { 5212 /// Checker for the non-rectangular loops. Checks if the initializer or 5213 /// condition expression references loop counter variable. 5214 class LoopCounterRefChecker final 5215 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5216 Sema &SemaRef; 5217 DSAStackTy &Stack; 5218 const ValueDecl *CurLCDecl = nullptr; 5219 const ValueDecl *DepDecl = nullptr; 5220 const ValueDecl *PrevDepDecl = nullptr; 5221 bool IsInitializer = true; 5222 unsigned BaseLoopId = 0; 5223 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5224 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5225 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5226 << (IsInitializer ? 0 : 1); 5227 return false; 5228 } 5229 const auto &&Data = Stack.isLoopControlVariable(VD); 5230 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5231 // The type of the loop iterator on which we depend may not have a random 5232 // access iterator type. 5233 if (Data.first && VD->getType()->isRecordType()) { 5234 SmallString<128> Name; 5235 llvm::raw_svector_ostream OS(Name); 5236 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5237 /*Qualified=*/true); 5238 SemaRef.Diag(E->getExprLoc(), 5239 diag::err_omp_wrong_dependency_iterator_type) 5240 << OS.str(); 5241 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5242 return false; 5243 } 5244 if (Data.first && 5245 (DepDecl || (PrevDepDecl && 5246 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5247 if (!DepDecl && PrevDepDecl) 5248 DepDecl = PrevDepDecl; 5249 SmallString<128> Name; 5250 llvm::raw_svector_ostream OS(Name); 5251 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5252 /*Qualified=*/true); 5253 SemaRef.Diag(E->getExprLoc(), 5254 diag::err_omp_invariant_or_linear_dependency) 5255 << OS.str(); 5256 return false; 5257 } 5258 if (Data.first) { 5259 DepDecl = VD; 5260 BaseLoopId = Data.first; 5261 } 5262 return Data.first; 5263 } 5264 5265 public: 5266 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5267 const ValueDecl *VD = E->getDecl(); 5268 if (isa<VarDecl>(VD)) 5269 return checkDecl(E, VD); 5270 return false; 5271 } 5272 bool VisitMemberExpr(const MemberExpr *E) { 5273 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5274 const ValueDecl *VD = E->getMemberDecl(); 5275 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5276 return checkDecl(E, VD); 5277 } 5278 return false; 5279 } 5280 bool VisitStmt(const Stmt *S) { 5281 bool Res = false; 5282 for (const Stmt *Child : S->children()) 5283 Res = (Child && Visit(Child)) || Res; 5284 return Res; 5285 } 5286 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5287 const ValueDecl *CurLCDecl, bool IsInitializer, 5288 const ValueDecl *PrevDepDecl = nullptr) 5289 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5290 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5291 unsigned getBaseLoopId() const { 5292 assert(CurLCDecl && "Expected loop dependency."); 5293 return BaseLoopId; 5294 } 5295 const ValueDecl *getDepDecl() const { 5296 assert(CurLCDecl && "Expected loop dependency."); 5297 return DepDecl; 5298 } 5299 }; 5300 } // namespace 5301 5302 Optional<unsigned> 5303 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5304 bool IsInitializer) { 5305 // Check for the non-rectangular loops. 5306 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5307 DepDecl); 5308 if (LoopStmtChecker.Visit(S)) { 5309 DepDecl = LoopStmtChecker.getDepDecl(); 5310 return LoopStmtChecker.getBaseLoopId(); 5311 } 5312 return llvm::None; 5313 } 5314 5315 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5316 // Check init-expr for canonical loop form and save loop counter 5317 // variable - #Var and its initialization value - #LB. 5318 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5319 // var = lb 5320 // integer-type var = lb 5321 // random-access-iterator-type var = lb 5322 // pointer-type var = lb 5323 // 5324 if (!S) { 5325 if (EmitDiags) { 5326 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5327 } 5328 return true; 5329 } 5330 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5331 if (!ExprTemp->cleanupsHaveSideEffects()) 5332 S = ExprTemp->getSubExpr(); 5333 5334 InitSrcRange = S->getSourceRange(); 5335 if (Expr *E = dyn_cast<Expr>(S)) 5336 S = E->IgnoreParens(); 5337 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5338 if (BO->getOpcode() == BO_Assign) { 5339 Expr *LHS = BO->getLHS()->IgnoreParens(); 5340 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5341 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5342 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5343 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5344 EmitDiags); 5345 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5346 } 5347 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5348 if (ME->isArrow() && 5349 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5350 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5351 EmitDiags); 5352 } 5353 } 5354 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5355 if (DS->isSingleDecl()) { 5356 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5357 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5358 // Accept non-canonical init form here but emit ext. warning. 5359 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5360 SemaRef.Diag(S->getBeginLoc(), 5361 diag::ext_omp_loop_not_canonical_init) 5362 << S->getSourceRange(); 5363 return setLCDeclAndLB( 5364 Var, 5365 buildDeclRefExpr(SemaRef, Var, 5366 Var->getType().getNonReferenceType(), 5367 DS->getBeginLoc()), 5368 Var->getInit(), EmitDiags); 5369 } 5370 } 5371 } 5372 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5373 if (CE->getOperator() == OO_Equal) { 5374 Expr *LHS = CE->getArg(0); 5375 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5376 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5377 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5378 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5379 EmitDiags); 5380 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5381 } 5382 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5383 if (ME->isArrow() && 5384 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5385 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5386 EmitDiags); 5387 } 5388 } 5389 } 5390 5391 if (dependent() || SemaRef.CurContext->isDependentContext()) 5392 return false; 5393 if (EmitDiags) { 5394 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5395 << S->getSourceRange(); 5396 } 5397 return true; 5398 } 5399 5400 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5401 /// variable (which may be the loop variable) if possible. 5402 static const ValueDecl *getInitLCDecl(const Expr *E) { 5403 if (!E) 5404 return nullptr; 5405 E = getExprAsWritten(E); 5406 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5407 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5408 if ((Ctor->isCopyOrMoveConstructor() || 5409 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5410 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5411 E = CE->getArg(0)->IgnoreParenImpCasts(); 5412 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5413 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5414 return getCanonicalDecl(VD); 5415 } 5416 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5417 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5418 return getCanonicalDecl(ME->getMemberDecl()); 5419 return nullptr; 5420 } 5421 5422 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5423 // Check test-expr for canonical form, save upper-bound UB, flags for 5424 // less/greater and for strict/non-strict comparison. 5425 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5426 // var relational-op b 5427 // b relational-op var 5428 // 5429 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5430 if (!S) { 5431 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5432 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5433 return true; 5434 } 5435 Condition = S; 5436 S = getExprAsWritten(S); 5437 SourceLocation CondLoc = S->getBeginLoc(); 5438 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5439 if (BO->isRelationalOp()) { 5440 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5441 return setUB(BO->getRHS(), 5442 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5443 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5444 BO->getSourceRange(), BO->getOperatorLoc()); 5445 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5446 return setUB(BO->getLHS(), 5447 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5448 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5449 BO->getSourceRange(), BO->getOperatorLoc()); 5450 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5451 return setUB( 5452 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5453 /*LessOp=*/llvm::None, 5454 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5455 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5456 if (CE->getNumArgs() == 2) { 5457 auto Op = CE->getOperator(); 5458 switch (Op) { 5459 case OO_Greater: 5460 case OO_GreaterEqual: 5461 case OO_Less: 5462 case OO_LessEqual: 5463 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5464 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5465 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5466 CE->getOperatorLoc()); 5467 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5468 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5469 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5470 CE->getOperatorLoc()); 5471 break; 5472 case OO_ExclaimEqual: 5473 if (IneqCondIsCanonical) 5474 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5475 : CE->getArg(0), 5476 /*LessOp=*/llvm::None, 5477 /*StrictOp=*/true, CE->getSourceRange(), 5478 CE->getOperatorLoc()); 5479 break; 5480 default: 5481 break; 5482 } 5483 } 5484 } 5485 if (dependent() || SemaRef.CurContext->isDependentContext()) 5486 return false; 5487 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5488 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5489 return true; 5490 } 5491 5492 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5493 // RHS of canonical loop form increment can be: 5494 // var + incr 5495 // incr + var 5496 // var - incr 5497 // 5498 RHS = RHS->IgnoreParenImpCasts(); 5499 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5500 if (BO->isAdditiveOp()) { 5501 bool IsAdd = BO->getOpcode() == BO_Add; 5502 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5503 return setStep(BO->getRHS(), !IsAdd); 5504 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5505 return setStep(BO->getLHS(), /*Subtract=*/false); 5506 } 5507 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5508 bool IsAdd = CE->getOperator() == OO_Plus; 5509 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5510 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5511 return setStep(CE->getArg(1), !IsAdd); 5512 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5513 return setStep(CE->getArg(0), /*Subtract=*/false); 5514 } 5515 } 5516 if (dependent() || SemaRef.CurContext->isDependentContext()) 5517 return false; 5518 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5519 << RHS->getSourceRange() << LCDecl; 5520 return true; 5521 } 5522 5523 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5524 // Check incr-expr for canonical loop form and return true if it 5525 // does not conform. 5526 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5527 // ++var 5528 // var++ 5529 // --var 5530 // var-- 5531 // var += incr 5532 // var -= incr 5533 // var = var + incr 5534 // var = incr + var 5535 // var = var - incr 5536 // 5537 if (!S) { 5538 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5539 return true; 5540 } 5541 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5542 if (!ExprTemp->cleanupsHaveSideEffects()) 5543 S = ExprTemp->getSubExpr(); 5544 5545 IncrementSrcRange = S->getSourceRange(); 5546 S = S->IgnoreParens(); 5547 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5548 if (UO->isIncrementDecrementOp() && 5549 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5550 return setStep(SemaRef 5551 .ActOnIntegerConstant(UO->getBeginLoc(), 5552 (UO->isDecrementOp() ? -1 : 1)) 5553 .get(), 5554 /*Subtract=*/false); 5555 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5556 switch (BO->getOpcode()) { 5557 case BO_AddAssign: 5558 case BO_SubAssign: 5559 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5560 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5561 break; 5562 case BO_Assign: 5563 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5564 return checkAndSetIncRHS(BO->getRHS()); 5565 break; 5566 default: 5567 break; 5568 } 5569 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5570 switch (CE->getOperator()) { 5571 case OO_PlusPlus: 5572 case OO_MinusMinus: 5573 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5574 return setStep(SemaRef 5575 .ActOnIntegerConstant( 5576 CE->getBeginLoc(), 5577 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5578 .get(), 5579 /*Subtract=*/false); 5580 break; 5581 case OO_PlusEqual: 5582 case OO_MinusEqual: 5583 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5584 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5585 break; 5586 case OO_Equal: 5587 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5588 return checkAndSetIncRHS(CE->getArg(1)); 5589 break; 5590 default: 5591 break; 5592 } 5593 } 5594 if (dependent() || SemaRef.CurContext->isDependentContext()) 5595 return false; 5596 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5597 << S->getSourceRange() << LCDecl; 5598 return true; 5599 } 5600 5601 static ExprResult 5602 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5603 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5604 if (SemaRef.CurContext->isDependentContext()) 5605 return ExprResult(Capture); 5606 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5607 return SemaRef.PerformImplicitConversion( 5608 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5609 /*AllowExplicit=*/true); 5610 auto I = Captures.find(Capture); 5611 if (I != Captures.end()) 5612 return buildCapture(SemaRef, Capture, I->second); 5613 DeclRefExpr *Ref = nullptr; 5614 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5615 Captures[Capture] = Ref; 5616 return Res; 5617 } 5618 5619 /// Build the expression to calculate the number of iterations. 5620 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5621 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5622 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5623 ExprResult Diff; 5624 QualType VarType = LCDecl->getType().getNonReferenceType(); 5625 if (VarType->isIntegerType() || VarType->isPointerType() || 5626 SemaRef.getLangOpts().CPlusPlus) { 5627 Expr *LBVal = LB; 5628 Expr *UBVal = UB; 5629 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5630 // max(LB(MinVal), LB(MaxVal)) 5631 if (InitDependOnLC) { 5632 const LoopIterationSpace &IS = 5633 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5634 InitDependOnLC.getValueOr( 5635 CondDependOnLC.getValueOr(0))]; 5636 if (!IS.MinValue || !IS.MaxValue) 5637 return nullptr; 5638 // OuterVar = Min 5639 ExprResult MinValue = 5640 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5641 if (!MinValue.isUsable()) 5642 return nullptr; 5643 5644 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5645 IS.CounterVar, MinValue.get()); 5646 if (!LBMinVal.isUsable()) 5647 return nullptr; 5648 // OuterVar = Min, LBVal 5649 LBMinVal = 5650 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5651 if (!LBMinVal.isUsable()) 5652 return nullptr; 5653 // (OuterVar = Min, LBVal) 5654 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5655 if (!LBMinVal.isUsable()) 5656 return nullptr; 5657 5658 // OuterVar = Max 5659 ExprResult MaxValue = 5660 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5661 if (!MaxValue.isUsable()) 5662 return nullptr; 5663 5664 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5665 IS.CounterVar, MaxValue.get()); 5666 if (!LBMaxVal.isUsable()) 5667 return nullptr; 5668 // OuterVar = Max, LBVal 5669 LBMaxVal = 5670 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5671 if (!LBMaxVal.isUsable()) 5672 return nullptr; 5673 // (OuterVar = Max, LBVal) 5674 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5675 if (!LBMaxVal.isUsable()) 5676 return nullptr; 5677 5678 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 5679 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 5680 if (!LBMin || !LBMax) 5681 return nullptr; 5682 // LB(MinVal) < LB(MaxVal) 5683 ExprResult MinLessMaxRes = 5684 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 5685 if (!MinLessMaxRes.isUsable()) 5686 return nullptr; 5687 Expr *MinLessMax = 5688 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 5689 if (!MinLessMax) 5690 return nullptr; 5691 if (TestIsLessOp.getValue()) { 5692 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 5693 // LB(MaxVal)) 5694 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5695 MinLessMax, LBMin, LBMax); 5696 if (!MinLB.isUsable()) 5697 return nullptr; 5698 LBVal = MinLB.get(); 5699 } else { 5700 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 5701 // LB(MaxVal)) 5702 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5703 MinLessMax, LBMax, LBMin); 5704 if (!MaxLB.isUsable()) 5705 return nullptr; 5706 LBVal = MaxLB.get(); 5707 } 5708 } 5709 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 5710 // min(UB(MinVal), UB(MaxVal)) 5711 if (CondDependOnLC) { 5712 const LoopIterationSpace &IS = 5713 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5714 InitDependOnLC.getValueOr( 5715 CondDependOnLC.getValueOr(0))]; 5716 if (!IS.MinValue || !IS.MaxValue) 5717 return nullptr; 5718 // OuterVar = Min 5719 ExprResult MinValue = 5720 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5721 if (!MinValue.isUsable()) 5722 return nullptr; 5723 5724 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5725 IS.CounterVar, MinValue.get()); 5726 if (!UBMinVal.isUsable()) 5727 return nullptr; 5728 // OuterVar = Min, UBVal 5729 UBMinVal = 5730 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 5731 if (!UBMinVal.isUsable()) 5732 return nullptr; 5733 // (OuterVar = Min, UBVal) 5734 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 5735 if (!UBMinVal.isUsable()) 5736 return nullptr; 5737 5738 // OuterVar = Max 5739 ExprResult MaxValue = 5740 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5741 if (!MaxValue.isUsable()) 5742 return nullptr; 5743 5744 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5745 IS.CounterVar, MaxValue.get()); 5746 if (!UBMaxVal.isUsable()) 5747 return nullptr; 5748 // OuterVar = Max, UBVal 5749 UBMaxVal = 5750 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 5751 if (!UBMaxVal.isUsable()) 5752 return nullptr; 5753 // (OuterVar = Max, UBVal) 5754 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 5755 if (!UBMaxVal.isUsable()) 5756 return nullptr; 5757 5758 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 5759 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 5760 if (!UBMin || !UBMax) 5761 return nullptr; 5762 // UB(MinVal) > UB(MaxVal) 5763 ExprResult MinGreaterMaxRes = 5764 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 5765 if (!MinGreaterMaxRes.isUsable()) 5766 return nullptr; 5767 Expr *MinGreaterMax = 5768 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 5769 if (!MinGreaterMax) 5770 return nullptr; 5771 if (TestIsLessOp.getValue()) { 5772 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 5773 // UB(MaxVal)) 5774 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 5775 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 5776 if (!MaxUB.isUsable()) 5777 return nullptr; 5778 UBVal = MaxUB.get(); 5779 } else { 5780 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 5781 // UB(MaxVal)) 5782 ExprResult MinUB = SemaRef.ActOnConditionalOp( 5783 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 5784 if (!MinUB.isUsable()) 5785 return nullptr; 5786 UBVal = MinUB.get(); 5787 } 5788 } 5789 // Upper - Lower 5790 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 5791 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 5792 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5793 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5794 if (!Upper || !Lower) 5795 return nullptr; 5796 5797 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5798 5799 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5800 // BuildBinOp already emitted error, this one is to point user to upper 5801 // and lower bound, and to tell what is passed to 'operator-'. 5802 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5803 << Upper->getSourceRange() << Lower->getSourceRange(); 5804 return nullptr; 5805 } 5806 } 5807 5808 if (!Diff.isUsable()) 5809 return nullptr; 5810 5811 // Upper - Lower [- 1] 5812 if (TestIsStrictOp) 5813 Diff = SemaRef.BuildBinOp( 5814 S, DefaultLoc, BO_Sub, Diff.get(), 5815 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5816 if (!Diff.isUsable()) 5817 return nullptr; 5818 5819 // Upper - Lower [- 1] + Step 5820 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5821 if (!NewStep.isUsable()) 5822 return nullptr; 5823 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5824 if (!Diff.isUsable()) 5825 return nullptr; 5826 5827 // Parentheses (for dumping/debugging purposes only). 5828 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5829 if (!Diff.isUsable()) 5830 return nullptr; 5831 5832 // (Upper - Lower [- 1] + Step) / Step 5833 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5834 if (!Diff.isUsable()) 5835 return nullptr; 5836 5837 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5838 QualType Type = Diff.get()->getType(); 5839 ASTContext &C = SemaRef.Context; 5840 bool UseVarType = VarType->hasIntegerRepresentation() && 5841 C.getTypeSize(Type) > C.getTypeSize(VarType); 5842 if (!Type->isIntegerType() || UseVarType) { 5843 unsigned NewSize = 5844 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5845 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5846 : Type->hasSignedIntegerRepresentation(); 5847 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5848 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5849 Diff = SemaRef.PerformImplicitConversion( 5850 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5851 if (!Diff.isUsable()) 5852 return nullptr; 5853 } 5854 } 5855 if (LimitedType) { 5856 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5857 if (NewSize != C.getTypeSize(Type)) { 5858 if (NewSize < C.getTypeSize(Type)) { 5859 assert(NewSize == 64 && "incorrect loop var size"); 5860 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5861 << InitSrcRange << ConditionSrcRange; 5862 } 5863 QualType NewType = C.getIntTypeForBitwidth( 5864 NewSize, Type->hasSignedIntegerRepresentation() || 5865 C.getTypeSize(Type) < NewSize); 5866 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5867 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5868 Sema::AA_Converting, true); 5869 if (!Diff.isUsable()) 5870 return nullptr; 5871 } 5872 } 5873 } 5874 5875 return Diff.get(); 5876 } 5877 5878 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 5879 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5880 // Do not build for iterators, they cannot be used in non-rectangular loop 5881 // nests. 5882 if (LCDecl->getType()->isRecordType()) 5883 return std::make_pair(nullptr, nullptr); 5884 // If we subtract, the min is in the condition, otherwise the min is in the 5885 // init value. 5886 Expr *MinExpr = nullptr; 5887 Expr *MaxExpr = nullptr; 5888 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5889 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5890 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 5891 : CondDependOnLC.hasValue(); 5892 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 5893 : InitDependOnLC.hasValue(); 5894 Expr *Lower = 5895 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5896 Expr *Upper = 5897 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5898 if (!Upper || !Lower) 5899 return std::make_pair(nullptr, nullptr); 5900 5901 if (TestIsLessOp.getValue()) 5902 MinExpr = Lower; 5903 else 5904 MaxExpr = Upper; 5905 5906 // Build minimum/maximum value based on number of iterations. 5907 ExprResult Diff; 5908 QualType VarType = LCDecl->getType().getNonReferenceType(); 5909 5910 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5911 if (!Diff.isUsable()) 5912 return std::make_pair(nullptr, nullptr); 5913 5914 // Upper - Lower [- 1] 5915 if (TestIsStrictOp) 5916 Diff = SemaRef.BuildBinOp( 5917 S, DefaultLoc, BO_Sub, Diff.get(), 5918 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5919 if (!Diff.isUsable()) 5920 return std::make_pair(nullptr, nullptr); 5921 5922 // Upper - Lower [- 1] + Step 5923 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5924 if (!NewStep.isUsable()) 5925 return std::make_pair(nullptr, nullptr); 5926 5927 // Parentheses (for dumping/debugging purposes only). 5928 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5929 if (!Diff.isUsable()) 5930 return std::make_pair(nullptr, nullptr); 5931 5932 // (Upper - Lower [- 1]) / Step 5933 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5934 if (!Diff.isUsable()) 5935 return std::make_pair(nullptr, nullptr); 5936 5937 // ((Upper - Lower [- 1]) / Step) * Step 5938 // Parentheses (for dumping/debugging purposes only). 5939 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5940 if (!Diff.isUsable()) 5941 return std::make_pair(nullptr, nullptr); 5942 5943 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 5944 if (!Diff.isUsable()) 5945 return std::make_pair(nullptr, nullptr); 5946 5947 // Convert to the original type or ptrdiff_t, if original type is pointer. 5948 if (!VarType->isAnyPointerType() && 5949 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 5950 Diff = SemaRef.PerformImplicitConversion( 5951 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 5952 } else if (VarType->isAnyPointerType() && 5953 !SemaRef.Context.hasSameType( 5954 Diff.get()->getType(), 5955 SemaRef.Context.getUnsignedPointerDiffType())) { 5956 Diff = SemaRef.PerformImplicitConversion( 5957 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 5958 Sema::AA_Converting, /*AllowExplicit=*/true); 5959 } 5960 if (!Diff.isUsable()) 5961 return std::make_pair(nullptr, nullptr); 5962 5963 // Parentheses (for dumping/debugging purposes only). 5964 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5965 if (!Diff.isUsable()) 5966 return std::make_pair(nullptr, nullptr); 5967 5968 if (TestIsLessOp.getValue()) { 5969 // MinExpr = Lower; 5970 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 5971 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 5972 if (!Diff.isUsable()) 5973 return std::make_pair(nullptr, nullptr); 5974 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 5975 if (!Diff.isUsable()) 5976 return std::make_pair(nullptr, nullptr); 5977 MaxExpr = Diff.get(); 5978 } else { 5979 // MaxExpr = Upper; 5980 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 5981 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 5982 if (!Diff.isUsable()) 5983 return std::make_pair(nullptr, nullptr); 5984 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 5985 if (!Diff.isUsable()) 5986 return std::make_pair(nullptr, nullptr); 5987 MinExpr = Diff.get(); 5988 } 5989 5990 return std::make_pair(MinExpr, MaxExpr); 5991 } 5992 5993 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 5994 if (InitDependOnLC || CondDependOnLC) 5995 return Condition; 5996 return nullptr; 5997 } 5998 5999 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6000 Scope *S, Expr *Cond, 6001 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6002 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6003 Sema::TentativeAnalysisScope Trap(SemaRef); 6004 6005 ExprResult NewLB = 6006 InitDependOnLC ? LB : tryBuildCapture(SemaRef, LB, Captures); 6007 ExprResult NewUB = 6008 CondDependOnLC ? UB : tryBuildCapture(SemaRef, UB, Captures); 6009 if (!NewLB.isUsable() || !NewUB.isUsable()) 6010 return nullptr; 6011 6012 ExprResult CondExpr = 6013 SemaRef.BuildBinOp(S, DefaultLoc, 6014 TestIsLessOp.getValue() ? 6015 (TestIsStrictOp ? BO_LT : BO_LE) : 6016 (TestIsStrictOp ? BO_GT : BO_GE), 6017 NewLB.get(), NewUB.get()); 6018 if (CondExpr.isUsable()) { 6019 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6020 SemaRef.Context.BoolTy)) 6021 CondExpr = SemaRef.PerformImplicitConversion( 6022 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6023 /*AllowExplicit=*/true); 6024 } 6025 6026 // Otherwise use original loop condition and evaluate it in runtime. 6027 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6028 } 6029 6030 /// Build reference expression to the counter be used for codegen. 6031 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6032 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6033 DSAStackTy &DSA) const { 6034 auto *VD = dyn_cast<VarDecl>(LCDecl); 6035 if (!VD) { 6036 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6037 DeclRefExpr *Ref = buildDeclRefExpr( 6038 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6039 const DSAStackTy::DSAVarData Data = 6040 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6041 // If the loop control decl is explicitly marked as private, do not mark it 6042 // as captured again. 6043 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6044 Captures.insert(std::make_pair(LCRef, Ref)); 6045 return Ref; 6046 } 6047 return cast<DeclRefExpr>(LCRef); 6048 } 6049 6050 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6051 if (LCDecl && !LCDecl->isInvalidDecl()) { 6052 QualType Type = LCDecl->getType().getNonReferenceType(); 6053 VarDecl *PrivateVar = buildVarDecl( 6054 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6055 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6056 isa<VarDecl>(LCDecl) 6057 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6058 : nullptr); 6059 if (PrivateVar->isInvalidDecl()) 6060 return nullptr; 6061 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6062 } 6063 return nullptr; 6064 } 6065 6066 /// Build initialization of the counter to be used for codegen. 6067 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6068 6069 /// Build step of the counter be used for codegen. 6070 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6071 6072 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6073 Scope *S, Expr *Counter, 6074 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6075 Expr *Inc, OverloadedOperatorKind OOK) { 6076 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6077 if (!Cnt) 6078 return nullptr; 6079 if (Inc) { 6080 assert((OOK == OO_Plus || OOK == OO_Minus) && 6081 "Expected only + or - operations for depend clauses."); 6082 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6083 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6084 if (!Cnt) 6085 return nullptr; 6086 } 6087 ExprResult Diff; 6088 QualType VarType = LCDecl->getType().getNonReferenceType(); 6089 if (VarType->isIntegerType() || VarType->isPointerType() || 6090 SemaRef.getLangOpts().CPlusPlus) { 6091 // Upper - Lower 6092 Expr *Upper = TestIsLessOp.getValue() 6093 ? Cnt 6094 : tryBuildCapture(SemaRef, UB, Captures).get(); 6095 Expr *Lower = TestIsLessOp.getValue() 6096 ? tryBuildCapture(SemaRef, LB, Captures).get() 6097 : Cnt; 6098 if (!Upper || !Lower) 6099 return nullptr; 6100 6101 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6102 6103 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6104 // BuildBinOp already emitted error, this one is to point user to upper 6105 // and lower bound, and to tell what is passed to 'operator-'. 6106 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6107 << Upper->getSourceRange() << Lower->getSourceRange(); 6108 return nullptr; 6109 } 6110 } 6111 6112 if (!Diff.isUsable()) 6113 return nullptr; 6114 6115 // Parentheses (for dumping/debugging purposes only). 6116 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6117 if (!Diff.isUsable()) 6118 return nullptr; 6119 6120 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6121 if (!NewStep.isUsable()) 6122 return nullptr; 6123 // (Upper - Lower) / Step 6124 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6125 if (!Diff.isUsable()) 6126 return nullptr; 6127 6128 return Diff.get(); 6129 } 6130 } // namespace 6131 6132 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6133 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6134 assert(Init && "Expected loop in canonical form."); 6135 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6136 if (AssociatedLoops > 0 && 6137 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6138 DSAStack->loopStart(); 6139 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6140 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6141 if (ValueDecl *D = ISC.getLoopDecl()) { 6142 auto *VD = dyn_cast<VarDecl>(D); 6143 DeclRefExpr *PrivateRef = nullptr; 6144 if (!VD) { 6145 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6146 VD = Private; 6147 } else { 6148 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6149 /*WithInit=*/false); 6150 VD = cast<VarDecl>(PrivateRef->getDecl()); 6151 } 6152 } 6153 DSAStack->addLoopControlVariable(D, VD); 6154 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6155 if (LD != D->getCanonicalDecl()) { 6156 DSAStack->resetPossibleLoopCounter(); 6157 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6158 MarkDeclarationsReferencedInExpr( 6159 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6160 Var->getType().getNonLValueExprType(Context), 6161 ForLoc, /*RefersToCapture=*/true)); 6162 } 6163 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6164 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6165 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6166 // associated for-loop of a simd construct with just one associated 6167 // for-loop may be listed in a linear clause with a constant-linear-step 6168 // that is the increment of the associated for-loop. The loop iteration 6169 // variable(s) in the associated for-loop(s) of a for or parallel for 6170 // construct may be listed in a private or lastprivate clause. 6171 DSAStackTy::DSAVarData DVar = 6172 DSAStack->getTopDSA(D, /*FromParent=*/false); 6173 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6174 // is declared in the loop and it is predetermined as a private. 6175 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6176 OpenMPClauseKind PredeterminedCKind = 6177 isOpenMPSimdDirective(DKind) 6178 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6179 : OMPC_private; 6180 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6181 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6182 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6183 DVar.CKind != OMPC_private))) || 6184 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6185 isOpenMPDistributeDirective(DKind)) && 6186 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6187 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6188 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6189 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6190 << getOpenMPClauseName(DVar.CKind) 6191 << getOpenMPDirectiveName(DKind) 6192 << getOpenMPClauseName(PredeterminedCKind); 6193 if (DVar.RefExpr == nullptr) 6194 DVar.CKind = PredeterminedCKind; 6195 reportOriginalDsa(*this, DSAStack, D, DVar, 6196 /*IsLoopIterVar=*/true); 6197 } else if (LoopDeclRefExpr) { 6198 // Make the loop iteration variable private (for worksharing 6199 // constructs), linear (for simd directives with the only one 6200 // associated loop) or lastprivate (for simd directives with several 6201 // collapsed or ordered loops). 6202 if (DVar.CKind == OMPC_unknown) 6203 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6204 PrivateRef); 6205 } 6206 } 6207 } 6208 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6209 } 6210 } 6211 6212 /// Called on a for stmt to check and extract its iteration space 6213 /// for further processing (such as collapsing). 6214 static bool checkOpenMPIterationSpace( 6215 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6216 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6217 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6218 Expr *OrderedLoopCountExpr, 6219 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6220 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6221 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6222 // OpenMP [2.6, Canonical Loop Form] 6223 // for (init-expr; test-expr; incr-expr) structured-block 6224 auto *For = dyn_cast_or_null<ForStmt>(S); 6225 if (!For) { 6226 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6227 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6228 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6229 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6230 if (TotalNestedLoopCount > 1) { 6231 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6232 SemaRef.Diag(DSA.getConstructLoc(), 6233 diag::note_omp_collapse_ordered_expr) 6234 << 2 << CollapseLoopCountExpr->getSourceRange() 6235 << OrderedLoopCountExpr->getSourceRange(); 6236 else if (CollapseLoopCountExpr) 6237 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6238 diag::note_omp_collapse_ordered_expr) 6239 << 0 << CollapseLoopCountExpr->getSourceRange(); 6240 else 6241 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6242 diag::note_omp_collapse_ordered_expr) 6243 << 1 << OrderedLoopCountExpr->getSourceRange(); 6244 } 6245 return true; 6246 } 6247 assert(For->getBody()); 6248 6249 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 6250 6251 // Check init. 6252 Stmt *Init = For->getInit(); 6253 if (ISC.checkAndSetInit(Init)) 6254 return true; 6255 6256 bool HasErrors = false; 6257 6258 // Check loop variable's type. 6259 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6260 // OpenMP [2.6, Canonical Loop Form] 6261 // Var is one of the following: 6262 // A variable of signed or unsigned integer type. 6263 // For C++, a variable of a random access iterator type. 6264 // For C, a variable of a pointer type. 6265 QualType VarType = LCDecl->getType().getNonReferenceType(); 6266 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6267 !VarType->isPointerType() && 6268 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6269 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6270 << SemaRef.getLangOpts().CPlusPlus; 6271 HasErrors = true; 6272 } 6273 6274 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6275 // a Construct 6276 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6277 // parallel for construct is (are) private. 6278 // The loop iteration variable in the associated for-loop of a simd 6279 // construct with just one associated for-loop is linear with a 6280 // constant-linear-step that is the increment of the associated for-loop. 6281 // Exclude loop var from the list of variables with implicitly defined data 6282 // sharing attributes. 6283 VarsWithImplicitDSA.erase(LCDecl); 6284 6285 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6286 6287 // Check test-expr. 6288 HasErrors |= ISC.checkAndSetCond(For->getCond()); 6289 6290 // Check incr-expr. 6291 HasErrors |= ISC.checkAndSetInc(For->getInc()); 6292 } 6293 6294 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6295 return HasErrors; 6296 6297 // Build the loop's iteration space representation. 6298 ResultIterSpaces[CurrentNestedLoopCount].PreCond = 6299 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 6300 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6301 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6302 (isOpenMPWorksharingDirective(DKind) || 6303 isOpenMPTaskLoopDirective(DKind) || 6304 isOpenMPDistributeDirective(DKind)), 6305 Captures); 6306 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6307 ISC.buildCounterVar(Captures, DSA); 6308 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6309 ISC.buildPrivateCounterVar(); 6310 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6311 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6312 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6313 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6314 ISC.getConditionSrcRange(); 6315 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6316 ISC.getIncrementSrcRange(); 6317 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6318 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6319 ISC.isStrictTestOp(); 6320 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6321 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6322 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6323 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6324 ISC.buildFinalCondition(DSA.getCurScope()); 6325 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6326 ISC.doesInitDependOnLC(); 6327 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6328 ISC.doesCondDependOnLC(); 6329 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6330 ISC.getLoopDependentIdx(); 6331 6332 HasErrors |= 6333 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6334 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6335 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6336 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6337 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6338 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6339 if (!HasErrors && DSA.isOrderedRegion()) { 6340 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6341 if (CurrentNestedLoopCount < 6342 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6343 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6344 CurrentNestedLoopCount, 6345 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6346 DSA.getOrderedRegionParam().second->setLoopCounter( 6347 CurrentNestedLoopCount, 6348 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6349 } 6350 } 6351 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6352 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6353 // Erroneous case - clause has some problems. 6354 continue; 6355 } 6356 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6357 Pair.second.size() <= CurrentNestedLoopCount) { 6358 // Erroneous case - clause has some problems. 6359 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6360 continue; 6361 } 6362 Expr *CntValue; 6363 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6364 CntValue = ISC.buildOrderedLoopData( 6365 DSA.getCurScope(), 6366 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6367 Pair.first->getDependencyLoc()); 6368 else 6369 CntValue = ISC.buildOrderedLoopData( 6370 DSA.getCurScope(), 6371 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6372 Pair.first->getDependencyLoc(), 6373 Pair.second[CurrentNestedLoopCount].first, 6374 Pair.second[CurrentNestedLoopCount].second); 6375 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6376 } 6377 } 6378 6379 return HasErrors; 6380 } 6381 6382 /// Build 'VarRef = Start. 6383 static ExprResult 6384 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6385 ExprResult Start, bool IsNonRectangularLB, 6386 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6387 // Build 'VarRef = Start. 6388 ExprResult NewStart = IsNonRectangularLB 6389 ? Start.get() 6390 : tryBuildCapture(SemaRef, Start.get(), Captures); 6391 if (!NewStart.isUsable()) 6392 return ExprError(); 6393 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6394 VarRef.get()->getType())) { 6395 NewStart = SemaRef.PerformImplicitConversion( 6396 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6397 /*AllowExplicit=*/true); 6398 if (!NewStart.isUsable()) 6399 return ExprError(); 6400 } 6401 6402 ExprResult Init = 6403 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6404 return Init; 6405 } 6406 6407 /// Build 'VarRef = Start + Iter * Step'. 6408 static ExprResult buildCounterUpdate( 6409 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6410 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6411 bool IsNonRectangularLB, 6412 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6413 // Add parentheses (for debugging purposes only). 6414 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6415 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6416 !Step.isUsable()) 6417 return ExprError(); 6418 6419 ExprResult NewStep = Step; 6420 if (Captures) 6421 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6422 if (NewStep.isInvalid()) 6423 return ExprError(); 6424 ExprResult Update = 6425 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6426 if (!Update.isUsable()) 6427 return ExprError(); 6428 6429 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6430 // 'VarRef = Start (+|-) Iter * Step'. 6431 if (!Start.isUsable()) 6432 return ExprError(); 6433 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6434 if (!NewStart.isUsable()) 6435 return ExprError(); 6436 if (Captures && !IsNonRectangularLB) 6437 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6438 if (NewStart.isInvalid()) 6439 return ExprError(); 6440 6441 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6442 ExprResult SavedUpdate = Update; 6443 ExprResult UpdateVal; 6444 if (VarRef.get()->getType()->isOverloadableType() || 6445 NewStart.get()->getType()->isOverloadableType() || 6446 Update.get()->getType()->isOverloadableType()) { 6447 Sema::TentativeAnalysisScope Trap(SemaRef); 6448 6449 Update = 6450 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6451 if (Update.isUsable()) { 6452 UpdateVal = 6453 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6454 VarRef.get(), SavedUpdate.get()); 6455 if (UpdateVal.isUsable()) { 6456 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6457 UpdateVal.get()); 6458 } 6459 } 6460 } 6461 6462 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6463 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6464 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6465 NewStart.get(), SavedUpdate.get()); 6466 if (!Update.isUsable()) 6467 return ExprError(); 6468 6469 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6470 VarRef.get()->getType())) { 6471 Update = SemaRef.PerformImplicitConversion( 6472 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6473 if (!Update.isUsable()) 6474 return ExprError(); 6475 } 6476 6477 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6478 } 6479 return Update; 6480 } 6481 6482 /// Convert integer expression \a E to make it have at least \a Bits 6483 /// bits. 6484 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6485 if (E == nullptr) 6486 return ExprError(); 6487 ASTContext &C = SemaRef.Context; 6488 QualType OldType = E->getType(); 6489 unsigned HasBits = C.getTypeSize(OldType); 6490 if (HasBits >= Bits) 6491 return ExprResult(E); 6492 // OK to convert to signed, because new type has more bits than old. 6493 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6494 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6495 true); 6496 } 6497 6498 /// Check if the given expression \a E is a constant integer that fits 6499 /// into \a Bits bits. 6500 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6501 if (E == nullptr) 6502 return false; 6503 llvm::APSInt Result; 6504 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6505 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6506 return false; 6507 } 6508 6509 /// Build preinits statement for the given declarations. 6510 static Stmt *buildPreInits(ASTContext &Context, 6511 MutableArrayRef<Decl *> PreInits) { 6512 if (!PreInits.empty()) { 6513 return new (Context) DeclStmt( 6514 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6515 SourceLocation(), SourceLocation()); 6516 } 6517 return nullptr; 6518 } 6519 6520 /// Build preinits statement for the given declarations. 6521 static Stmt * 6522 buildPreInits(ASTContext &Context, 6523 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6524 if (!Captures.empty()) { 6525 SmallVector<Decl *, 16> PreInits; 6526 for (const auto &Pair : Captures) 6527 PreInits.push_back(Pair.second->getDecl()); 6528 return buildPreInits(Context, PreInits); 6529 } 6530 return nullptr; 6531 } 6532 6533 /// Build postupdate expression for the given list of postupdates expressions. 6534 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6535 Expr *PostUpdate = nullptr; 6536 if (!PostUpdates.empty()) { 6537 for (Expr *E : PostUpdates) { 6538 Expr *ConvE = S.BuildCStyleCastExpr( 6539 E->getExprLoc(), 6540 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6541 E->getExprLoc(), E) 6542 .get(); 6543 PostUpdate = PostUpdate 6544 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6545 PostUpdate, ConvE) 6546 .get() 6547 : ConvE; 6548 } 6549 } 6550 return PostUpdate; 6551 } 6552 6553 /// Called on a for stmt to check itself and nested loops (if any). 6554 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6555 /// number of collapsed loops otherwise. 6556 static unsigned 6557 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6558 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6559 DSAStackTy &DSA, 6560 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6561 OMPLoopDirective::HelperExprs &Built) { 6562 unsigned NestedLoopCount = 1; 6563 if (CollapseLoopCountExpr) { 6564 // Found 'collapse' clause - calculate collapse number. 6565 Expr::EvalResult Result; 6566 if (!CollapseLoopCountExpr->isValueDependent() && 6567 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6568 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6569 } else { 6570 Built.clear(/*Size=*/1); 6571 return 1; 6572 } 6573 } 6574 unsigned OrderedLoopCount = 1; 6575 if (OrderedLoopCountExpr) { 6576 // Found 'ordered' clause - calculate collapse number. 6577 Expr::EvalResult EVResult; 6578 if (!OrderedLoopCountExpr->isValueDependent() && 6579 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6580 SemaRef.getASTContext())) { 6581 llvm::APSInt Result = EVResult.Val.getInt(); 6582 if (Result.getLimitedValue() < NestedLoopCount) { 6583 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6584 diag::err_omp_wrong_ordered_loop_count) 6585 << OrderedLoopCountExpr->getSourceRange(); 6586 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6587 diag::note_collapse_loop_count) 6588 << CollapseLoopCountExpr->getSourceRange(); 6589 } 6590 OrderedLoopCount = Result.getLimitedValue(); 6591 } else { 6592 Built.clear(/*Size=*/1); 6593 return 1; 6594 } 6595 } 6596 // This is helper routine for loop directives (e.g., 'for', 'simd', 6597 // 'for simd', etc.). 6598 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6599 SmallVector<LoopIterationSpace, 4> IterSpaces( 6600 std::max(OrderedLoopCount, NestedLoopCount)); 6601 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6602 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6603 if (checkOpenMPIterationSpace( 6604 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6605 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6606 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6607 return 0; 6608 // Move on to the next nested for loop, or to the loop body. 6609 // OpenMP [2.8.1, simd construct, Restrictions] 6610 // All loops associated with the construct must be perfectly nested; that 6611 // is, there must be no intervening code nor any OpenMP directive between 6612 // any two loops. 6613 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6614 } 6615 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6616 if (checkOpenMPIterationSpace( 6617 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6618 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6619 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6620 return 0; 6621 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6622 // Handle initialization of captured loop iterator variables. 6623 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6624 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6625 Captures[DRE] = DRE; 6626 } 6627 } 6628 // Move on to the next nested for loop, or to the loop body. 6629 // OpenMP [2.8.1, simd construct, Restrictions] 6630 // All loops associated with the construct must be perfectly nested; that 6631 // is, there must be no intervening code nor any OpenMP directive between 6632 // any two loops. 6633 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6634 } 6635 6636 Built.clear(/* size */ NestedLoopCount); 6637 6638 if (SemaRef.CurContext->isDependentContext()) 6639 return NestedLoopCount; 6640 6641 // An example of what is generated for the following code: 6642 // 6643 // #pragma omp simd collapse(2) ordered(2) 6644 // for (i = 0; i < NI; ++i) 6645 // for (k = 0; k < NK; ++k) 6646 // for (j = J0; j < NJ; j+=2) { 6647 // <loop body> 6648 // } 6649 // 6650 // We generate the code below. 6651 // Note: the loop body may be outlined in CodeGen. 6652 // Note: some counters may be C++ classes, operator- is used to find number of 6653 // iterations and operator+= to calculate counter value. 6654 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6655 // or i64 is currently supported). 6656 // 6657 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6658 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6659 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6660 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6661 // // similar updates for vars in clauses (e.g. 'linear') 6662 // <loop body (using local i and j)> 6663 // } 6664 // i = NI; // assign final values of counters 6665 // j = NJ; 6666 // 6667 6668 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6669 // the iteration counts of the collapsed for loops. 6670 // Precondition tests if there is at least one iteration (all conditions are 6671 // true). 6672 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6673 Expr *N0 = IterSpaces[0].NumIterations; 6674 ExprResult LastIteration32 = 6675 widenIterationCount(/*Bits=*/32, 6676 SemaRef 6677 .PerformImplicitConversion( 6678 N0->IgnoreImpCasts(), N0->getType(), 6679 Sema::AA_Converting, /*AllowExplicit=*/true) 6680 .get(), 6681 SemaRef); 6682 ExprResult LastIteration64 = widenIterationCount( 6683 /*Bits=*/64, 6684 SemaRef 6685 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6686 Sema::AA_Converting, 6687 /*AllowExplicit=*/true) 6688 .get(), 6689 SemaRef); 6690 6691 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6692 return NestedLoopCount; 6693 6694 ASTContext &C = SemaRef.Context; 6695 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6696 6697 Scope *CurScope = DSA.getCurScope(); 6698 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6699 if (PreCond.isUsable()) { 6700 PreCond = 6701 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6702 PreCond.get(), IterSpaces[Cnt].PreCond); 6703 } 6704 Expr *N = IterSpaces[Cnt].NumIterations; 6705 SourceLocation Loc = N->getExprLoc(); 6706 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6707 if (LastIteration32.isUsable()) 6708 LastIteration32 = SemaRef.BuildBinOp( 6709 CurScope, Loc, BO_Mul, LastIteration32.get(), 6710 SemaRef 6711 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6712 Sema::AA_Converting, 6713 /*AllowExplicit=*/true) 6714 .get()); 6715 if (LastIteration64.isUsable()) 6716 LastIteration64 = SemaRef.BuildBinOp( 6717 CurScope, Loc, BO_Mul, LastIteration64.get(), 6718 SemaRef 6719 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6720 Sema::AA_Converting, 6721 /*AllowExplicit=*/true) 6722 .get()); 6723 } 6724 6725 // Choose either the 32-bit or 64-bit version. 6726 ExprResult LastIteration = LastIteration64; 6727 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6728 (LastIteration32.isUsable() && 6729 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6730 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6731 fitsInto( 6732 /*Bits=*/32, 6733 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6734 LastIteration64.get(), SemaRef)))) 6735 LastIteration = LastIteration32; 6736 QualType VType = LastIteration.get()->getType(); 6737 QualType RealVType = VType; 6738 QualType StrideVType = VType; 6739 if (isOpenMPTaskLoopDirective(DKind)) { 6740 VType = 6741 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6742 StrideVType = 6743 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6744 } 6745 6746 if (!LastIteration.isUsable()) 6747 return 0; 6748 6749 // Save the number of iterations. 6750 ExprResult NumIterations = LastIteration; 6751 { 6752 LastIteration = SemaRef.BuildBinOp( 6753 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6754 LastIteration.get(), 6755 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6756 if (!LastIteration.isUsable()) 6757 return 0; 6758 } 6759 6760 // Calculate the last iteration number beforehand instead of doing this on 6761 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6762 llvm::APSInt Result; 6763 bool IsConstant = 6764 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6765 ExprResult CalcLastIteration; 6766 if (!IsConstant) { 6767 ExprResult SaveRef = 6768 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6769 LastIteration = SaveRef; 6770 6771 // Prepare SaveRef + 1. 6772 NumIterations = SemaRef.BuildBinOp( 6773 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6774 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6775 if (!NumIterations.isUsable()) 6776 return 0; 6777 } 6778 6779 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6780 6781 // Build variables passed into runtime, necessary for worksharing directives. 6782 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6783 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6784 isOpenMPDistributeDirective(DKind)) { 6785 // Lower bound variable, initialized with zero. 6786 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6787 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6788 SemaRef.AddInitializerToDecl(LBDecl, 6789 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6790 /*DirectInit*/ false); 6791 6792 // Upper bound variable, initialized with last iteration number. 6793 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6794 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6795 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6796 /*DirectInit*/ false); 6797 6798 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6799 // This will be used to implement clause 'lastprivate'. 6800 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6801 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6802 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6803 SemaRef.AddInitializerToDecl(ILDecl, 6804 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6805 /*DirectInit*/ false); 6806 6807 // Stride variable returned by runtime (we initialize it to 1 by default). 6808 VarDecl *STDecl = 6809 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6810 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6811 SemaRef.AddInitializerToDecl(STDecl, 6812 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6813 /*DirectInit*/ false); 6814 6815 // Build expression: UB = min(UB, LastIteration) 6816 // It is necessary for CodeGen of directives with static scheduling. 6817 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6818 UB.get(), LastIteration.get()); 6819 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6820 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6821 LastIteration.get(), UB.get()); 6822 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6823 CondOp.get()); 6824 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6825 6826 // If we have a combined directive that combines 'distribute', 'for' or 6827 // 'simd' we need to be able to access the bounds of the schedule of the 6828 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6829 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6830 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6831 // Lower bound variable, initialized with zero. 6832 VarDecl *CombLBDecl = 6833 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6834 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6835 SemaRef.AddInitializerToDecl( 6836 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6837 /*DirectInit*/ false); 6838 6839 // Upper bound variable, initialized with last iteration number. 6840 VarDecl *CombUBDecl = 6841 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6842 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6843 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6844 /*DirectInit*/ false); 6845 6846 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6847 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6848 ExprResult CombCondOp = 6849 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6850 LastIteration.get(), CombUB.get()); 6851 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6852 CombCondOp.get()); 6853 CombEUB = 6854 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6855 6856 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6857 // We expect to have at least 2 more parameters than the 'parallel' 6858 // directive does - the lower and upper bounds of the previous schedule. 6859 assert(CD->getNumParams() >= 4 && 6860 "Unexpected number of parameters in loop combined directive"); 6861 6862 // Set the proper type for the bounds given what we learned from the 6863 // enclosed loops. 6864 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6865 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6866 6867 // Previous lower and upper bounds are obtained from the region 6868 // parameters. 6869 PrevLB = 6870 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6871 PrevUB = 6872 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6873 } 6874 } 6875 6876 // Build the iteration variable and its initialization before loop. 6877 ExprResult IV; 6878 ExprResult Init, CombInit; 6879 { 6880 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6881 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6882 Expr *RHS = 6883 (isOpenMPWorksharingDirective(DKind) || 6884 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6885 ? LB.get() 6886 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6887 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6888 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6889 6890 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6891 Expr *CombRHS = 6892 (isOpenMPWorksharingDirective(DKind) || 6893 isOpenMPTaskLoopDirective(DKind) || 6894 isOpenMPDistributeDirective(DKind)) 6895 ? CombLB.get() 6896 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6897 CombInit = 6898 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6899 CombInit = 6900 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6901 } 6902 } 6903 6904 bool UseStrictCompare = 6905 RealVType->hasUnsignedIntegerRepresentation() && 6906 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6907 return LIS.IsStrictCompare; 6908 }); 6909 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6910 // unsigned IV)) for worksharing loops. 6911 SourceLocation CondLoc = AStmt->getBeginLoc(); 6912 Expr *BoundUB = UB.get(); 6913 if (UseStrictCompare) { 6914 BoundUB = 6915 SemaRef 6916 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6917 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6918 .get(); 6919 BoundUB = 6920 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6921 } 6922 ExprResult Cond = 6923 (isOpenMPWorksharingDirective(DKind) || 6924 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6925 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6926 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6927 BoundUB) 6928 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6929 NumIterations.get()); 6930 ExprResult CombDistCond; 6931 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6932 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6933 NumIterations.get()); 6934 } 6935 6936 ExprResult CombCond; 6937 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6938 Expr *BoundCombUB = CombUB.get(); 6939 if (UseStrictCompare) { 6940 BoundCombUB = 6941 SemaRef 6942 .BuildBinOp( 6943 CurScope, CondLoc, BO_Add, BoundCombUB, 6944 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6945 .get(); 6946 BoundCombUB = 6947 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6948 .get(); 6949 } 6950 CombCond = 6951 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6952 IV.get(), BoundCombUB); 6953 } 6954 // Loop increment (IV = IV + 1) 6955 SourceLocation IncLoc = AStmt->getBeginLoc(); 6956 ExprResult Inc = 6957 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6958 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6959 if (!Inc.isUsable()) 6960 return 0; 6961 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6962 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6963 if (!Inc.isUsable()) 6964 return 0; 6965 6966 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6967 // Used for directives with static scheduling. 6968 // In combined construct, add combined version that use CombLB and CombUB 6969 // base variables for the update 6970 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6971 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6972 isOpenMPDistributeDirective(DKind)) { 6973 // LB + ST 6974 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6975 if (!NextLB.isUsable()) 6976 return 0; 6977 // LB = LB + ST 6978 NextLB = 6979 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6980 NextLB = 6981 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6982 if (!NextLB.isUsable()) 6983 return 0; 6984 // UB + ST 6985 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6986 if (!NextUB.isUsable()) 6987 return 0; 6988 // UB = UB + ST 6989 NextUB = 6990 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6991 NextUB = 6992 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6993 if (!NextUB.isUsable()) 6994 return 0; 6995 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6996 CombNextLB = 6997 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6998 if (!NextLB.isUsable()) 6999 return 0; 7000 // LB = LB + ST 7001 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7002 CombNextLB.get()); 7003 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7004 /*DiscardedValue*/ false); 7005 if (!CombNextLB.isUsable()) 7006 return 0; 7007 // UB + ST 7008 CombNextUB = 7009 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7010 if (!CombNextUB.isUsable()) 7011 return 0; 7012 // UB = UB + ST 7013 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7014 CombNextUB.get()); 7015 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7016 /*DiscardedValue*/ false); 7017 if (!CombNextUB.isUsable()) 7018 return 0; 7019 } 7020 } 7021 7022 // Create increment expression for distribute loop when combined in a same 7023 // directive with for as IV = IV + ST; ensure upper bound expression based 7024 // on PrevUB instead of NumIterations - used to implement 'for' when found 7025 // in combination with 'distribute', like in 'distribute parallel for' 7026 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7027 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7028 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7029 DistCond = SemaRef.BuildBinOp( 7030 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7031 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7032 7033 DistInc = 7034 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7035 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7036 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7037 DistInc.get()); 7038 DistInc = 7039 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7040 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7041 7042 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7043 // construct 7044 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7045 ExprResult IsUBGreater = 7046 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7047 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7048 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7049 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7050 CondOp.get()); 7051 PrevEUB = 7052 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7053 7054 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7055 // parallel for is in combination with a distribute directive with 7056 // schedule(static, 1) 7057 Expr *BoundPrevUB = PrevUB.get(); 7058 if (UseStrictCompare) { 7059 BoundPrevUB = 7060 SemaRef 7061 .BuildBinOp( 7062 CurScope, CondLoc, BO_Add, BoundPrevUB, 7063 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7064 .get(); 7065 BoundPrevUB = 7066 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7067 .get(); 7068 } 7069 ParForInDistCond = 7070 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7071 IV.get(), BoundPrevUB); 7072 } 7073 7074 // Build updates and final values of the loop counters. 7075 bool HasErrors = false; 7076 Built.Counters.resize(NestedLoopCount); 7077 Built.Inits.resize(NestedLoopCount); 7078 Built.Updates.resize(NestedLoopCount); 7079 Built.Finals.resize(NestedLoopCount); 7080 Built.DependentCounters.resize(NestedLoopCount); 7081 Built.DependentInits.resize(NestedLoopCount); 7082 Built.FinalsConditions.resize(NestedLoopCount); 7083 { 7084 // We implement the following algorithm for obtaining the 7085 // original loop iteration variable values based on the 7086 // value of the collapsed loop iteration variable IV. 7087 // 7088 // Let n+1 be the number of collapsed loops in the nest. 7089 // Iteration variables (I0, I1, .... In) 7090 // Iteration counts (N0, N1, ... Nn) 7091 // 7092 // Acc = IV; 7093 // 7094 // To compute Ik for loop k, 0 <= k <= n, generate: 7095 // Prod = N(k+1) * N(k+2) * ... * Nn; 7096 // Ik = Acc / Prod; 7097 // Acc -= Ik * Prod; 7098 // 7099 ExprResult Acc = IV; 7100 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7101 LoopIterationSpace &IS = IterSpaces[Cnt]; 7102 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7103 ExprResult Iter; 7104 7105 // Compute prod 7106 ExprResult Prod = 7107 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7108 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7109 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7110 IterSpaces[K].NumIterations); 7111 7112 // Iter = Acc / Prod 7113 // If there is at least one more inner loop to avoid 7114 // multiplication by 1. 7115 if (Cnt + 1 < NestedLoopCount) 7116 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7117 Acc.get(), Prod.get()); 7118 else 7119 Iter = Acc; 7120 if (!Iter.isUsable()) { 7121 HasErrors = true; 7122 break; 7123 } 7124 7125 // Update Acc: 7126 // Acc -= Iter * Prod 7127 // Check if there is at least one more inner loop to avoid 7128 // multiplication by 1. 7129 if (Cnt + 1 < NestedLoopCount) 7130 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7131 Iter.get(), Prod.get()); 7132 else 7133 Prod = Iter; 7134 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7135 Acc.get(), Prod.get()); 7136 7137 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7138 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7139 DeclRefExpr *CounterVar = buildDeclRefExpr( 7140 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7141 /*RefersToCapture=*/true); 7142 ExprResult Init = 7143 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7144 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7145 if (!Init.isUsable()) { 7146 HasErrors = true; 7147 break; 7148 } 7149 ExprResult Update = buildCounterUpdate( 7150 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7151 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7152 if (!Update.isUsable()) { 7153 HasErrors = true; 7154 break; 7155 } 7156 7157 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7158 ExprResult Final = 7159 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7160 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7161 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7162 if (!Final.isUsable()) { 7163 HasErrors = true; 7164 break; 7165 } 7166 7167 if (!Update.isUsable() || !Final.isUsable()) { 7168 HasErrors = true; 7169 break; 7170 } 7171 // Save results 7172 Built.Counters[Cnt] = IS.CounterVar; 7173 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7174 Built.Inits[Cnt] = Init.get(); 7175 Built.Updates[Cnt] = Update.get(); 7176 Built.Finals[Cnt] = Final.get(); 7177 Built.DependentCounters[Cnt] = nullptr; 7178 Built.DependentInits[Cnt] = nullptr; 7179 Built.FinalsConditions[Cnt] = nullptr; 7180 if (IS.IsNonRectangularLB) { 7181 Built.DependentCounters[Cnt] = 7182 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7183 Built.DependentInits[Cnt] = 7184 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7185 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7186 } 7187 } 7188 } 7189 7190 if (HasErrors) 7191 return 0; 7192 7193 // Save results 7194 Built.IterationVarRef = IV.get(); 7195 Built.LastIteration = LastIteration.get(); 7196 Built.NumIterations = NumIterations.get(); 7197 Built.CalcLastIteration = SemaRef 7198 .ActOnFinishFullExpr(CalcLastIteration.get(), 7199 /*DiscardedValue=*/false) 7200 .get(); 7201 Built.PreCond = PreCond.get(); 7202 Built.PreInits = buildPreInits(C, Captures); 7203 Built.Cond = Cond.get(); 7204 Built.Init = Init.get(); 7205 Built.Inc = Inc.get(); 7206 Built.LB = LB.get(); 7207 Built.UB = UB.get(); 7208 Built.IL = IL.get(); 7209 Built.ST = ST.get(); 7210 Built.EUB = EUB.get(); 7211 Built.NLB = NextLB.get(); 7212 Built.NUB = NextUB.get(); 7213 Built.PrevLB = PrevLB.get(); 7214 Built.PrevUB = PrevUB.get(); 7215 Built.DistInc = DistInc.get(); 7216 Built.PrevEUB = PrevEUB.get(); 7217 Built.DistCombinedFields.LB = CombLB.get(); 7218 Built.DistCombinedFields.UB = CombUB.get(); 7219 Built.DistCombinedFields.EUB = CombEUB.get(); 7220 Built.DistCombinedFields.Init = CombInit.get(); 7221 Built.DistCombinedFields.Cond = CombCond.get(); 7222 Built.DistCombinedFields.NLB = CombNextLB.get(); 7223 Built.DistCombinedFields.NUB = CombNextUB.get(); 7224 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7225 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7226 7227 return NestedLoopCount; 7228 } 7229 7230 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7231 auto CollapseClauses = 7232 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7233 if (CollapseClauses.begin() != CollapseClauses.end()) 7234 return (*CollapseClauses.begin())->getNumForLoops(); 7235 return nullptr; 7236 } 7237 7238 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7239 auto OrderedClauses = 7240 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7241 if (OrderedClauses.begin() != OrderedClauses.end()) 7242 return (*OrderedClauses.begin())->getNumForLoops(); 7243 return nullptr; 7244 } 7245 7246 static bool checkSimdlenSafelenSpecified(Sema &S, 7247 const ArrayRef<OMPClause *> Clauses) { 7248 const OMPSafelenClause *Safelen = nullptr; 7249 const OMPSimdlenClause *Simdlen = nullptr; 7250 7251 for (const OMPClause *Clause : Clauses) { 7252 if (Clause->getClauseKind() == OMPC_safelen) 7253 Safelen = cast<OMPSafelenClause>(Clause); 7254 else if (Clause->getClauseKind() == OMPC_simdlen) 7255 Simdlen = cast<OMPSimdlenClause>(Clause); 7256 if (Safelen && Simdlen) 7257 break; 7258 } 7259 7260 if (Simdlen && Safelen) { 7261 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7262 const Expr *SafelenLength = Safelen->getSafelen(); 7263 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7264 SimdlenLength->isInstantiationDependent() || 7265 SimdlenLength->containsUnexpandedParameterPack()) 7266 return false; 7267 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7268 SafelenLength->isInstantiationDependent() || 7269 SafelenLength->containsUnexpandedParameterPack()) 7270 return false; 7271 Expr::EvalResult SimdlenResult, SafelenResult; 7272 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7273 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7274 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7275 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7276 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7277 // If both simdlen and safelen clauses are specified, the value of the 7278 // simdlen parameter must be less than or equal to the value of the safelen 7279 // parameter. 7280 if (SimdlenRes > SafelenRes) { 7281 S.Diag(SimdlenLength->getExprLoc(), 7282 diag::err_omp_wrong_simdlen_safelen_values) 7283 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7284 return true; 7285 } 7286 } 7287 return false; 7288 } 7289 7290 StmtResult 7291 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7292 SourceLocation StartLoc, SourceLocation EndLoc, 7293 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7294 if (!AStmt) 7295 return StmtError(); 7296 7297 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7298 OMPLoopDirective::HelperExprs B; 7299 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7300 // define the nested loops number. 7301 unsigned NestedLoopCount = checkOpenMPLoop( 7302 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7303 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7304 if (NestedLoopCount == 0) 7305 return StmtError(); 7306 7307 assert((CurContext->isDependentContext() || B.builtAll()) && 7308 "omp simd loop exprs were not built"); 7309 7310 if (!CurContext->isDependentContext()) { 7311 // Finalize the clauses that need pre-built expressions for CodeGen. 7312 for (OMPClause *C : Clauses) { 7313 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7314 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7315 B.NumIterations, *this, CurScope, 7316 DSAStack)) 7317 return StmtError(); 7318 } 7319 } 7320 7321 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7322 return StmtError(); 7323 7324 setFunctionHasBranchProtectedScope(); 7325 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7326 Clauses, AStmt, B); 7327 } 7328 7329 StmtResult 7330 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7331 SourceLocation StartLoc, SourceLocation EndLoc, 7332 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7333 if (!AStmt) 7334 return StmtError(); 7335 7336 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7337 OMPLoopDirective::HelperExprs B; 7338 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7339 // define the nested loops number. 7340 unsigned NestedLoopCount = checkOpenMPLoop( 7341 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7342 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7343 if (NestedLoopCount == 0) 7344 return StmtError(); 7345 7346 assert((CurContext->isDependentContext() || B.builtAll()) && 7347 "omp for loop exprs were not built"); 7348 7349 if (!CurContext->isDependentContext()) { 7350 // Finalize the clauses that need pre-built expressions for CodeGen. 7351 for (OMPClause *C : Clauses) { 7352 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7353 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7354 B.NumIterations, *this, CurScope, 7355 DSAStack)) 7356 return StmtError(); 7357 } 7358 } 7359 7360 setFunctionHasBranchProtectedScope(); 7361 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7362 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7363 } 7364 7365 StmtResult Sema::ActOnOpenMPForSimdDirective( 7366 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7367 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7368 if (!AStmt) 7369 return StmtError(); 7370 7371 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7372 OMPLoopDirective::HelperExprs B; 7373 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7374 // define the nested loops number. 7375 unsigned NestedLoopCount = 7376 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7377 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7378 VarsWithImplicitDSA, B); 7379 if (NestedLoopCount == 0) 7380 return StmtError(); 7381 7382 assert((CurContext->isDependentContext() || B.builtAll()) && 7383 "omp for simd loop exprs were not built"); 7384 7385 if (!CurContext->isDependentContext()) { 7386 // Finalize the clauses that need pre-built expressions for CodeGen. 7387 for (OMPClause *C : Clauses) { 7388 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7389 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7390 B.NumIterations, *this, CurScope, 7391 DSAStack)) 7392 return StmtError(); 7393 } 7394 } 7395 7396 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7397 return StmtError(); 7398 7399 setFunctionHasBranchProtectedScope(); 7400 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7401 Clauses, AStmt, B); 7402 } 7403 7404 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7405 Stmt *AStmt, 7406 SourceLocation StartLoc, 7407 SourceLocation EndLoc) { 7408 if (!AStmt) 7409 return StmtError(); 7410 7411 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7412 auto BaseStmt = AStmt; 7413 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7414 BaseStmt = CS->getCapturedStmt(); 7415 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7416 auto S = C->children(); 7417 if (S.begin() == S.end()) 7418 return StmtError(); 7419 // All associated statements must be '#pragma omp section' except for 7420 // the first one. 7421 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7422 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7423 if (SectionStmt) 7424 Diag(SectionStmt->getBeginLoc(), 7425 diag::err_omp_sections_substmt_not_section); 7426 return StmtError(); 7427 } 7428 cast<OMPSectionDirective>(SectionStmt) 7429 ->setHasCancel(DSAStack->isCancelRegion()); 7430 } 7431 } else { 7432 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7433 return StmtError(); 7434 } 7435 7436 setFunctionHasBranchProtectedScope(); 7437 7438 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7439 DSAStack->isCancelRegion()); 7440 } 7441 7442 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7443 SourceLocation StartLoc, 7444 SourceLocation EndLoc) { 7445 if (!AStmt) 7446 return StmtError(); 7447 7448 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7449 7450 setFunctionHasBranchProtectedScope(); 7451 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7452 7453 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7454 DSAStack->isCancelRegion()); 7455 } 7456 7457 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7458 Stmt *AStmt, 7459 SourceLocation StartLoc, 7460 SourceLocation EndLoc) { 7461 if (!AStmt) 7462 return StmtError(); 7463 7464 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7465 7466 setFunctionHasBranchProtectedScope(); 7467 7468 // OpenMP [2.7.3, single Construct, Restrictions] 7469 // The copyprivate clause must not be used with the nowait clause. 7470 const OMPClause *Nowait = nullptr; 7471 const OMPClause *Copyprivate = nullptr; 7472 for (const OMPClause *Clause : Clauses) { 7473 if (Clause->getClauseKind() == OMPC_nowait) 7474 Nowait = Clause; 7475 else if (Clause->getClauseKind() == OMPC_copyprivate) 7476 Copyprivate = Clause; 7477 if (Copyprivate && Nowait) { 7478 Diag(Copyprivate->getBeginLoc(), 7479 diag::err_omp_single_copyprivate_with_nowait); 7480 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7481 return StmtError(); 7482 } 7483 } 7484 7485 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7486 } 7487 7488 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7489 SourceLocation StartLoc, 7490 SourceLocation EndLoc) { 7491 if (!AStmt) 7492 return StmtError(); 7493 7494 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7495 7496 setFunctionHasBranchProtectedScope(); 7497 7498 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7499 } 7500 7501 StmtResult Sema::ActOnOpenMPCriticalDirective( 7502 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7503 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7504 if (!AStmt) 7505 return StmtError(); 7506 7507 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7508 7509 bool ErrorFound = false; 7510 llvm::APSInt Hint; 7511 SourceLocation HintLoc; 7512 bool DependentHint = false; 7513 for (const OMPClause *C : Clauses) { 7514 if (C->getClauseKind() == OMPC_hint) { 7515 if (!DirName.getName()) { 7516 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7517 ErrorFound = true; 7518 } 7519 Expr *E = cast<OMPHintClause>(C)->getHint(); 7520 if (E->isTypeDependent() || E->isValueDependent() || 7521 E->isInstantiationDependent()) { 7522 DependentHint = true; 7523 } else { 7524 Hint = E->EvaluateKnownConstInt(Context); 7525 HintLoc = C->getBeginLoc(); 7526 } 7527 } 7528 } 7529 if (ErrorFound) 7530 return StmtError(); 7531 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7532 if (Pair.first && DirName.getName() && !DependentHint) { 7533 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7534 Diag(StartLoc, diag::err_omp_critical_with_hint); 7535 if (HintLoc.isValid()) 7536 Diag(HintLoc, diag::note_omp_critical_hint_here) 7537 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7538 else 7539 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7540 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7541 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7542 << 1 7543 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7544 /*Radix=*/10, /*Signed=*/false); 7545 } else { 7546 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7547 } 7548 } 7549 } 7550 7551 setFunctionHasBranchProtectedScope(); 7552 7553 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7554 Clauses, AStmt); 7555 if (!Pair.first && DirName.getName() && !DependentHint) 7556 DSAStack->addCriticalWithHint(Dir, Hint); 7557 return Dir; 7558 } 7559 7560 StmtResult Sema::ActOnOpenMPParallelForDirective( 7561 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7562 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7563 if (!AStmt) 7564 return StmtError(); 7565 7566 auto *CS = cast<CapturedStmt>(AStmt); 7567 // 1.2.2 OpenMP Language Terminology 7568 // Structured block - An executable statement with a single entry at the 7569 // top and a single exit at the bottom. 7570 // The point of exit cannot be a branch out of the structured block. 7571 // longjmp() and throw() must not violate the entry/exit criteria. 7572 CS->getCapturedDecl()->setNothrow(); 7573 7574 OMPLoopDirective::HelperExprs B; 7575 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7576 // define the nested loops number. 7577 unsigned NestedLoopCount = 7578 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7579 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7580 VarsWithImplicitDSA, B); 7581 if (NestedLoopCount == 0) 7582 return StmtError(); 7583 7584 assert((CurContext->isDependentContext() || B.builtAll()) && 7585 "omp parallel for loop exprs were not built"); 7586 7587 if (!CurContext->isDependentContext()) { 7588 // Finalize the clauses that need pre-built expressions for CodeGen. 7589 for (OMPClause *C : Clauses) { 7590 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7591 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7592 B.NumIterations, *this, CurScope, 7593 DSAStack)) 7594 return StmtError(); 7595 } 7596 } 7597 7598 setFunctionHasBranchProtectedScope(); 7599 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7600 NestedLoopCount, Clauses, AStmt, B, 7601 DSAStack->isCancelRegion()); 7602 } 7603 7604 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7605 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7606 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7607 if (!AStmt) 7608 return StmtError(); 7609 7610 auto *CS = cast<CapturedStmt>(AStmt); 7611 // 1.2.2 OpenMP Language Terminology 7612 // Structured block - An executable statement with a single entry at the 7613 // top and a single exit at the bottom. 7614 // The point of exit cannot be a branch out of the structured block. 7615 // longjmp() and throw() must not violate the entry/exit criteria. 7616 CS->getCapturedDecl()->setNothrow(); 7617 7618 OMPLoopDirective::HelperExprs B; 7619 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7620 // define the nested loops number. 7621 unsigned NestedLoopCount = 7622 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7623 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7624 VarsWithImplicitDSA, B); 7625 if (NestedLoopCount == 0) 7626 return StmtError(); 7627 7628 if (!CurContext->isDependentContext()) { 7629 // Finalize the clauses that need pre-built expressions for CodeGen. 7630 for (OMPClause *C : Clauses) { 7631 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7632 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7633 B.NumIterations, *this, CurScope, 7634 DSAStack)) 7635 return StmtError(); 7636 } 7637 } 7638 7639 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7640 return StmtError(); 7641 7642 setFunctionHasBranchProtectedScope(); 7643 return OMPParallelForSimdDirective::Create( 7644 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7645 } 7646 7647 StmtResult 7648 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7649 Stmt *AStmt, SourceLocation StartLoc, 7650 SourceLocation EndLoc) { 7651 if (!AStmt) 7652 return StmtError(); 7653 7654 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7655 auto BaseStmt = AStmt; 7656 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7657 BaseStmt = CS->getCapturedStmt(); 7658 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7659 auto S = C->children(); 7660 if (S.begin() == S.end()) 7661 return StmtError(); 7662 // All associated statements must be '#pragma omp section' except for 7663 // the first one. 7664 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7665 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7666 if (SectionStmt) 7667 Diag(SectionStmt->getBeginLoc(), 7668 diag::err_omp_parallel_sections_substmt_not_section); 7669 return StmtError(); 7670 } 7671 cast<OMPSectionDirective>(SectionStmt) 7672 ->setHasCancel(DSAStack->isCancelRegion()); 7673 } 7674 } else { 7675 Diag(AStmt->getBeginLoc(), 7676 diag::err_omp_parallel_sections_not_compound_stmt); 7677 return StmtError(); 7678 } 7679 7680 setFunctionHasBranchProtectedScope(); 7681 7682 return OMPParallelSectionsDirective::Create( 7683 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7684 } 7685 7686 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7687 Stmt *AStmt, SourceLocation StartLoc, 7688 SourceLocation EndLoc) { 7689 if (!AStmt) 7690 return StmtError(); 7691 7692 auto *CS = cast<CapturedStmt>(AStmt); 7693 // 1.2.2 OpenMP Language Terminology 7694 // Structured block - An executable statement with a single entry at the 7695 // top and a single exit at the bottom. 7696 // The point of exit cannot be a branch out of the structured block. 7697 // longjmp() and throw() must not violate the entry/exit criteria. 7698 CS->getCapturedDecl()->setNothrow(); 7699 7700 setFunctionHasBranchProtectedScope(); 7701 7702 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7703 DSAStack->isCancelRegion()); 7704 } 7705 7706 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7707 SourceLocation EndLoc) { 7708 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7709 } 7710 7711 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7712 SourceLocation EndLoc) { 7713 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7714 } 7715 7716 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7717 SourceLocation EndLoc) { 7718 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7719 } 7720 7721 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7722 Stmt *AStmt, 7723 SourceLocation StartLoc, 7724 SourceLocation EndLoc) { 7725 if (!AStmt) 7726 return StmtError(); 7727 7728 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7729 7730 setFunctionHasBranchProtectedScope(); 7731 7732 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7733 AStmt, 7734 DSAStack->getTaskgroupReductionRef()); 7735 } 7736 7737 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7738 SourceLocation StartLoc, 7739 SourceLocation EndLoc) { 7740 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7741 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7742 } 7743 7744 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7745 Stmt *AStmt, 7746 SourceLocation StartLoc, 7747 SourceLocation EndLoc) { 7748 const OMPClause *DependFound = nullptr; 7749 const OMPClause *DependSourceClause = nullptr; 7750 const OMPClause *DependSinkClause = nullptr; 7751 bool ErrorFound = false; 7752 const OMPThreadsClause *TC = nullptr; 7753 const OMPSIMDClause *SC = nullptr; 7754 for (const OMPClause *C : Clauses) { 7755 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7756 DependFound = C; 7757 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7758 if (DependSourceClause) { 7759 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7760 << getOpenMPDirectiveName(OMPD_ordered) 7761 << getOpenMPClauseName(OMPC_depend) << 2; 7762 ErrorFound = true; 7763 } else { 7764 DependSourceClause = C; 7765 } 7766 if (DependSinkClause) { 7767 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7768 << 0; 7769 ErrorFound = true; 7770 } 7771 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7772 if (DependSourceClause) { 7773 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7774 << 1; 7775 ErrorFound = true; 7776 } 7777 DependSinkClause = C; 7778 } 7779 } else if (C->getClauseKind() == OMPC_threads) { 7780 TC = cast<OMPThreadsClause>(C); 7781 } else if (C->getClauseKind() == OMPC_simd) { 7782 SC = cast<OMPSIMDClause>(C); 7783 } 7784 } 7785 if (!ErrorFound && !SC && 7786 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7787 // OpenMP [2.8.1,simd Construct, Restrictions] 7788 // An ordered construct with the simd clause is the only OpenMP construct 7789 // that can appear in the simd region. 7790 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7791 ErrorFound = true; 7792 } else if (DependFound && (TC || SC)) { 7793 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7794 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7795 ErrorFound = true; 7796 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7797 Diag(DependFound->getBeginLoc(), 7798 diag::err_omp_ordered_directive_without_param); 7799 ErrorFound = true; 7800 } else if (TC || Clauses.empty()) { 7801 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 7802 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 7803 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 7804 << (TC != nullptr); 7805 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7806 ErrorFound = true; 7807 } 7808 } 7809 if ((!AStmt && !DependFound) || ErrorFound) 7810 return StmtError(); 7811 7812 if (AStmt) { 7813 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7814 7815 setFunctionHasBranchProtectedScope(); 7816 } 7817 7818 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7819 } 7820 7821 namespace { 7822 /// Helper class for checking expression in 'omp atomic [update]' 7823 /// construct. 7824 class OpenMPAtomicUpdateChecker { 7825 /// Error results for atomic update expressions. 7826 enum ExprAnalysisErrorCode { 7827 /// A statement is not an expression statement. 7828 NotAnExpression, 7829 /// Expression is not builtin binary or unary operation. 7830 NotABinaryOrUnaryExpression, 7831 /// Unary operation is not post-/pre- increment/decrement operation. 7832 NotAnUnaryIncDecExpression, 7833 /// An expression is not of scalar type. 7834 NotAScalarType, 7835 /// A binary operation is not an assignment operation. 7836 NotAnAssignmentOp, 7837 /// RHS part of the binary operation is not a binary expression. 7838 NotABinaryExpression, 7839 /// RHS part is not additive/multiplicative/shift/biwise binary 7840 /// expression. 7841 NotABinaryOperator, 7842 /// RHS binary operation does not have reference to the updated LHS 7843 /// part. 7844 NotAnUpdateExpression, 7845 /// No errors is found. 7846 NoError 7847 }; 7848 /// Reference to Sema. 7849 Sema &SemaRef; 7850 /// A location for note diagnostics (when error is found). 7851 SourceLocation NoteLoc; 7852 /// 'x' lvalue part of the source atomic expression. 7853 Expr *X; 7854 /// 'expr' rvalue part of the source atomic expression. 7855 Expr *E; 7856 /// Helper expression of the form 7857 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7858 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7859 Expr *UpdateExpr; 7860 /// Is 'x' a LHS in a RHS part of full update expression. It is 7861 /// important for non-associative operations. 7862 bool IsXLHSInRHSPart; 7863 BinaryOperatorKind Op; 7864 SourceLocation OpLoc; 7865 /// true if the source expression is a postfix unary operation, false 7866 /// if it is a prefix unary operation. 7867 bool IsPostfixUpdate; 7868 7869 public: 7870 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7871 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7872 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7873 /// Check specified statement that it is suitable for 'atomic update' 7874 /// constructs and extract 'x', 'expr' and Operation from the original 7875 /// expression. If DiagId and NoteId == 0, then only check is performed 7876 /// without error notification. 7877 /// \param DiagId Diagnostic which should be emitted if error is found. 7878 /// \param NoteId Diagnostic note for the main error message. 7879 /// \return true if statement is not an update expression, false otherwise. 7880 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7881 /// Return the 'x' lvalue part of the source atomic expression. 7882 Expr *getX() const { return X; } 7883 /// Return the 'expr' rvalue part of the source atomic expression. 7884 Expr *getExpr() const { return E; } 7885 /// Return the update expression used in calculation of the updated 7886 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7887 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7888 Expr *getUpdateExpr() const { return UpdateExpr; } 7889 /// Return true if 'x' is LHS in RHS part of full update expression, 7890 /// false otherwise. 7891 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7892 7893 /// true if the source expression is a postfix unary operation, false 7894 /// if it is a prefix unary operation. 7895 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7896 7897 private: 7898 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7899 unsigned NoteId = 0); 7900 }; 7901 } // namespace 7902 7903 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7904 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7905 ExprAnalysisErrorCode ErrorFound = NoError; 7906 SourceLocation ErrorLoc, NoteLoc; 7907 SourceRange ErrorRange, NoteRange; 7908 // Allowed constructs are: 7909 // x = x binop expr; 7910 // x = expr binop x; 7911 if (AtomicBinOp->getOpcode() == BO_Assign) { 7912 X = AtomicBinOp->getLHS(); 7913 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7914 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7915 if (AtomicInnerBinOp->isMultiplicativeOp() || 7916 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7917 AtomicInnerBinOp->isBitwiseOp()) { 7918 Op = AtomicInnerBinOp->getOpcode(); 7919 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7920 Expr *LHS = AtomicInnerBinOp->getLHS(); 7921 Expr *RHS = AtomicInnerBinOp->getRHS(); 7922 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7923 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7924 /*Canonical=*/true); 7925 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7926 /*Canonical=*/true); 7927 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7928 /*Canonical=*/true); 7929 if (XId == LHSId) { 7930 E = RHS; 7931 IsXLHSInRHSPart = true; 7932 } else if (XId == RHSId) { 7933 E = LHS; 7934 IsXLHSInRHSPart = false; 7935 } else { 7936 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7937 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7938 NoteLoc = X->getExprLoc(); 7939 NoteRange = X->getSourceRange(); 7940 ErrorFound = NotAnUpdateExpression; 7941 } 7942 } else { 7943 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7944 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7945 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7946 NoteRange = SourceRange(NoteLoc, NoteLoc); 7947 ErrorFound = NotABinaryOperator; 7948 } 7949 } else { 7950 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7951 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7952 ErrorFound = NotABinaryExpression; 7953 } 7954 } else { 7955 ErrorLoc = AtomicBinOp->getExprLoc(); 7956 ErrorRange = AtomicBinOp->getSourceRange(); 7957 NoteLoc = AtomicBinOp->getOperatorLoc(); 7958 NoteRange = SourceRange(NoteLoc, NoteLoc); 7959 ErrorFound = NotAnAssignmentOp; 7960 } 7961 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7962 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7963 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7964 return true; 7965 } 7966 if (SemaRef.CurContext->isDependentContext()) 7967 E = X = UpdateExpr = nullptr; 7968 return ErrorFound != NoError; 7969 } 7970 7971 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7972 unsigned NoteId) { 7973 ExprAnalysisErrorCode ErrorFound = NoError; 7974 SourceLocation ErrorLoc, NoteLoc; 7975 SourceRange ErrorRange, NoteRange; 7976 // Allowed constructs are: 7977 // x++; 7978 // x--; 7979 // ++x; 7980 // --x; 7981 // x binop= expr; 7982 // x = x binop expr; 7983 // x = expr binop x; 7984 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7985 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7986 if (AtomicBody->getType()->isScalarType() || 7987 AtomicBody->isInstantiationDependent()) { 7988 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7989 AtomicBody->IgnoreParenImpCasts())) { 7990 // Check for Compound Assignment Operation 7991 Op = BinaryOperator::getOpForCompoundAssignment( 7992 AtomicCompAssignOp->getOpcode()); 7993 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7994 E = AtomicCompAssignOp->getRHS(); 7995 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7996 IsXLHSInRHSPart = true; 7997 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7998 AtomicBody->IgnoreParenImpCasts())) { 7999 // Check for Binary Operation 8000 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8001 return true; 8002 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8003 AtomicBody->IgnoreParenImpCasts())) { 8004 // Check for Unary Operation 8005 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8006 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8007 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8008 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8009 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8010 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8011 IsXLHSInRHSPart = true; 8012 } else { 8013 ErrorFound = NotAnUnaryIncDecExpression; 8014 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8015 ErrorRange = AtomicUnaryOp->getSourceRange(); 8016 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8017 NoteRange = SourceRange(NoteLoc, NoteLoc); 8018 } 8019 } else if (!AtomicBody->isInstantiationDependent()) { 8020 ErrorFound = NotABinaryOrUnaryExpression; 8021 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8022 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8023 } 8024 } else { 8025 ErrorFound = NotAScalarType; 8026 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8027 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8028 } 8029 } else { 8030 ErrorFound = NotAnExpression; 8031 NoteLoc = ErrorLoc = S->getBeginLoc(); 8032 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8033 } 8034 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8035 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8036 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8037 return true; 8038 } 8039 if (SemaRef.CurContext->isDependentContext()) 8040 E = X = UpdateExpr = nullptr; 8041 if (ErrorFound == NoError && E && X) { 8042 // Build an update expression of form 'OpaqueValueExpr(x) binop 8043 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8044 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8045 auto *OVEX = new (SemaRef.getASTContext()) 8046 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8047 auto *OVEExpr = new (SemaRef.getASTContext()) 8048 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8049 ExprResult Update = 8050 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8051 IsXLHSInRHSPart ? OVEExpr : OVEX); 8052 if (Update.isInvalid()) 8053 return true; 8054 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8055 Sema::AA_Casting); 8056 if (Update.isInvalid()) 8057 return true; 8058 UpdateExpr = Update.get(); 8059 } 8060 return ErrorFound != NoError; 8061 } 8062 8063 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8064 Stmt *AStmt, 8065 SourceLocation StartLoc, 8066 SourceLocation EndLoc) { 8067 if (!AStmt) 8068 return StmtError(); 8069 8070 auto *CS = cast<CapturedStmt>(AStmt); 8071 // 1.2.2 OpenMP Language Terminology 8072 // Structured block - An executable statement with a single entry at the 8073 // top and a single exit at the bottom. 8074 // The point of exit cannot be a branch out of the structured block. 8075 // longjmp() and throw() must not violate the entry/exit criteria. 8076 OpenMPClauseKind AtomicKind = OMPC_unknown; 8077 SourceLocation AtomicKindLoc; 8078 for (const OMPClause *C : Clauses) { 8079 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8080 C->getClauseKind() == OMPC_update || 8081 C->getClauseKind() == OMPC_capture) { 8082 if (AtomicKind != OMPC_unknown) { 8083 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8084 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8085 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8086 << getOpenMPClauseName(AtomicKind); 8087 } else { 8088 AtomicKind = C->getClauseKind(); 8089 AtomicKindLoc = C->getBeginLoc(); 8090 } 8091 } 8092 } 8093 8094 Stmt *Body = CS->getCapturedStmt(); 8095 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8096 Body = EWC->getSubExpr(); 8097 8098 Expr *X = nullptr; 8099 Expr *V = nullptr; 8100 Expr *E = nullptr; 8101 Expr *UE = nullptr; 8102 bool IsXLHSInRHSPart = false; 8103 bool IsPostfixUpdate = false; 8104 // OpenMP [2.12.6, atomic Construct] 8105 // In the next expressions: 8106 // * x and v (as applicable) are both l-value expressions with scalar type. 8107 // * During the execution of an atomic region, multiple syntactic 8108 // occurrences of x must designate the same storage location. 8109 // * Neither of v and expr (as applicable) may access the storage location 8110 // designated by x. 8111 // * Neither of x and expr (as applicable) may access the storage location 8112 // designated by v. 8113 // * expr is an expression with scalar type. 8114 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8115 // * binop, binop=, ++, and -- are not overloaded operators. 8116 // * The expression x binop expr must be numerically equivalent to x binop 8117 // (expr). This requirement is satisfied if the operators in expr have 8118 // precedence greater than binop, or by using parentheses around expr or 8119 // subexpressions of expr. 8120 // * The expression expr binop x must be numerically equivalent to (expr) 8121 // binop x. This requirement is satisfied if the operators in expr have 8122 // precedence equal to or greater than binop, or by using parentheses around 8123 // expr or subexpressions of expr. 8124 // * For forms that allow multiple occurrences of x, the number of times 8125 // that x is evaluated is unspecified. 8126 if (AtomicKind == OMPC_read) { 8127 enum { 8128 NotAnExpression, 8129 NotAnAssignmentOp, 8130 NotAScalarType, 8131 NotAnLValue, 8132 NoError 8133 } ErrorFound = NoError; 8134 SourceLocation ErrorLoc, NoteLoc; 8135 SourceRange ErrorRange, NoteRange; 8136 // If clause is read: 8137 // v = x; 8138 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8139 const auto *AtomicBinOp = 8140 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8141 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8142 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8143 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8144 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8145 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8146 if (!X->isLValue() || !V->isLValue()) { 8147 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8148 ErrorFound = NotAnLValue; 8149 ErrorLoc = AtomicBinOp->getExprLoc(); 8150 ErrorRange = AtomicBinOp->getSourceRange(); 8151 NoteLoc = NotLValueExpr->getExprLoc(); 8152 NoteRange = NotLValueExpr->getSourceRange(); 8153 } 8154 } else if (!X->isInstantiationDependent() || 8155 !V->isInstantiationDependent()) { 8156 const Expr *NotScalarExpr = 8157 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8158 ? V 8159 : X; 8160 ErrorFound = NotAScalarType; 8161 ErrorLoc = AtomicBinOp->getExprLoc(); 8162 ErrorRange = AtomicBinOp->getSourceRange(); 8163 NoteLoc = NotScalarExpr->getExprLoc(); 8164 NoteRange = NotScalarExpr->getSourceRange(); 8165 } 8166 } else if (!AtomicBody->isInstantiationDependent()) { 8167 ErrorFound = NotAnAssignmentOp; 8168 ErrorLoc = AtomicBody->getExprLoc(); 8169 ErrorRange = AtomicBody->getSourceRange(); 8170 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8171 : AtomicBody->getExprLoc(); 8172 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8173 : AtomicBody->getSourceRange(); 8174 } 8175 } else { 8176 ErrorFound = NotAnExpression; 8177 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8178 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8179 } 8180 if (ErrorFound != NoError) { 8181 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8182 << ErrorRange; 8183 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8184 << NoteRange; 8185 return StmtError(); 8186 } 8187 if (CurContext->isDependentContext()) 8188 V = X = nullptr; 8189 } else if (AtomicKind == OMPC_write) { 8190 enum { 8191 NotAnExpression, 8192 NotAnAssignmentOp, 8193 NotAScalarType, 8194 NotAnLValue, 8195 NoError 8196 } ErrorFound = NoError; 8197 SourceLocation ErrorLoc, NoteLoc; 8198 SourceRange ErrorRange, NoteRange; 8199 // If clause is write: 8200 // x = expr; 8201 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8202 const auto *AtomicBinOp = 8203 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8204 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8205 X = AtomicBinOp->getLHS(); 8206 E = AtomicBinOp->getRHS(); 8207 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8208 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8209 if (!X->isLValue()) { 8210 ErrorFound = NotAnLValue; 8211 ErrorLoc = AtomicBinOp->getExprLoc(); 8212 ErrorRange = AtomicBinOp->getSourceRange(); 8213 NoteLoc = X->getExprLoc(); 8214 NoteRange = X->getSourceRange(); 8215 } 8216 } else if (!X->isInstantiationDependent() || 8217 !E->isInstantiationDependent()) { 8218 const Expr *NotScalarExpr = 8219 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8220 ? E 8221 : X; 8222 ErrorFound = NotAScalarType; 8223 ErrorLoc = AtomicBinOp->getExprLoc(); 8224 ErrorRange = AtomicBinOp->getSourceRange(); 8225 NoteLoc = NotScalarExpr->getExprLoc(); 8226 NoteRange = NotScalarExpr->getSourceRange(); 8227 } 8228 } else if (!AtomicBody->isInstantiationDependent()) { 8229 ErrorFound = NotAnAssignmentOp; 8230 ErrorLoc = AtomicBody->getExprLoc(); 8231 ErrorRange = AtomicBody->getSourceRange(); 8232 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8233 : AtomicBody->getExprLoc(); 8234 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8235 : AtomicBody->getSourceRange(); 8236 } 8237 } else { 8238 ErrorFound = NotAnExpression; 8239 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8240 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8241 } 8242 if (ErrorFound != NoError) { 8243 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8244 << ErrorRange; 8245 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8246 << NoteRange; 8247 return StmtError(); 8248 } 8249 if (CurContext->isDependentContext()) 8250 E = X = nullptr; 8251 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8252 // If clause is update: 8253 // x++; 8254 // x--; 8255 // ++x; 8256 // --x; 8257 // x binop= expr; 8258 // x = x binop expr; 8259 // x = expr binop x; 8260 OpenMPAtomicUpdateChecker Checker(*this); 8261 if (Checker.checkStatement( 8262 Body, (AtomicKind == OMPC_update) 8263 ? diag::err_omp_atomic_update_not_expression_statement 8264 : diag::err_omp_atomic_not_expression_statement, 8265 diag::note_omp_atomic_update)) 8266 return StmtError(); 8267 if (!CurContext->isDependentContext()) { 8268 E = Checker.getExpr(); 8269 X = Checker.getX(); 8270 UE = Checker.getUpdateExpr(); 8271 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8272 } 8273 } else if (AtomicKind == OMPC_capture) { 8274 enum { 8275 NotAnAssignmentOp, 8276 NotACompoundStatement, 8277 NotTwoSubstatements, 8278 NotASpecificExpression, 8279 NoError 8280 } ErrorFound = NoError; 8281 SourceLocation ErrorLoc, NoteLoc; 8282 SourceRange ErrorRange, NoteRange; 8283 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8284 // If clause is a capture: 8285 // v = x++; 8286 // v = x--; 8287 // v = ++x; 8288 // v = --x; 8289 // v = x binop= expr; 8290 // v = x = x binop expr; 8291 // v = x = expr binop x; 8292 const auto *AtomicBinOp = 8293 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8294 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8295 V = AtomicBinOp->getLHS(); 8296 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8297 OpenMPAtomicUpdateChecker Checker(*this); 8298 if (Checker.checkStatement( 8299 Body, diag::err_omp_atomic_capture_not_expression_statement, 8300 diag::note_omp_atomic_update)) 8301 return StmtError(); 8302 E = Checker.getExpr(); 8303 X = Checker.getX(); 8304 UE = Checker.getUpdateExpr(); 8305 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8306 IsPostfixUpdate = Checker.isPostfixUpdate(); 8307 } else if (!AtomicBody->isInstantiationDependent()) { 8308 ErrorLoc = AtomicBody->getExprLoc(); 8309 ErrorRange = AtomicBody->getSourceRange(); 8310 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8311 : AtomicBody->getExprLoc(); 8312 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8313 : AtomicBody->getSourceRange(); 8314 ErrorFound = NotAnAssignmentOp; 8315 } 8316 if (ErrorFound != NoError) { 8317 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8318 << ErrorRange; 8319 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8320 return StmtError(); 8321 } 8322 if (CurContext->isDependentContext()) 8323 UE = V = E = X = nullptr; 8324 } else { 8325 // If clause is a capture: 8326 // { v = x; x = expr; } 8327 // { v = x; x++; } 8328 // { v = x; x--; } 8329 // { v = x; ++x; } 8330 // { v = x; --x; } 8331 // { v = x; x binop= expr; } 8332 // { v = x; x = x binop expr; } 8333 // { v = x; x = expr binop x; } 8334 // { x++; v = x; } 8335 // { x--; v = x; } 8336 // { ++x; v = x; } 8337 // { --x; v = x; } 8338 // { x binop= expr; v = x; } 8339 // { x = x binop expr; v = x; } 8340 // { x = expr binop x; v = x; } 8341 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8342 // Check that this is { expr1; expr2; } 8343 if (CS->size() == 2) { 8344 Stmt *First = CS->body_front(); 8345 Stmt *Second = CS->body_back(); 8346 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8347 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8348 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8349 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8350 // Need to find what subexpression is 'v' and what is 'x'. 8351 OpenMPAtomicUpdateChecker Checker(*this); 8352 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8353 BinaryOperator *BinOp = nullptr; 8354 if (IsUpdateExprFound) { 8355 BinOp = dyn_cast<BinaryOperator>(First); 8356 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8357 } 8358 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8359 // { v = x; x++; } 8360 // { v = x; x--; } 8361 // { v = x; ++x; } 8362 // { v = x; --x; } 8363 // { v = x; x binop= expr; } 8364 // { v = x; x = x binop expr; } 8365 // { v = x; x = expr binop x; } 8366 // Check that the first expression has form v = x. 8367 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8368 llvm::FoldingSetNodeID XId, PossibleXId; 8369 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8370 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8371 IsUpdateExprFound = XId == PossibleXId; 8372 if (IsUpdateExprFound) { 8373 V = BinOp->getLHS(); 8374 X = Checker.getX(); 8375 E = Checker.getExpr(); 8376 UE = Checker.getUpdateExpr(); 8377 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8378 IsPostfixUpdate = true; 8379 } 8380 } 8381 if (!IsUpdateExprFound) { 8382 IsUpdateExprFound = !Checker.checkStatement(First); 8383 BinOp = nullptr; 8384 if (IsUpdateExprFound) { 8385 BinOp = dyn_cast<BinaryOperator>(Second); 8386 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8387 } 8388 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8389 // { x++; v = x; } 8390 // { x--; v = x; } 8391 // { ++x; v = x; } 8392 // { --x; v = x; } 8393 // { x binop= expr; v = x; } 8394 // { x = x binop expr; v = x; } 8395 // { x = expr binop x; v = x; } 8396 // Check that the second expression has form v = x. 8397 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8398 llvm::FoldingSetNodeID XId, PossibleXId; 8399 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8400 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8401 IsUpdateExprFound = XId == PossibleXId; 8402 if (IsUpdateExprFound) { 8403 V = BinOp->getLHS(); 8404 X = Checker.getX(); 8405 E = Checker.getExpr(); 8406 UE = Checker.getUpdateExpr(); 8407 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8408 IsPostfixUpdate = false; 8409 } 8410 } 8411 } 8412 if (!IsUpdateExprFound) { 8413 // { v = x; x = expr; } 8414 auto *FirstExpr = dyn_cast<Expr>(First); 8415 auto *SecondExpr = dyn_cast<Expr>(Second); 8416 if (!FirstExpr || !SecondExpr || 8417 !(FirstExpr->isInstantiationDependent() || 8418 SecondExpr->isInstantiationDependent())) { 8419 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8420 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8421 ErrorFound = NotAnAssignmentOp; 8422 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8423 : First->getBeginLoc(); 8424 NoteRange = ErrorRange = FirstBinOp 8425 ? FirstBinOp->getSourceRange() 8426 : SourceRange(ErrorLoc, ErrorLoc); 8427 } else { 8428 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8429 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8430 ErrorFound = NotAnAssignmentOp; 8431 NoteLoc = ErrorLoc = SecondBinOp 8432 ? SecondBinOp->getOperatorLoc() 8433 : Second->getBeginLoc(); 8434 NoteRange = ErrorRange = 8435 SecondBinOp ? SecondBinOp->getSourceRange() 8436 : SourceRange(ErrorLoc, ErrorLoc); 8437 } else { 8438 Expr *PossibleXRHSInFirst = 8439 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8440 Expr *PossibleXLHSInSecond = 8441 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8442 llvm::FoldingSetNodeID X1Id, X2Id; 8443 PossibleXRHSInFirst->Profile(X1Id, Context, 8444 /*Canonical=*/true); 8445 PossibleXLHSInSecond->Profile(X2Id, Context, 8446 /*Canonical=*/true); 8447 IsUpdateExprFound = X1Id == X2Id; 8448 if (IsUpdateExprFound) { 8449 V = FirstBinOp->getLHS(); 8450 X = SecondBinOp->getLHS(); 8451 E = SecondBinOp->getRHS(); 8452 UE = nullptr; 8453 IsXLHSInRHSPart = false; 8454 IsPostfixUpdate = true; 8455 } else { 8456 ErrorFound = NotASpecificExpression; 8457 ErrorLoc = FirstBinOp->getExprLoc(); 8458 ErrorRange = FirstBinOp->getSourceRange(); 8459 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8460 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8461 } 8462 } 8463 } 8464 } 8465 } 8466 } else { 8467 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8468 NoteRange = ErrorRange = 8469 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8470 ErrorFound = NotTwoSubstatements; 8471 } 8472 } else { 8473 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8474 NoteRange = ErrorRange = 8475 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8476 ErrorFound = NotACompoundStatement; 8477 } 8478 if (ErrorFound != NoError) { 8479 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8480 << ErrorRange; 8481 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8482 return StmtError(); 8483 } 8484 if (CurContext->isDependentContext()) 8485 UE = V = E = X = nullptr; 8486 } 8487 } 8488 8489 setFunctionHasBranchProtectedScope(); 8490 8491 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8492 X, V, E, UE, IsXLHSInRHSPart, 8493 IsPostfixUpdate); 8494 } 8495 8496 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8497 Stmt *AStmt, 8498 SourceLocation StartLoc, 8499 SourceLocation EndLoc) { 8500 if (!AStmt) 8501 return StmtError(); 8502 8503 auto *CS = cast<CapturedStmt>(AStmt); 8504 // 1.2.2 OpenMP Language Terminology 8505 // Structured block - An executable statement with a single entry at the 8506 // top and a single exit at the bottom. 8507 // The point of exit cannot be a branch out of the structured block. 8508 // longjmp() and throw() must not violate the entry/exit criteria. 8509 CS->getCapturedDecl()->setNothrow(); 8510 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8511 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8512 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8513 // 1.2.2 OpenMP Language Terminology 8514 // Structured block - An executable statement with a single entry at the 8515 // top and a single exit at the bottom. 8516 // The point of exit cannot be a branch out of the structured block. 8517 // longjmp() and throw() must not violate the entry/exit criteria. 8518 CS->getCapturedDecl()->setNothrow(); 8519 } 8520 8521 // OpenMP [2.16, Nesting of Regions] 8522 // If specified, a teams construct must be contained within a target 8523 // construct. That target construct must contain no statements or directives 8524 // outside of the teams construct. 8525 if (DSAStack->hasInnerTeamsRegion()) { 8526 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8527 bool OMPTeamsFound = true; 8528 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8529 auto I = CS->body_begin(); 8530 while (I != CS->body_end()) { 8531 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8532 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8533 OMPTeamsFound) { 8534 8535 OMPTeamsFound = false; 8536 break; 8537 } 8538 ++I; 8539 } 8540 assert(I != CS->body_end() && "Not found statement"); 8541 S = *I; 8542 } else { 8543 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8544 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8545 } 8546 if (!OMPTeamsFound) { 8547 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8548 Diag(DSAStack->getInnerTeamsRegionLoc(), 8549 diag::note_omp_nested_teams_construct_here); 8550 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8551 << isa<OMPExecutableDirective>(S); 8552 return StmtError(); 8553 } 8554 } 8555 8556 setFunctionHasBranchProtectedScope(); 8557 8558 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8559 } 8560 8561 StmtResult 8562 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8563 Stmt *AStmt, SourceLocation StartLoc, 8564 SourceLocation EndLoc) { 8565 if (!AStmt) 8566 return StmtError(); 8567 8568 auto *CS = cast<CapturedStmt>(AStmt); 8569 // 1.2.2 OpenMP Language Terminology 8570 // Structured block - An executable statement with a single entry at the 8571 // top and a single exit at the bottom. 8572 // The point of exit cannot be a branch out of the structured block. 8573 // longjmp() and throw() must not violate the entry/exit criteria. 8574 CS->getCapturedDecl()->setNothrow(); 8575 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8576 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8577 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8578 // 1.2.2 OpenMP Language Terminology 8579 // Structured block - An executable statement with a single entry at the 8580 // top and a single exit at the bottom. 8581 // The point of exit cannot be a branch out of the structured block. 8582 // longjmp() and throw() must not violate the entry/exit criteria. 8583 CS->getCapturedDecl()->setNothrow(); 8584 } 8585 8586 setFunctionHasBranchProtectedScope(); 8587 8588 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8589 AStmt); 8590 } 8591 8592 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8593 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8594 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8595 if (!AStmt) 8596 return StmtError(); 8597 8598 auto *CS = cast<CapturedStmt>(AStmt); 8599 // 1.2.2 OpenMP Language Terminology 8600 // Structured block - An executable statement with a single entry at the 8601 // top and a single exit at the bottom. 8602 // The point of exit cannot be a branch out of the structured block. 8603 // longjmp() and throw() must not violate the entry/exit criteria. 8604 CS->getCapturedDecl()->setNothrow(); 8605 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8606 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8607 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8608 // 1.2.2 OpenMP Language Terminology 8609 // Structured block - An executable statement with a single entry at the 8610 // top and a single exit at the bottom. 8611 // The point of exit cannot be a branch out of the structured block. 8612 // longjmp() and throw() must not violate the entry/exit criteria. 8613 CS->getCapturedDecl()->setNothrow(); 8614 } 8615 8616 OMPLoopDirective::HelperExprs B; 8617 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8618 // define the nested loops number. 8619 unsigned NestedLoopCount = 8620 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8621 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8622 VarsWithImplicitDSA, B); 8623 if (NestedLoopCount == 0) 8624 return StmtError(); 8625 8626 assert((CurContext->isDependentContext() || B.builtAll()) && 8627 "omp target parallel for loop exprs were not built"); 8628 8629 if (!CurContext->isDependentContext()) { 8630 // Finalize the clauses that need pre-built expressions for CodeGen. 8631 for (OMPClause *C : Clauses) { 8632 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8633 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8634 B.NumIterations, *this, CurScope, 8635 DSAStack)) 8636 return StmtError(); 8637 } 8638 } 8639 8640 setFunctionHasBranchProtectedScope(); 8641 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8642 NestedLoopCount, Clauses, AStmt, 8643 B, DSAStack->isCancelRegion()); 8644 } 8645 8646 /// Check for existence of a map clause in the list of clauses. 8647 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8648 const OpenMPClauseKind K) { 8649 return llvm::any_of( 8650 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8651 } 8652 8653 template <typename... Params> 8654 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8655 const Params... ClauseTypes) { 8656 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8657 } 8658 8659 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8660 Stmt *AStmt, 8661 SourceLocation StartLoc, 8662 SourceLocation EndLoc) { 8663 if (!AStmt) 8664 return StmtError(); 8665 8666 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8667 8668 // OpenMP [2.10.1, Restrictions, p. 97] 8669 // At least one map clause must appear on the directive. 8670 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8671 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8672 << "'map' or 'use_device_ptr'" 8673 << getOpenMPDirectiveName(OMPD_target_data); 8674 return StmtError(); 8675 } 8676 8677 setFunctionHasBranchProtectedScope(); 8678 8679 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8680 AStmt); 8681 } 8682 8683 StmtResult 8684 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8685 SourceLocation StartLoc, 8686 SourceLocation EndLoc, Stmt *AStmt) { 8687 if (!AStmt) 8688 return StmtError(); 8689 8690 auto *CS = cast<CapturedStmt>(AStmt); 8691 // 1.2.2 OpenMP Language Terminology 8692 // Structured block - An executable statement with a single entry at the 8693 // top and a single exit at the bottom. 8694 // The point of exit cannot be a branch out of the structured block. 8695 // longjmp() and throw() must not violate the entry/exit criteria. 8696 CS->getCapturedDecl()->setNothrow(); 8697 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8698 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8699 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8700 // 1.2.2 OpenMP Language Terminology 8701 // Structured block - An executable statement with a single entry at the 8702 // top and a single exit at the bottom. 8703 // The point of exit cannot be a branch out of the structured block. 8704 // longjmp() and throw() must not violate the entry/exit criteria. 8705 CS->getCapturedDecl()->setNothrow(); 8706 } 8707 8708 // OpenMP [2.10.2, Restrictions, p. 99] 8709 // At least one map clause must appear on the directive. 8710 if (!hasClauses(Clauses, OMPC_map)) { 8711 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8712 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8713 return StmtError(); 8714 } 8715 8716 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8717 AStmt); 8718 } 8719 8720 StmtResult 8721 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8722 SourceLocation StartLoc, 8723 SourceLocation EndLoc, Stmt *AStmt) { 8724 if (!AStmt) 8725 return StmtError(); 8726 8727 auto *CS = cast<CapturedStmt>(AStmt); 8728 // 1.2.2 OpenMP Language Terminology 8729 // Structured block - An executable statement with a single entry at the 8730 // top and a single exit at the bottom. 8731 // The point of exit cannot be a branch out of the structured block. 8732 // longjmp() and throw() must not violate the entry/exit criteria. 8733 CS->getCapturedDecl()->setNothrow(); 8734 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8735 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8736 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8737 // 1.2.2 OpenMP Language Terminology 8738 // Structured block - An executable statement with a single entry at the 8739 // top and a single exit at the bottom. 8740 // The point of exit cannot be a branch out of the structured block. 8741 // longjmp() and throw() must not violate the entry/exit criteria. 8742 CS->getCapturedDecl()->setNothrow(); 8743 } 8744 8745 // OpenMP [2.10.3, Restrictions, p. 102] 8746 // At least one map clause must appear on the directive. 8747 if (!hasClauses(Clauses, OMPC_map)) { 8748 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8749 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8750 return StmtError(); 8751 } 8752 8753 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8754 AStmt); 8755 } 8756 8757 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8758 SourceLocation StartLoc, 8759 SourceLocation EndLoc, 8760 Stmt *AStmt) { 8761 if (!AStmt) 8762 return StmtError(); 8763 8764 auto *CS = cast<CapturedStmt>(AStmt); 8765 // 1.2.2 OpenMP Language Terminology 8766 // Structured block - An executable statement with a single entry at the 8767 // top and a single exit at the bottom. 8768 // The point of exit cannot be a branch out of the structured block. 8769 // longjmp() and throw() must not violate the entry/exit criteria. 8770 CS->getCapturedDecl()->setNothrow(); 8771 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8772 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8773 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8774 // 1.2.2 OpenMP Language Terminology 8775 // Structured block - An executable statement with a single entry at the 8776 // top and a single exit at the bottom. 8777 // The point of exit cannot be a branch out of the structured block. 8778 // longjmp() and throw() must not violate the entry/exit criteria. 8779 CS->getCapturedDecl()->setNothrow(); 8780 } 8781 8782 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8783 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8784 return StmtError(); 8785 } 8786 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8787 AStmt); 8788 } 8789 8790 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8791 Stmt *AStmt, SourceLocation StartLoc, 8792 SourceLocation EndLoc) { 8793 if (!AStmt) 8794 return StmtError(); 8795 8796 auto *CS = cast<CapturedStmt>(AStmt); 8797 // 1.2.2 OpenMP Language Terminology 8798 // Structured block - An executable statement with a single entry at the 8799 // top and a single exit at the bottom. 8800 // The point of exit cannot be a branch out of the structured block. 8801 // longjmp() and throw() must not violate the entry/exit criteria. 8802 CS->getCapturedDecl()->setNothrow(); 8803 8804 setFunctionHasBranchProtectedScope(); 8805 8806 DSAStack->setParentTeamsRegionLoc(StartLoc); 8807 8808 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8809 } 8810 8811 StmtResult 8812 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8813 SourceLocation EndLoc, 8814 OpenMPDirectiveKind CancelRegion) { 8815 if (DSAStack->isParentNowaitRegion()) { 8816 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8817 return StmtError(); 8818 } 8819 if (DSAStack->isParentOrderedRegion()) { 8820 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8821 return StmtError(); 8822 } 8823 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8824 CancelRegion); 8825 } 8826 8827 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8828 SourceLocation StartLoc, 8829 SourceLocation EndLoc, 8830 OpenMPDirectiveKind CancelRegion) { 8831 if (DSAStack->isParentNowaitRegion()) { 8832 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8833 return StmtError(); 8834 } 8835 if (DSAStack->isParentOrderedRegion()) { 8836 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8837 return StmtError(); 8838 } 8839 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8840 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8841 CancelRegion); 8842 } 8843 8844 static bool checkGrainsizeNumTasksClauses(Sema &S, 8845 ArrayRef<OMPClause *> Clauses) { 8846 const OMPClause *PrevClause = nullptr; 8847 bool ErrorFound = false; 8848 for (const OMPClause *C : Clauses) { 8849 if (C->getClauseKind() == OMPC_grainsize || 8850 C->getClauseKind() == OMPC_num_tasks) { 8851 if (!PrevClause) 8852 PrevClause = C; 8853 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8854 S.Diag(C->getBeginLoc(), 8855 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8856 << getOpenMPClauseName(C->getClauseKind()) 8857 << getOpenMPClauseName(PrevClause->getClauseKind()); 8858 S.Diag(PrevClause->getBeginLoc(), 8859 diag::note_omp_previous_grainsize_num_tasks) 8860 << getOpenMPClauseName(PrevClause->getClauseKind()); 8861 ErrorFound = true; 8862 } 8863 } 8864 } 8865 return ErrorFound; 8866 } 8867 8868 static bool checkReductionClauseWithNogroup(Sema &S, 8869 ArrayRef<OMPClause *> Clauses) { 8870 const OMPClause *ReductionClause = nullptr; 8871 const OMPClause *NogroupClause = nullptr; 8872 for (const OMPClause *C : Clauses) { 8873 if (C->getClauseKind() == OMPC_reduction) { 8874 ReductionClause = C; 8875 if (NogroupClause) 8876 break; 8877 continue; 8878 } 8879 if (C->getClauseKind() == OMPC_nogroup) { 8880 NogroupClause = C; 8881 if (ReductionClause) 8882 break; 8883 continue; 8884 } 8885 } 8886 if (ReductionClause && NogroupClause) { 8887 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8888 << SourceRange(NogroupClause->getBeginLoc(), 8889 NogroupClause->getEndLoc()); 8890 return true; 8891 } 8892 return false; 8893 } 8894 8895 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8896 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8897 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8898 if (!AStmt) 8899 return StmtError(); 8900 8901 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8902 OMPLoopDirective::HelperExprs B; 8903 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8904 // define the nested loops number. 8905 unsigned NestedLoopCount = 8906 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8907 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8908 VarsWithImplicitDSA, B); 8909 if (NestedLoopCount == 0) 8910 return StmtError(); 8911 8912 assert((CurContext->isDependentContext() || B.builtAll()) && 8913 "omp for loop exprs were not built"); 8914 8915 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8916 // The grainsize clause and num_tasks clause are mutually exclusive and may 8917 // not appear on the same taskloop directive. 8918 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8919 return StmtError(); 8920 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8921 // If a reduction clause is present on the taskloop directive, the nogroup 8922 // clause must not be specified. 8923 if (checkReductionClauseWithNogroup(*this, Clauses)) 8924 return StmtError(); 8925 8926 setFunctionHasBranchProtectedScope(); 8927 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8928 NestedLoopCount, Clauses, AStmt, B); 8929 } 8930 8931 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8932 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8933 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8934 if (!AStmt) 8935 return StmtError(); 8936 8937 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8938 OMPLoopDirective::HelperExprs B; 8939 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8940 // define the nested loops number. 8941 unsigned NestedLoopCount = 8942 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8943 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8944 VarsWithImplicitDSA, B); 8945 if (NestedLoopCount == 0) 8946 return StmtError(); 8947 8948 assert((CurContext->isDependentContext() || B.builtAll()) && 8949 "omp for loop exprs were not built"); 8950 8951 if (!CurContext->isDependentContext()) { 8952 // Finalize the clauses that need pre-built expressions for CodeGen. 8953 for (OMPClause *C : Clauses) { 8954 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8955 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8956 B.NumIterations, *this, CurScope, 8957 DSAStack)) 8958 return StmtError(); 8959 } 8960 } 8961 8962 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8963 // The grainsize clause and num_tasks clause are mutually exclusive and may 8964 // not appear on the same taskloop directive. 8965 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8966 return StmtError(); 8967 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8968 // If a reduction clause is present on the taskloop directive, the nogroup 8969 // clause must not be specified. 8970 if (checkReductionClauseWithNogroup(*this, Clauses)) 8971 return StmtError(); 8972 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8973 return StmtError(); 8974 8975 setFunctionHasBranchProtectedScope(); 8976 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8977 NestedLoopCount, Clauses, AStmt, B); 8978 } 8979 8980 StmtResult Sema::ActOnOpenMPDistributeDirective( 8981 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8982 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8983 if (!AStmt) 8984 return StmtError(); 8985 8986 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8987 OMPLoopDirective::HelperExprs B; 8988 // In presence of clause 'collapse' with number of loops, it will 8989 // define the nested loops number. 8990 unsigned NestedLoopCount = 8991 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8992 nullptr /*ordered not a clause on distribute*/, AStmt, 8993 *this, *DSAStack, VarsWithImplicitDSA, B); 8994 if (NestedLoopCount == 0) 8995 return StmtError(); 8996 8997 assert((CurContext->isDependentContext() || B.builtAll()) && 8998 "omp for loop exprs were not built"); 8999 9000 setFunctionHasBranchProtectedScope(); 9001 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9002 NestedLoopCount, Clauses, AStmt, B); 9003 } 9004 9005 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9006 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9007 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9008 if (!AStmt) 9009 return StmtError(); 9010 9011 auto *CS = cast<CapturedStmt>(AStmt); 9012 // 1.2.2 OpenMP Language Terminology 9013 // Structured block - An executable statement with a single entry at the 9014 // top and a single exit at the bottom. 9015 // The point of exit cannot be a branch out of the structured block. 9016 // longjmp() and throw() must not violate the entry/exit criteria. 9017 CS->getCapturedDecl()->setNothrow(); 9018 for (int ThisCaptureLevel = 9019 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9020 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9021 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9022 // 1.2.2 OpenMP Language Terminology 9023 // Structured block - An executable statement with a single entry at the 9024 // top and a single exit at the bottom. 9025 // The point of exit cannot be a branch out of the structured block. 9026 // longjmp() and throw() must not violate the entry/exit criteria. 9027 CS->getCapturedDecl()->setNothrow(); 9028 } 9029 9030 OMPLoopDirective::HelperExprs B; 9031 // In presence of clause 'collapse' with number of loops, it will 9032 // define the nested loops number. 9033 unsigned NestedLoopCount = checkOpenMPLoop( 9034 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9035 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9036 VarsWithImplicitDSA, B); 9037 if (NestedLoopCount == 0) 9038 return StmtError(); 9039 9040 assert((CurContext->isDependentContext() || B.builtAll()) && 9041 "omp for loop exprs were not built"); 9042 9043 setFunctionHasBranchProtectedScope(); 9044 return OMPDistributeParallelForDirective::Create( 9045 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9046 DSAStack->isCancelRegion()); 9047 } 9048 9049 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9050 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9051 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9052 if (!AStmt) 9053 return StmtError(); 9054 9055 auto *CS = cast<CapturedStmt>(AStmt); 9056 // 1.2.2 OpenMP Language Terminology 9057 // Structured block - An executable statement with a single entry at the 9058 // top and a single exit at the bottom. 9059 // The point of exit cannot be a branch out of the structured block. 9060 // longjmp() and throw() must not violate the entry/exit criteria. 9061 CS->getCapturedDecl()->setNothrow(); 9062 for (int ThisCaptureLevel = 9063 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9064 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9065 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9066 // 1.2.2 OpenMP Language Terminology 9067 // Structured block - An executable statement with a single entry at the 9068 // top and a single exit at the bottom. 9069 // The point of exit cannot be a branch out of the structured block. 9070 // longjmp() and throw() must not violate the entry/exit criteria. 9071 CS->getCapturedDecl()->setNothrow(); 9072 } 9073 9074 OMPLoopDirective::HelperExprs B; 9075 // In presence of clause 'collapse' with number of loops, it will 9076 // define the nested loops number. 9077 unsigned NestedLoopCount = checkOpenMPLoop( 9078 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9079 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9080 VarsWithImplicitDSA, B); 9081 if (NestedLoopCount == 0) 9082 return StmtError(); 9083 9084 assert((CurContext->isDependentContext() || B.builtAll()) && 9085 "omp for loop exprs were not built"); 9086 9087 if (!CurContext->isDependentContext()) { 9088 // Finalize the clauses that need pre-built expressions for CodeGen. 9089 for (OMPClause *C : Clauses) { 9090 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9091 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9092 B.NumIterations, *this, CurScope, 9093 DSAStack)) 9094 return StmtError(); 9095 } 9096 } 9097 9098 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9099 return StmtError(); 9100 9101 setFunctionHasBranchProtectedScope(); 9102 return OMPDistributeParallelForSimdDirective::Create( 9103 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9104 } 9105 9106 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9107 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9108 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9109 if (!AStmt) 9110 return StmtError(); 9111 9112 auto *CS = cast<CapturedStmt>(AStmt); 9113 // 1.2.2 OpenMP Language Terminology 9114 // Structured block - An executable statement with a single entry at the 9115 // top and a single exit at the bottom. 9116 // The point of exit cannot be a branch out of the structured block. 9117 // longjmp() and throw() must not violate the entry/exit criteria. 9118 CS->getCapturedDecl()->setNothrow(); 9119 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9120 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9121 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9122 // 1.2.2 OpenMP Language Terminology 9123 // Structured block - An executable statement with a single entry at the 9124 // top and a single exit at the bottom. 9125 // The point of exit cannot be a branch out of the structured block. 9126 // longjmp() and throw() must not violate the entry/exit criteria. 9127 CS->getCapturedDecl()->setNothrow(); 9128 } 9129 9130 OMPLoopDirective::HelperExprs B; 9131 // In presence of clause 'collapse' with number of loops, it will 9132 // define the nested loops number. 9133 unsigned NestedLoopCount = 9134 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9135 nullptr /*ordered not a clause on distribute*/, CS, *this, 9136 *DSAStack, VarsWithImplicitDSA, B); 9137 if (NestedLoopCount == 0) 9138 return StmtError(); 9139 9140 assert((CurContext->isDependentContext() || B.builtAll()) && 9141 "omp for loop exprs were not built"); 9142 9143 if (!CurContext->isDependentContext()) { 9144 // Finalize the clauses that need pre-built expressions for CodeGen. 9145 for (OMPClause *C : Clauses) { 9146 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9147 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9148 B.NumIterations, *this, CurScope, 9149 DSAStack)) 9150 return StmtError(); 9151 } 9152 } 9153 9154 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9155 return StmtError(); 9156 9157 setFunctionHasBranchProtectedScope(); 9158 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9159 NestedLoopCount, Clauses, AStmt, B); 9160 } 9161 9162 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9163 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9164 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9165 if (!AStmt) 9166 return StmtError(); 9167 9168 auto *CS = cast<CapturedStmt>(AStmt); 9169 // 1.2.2 OpenMP Language Terminology 9170 // Structured block - An executable statement with a single entry at the 9171 // top and a single exit at the bottom. 9172 // The point of exit cannot be a branch out of the structured block. 9173 // longjmp() and throw() must not violate the entry/exit criteria. 9174 CS->getCapturedDecl()->setNothrow(); 9175 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9176 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9177 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9178 // 1.2.2 OpenMP Language Terminology 9179 // Structured block - An executable statement with a single entry at the 9180 // top and a single exit at the bottom. 9181 // The point of exit cannot be a branch out of the structured block. 9182 // longjmp() and throw() must not violate the entry/exit criteria. 9183 CS->getCapturedDecl()->setNothrow(); 9184 } 9185 9186 OMPLoopDirective::HelperExprs B; 9187 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9188 // define the nested loops number. 9189 unsigned NestedLoopCount = checkOpenMPLoop( 9190 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9191 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9192 VarsWithImplicitDSA, B); 9193 if (NestedLoopCount == 0) 9194 return StmtError(); 9195 9196 assert((CurContext->isDependentContext() || B.builtAll()) && 9197 "omp target parallel for simd loop exprs were not built"); 9198 9199 if (!CurContext->isDependentContext()) { 9200 // Finalize the clauses that need pre-built expressions for CodeGen. 9201 for (OMPClause *C : Clauses) { 9202 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9203 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9204 B.NumIterations, *this, CurScope, 9205 DSAStack)) 9206 return StmtError(); 9207 } 9208 } 9209 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9210 return StmtError(); 9211 9212 setFunctionHasBranchProtectedScope(); 9213 return OMPTargetParallelForSimdDirective::Create( 9214 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9215 } 9216 9217 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9218 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9219 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9220 if (!AStmt) 9221 return StmtError(); 9222 9223 auto *CS = cast<CapturedStmt>(AStmt); 9224 // 1.2.2 OpenMP Language Terminology 9225 // Structured block - An executable statement with a single entry at the 9226 // top and a single exit at the bottom. 9227 // The point of exit cannot be a branch out of the structured block. 9228 // longjmp() and throw() must not violate the entry/exit criteria. 9229 CS->getCapturedDecl()->setNothrow(); 9230 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9231 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9232 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9233 // 1.2.2 OpenMP Language Terminology 9234 // Structured block - An executable statement with a single entry at the 9235 // top and a single exit at the bottom. 9236 // The point of exit cannot be a branch out of the structured block. 9237 // longjmp() and throw() must not violate the entry/exit criteria. 9238 CS->getCapturedDecl()->setNothrow(); 9239 } 9240 9241 OMPLoopDirective::HelperExprs B; 9242 // In presence of clause 'collapse' with number of loops, it will define the 9243 // nested loops number. 9244 unsigned NestedLoopCount = 9245 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9246 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9247 VarsWithImplicitDSA, B); 9248 if (NestedLoopCount == 0) 9249 return StmtError(); 9250 9251 assert((CurContext->isDependentContext() || B.builtAll()) && 9252 "omp target simd loop exprs were not built"); 9253 9254 if (!CurContext->isDependentContext()) { 9255 // Finalize the clauses that need pre-built expressions for CodeGen. 9256 for (OMPClause *C : Clauses) { 9257 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9258 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9259 B.NumIterations, *this, CurScope, 9260 DSAStack)) 9261 return StmtError(); 9262 } 9263 } 9264 9265 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9266 return StmtError(); 9267 9268 setFunctionHasBranchProtectedScope(); 9269 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9270 NestedLoopCount, Clauses, AStmt, B); 9271 } 9272 9273 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9274 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9275 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9276 if (!AStmt) 9277 return StmtError(); 9278 9279 auto *CS = cast<CapturedStmt>(AStmt); 9280 // 1.2.2 OpenMP Language Terminology 9281 // Structured block - An executable statement with a single entry at the 9282 // top and a single exit at the bottom. 9283 // The point of exit cannot be a branch out of the structured block. 9284 // longjmp() and throw() must not violate the entry/exit criteria. 9285 CS->getCapturedDecl()->setNothrow(); 9286 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9287 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9288 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9289 // 1.2.2 OpenMP Language Terminology 9290 // Structured block - An executable statement with a single entry at the 9291 // top and a single exit at the bottom. 9292 // The point of exit cannot be a branch out of the structured block. 9293 // longjmp() and throw() must not violate the entry/exit criteria. 9294 CS->getCapturedDecl()->setNothrow(); 9295 } 9296 9297 OMPLoopDirective::HelperExprs B; 9298 // In presence of clause 'collapse' with number of loops, it will 9299 // define the nested loops number. 9300 unsigned NestedLoopCount = 9301 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9302 nullptr /*ordered not a clause on distribute*/, CS, *this, 9303 *DSAStack, VarsWithImplicitDSA, B); 9304 if (NestedLoopCount == 0) 9305 return StmtError(); 9306 9307 assert((CurContext->isDependentContext() || B.builtAll()) && 9308 "omp teams distribute loop exprs were not built"); 9309 9310 setFunctionHasBranchProtectedScope(); 9311 9312 DSAStack->setParentTeamsRegionLoc(StartLoc); 9313 9314 return OMPTeamsDistributeDirective::Create( 9315 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9316 } 9317 9318 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9319 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9320 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9321 if (!AStmt) 9322 return StmtError(); 9323 9324 auto *CS = cast<CapturedStmt>(AStmt); 9325 // 1.2.2 OpenMP Language Terminology 9326 // Structured block - An executable statement with a single entry at the 9327 // top and a single exit at the bottom. 9328 // The point of exit cannot be a branch out of the structured block. 9329 // longjmp() and throw() must not violate the entry/exit criteria. 9330 CS->getCapturedDecl()->setNothrow(); 9331 for (int ThisCaptureLevel = 9332 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9333 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9334 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9335 // 1.2.2 OpenMP Language Terminology 9336 // Structured block - An executable statement with a single entry at the 9337 // top and a single exit at the bottom. 9338 // The point of exit cannot be a branch out of the structured block. 9339 // longjmp() and throw() must not violate the entry/exit criteria. 9340 CS->getCapturedDecl()->setNothrow(); 9341 } 9342 9343 9344 OMPLoopDirective::HelperExprs B; 9345 // In presence of clause 'collapse' with number of loops, it will 9346 // define the nested loops number. 9347 unsigned NestedLoopCount = checkOpenMPLoop( 9348 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9349 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9350 VarsWithImplicitDSA, B); 9351 9352 if (NestedLoopCount == 0) 9353 return StmtError(); 9354 9355 assert((CurContext->isDependentContext() || B.builtAll()) && 9356 "omp teams distribute simd loop exprs were not built"); 9357 9358 if (!CurContext->isDependentContext()) { 9359 // Finalize the clauses that need pre-built expressions for CodeGen. 9360 for (OMPClause *C : Clauses) { 9361 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9362 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9363 B.NumIterations, *this, CurScope, 9364 DSAStack)) 9365 return StmtError(); 9366 } 9367 } 9368 9369 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9370 return StmtError(); 9371 9372 setFunctionHasBranchProtectedScope(); 9373 9374 DSAStack->setParentTeamsRegionLoc(StartLoc); 9375 9376 return OMPTeamsDistributeSimdDirective::Create( 9377 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9378 } 9379 9380 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9381 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9382 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9383 if (!AStmt) 9384 return StmtError(); 9385 9386 auto *CS = cast<CapturedStmt>(AStmt); 9387 // 1.2.2 OpenMP Language Terminology 9388 // Structured block - An executable statement with a single entry at the 9389 // top and a single exit at the bottom. 9390 // The point of exit cannot be a branch out of the structured block. 9391 // longjmp() and throw() must not violate the entry/exit criteria. 9392 CS->getCapturedDecl()->setNothrow(); 9393 9394 for (int ThisCaptureLevel = 9395 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9396 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9397 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9398 // 1.2.2 OpenMP Language Terminology 9399 // Structured block - An executable statement with a single entry at the 9400 // top and a single exit at the bottom. 9401 // The point of exit cannot be a branch out of the structured block. 9402 // longjmp() and throw() must not violate the entry/exit criteria. 9403 CS->getCapturedDecl()->setNothrow(); 9404 } 9405 9406 OMPLoopDirective::HelperExprs B; 9407 // In presence of clause 'collapse' with number of loops, it will 9408 // define the nested loops number. 9409 unsigned NestedLoopCount = checkOpenMPLoop( 9410 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9411 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9412 VarsWithImplicitDSA, B); 9413 9414 if (NestedLoopCount == 0) 9415 return StmtError(); 9416 9417 assert((CurContext->isDependentContext() || B.builtAll()) && 9418 "omp for loop exprs were not built"); 9419 9420 if (!CurContext->isDependentContext()) { 9421 // Finalize the clauses that need pre-built expressions for CodeGen. 9422 for (OMPClause *C : Clauses) { 9423 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9424 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9425 B.NumIterations, *this, CurScope, 9426 DSAStack)) 9427 return StmtError(); 9428 } 9429 } 9430 9431 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9432 return StmtError(); 9433 9434 setFunctionHasBranchProtectedScope(); 9435 9436 DSAStack->setParentTeamsRegionLoc(StartLoc); 9437 9438 return OMPTeamsDistributeParallelForSimdDirective::Create( 9439 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9440 } 9441 9442 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9443 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9444 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9445 if (!AStmt) 9446 return StmtError(); 9447 9448 auto *CS = cast<CapturedStmt>(AStmt); 9449 // 1.2.2 OpenMP Language Terminology 9450 // Structured block - An executable statement with a single entry at the 9451 // top and a single exit at the bottom. 9452 // The point of exit cannot be a branch out of the structured block. 9453 // longjmp() and throw() must not violate the entry/exit criteria. 9454 CS->getCapturedDecl()->setNothrow(); 9455 9456 for (int ThisCaptureLevel = 9457 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9458 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9459 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9460 // 1.2.2 OpenMP Language Terminology 9461 // Structured block - An executable statement with a single entry at the 9462 // top and a single exit at the bottom. 9463 // The point of exit cannot be a branch out of the structured block. 9464 // longjmp() and throw() must not violate the entry/exit criteria. 9465 CS->getCapturedDecl()->setNothrow(); 9466 } 9467 9468 OMPLoopDirective::HelperExprs B; 9469 // In presence of clause 'collapse' with number of loops, it will 9470 // define the nested loops number. 9471 unsigned NestedLoopCount = checkOpenMPLoop( 9472 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9473 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9474 VarsWithImplicitDSA, B); 9475 9476 if (NestedLoopCount == 0) 9477 return StmtError(); 9478 9479 assert((CurContext->isDependentContext() || B.builtAll()) && 9480 "omp for loop exprs were not built"); 9481 9482 setFunctionHasBranchProtectedScope(); 9483 9484 DSAStack->setParentTeamsRegionLoc(StartLoc); 9485 9486 return OMPTeamsDistributeParallelForDirective::Create( 9487 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9488 DSAStack->isCancelRegion()); 9489 } 9490 9491 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9492 Stmt *AStmt, 9493 SourceLocation StartLoc, 9494 SourceLocation EndLoc) { 9495 if (!AStmt) 9496 return StmtError(); 9497 9498 auto *CS = cast<CapturedStmt>(AStmt); 9499 // 1.2.2 OpenMP Language Terminology 9500 // Structured block - An executable statement with a single entry at the 9501 // top and a single exit at the bottom. 9502 // The point of exit cannot be a branch out of the structured block. 9503 // longjmp() and throw() must not violate the entry/exit criteria. 9504 CS->getCapturedDecl()->setNothrow(); 9505 9506 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9507 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9508 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9509 // 1.2.2 OpenMP Language Terminology 9510 // Structured block - An executable statement with a single entry at the 9511 // top and a single exit at the bottom. 9512 // The point of exit cannot be a branch out of the structured block. 9513 // longjmp() and throw() must not violate the entry/exit criteria. 9514 CS->getCapturedDecl()->setNothrow(); 9515 } 9516 setFunctionHasBranchProtectedScope(); 9517 9518 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9519 AStmt); 9520 } 9521 9522 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9523 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9524 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9525 if (!AStmt) 9526 return StmtError(); 9527 9528 auto *CS = cast<CapturedStmt>(AStmt); 9529 // 1.2.2 OpenMP Language Terminology 9530 // Structured block - An executable statement with a single entry at the 9531 // top and a single exit at the bottom. 9532 // The point of exit cannot be a branch out of the structured block. 9533 // longjmp() and throw() must not violate the entry/exit criteria. 9534 CS->getCapturedDecl()->setNothrow(); 9535 for (int ThisCaptureLevel = 9536 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9537 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9538 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9539 // 1.2.2 OpenMP Language Terminology 9540 // Structured block - An executable statement with a single entry at the 9541 // top and a single exit at the bottom. 9542 // The point of exit cannot be a branch out of the structured block. 9543 // longjmp() and throw() must not violate the entry/exit criteria. 9544 CS->getCapturedDecl()->setNothrow(); 9545 } 9546 9547 OMPLoopDirective::HelperExprs B; 9548 // In presence of clause 'collapse' with number of loops, it will 9549 // define the nested loops number. 9550 unsigned NestedLoopCount = checkOpenMPLoop( 9551 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9552 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9553 VarsWithImplicitDSA, B); 9554 if (NestedLoopCount == 0) 9555 return StmtError(); 9556 9557 assert((CurContext->isDependentContext() || B.builtAll()) && 9558 "omp target teams distribute loop exprs were not built"); 9559 9560 setFunctionHasBranchProtectedScope(); 9561 return OMPTargetTeamsDistributeDirective::Create( 9562 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9563 } 9564 9565 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 9566 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9567 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9568 if (!AStmt) 9569 return StmtError(); 9570 9571 auto *CS = cast<CapturedStmt>(AStmt); 9572 // 1.2.2 OpenMP Language Terminology 9573 // Structured block - An executable statement with a single entry at the 9574 // top and a single exit at the bottom. 9575 // The point of exit cannot be a branch out of the structured block. 9576 // longjmp() and throw() must not violate the entry/exit criteria. 9577 CS->getCapturedDecl()->setNothrow(); 9578 for (int ThisCaptureLevel = 9579 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 9580 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9581 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9582 // 1.2.2 OpenMP Language Terminology 9583 // Structured block - An executable statement with a single entry at the 9584 // top and a single exit at the bottom. 9585 // The point of exit cannot be a branch out of the structured block. 9586 // longjmp() and throw() must not violate the entry/exit criteria. 9587 CS->getCapturedDecl()->setNothrow(); 9588 } 9589 9590 OMPLoopDirective::HelperExprs B; 9591 // In presence of clause 'collapse' with number of loops, it will 9592 // define the nested loops number. 9593 unsigned NestedLoopCount = checkOpenMPLoop( 9594 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9595 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9596 VarsWithImplicitDSA, B); 9597 if (NestedLoopCount == 0) 9598 return StmtError(); 9599 9600 assert((CurContext->isDependentContext() || B.builtAll()) && 9601 "omp target teams distribute parallel for loop exprs were not built"); 9602 9603 if (!CurContext->isDependentContext()) { 9604 // Finalize the clauses that need pre-built expressions for CodeGen. 9605 for (OMPClause *C : Clauses) { 9606 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9607 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9608 B.NumIterations, *this, CurScope, 9609 DSAStack)) 9610 return StmtError(); 9611 } 9612 } 9613 9614 setFunctionHasBranchProtectedScope(); 9615 return OMPTargetTeamsDistributeParallelForDirective::Create( 9616 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9617 DSAStack->isCancelRegion()); 9618 } 9619 9620 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9621 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9622 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9623 if (!AStmt) 9624 return StmtError(); 9625 9626 auto *CS = cast<CapturedStmt>(AStmt); 9627 // 1.2.2 OpenMP Language Terminology 9628 // Structured block - An executable statement with a single entry at the 9629 // top and a single exit at the bottom. 9630 // The point of exit cannot be a branch out of the structured block. 9631 // longjmp() and throw() must not violate the entry/exit criteria. 9632 CS->getCapturedDecl()->setNothrow(); 9633 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9634 OMPD_target_teams_distribute_parallel_for_simd); 9635 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9636 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9637 // 1.2.2 OpenMP Language Terminology 9638 // Structured block - An executable statement with a single entry at the 9639 // top and a single exit at the bottom. 9640 // The point of exit cannot be a branch out of the structured block. 9641 // longjmp() and throw() must not violate the entry/exit criteria. 9642 CS->getCapturedDecl()->setNothrow(); 9643 } 9644 9645 OMPLoopDirective::HelperExprs B; 9646 // In presence of clause 'collapse' with number of loops, it will 9647 // define the nested loops number. 9648 unsigned NestedLoopCount = 9649 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9650 getCollapseNumberExpr(Clauses), 9651 nullptr /*ordered not a clause on distribute*/, CS, *this, 9652 *DSAStack, VarsWithImplicitDSA, B); 9653 if (NestedLoopCount == 0) 9654 return StmtError(); 9655 9656 assert((CurContext->isDependentContext() || B.builtAll()) && 9657 "omp target teams distribute parallel for simd loop exprs were not " 9658 "built"); 9659 9660 if (!CurContext->isDependentContext()) { 9661 // Finalize the clauses that need pre-built expressions for CodeGen. 9662 for (OMPClause *C : Clauses) { 9663 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9664 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9665 B.NumIterations, *this, CurScope, 9666 DSAStack)) 9667 return StmtError(); 9668 } 9669 } 9670 9671 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9672 return StmtError(); 9673 9674 setFunctionHasBranchProtectedScope(); 9675 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9676 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9677 } 9678 9679 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9680 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9681 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9682 if (!AStmt) 9683 return StmtError(); 9684 9685 auto *CS = cast<CapturedStmt>(AStmt); 9686 // 1.2.2 OpenMP Language Terminology 9687 // Structured block - An executable statement with a single entry at the 9688 // top and a single exit at the bottom. 9689 // The point of exit cannot be a branch out of the structured block. 9690 // longjmp() and throw() must not violate the entry/exit criteria. 9691 CS->getCapturedDecl()->setNothrow(); 9692 for (int ThisCaptureLevel = 9693 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9694 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9695 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9696 // 1.2.2 OpenMP Language Terminology 9697 // Structured block - An executable statement with a single entry at the 9698 // top and a single exit at the bottom. 9699 // The point of exit cannot be a branch out of the structured block. 9700 // longjmp() and throw() must not violate the entry/exit criteria. 9701 CS->getCapturedDecl()->setNothrow(); 9702 } 9703 9704 OMPLoopDirective::HelperExprs B; 9705 // In presence of clause 'collapse' with number of loops, it will 9706 // define the nested loops number. 9707 unsigned NestedLoopCount = checkOpenMPLoop( 9708 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9709 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9710 VarsWithImplicitDSA, B); 9711 if (NestedLoopCount == 0) 9712 return StmtError(); 9713 9714 assert((CurContext->isDependentContext() || B.builtAll()) && 9715 "omp target teams distribute simd loop exprs were not built"); 9716 9717 if (!CurContext->isDependentContext()) { 9718 // Finalize the clauses that need pre-built expressions for CodeGen. 9719 for (OMPClause *C : Clauses) { 9720 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9721 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9722 B.NumIterations, *this, CurScope, 9723 DSAStack)) 9724 return StmtError(); 9725 } 9726 } 9727 9728 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9729 return StmtError(); 9730 9731 setFunctionHasBranchProtectedScope(); 9732 return OMPTargetTeamsDistributeSimdDirective::Create( 9733 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9734 } 9735 9736 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9737 SourceLocation StartLoc, 9738 SourceLocation LParenLoc, 9739 SourceLocation EndLoc) { 9740 OMPClause *Res = nullptr; 9741 switch (Kind) { 9742 case OMPC_final: 9743 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9744 break; 9745 case OMPC_num_threads: 9746 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9747 break; 9748 case OMPC_safelen: 9749 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9750 break; 9751 case OMPC_simdlen: 9752 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9753 break; 9754 case OMPC_allocator: 9755 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9756 break; 9757 case OMPC_collapse: 9758 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9759 break; 9760 case OMPC_ordered: 9761 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9762 break; 9763 case OMPC_device: 9764 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9765 break; 9766 case OMPC_num_teams: 9767 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9768 break; 9769 case OMPC_thread_limit: 9770 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9771 break; 9772 case OMPC_priority: 9773 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9774 break; 9775 case OMPC_grainsize: 9776 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9777 break; 9778 case OMPC_num_tasks: 9779 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9780 break; 9781 case OMPC_hint: 9782 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9783 break; 9784 case OMPC_if: 9785 case OMPC_default: 9786 case OMPC_proc_bind: 9787 case OMPC_schedule: 9788 case OMPC_private: 9789 case OMPC_firstprivate: 9790 case OMPC_lastprivate: 9791 case OMPC_shared: 9792 case OMPC_reduction: 9793 case OMPC_task_reduction: 9794 case OMPC_in_reduction: 9795 case OMPC_linear: 9796 case OMPC_aligned: 9797 case OMPC_copyin: 9798 case OMPC_copyprivate: 9799 case OMPC_nowait: 9800 case OMPC_untied: 9801 case OMPC_mergeable: 9802 case OMPC_threadprivate: 9803 case OMPC_allocate: 9804 case OMPC_flush: 9805 case OMPC_read: 9806 case OMPC_write: 9807 case OMPC_update: 9808 case OMPC_capture: 9809 case OMPC_seq_cst: 9810 case OMPC_depend: 9811 case OMPC_threads: 9812 case OMPC_simd: 9813 case OMPC_map: 9814 case OMPC_nogroup: 9815 case OMPC_dist_schedule: 9816 case OMPC_defaultmap: 9817 case OMPC_unknown: 9818 case OMPC_uniform: 9819 case OMPC_to: 9820 case OMPC_from: 9821 case OMPC_use_device_ptr: 9822 case OMPC_is_device_ptr: 9823 case OMPC_unified_address: 9824 case OMPC_unified_shared_memory: 9825 case OMPC_reverse_offload: 9826 case OMPC_dynamic_allocators: 9827 case OMPC_atomic_default_mem_order: 9828 case OMPC_device_type: 9829 llvm_unreachable("Clause is not allowed."); 9830 } 9831 return Res; 9832 } 9833 9834 // An OpenMP directive such as 'target parallel' has two captured regions: 9835 // for the 'target' and 'parallel' respectively. This function returns 9836 // the region in which to capture expressions associated with a clause. 9837 // A return value of OMPD_unknown signifies that the expression should not 9838 // be captured. 9839 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9840 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9841 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9842 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9843 switch (CKind) { 9844 case OMPC_if: 9845 switch (DKind) { 9846 case OMPD_target_parallel: 9847 case OMPD_target_parallel_for: 9848 case OMPD_target_parallel_for_simd: 9849 // If this clause applies to the nested 'parallel' region, capture within 9850 // the 'target' region, otherwise do not capture. 9851 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9852 CaptureRegion = OMPD_target; 9853 break; 9854 case OMPD_target_teams_distribute_parallel_for: 9855 case OMPD_target_teams_distribute_parallel_for_simd: 9856 // If this clause applies to the nested 'parallel' region, capture within 9857 // the 'teams' region, otherwise do not capture. 9858 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9859 CaptureRegion = OMPD_teams; 9860 break; 9861 case OMPD_teams_distribute_parallel_for: 9862 case OMPD_teams_distribute_parallel_for_simd: 9863 CaptureRegion = OMPD_teams; 9864 break; 9865 case OMPD_target_update: 9866 case OMPD_target_enter_data: 9867 case OMPD_target_exit_data: 9868 CaptureRegion = OMPD_task; 9869 break; 9870 case OMPD_cancel: 9871 case OMPD_parallel: 9872 case OMPD_parallel_sections: 9873 case OMPD_parallel_for: 9874 case OMPD_parallel_for_simd: 9875 case OMPD_target: 9876 case OMPD_target_simd: 9877 case OMPD_target_teams: 9878 case OMPD_target_teams_distribute: 9879 case OMPD_target_teams_distribute_simd: 9880 case OMPD_distribute_parallel_for: 9881 case OMPD_distribute_parallel_for_simd: 9882 case OMPD_task: 9883 case OMPD_taskloop: 9884 case OMPD_taskloop_simd: 9885 case OMPD_target_data: 9886 // Do not capture if-clause expressions. 9887 break; 9888 case OMPD_threadprivate: 9889 case OMPD_allocate: 9890 case OMPD_taskyield: 9891 case OMPD_barrier: 9892 case OMPD_taskwait: 9893 case OMPD_cancellation_point: 9894 case OMPD_flush: 9895 case OMPD_declare_reduction: 9896 case OMPD_declare_mapper: 9897 case OMPD_declare_simd: 9898 case OMPD_declare_target: 9899 case OMPD_end_declare_target: 9900 case OMPD_teams: 9901 case OMPD_simd: 9902 case OMPD_for: 9903 case OMPD_for_simd: 9904 case OMPD_sections: 9905 case OMPD_section: 9906 case OMPD_single: 9907 case OMPD_master: 9908 case OMPD_critical: 9909 case OMPD_taskgroup: 9910 case OMPD_distribute: 9911 case OMPD_ordered: 9912 case OMPD_atomic: 9913 case OMPD_distribute_simd: 9914 case OMPD_teams_distribute: 9915 case OMPD_teams_distribute_simd: 9916 case OMPD_requires: 9917 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9918 case OMPD_unknown: 9919 llvm_unreachable("Unknown OpenMP directive"); 9920 } 9921 break; 9922 case OMPC_num_threads: 9923 switch (DKind) { 9924 case OMPD_target_parallel: 9925 case OMPD_target_parallel_for: 9926 case OMPD_target_parallel_for_simd: 9927 CaptureRegion = OMPD_target; 9928 break; 9929 case OMPD_teams_distribute_parallel_for: 9930 case OMPD_teams_distribute_parallel_for_simd: 9931 case OMPD_target_teams_distribute_parallel_for: 9932 case OMPD_target_teams_distribute_parallel_for_simd: 9933 CaptureRegion = OMPD_teams; 9934 break; 9935 case OMPD_parallel: 9936 case OMPD_parallel_sections: 9937 case OMPD_parallel_for: 9938 case OMPD_parallel_for_simd: 9939 case OMPD_distribute_parallel_for: 9940 case OMPD_distribute_parallel_for_simd: 9941 // Do not capture num_threads-clause expressions. 9942 break; 9943 case OMPD_target_data: 9944 case OMPD_target_enter_data: 9945 case OMPD_target_exit_data: 9946 case OMPD_target_update: 9947 case OMPD_target: 9948 case OMPD_target_simd: 9949 case OMPD_target_teams: 9950 case OMPD_target_teams_distribute: 9951 case OMPD_target_teams_distribute_simd: 9952 case OMPD_cancel: 9953 case OMPD_task: 9954 case OMPD_taskloop: 9955 case OMPD_taskloop_simd: 9956 case OMPD_threadprivate: 9957 case OMPD_allocate: 9958 case OMPD_taskyield: 9959 case OMPD_barrier: 9960 case OMPD_taskwait: 9961 case OMPD_cancellation_point: 9962 case OMPD_flush: 9963 case OMPD_declare_reduction: 9964 case OMPD_declare_mapper: 9965 case OMPD_declare_simd: 9966 case OMPD_declare_target: 9967 case OMPD_end_declare_target: 9968 case OMPD_teams: 9969 case OMPD_simd: 9970 case OMPD_for: 9971 case OMPD_for_simd: 9972 case OMPD_sections: 9973 case OMPD_section: 9974 case OMPD_single: 9975 case OMPD_master: 9976 case OMPD_critical: 9977 case OMPD_taskgroup: 9978 case OMPD_distribute: 9979 case OMPD_ordered: 9980 case OMPD_atomic: 9981 case OMPD_distribute_simd: 9982 case OMPD_teams_distribute: 9983 case OMPD_teams_distribute_simd: 9984 case OMPD_requires: 9985 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9986 case OMPD_unknown: 9987 llvm_unreachable("Unknown OpenMP directive"); 9988 } 9989 break; 9990 case OMPC_num_teams: 9991 switch (DKind) { 9992 case OMPD_target_teams: 9993 case OMPD_target_teams_distribute: 9994 case OMPD_target_teams_distribute_simd: 9995 case OMPD_target_teams_distribute_parallel_for: 9996 case OMPD_target_teams_distribute_parallel_for_simd: 9997 CaptureRegion = OMPD_target; 9998 break; 9999 case OMPD_teams_distribute_parallel_for: 10000 case OMPD_teams_distribute_parallel_for_simd: 10001 case OMPD_teams: 10002 case OMPD_teams_distribute: 10003 case OMPD_teams_distribute_simd: 10004 // Do not capture num_teams-clause expressions. 10005 break; 10006 case OMPD_distribute_parallel_for: 10007 case OMPD_distribute_parallel_for_simd: 10008 case OMPD_task: 10009 case OMPD_taskloop: 10010 case OMPD_taskloop_simd: 10011 case OMPD_target_data: 10012 case OMPD_target_enter_data: 10013 case OMPD_target_exit_data: 10014 case OMPD_target_update: 10015 case OMPD_cancel: 10016 case OMPD_parallel: 10017 case OMPD_parallel_sections: 10018 case OMPD_parallel_for: 10019 case OMPD_parallel_for_simd: 10020 case OMPD_target: 10021 case OMPD_target_simd: 10022 case OMPD_target_parallel: 10023 case OMPD_target_parallel_for: 10024 case OMPD_target_parallel_for_simd: 10025 case OMPD_threadprivate: 10026 case OMPD_allocate: 10027 case OMPD_taskyield: 10028 case OMPD_barrier: 10029 case OMPD_taskwait: 10030 case OMPD_cancellation_point: 10031 case OMPD_flush: 10032 case OMPD_declare_reduction: 10033 case OMPD_declare_mapper: 10034 case OMPD_declare_simd: 10035 case OMPD_declare_target: 10036 case OMPD_end_declare_target: 10037 case OMPD_simd: 10038 case OMPD_for: 10039 case OMPD_for_simd: 10040 case OMPD_sections: 10041 case OMPD_section: 10042 case OMPD_single: 10043 case OMPD_master: 10044 case OMPD_critical: 10045 case OMPD_taskgroup: 10046 case OMPD_distribute: 10047 case OMPD_ordered: 10048 case OMPD_atomic: 10049 case OMPD_distribute_simd: 10050 case OMPD_requires: 10051 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10052 case OMPD_unknown: 10053 llvm_unreachable("Unknown OpenMP directive"); 10054 } 10055 break; 10056 case OMPC_thread_limit: 10057 switch (DKind) { 10058 case OMPD_target_teams: 10059 case OMPD_target_teams_distribute: 10060 case OMPD_target_teams_distribute_simd: 10061 case OMPD_target_teams_distribute_parallel_for: 10062 case OMPD_target_teams_distribute_parallel_for_simd: 10063 CaptureRegion = OMPD_target; 10064 break; 10065 case OMPD_teams_distribute_parallel_for: 10066 case OMPD_teams_distribute_parallel_for_simd: 10067 case OMPD_teams: 10068 case OMPD_teams_distribute: 10069 case OMPD_teams_distribute_simd: 10070 // Do not capture thread_limit-clause expressions. 10071 break; 10072 case OMPD_distribute_parallel_for: 10073 case OMPD_distribute_parallel_for_simd: 10074 case OMPD_task: 10075 case OMPD_taskloop: 10076 case OMPD_taskloop_simd: 10077 case OMPD_target_data: 10078 case OMPD_target_enter_data: 10079 case OMPD_target_exit_data: 10080 case OMPD_target_update: 10081 case OMPD_cancel: 10082 case OMPD_parallel: 10083 case OMPD_parallel_sections: 10084 case OMPD_parallel_for: 10085 case OMPD_parallel_for_simd: 10086 case OMPD_target: 10087 case OMPD_target_simd: 10088 case OMPD_target_parallel: 10089 case OMPD_target_parallel_for: 10090 case OMPD_target_parallel_for_simd: 10091 case OMPD_threadprivate: 10092 case OMPD_allocate: 10093 case OMPD_taskyield: 10094 case OMPD_barrier: 10095 case OMPD_taskwait: 10096 case OMPD_cancellation_point: 10097 case OMPD_flush: 10098 case OMPD_declare_reduction: 10099 case OMPD_declare_mapper: 10100 case OMPD_declare_simd: 10101 case OMPD_declare_target: 10102 case OMPD_end_declare_target: 10103 case OMPD_simd: 10104 case OMPD_for: 10105 case OMPD_for_simd: 10106 case OMPD_sections: 10107 case OMPD_section: 10108 case OMPD_single: 10109 case OMPD_master: 10110 case OMPD_critical: 10111 case OMPD_taskgroup: 10112 case OMPD_distribute: 10113 case OMPD_ordered: 10114 case OMPD_atomic: 10115 case OMPD_distribute_simd: 10116 case OMPD_requires: 10117 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10118 case OMPD_unknown: 10119 llvm_unreachable("Unknown OpenMP directive"); 10120 } 10121 break; 10122 case OMPC_schedule: 10123 switch (DKind) { 10124 case OMPD_parallel_for: 10125 case OMPD_parallel_for_simd: 10126 case OMPD_distribute_parallel_for: 10127 case OMPD_distribute_parallel_for_simd: 10128 case OMPD_teams_distribute_parallel_for: 10129 case OMPD_teams_distribute_parallel_for_simd: 10130 case OMPD_target_parallel_for: 10131 case OMPD_target_parallel_for_simd: 10132 case OMPD_target_teams_distribute_parallel_for: 10133 case OMPD_target_teams_distribute_parallel_for_simd: 10134 CaptureRegion = OMPD_parallel; 10135 break; 10136 case OMPD_for: 10137 case OMPD_for_simd: 10138 // Do not capture schedule-clause expressions. 10139 break; 10140 case OMPD_task: 10141 case OMPD_taskloop: 10142 case OMPD_taskloop_simd: 10143 case OMPD_target_data: 10144 case OMPD_target_enter_data: 10145 case OMPD_target_exit_data: 10146 case OMPD_target_update: 10147 case OMPD_teams: 10148 case OMPD_teams_distribute: 10149 case OMPD_teams_distribute_simd: 10150 case OMPD_target_teams_distribute: 10151 case OMPD_target_teams_distribute_simd: 10152 case OMPD_target: 10153 case OMPD_target_simd: 10154 case OMPD_target_parallel: 10155 case OMPD_cancel: 10156 case OMPD_parallel: 10157 case OMPD_parallel_sections: 10158 case OMPD_threadprivate: 10159 case OMPD_allocate: 10160 case OMPD_taskyield: 10161 case OMPD_barrier: 10162 case OMPD_taskwait: 10163 case OMPD_cancellation_point: 10164 case OMPD_flush: 10165 case OMPD_declare_reduction: 10166 case OMPD_declare_mapper: 10167 case OMPD_declare_simd: 10168 case OMPD_declare_target: 10169 case OMPD_end_declare_target: 10170 case OMPD_simd: 10171 case OMPD_sections: 10172 case OMPD_section: 10173 case OMPD_single: 10174 case OMPD_master: 10175 case OMPD_critical: 10176 case OMPD_taskgroup: 10177 case OMPD_distribute: 10178 case OMPD_ordered: 10179 case OMPD_atomic: 10180 case OMPD_distribute_simd: 10181 case OMPD_target_teams: 10182 case OMPD_requires: 10183 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10184 case OMPD_unknown: 10185 llvm_unreachable("Unknown OpenMP directive"); 10186 } 10187 break; 10188 case OMPC_dist_schedule: 10189 switch (DKind) { 10190 case OMPD_teams_distribute_parallel_for: 10191 case OMPD_teams_distribute_parallel_for_simd: 10192 case OMPD_teams_distribute: 10193 case OMPD_teams_distribute_simd: 10194 case OMPD_target_teams_distribute_parallel_for: 10195 case OMPD_target_teams_distribute_parallel_for_simd: 10196 case OMPD_target_teams_distribute: 10197 case OMPD_target_teams_distribute_simd: 10198 CaptureRegion = OMPD_teams; 10199 break; 10200 case OMPD_distribute_parallel_for: 10201 case OMPD_distribute_parallel_for_simd: 10202 case OMPD_distribute: 10203 case OMPD_distribute_simd: 10204 // Do not capture thread_limit-clause expressions. 10205 break; 10206 case OMPD_parallel_for: 10207 case OMPD_parallel_for_simd: 10208 case OMPD_target_parallel_for_simd: 10209 case OMPD_target_parallel_for: 10210 case OMPD_task: 10211 case OMPD_taskloop: 10212 case OMPD_taskloop_simd: 10213 case OMPD_target_data: 10214 case OMPD_target_enter_data: 10215 case OMPD_target_exit_data: 10216 case OMPD_target_update: 10217 case OMPD_teams: 10218 case OMPD_target: 10219 case OMPD_target_simd: 10220 case OMPD_target_parallel: 10221 case OMPD_cancel: 10222 case OMPD_parallel: 10223 case OMPD_parallel_sections: 10224 case OMPD_threadprivate: 10225 case OMPD_allocate: 10226 case OMPD_taskyield: 10227 case OMPD_barrier: 10228 case OMPD_taskwait: 10229 case OMPD_cancellation_point: 10230 case OMPD_flush: 10231 case OMPD_declare_reduction: 10232 case OMPD_declare_mapper: 10233 case OMPD_declare_simd: 10234 case OMPD_declare_target: 10235 case OMPD_end_declare_target: 10236 case OMPD_simd: 10237 case OMPD_for: 10238 case OMPD_for_simd: 10239 case OMPD_sections: 10240 case OMPD_section: 10241 case OMPD_single: 10242 case OMPD_master: 10243 case OMPD_critical: 10244 case OMPD_taskgroup: 10245 case OMPD_ordered: 10246 case OMPD_atomic: 10247 case OMPD_target_teams: 10248 case OMPD_requires: 10249 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10250 case OMPD_unknown: 10251 llvm_unreachable("Unknown OpenMP directive"); 10252 } 10253 break; 10254 case OMPC_device: 10255 switch (DKind) { 10256 case OMPD_target_update: 10257 case OMPD_target_enter_data: 10258 case OMPD_target_exit_data: 10259 case OMPD_target: 10260 case OMPD_target_simd: 10261 case OMPD_target_teams: 10262 case OMPD_target_parallel: 10263 case OMPD_target_teams_distribute: 10264 case OMPD_target_teams_distribute_simd: 10265 case OMPD_target_parallel_for: 10266 case OMPD_target_parallel_for_simd: 10267 case OMPD_target_teams_distribute_parallel_for: 10268 case OMPD_target_teams_distribute_parallel_for_simd: 10269 CaptureRegion = OMPD_task; 10270 break; 10271 case OMPD_target_data: 10272 // Do not capture device-clause expressions. 10273 break; 10274 case OMPD_teams_distribute_parallel_for: 10275 case OMPD_teams_distribute_parallel_for_simd: 10276 case OMPD_teams: 10277 case OMPD_teams_distribute: 10278 case OMPD_teams_distribute_simd: 10279 case OMPD_distribute_parallel_for: 10280 case OMPD_distribute_parallel_for_simd: 10281 case OMPD_task: 10282 case OMPD_taskloop: 10283 case OMPD_taskloop_simd: 10284 case OMPD_cancel: 10285 case OMPD_parallel: 10286 case OMPD_parallel_sections: 10287 case OMPD_parallel_for: 10288 case OMPD_parallel_for_simd: 10289 case OMPD_threadprivate: 10290 case OMPD_allocate: 10291 case OMPD_taskyield: 10292 case OMPD_barrier: 10293 case OMPD_taskwait: 10294 case OMPD_cancellation_point: 10295 case OMPD_flush: 10296 case OMPD_declare_reduction: 10297 case OMPD_declare_mapper: 10298 case OMPD_declare_simd: 10299 case OMPD_declare_target: 10300 case OMPD_end_declare_target: 10301 case OMPD_simd: 10302 case OMPD_for: 10303 case OMPD_for_simd: 10304 case OMPD_sections: 10305 case OMPD_section: 10306 case OMPD_single: 10307 case OMPD_master: 10308 case OMPD_critical: 10309 case OMPD_taskgroup: 10310 case OMPD_distribute: 10311 case OMPD_ordered: 10312 case OMPD_atomic: 10313 case OMPD_distribute_simd: 10314 case OMPD_requires: 10315 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10316 case OMPD_unknown: 10317 llvm_unreachable("Unknown OpenMP directive"); 10318 } 10319 break; 10320 case OMPC_firstprivate: 10321 case OMPC_lastprivate: 10322 case OMPC_reduction: 10323 case OMPC_task_reduction: 10324 case OMPC_in_reduction: 10325 case OMPC_linear: 10326 case OMPC_default: 10327 case OMPC_proc_bind: 10328 case OMPC_final: 10329 case OMPC_safelen: 10330 case OMPC_simdlen: 10331 case OMPC_allocator: 10332 case OMPC_collapse: 10333 case OMPC_private: 10334 case OMPC_shared: 10335 case OMPC_aligned: 10336 case OMPC_copyin: 10337 case OMPC_copyprivate: 10338 case OMPC_ordered: 10339 case OMPC_nowait: 10340 case OMPC_untied: 10341 case OMPC_mergeable: 10342 case OMPC_threadprivate: 10343 case OMPC_allocate: 10344 case OMPC_flush: 10345 case OMPC_read: 10346 case OMPC_write: 10347 case OMPC_update: 10348 case OMPC_capture: 10349 case OMPC_seq_cst: 10350 case OMPC_depend: 10351 case OMPC_threads: 10352 case OMPC_simd: 10353 case OMPC_map: 10354 case OMPC_priority: 10355 case OMPC_grainsize: 10356 case OMPC_nogroup: 10357 case OMPC_num_tasks: 10358 case OMPC_hint: 10359 case OMPC_defaultmap: 10360 case OMPC_unknown: 10361 case OMPC_uniform: 10362 case OMPC_to: 10363 case OMPC_from: 10364 case OMPC_use_device_ptr: 10365 case OMPC_is_device_ptr: 10366 case OMPC_unified_address: 10367 case OMPC_unified_shared_memory: 10368 case OMPC_reverse_offload: 10369 case OMPC_dynamic_allocators: 10370 case OMPC_atomic_default_mem_order: 10371 case OMPC_device_type: 10372 llvm_unreachable("Unexpected OpenMP clause."); 10373 } 10374 return CaptureRegion; 10375 } 10376 10377 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10378 Expr *Condition, SourceLocation StartLoc, 10379 SourceLocation LParenLoc, 10380 SourceLocation NameModifierLoc, 10381 SourceLocation ColonLoc, 10382 SourceLocation EndLoc) { 10383 Expr *ValExpr = Condition; 10384 Stmt *HelperValStmt = nullptr; 10385 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10386 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10387 !Condition->isInstantiationDependent() && 10388 !Condition->containsUnexpandedParameterPack()) { 10389 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10390 if (Val.isInvalid()) 10391 return nullptr; 10392 10393 ValExpr = Val.get(); 10394 10395 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10396 CaptureRegion = 10397 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10398 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10399 ValExpr = MakeFullExpr(ValExpr).get(); 10400 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10401 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10402 HelperValStmt = buildPreInits(Context, Captures); 10403 } 10404 } 10405 10406 return new (Context) 10407 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10408 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10409 } 10410 10411 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10412 SourceLocation StartLoc, 10413 SourceLocation LParenLoc, 10414 SourceLocation EndLoc) { 10415 Expr *ValExpr = Condition; 10416 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10417 !Condition->isInstantiationDependent() && 10418 !Condition->containsUnexpandedParameterPack()) { 10419 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10420 if (Val.isInvalid()) 10421 return nullptr; 10422 10423 ValExpr = MakeFullExpr(Val.get()).get(); 10424 } 10425 10426 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10427 } 10428 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10429 Expr *Op) { 10430 if (!Op) 10431 return ExprError(); 10432 10433 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10434 public: 10435 IntConvertDiagnoser() 10436 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10437 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10438 QualType T) override { 10439 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10440 } 10441 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10442 QualType T) override { 10443 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10444 } 10445 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10446 QualType T, 10447 QualType ConvTy) override { 10448 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10449 } 10450 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 10451 QualType ConvTy) override { 10452 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10453 << ConvTy->isEnumeralType() << ConvTy; 10454 } 10455 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 10456 QualType T) override { 10457 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 10458 } 10459 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 10460 QualType ConvTy) override { 10461 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10462 << ConvTy->isEnumeralType() << ConvTy; 10463 } 10464 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 10465 QualType) override { 10466 llvm_unreachable("conversion functions are permitted"); 10467 } 10468 } ConvertDiagnoser; 10469 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 10470 } 10471 10472 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 10473 OpenMPClauseKind CKind, 10474 bool StrictlyPositive) { 10475 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 10476 !ValExpr->isInstantiationDependent()) { 10477 SourceLocation Loc = ValExpr->getExprLoc(); 10478 ExprResult Value = 10479 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 10480 if (Value.isInvalid()) 10481 return false; 10482 10483 ValExpr = Value.get(); 10484 // The expression must evaluate to a non-negative integer value. 10485 llvm::APSInt Result; 10486 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 10487 Result.isSigned() && 10488 !((!StrictlyPositive && Result.isNonNegative()) || 10489 (StrictlyPositive && Result.isStrictlyPositive()))) { 10490 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 10491 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10492 << ValExpr->getSourceRange(); 10493 return false; 10494 } 10495 } 10496 return true; 10497 } 10498 10499 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 10500 SourceLocation StartLoc, 10501 SourceLocation LParenLoc, 10502 SourceLocation EndLoc) { 10503 Expr *ValExpr = NumThreads; 10504 Stmt *HelperValStmt = nullptr; 10505 10506 // OpenMP [2.5, Restrictions] 10507 // The num_threads expression must evaluate to a positive integer value. 10508 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 10509 /*StrictlyPositive=*/true)) 10510 return nullptr; 10511 10512 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10513 OpenMPDirectiveKind CaptureRegion = 10514 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 10515 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10516 ValExpr = MakeFullExpr(ValExpr).get(); 10517 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10518 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10519 HelperValStmt = buildPreInits(Context, Captures); 10520 } 10521 10522 return new (Context) OMPNumThreadsClause( 10523 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 10524 } 10525 10526 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 10527 OpenMPClauseKind CKind, 10528 bool StrictlyPositive) { 10529 if (!E) 10530 return ExprError(); 10531 if (E->isValueDependent() || E->isTypeDependent() || 10532 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 10533 return E; 10534 llvm::APSInt Result; 10535 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 10536 if (ICE.isInvalid()) 10537 return ExprError(); 10538 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 10539 (!StrictlyPositive && !Result.isNonNegative())) { 10540 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 10541 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10542 << E->getSourceRange(); 10543 return ExprError(); 10544 } 10545 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 10546 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 10547 << E->getSourceRange(); 10548 return ExprError(); 10549 } 10550 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 10551 DSAStack->setAssociatedLoops(Result.getExtValue()); 10552 else if (CKind == OMPC_ordered) 10553 DSAStack->setAssociatedLoops(Result.getExtValue()); 10554 return ICE; 10555 } 10556 10557 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 10558 SourceLocation LParenLoc, 10559 SourceLocation EndLoc) { 10560 // OpenMP [2.8.1, simd construct, Description] 10561 // The parameter of the safelen clause must be a constant 10562 // positive integer expression. 10563 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 10564 if (Safelen.isInvalid()) 10565 return nullptr; 10566 return new (Context) 10567 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 10568 } 10569 10570 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 10571 SourceLocation LParenLoc, 10572 SourceLocation EndLoc) { 10573 // OpenMP [2.8.1, simd construct, Description] 10574 // The parameter of the simdlen clause must be a constant 10575 // positive integer expression. 10576 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 10577 if (Simdlen.isInvalid()) 10578 return nullptr; 10579 return new (Context) 10580 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 10581 } 10582 10583 /// Tries to find omp_allocator_handle_t type. 10584 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 10585 DSAStackTy *Stack) { 10586 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 10587 if (!OMPAllocatorHandleT.isNull()) 10588 return true; 10589 // Build the predefined allocator expressions. 10590 bool ErrorFound = false; 10591 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 10592 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 10593 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 10594 StringRef Allocator = 10595 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 10596 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 10597 auto *VD = dyn_cast_or_null<ValueDecl>( 10598 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 10599 if (!VD) { 10600 ErrorFound = true; 10601 break; 10602 } 10603 QualType AllocatorType = 10604 VD->getType().getNonLValueExprType(S.getASTContext()); 10605 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10606 if (!Res.isUsable()) { 10607 ErrorFound = true; 10608 break; 10609 } 10610 if (OMPAllocatorHandleT.isNull()) 10611 OMPAllocatorHandleT = AllocatorType; 10612 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10613 ErrorFound = true; 10614 break; 10615 } 10616 Stack->setAllocator(AllocatorKind, Res.get()); 10617 } 10618 if (ErrorFound) { 10619 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10620 return false; 10621 } 10622 OMPAllocatorHandleT.addConst(); 10623 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10624 return true; 10625 } 10626 10627 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10628 SourceLocation LParenLoc, 10629 SourceLocation EndLoc) { 10630 // OpenMP [2.11.3, allocate Directive, Description] 10631 // allocator is an expression of omp_allocator_handle_t type. 10632 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10633 return nullptr; 10634 10635 ExprResult Allocator = DefaultLvalueConversion(A); 10636 if (Allocator.isInvalid()) 10637 return nullptr; 10638 Allocator = PerformImplicitConversion(Allocator.get(), 10639 DSAStack->getOMPAllocatorHandleT(), 10640 Sema::AA_Initializing, 10641 /*AllowExplicit=*/true); 10642 if (Allocator.isInvalid()) 10643 return nullptr; 10644 return new (Context) 10645 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10646 } 10647 10648 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10649 SourceLocation StartLoc, 10650 SourceLocation LParenLoc, 10651 SourceLocation EndLoc) { 10652 // OpenMP [2.7.1, loop construct, Description] 10653 // OpenMP [2.8.1, simd construct, Description] 10654 // OpenMP [2.9.6, distribute construct, Description] 10655 // The parameter of the collapse clause must be a constant 10656 // positive integer expression. 10657 ExprResult NumForLoopsResult = 10658 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10659 if (NumForLoopsResult.isInvalid()) 10660 return nullptr; 10661 return new (Context) 10662 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10663 } 10664 10665 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10666 SourceLocation EndLoc, 10667 SourceLocation LParenLoc, 10668 Expr *NumForLoops) { 10669 // OpenMP [2.7.1, loop construct, Description] 10670 // OpenMP [2.8.1, simd construct, Description] 10671 // OpenMP [2.9.6, distribute construct, Description] 10672 // The parameter of the ordered clause must be a constant 10673 // positive integer expression if any. 10674 if (NumForLoops && LParenLoc.isValid()) { 10675 ExprResult NumForLoopsResult = 10676 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10677 if (NumForLoopsResult.isInvalid()) 10678 return nullptr; 10679 NumForLoops = NumForLoopsResult.get(); 10680 } else { 10681 NumForLoops = nullptr; 10682 } 10683 auto *Clause = OMPOrderedClause::Create( 10684 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10685 StartLoc, LParenLoc, EndLoc); 10686 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10687 return Clause; 10688 } 10689 10690 OMPClause *Sema::ActOnOpenMPSimpleClause( 10691 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10692 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10693 OMPClause *Res = nullptr; 10694 switch (Kind) { 10695 case OMPC_default: 10696 Res = 10697 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10698 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10699 break; 10700 case OMPC_proc_bind: 10701 Res = ActOnOpenMPProcBindClause( 10702 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10703 LParenLoc, EndLoc); 10704 break; 10705 case OMPC_atomic_default_mem_order: 10706 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10707 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10708 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10709 break; 10710 case OMPC_if: 10711 case OMPC_final: 10712 case OMPC_num_threads: 10713 case OMPC_safelen: 10714 case OMPC_simdlen: 10715 case OMPC_allocator: 10716 case OMPC_collapse: 10717 case OMPC_schedule: 10718 case OMPC_private: 10719 case OMPC_firstprivate: 10720 case OMPC_lastprivate: 10721 case OMPC_shared: 10722 case OMPC_reduction: 10723 case OMPC_task_reduction: 10724 case OMPC_in_reduction: 10725 case OMPC_linear: 10726 case OMPC_aligned: 10727 case OMPC_copyin: 10728 case OMPC_copyprivate: 10729 case OMPC_ordered: 10730 case OMPC_nowait: 10731 case OMPC_untied: 10732 case OMPC_mergeable: 10733 case OMPC_threadprivate: 10734 case OMPC_allocate: 10735 case OMPC_flush: 10736 case OMPC_read: 10737 case OMPC_write: 10738 case OMPC_update: 10739 case OMPC_capture: 10740 case OMPC_seq_cst: 10741 case OMPC_depend: 10742 case OMPC_device: 10743 case OMPC_threads: 10744 case OMPC_simd: 10745 case OMPC_map: 10746 case OMPC_num_teams: 10747 case OMPC_thread_limit: 10748 case OMPC_priority: 10749 case OMPC_grainsize: 10750 case OMPC_nogroup: 10751 case OMPC_num_tasks: 10752 case OMPC_hint: 10753 case OMPC_dist_schedule: 10754 case OMPC_defaultmap: 10755 case OMPC_unknown: 10756 case OMPC_uniform: 10757 case OMPC_to: 10758 case OMPC_from: 10759 case OMPC_use_device_ptr: 10760 case OMPC_is_device_ptr: 10761 case OMPC_unified_address: 10762 case OMPC_unified_shared_memory: 10763 case OMPC_reverse_offload: 10764 case OMPC_dynamic_allocators: 10765 case OMPC_device_type: 10766 llvm_unreachable("Clause is not allowed."); 10767 } 10768 return Res; 10769 } 10770 10771 static std::string 10772 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10773 ArrayRef<unsigned> Exclude = llvm::None) { 10774 SmallString<256> Buffer; 10775 llvm::raw_svector_ostream Out(Buffer); 10776 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10777 unsigned Skipped = Exclude.size(); 10778 auto S = Exclude.begin(), E = Exclude.end(); 10779 for (unsigned I = First; I < Last; ++I) { 10780 if (std::find(S, E, I) != E) { 10781 --Skipped; 10782 continue; 10783 } 10784 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10785 if (I == Bound - Skipped) 10786 Out << " or "; 10787 else if (I != Bound + 1 - Skipped) 10788 Out << ", "; 10789 } 10790 return Out.str(); 10791 } 10792 10793 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 10794 SourceLocation KindKwLoc, 10795 SourceLocation StartLoc, 10796 SourceLocation LParenLoc, 10797 SourceLocation EndLoc) { 10798 if (Kind == OMPC_DEFAULT_unknown) { 10799 static_assert(OMPC_DEFAULT_unknown > 0, 10800 "OMPC_DEFAULT_unknown not greater than 0"); 10801 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10802 << getListOfPossibleValues(OMPC_default, /*First=*/0, 10803 /*Last=*/OMPC_DEFAULT_unknown) 10804 << getOpenMPClauseName(OMPC_default); 10805 return nullptr; 10806 } 10807 switch (Kind) { 10808 case OMPC_DEFAULT_none: 10809 DSAStack->setDefaultDSANone(KindKwLoc); 10810 break; 10811 case OMPC_DEFAULT_shared: 10812 DSAStack->setDefaultDSAShared(KindKwLoc); 10813 break; 10814 case OMPC_DEFAULT_unknown: 10815 llvm_unreachable("Clause kind is not allowed."); 10816 break; 10817 } 10818 return new (Context) 10819 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10820 } 10821 10822 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10823 SourceLocation KindKwLoc, 10824 SourceLocation StartLoc, 10825 SourceLocation LParenLoc, 10826 SourceLocation EndLoc) { 10827 if (Kind == OMPC_PROC_BIND_unknown) { 10828 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10829 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10830 /*Last=*/OMPC_PROC_BIND_unknown) 10831 << getOpenMPClauseName(OMPC_proc_bind); 10832 return nullptr; 10833 } 10834 return new (Context) 10835 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10836 } 10837 10838 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10839 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10840 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10841 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10842 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10843 << getListOfPossibleValues( 10844 OMPC_atomic_default_mem_order, /*First=*/0, 10845 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10846 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10847 return nullptr; 10848 } 10849 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10850 LParenLoc, EndLoc); 10851 } 10852 10853 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10854 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10855 SourceLocation StartLoc, SourceLocation LParenLoc, 10856 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10857 SourceLocation EndLoc) { 10858 OMPClause *Res = nullptr; 10859 switch (Kind) { 10860 case OMPC_schedule: 10861 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10862 assert(Argument.size() == NumberOfElements && 10863 ArgumentLoc.size() == NumberOfElements); 10864 Res = ActOnOpenMPScheduleClause( 10865 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10866 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10867 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10868 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10869 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10870 break; 10871 case OMPC_if: 10872 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10873 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10874 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10875 DelimLoc, EndLoc); 10876 break; 10877 case OMPC_dist_schedule: 10878 Res = ActOnOpenMPDistScheduleClause( 10879 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10880 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10881 break; 10882 case OMPC_defaultmap: 10883 enum { Modifier, DefaultmapKind }; 10884 Res = ActOnOpenMPDefaultmapClause( 10885 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10886 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10887 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10888 EndLoc); 10889 break; 10890 case OMPC_final: 10891 case OMPC_num_threads: 10892 case OMPC_safelen: 10893 case OMPC_simdlen: 10894 case OMPC_allocator: 10895 case OMPC_collapse: 10896 case OMPC_default: 10897 case OMPC_proc_bind: 10898 case OMPC_private: 10899 case OMPC_firstprivate: 10900 case OMPC_lastprivate: 10901 case OMPC_shared: 10902 case OMPC_reduction: 10903 case OMPC_task_reduction: 10904 case OMPC_in_reduction: 10905 case OMPC_linear: 10906 case OMPC_aligned: 10907 case OMPC_copyin: 10908 case OMPC_copyprivate: 10909 case OMPC_ordered: 10910 case OMPC_nowait: 10911 case OMPC_untied: 10912 case OMPC_mergeable: 10913 case OMPC_threadprivate: 10914 case OMPC_allocate: 10915 case OMPC_flush: 10916 case OMPC_read: 10917 case OMPC_write: 10918 case OMPC_update: 10919 case OMPC_capture: 10920 case OMPC_seq_cst: 10921 case OMPC_depend: 10922 case OMPC_device: 10923 case OMPC_threads: 10924 case OMPC_simd: 10925 case OMPC_map: 10926 case OMPC_num_teams: 10927 case OMPC_thread_limit: 10928 case OMPC_priority: 10929 case OMPC_grainsize: 10930 case OMPC_nogroup: 10931 case OMPC_num_tasks: 10932 case OMPC_hint: 10933 case OMPC_unknown: 10934 case OMPC_uniform: 10935 case OMPC_to: 10936 case OMPC_from: 10937 case OMPC_use_device_ptr: 10938 case OMPC_is_device_ptr: 10939 case OMPC_unified_address: 10940 case OMPC_unified_shared_memory: 10941 case OMPC_reverse_offload: 10942 case OMPC_dynamic_allocators: 10943 case OMPC_atomic_default_mem_order: 10944 case OMPC_device_type: 10945 llvm_unreachable("Clause is not allowed."); 10946 } 10947 return Res; 10948 } 10949 10950 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10951 OpenMPScheduleClauseModifier M2, 10952 SourceLocation M1Loc, SourceLocation M2Loc) { 10953 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10954 SmallVector<unsigned, 2> Excluded; 10955 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10956 Excluded.push_back(M2); 10957 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10958 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10959 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10960 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10961 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10962 << getListOfPossibleValues(OMPC_schedule, 10963 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10964 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10965 Excluded) 10966 << getOpenMPClauseName(OMPC_schedule); 10967 return true; 10968 } 10969 return false; 10970 } 10971 10972 OMPClause *Sema::ActOnOpenMPScheduleClause( 10973 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10974 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10975 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10976 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10977 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10978 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10979 return nullptr; 10980 // OpenMP, 2.7.1, Loop Construct, Restrictions 10981 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10982 // but not both. 10983 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10984 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10985 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10986 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10987 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10988 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10989 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10990 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10991 return nullptr; 10992 } 10993 if (Kind == OMPC_SCHEDULE_unknown) { 10994 std::string Values; 10995 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10996 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10997 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10998 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10999 Exclude); 11000 } else { 11001 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11002 /*Last=*/OMPC_SCHEDULE_unknown); 11003 } 11004 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11005 << Values << getOpenMPClauseName(OMPC_schedule); 11006 return nullptr; 11007 } 11008 // OpenMP, 2.7.1, Loop Construct, Restrictions 11009 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11010 // schedule(guided). 11011 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11012 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11013 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11014 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11015 diag::err_omp_schedule_nonmonotonic_static); 11016 return nullptr; 11017 } 11018 Expr *ValExpr = ChunkSize; 11019 Stmt *HelperValStmt = nullptr; 11020 if (ChunkSize) { 11021 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11022 !ChunkSize->isInstantiationDependent() && 11023 !ChunkSize->containsUnexpandedParameterPack()) { 11024 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11025 ExprResult Val = 11026 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11027 if (Val.isInvalid()) 11028 return nullptr; 11029 11030 ValExpr = Val.get(); 11031 11032 // OpenMP [2.7.1, Restrictions] 11033 // chunk_size must be a loop invariant integer expression with a positive 11034 // value. 11035 llvm::APSInt Result; 11036 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11037 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11038 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11039 << "schedule" << 1 << ChunkSize->getSourceRange(); 11040 return nullptr; 11041 } 11042 } else if (getOpenMPCaptureRegionForClause( 11043 DSAStack->getCurrentDirective(), OMPC_schedule) != 11044 OMPD_unknown && 11045 !CurContext->isDependentContext()) { 11046 ValExpr = MakeFullExpr(ValExpr).get(); 11047 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11048 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11049 HelperValStmt = buildPreInits(Context, Captures); 11050 } 11051 } 11052 } 11053 11054 return new (Context) 11055 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11056 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11057 } 11058 11059 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11060 SourceLocation StartLoc, 11061 SourceLocation EndLoc) { 11062 OMPClause *Res = nullptr; 11063 switch (Kind) { 11064 case OMPC_ordered: 11065 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11066 break; 11067 case OMPC_nowait: 11068 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11069 break; 11070 case OMPC_untied: 11071 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11072 break; 11073 case OMPC_mergeable: 11074 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11075 break; 11076 case OMPC_read: 11077 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11078 break; 11079 case OMPC_write: 11080 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11081 break; 11082 case OMPC_update: 11083 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11084 break; 11085 case OMPC_capture: 11086 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11087 break; 11088 case OMPC_seq_cst: 11089 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11090 break; 11091 case OMPC_threads: 11092 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11093 break; 11094 case OMPC_simd: 11095 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11096 break; 11097 case OMPC_nogroup: 11098 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11099 break; 11100 case OMPC_unified_address: 11101 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11102 break; 11103 case OMPC_unified_shared_memory: 11104 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11105 break; 11106 case OMPC_reverse_offload: 11107 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11108 break; 11109 case OMPC_dynamic_allocators: 11110 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11111 break; 11112 case OMPC_if: 11113 case OMPC_final: 11114 case OMPC_num_threads: 11115 case OMPC_safelen: 11116 case OMPC_simdlen: 11117 case OMPC_allocator: 11118 case OMPC_collapse: 11119 case OMPC_schedule: 11120 case OMPC_private: 11121 case OMPC_firstprivate: 11122 case OMPC_lastprivate: 11123 case OMPC_shared: 11124 case OMPC_reduction: 11125 case OMPC_task_reduction: 11126 case OMPC_in_reduction: 11127 case OMPC_linear: 11128 case OMPC_aligned: 11129 case OMPC_copyin: 11130 case OMPC_copyprivate: 11131 case OMPC_default: 11132 case OMPC_proc_bind: 11133 case OMPC_threadprivate: 11134 case OMPC_allocate: 11135 case OMPC_flush: 11136 case OMPC_depend: 11137 case OMPC_device: 11138 case OMPC_map: 11139 case OMPC_num_teams: 11140 case OMPC_thread_limit: 11141 case OMPC_priority: 11142 case OMPC_grainsize: 11143 case OMPC_num_tasks: 11144 case OMPC_hint: 11145 case OMPC_dist_schedule: 11146 case OMPC_defaultmap: 11147 case OMPC_unknown: 11148 case OMPC_uniform: 11149 case OMPC_to: 11150 case OMPC_from: 11151 case OMPC_use_device_ptr: 11152 case OMPC_is_device_ptr: 11153 case OMPC_atomic_default_mem_order: 11154 case OMPC_device_type: 11155 llvm_unreachable("Clause is not allowed."); 11156 } 11157 return Res; 11158 } 11159 11160 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11161 SourceLocation EndLoc) { 11162 DSAStack->setNowaitRegion(); 11163 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11164 } 11165 11166 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11167 SourceLocation EndLoc) { 11168 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11169 } 11170 11171 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11172 SourceLocation EndLoc) { 11173 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11174 } 11175 11176 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11177 SourceLocation EndLoc) { 11178 return new (Context) OMPReadClause(StartLoc, EndLoc); 11179 } 11180 11181 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11182 SourceLocation EndLoc) { 11183 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11184 } 11185 11186 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11187 SourceLocation EndLoc) { 11188 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11189 } 11190 11191 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11192 SourceLocation EndLoc) { 11193 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11194 } 11195 11196 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11197 SourceLocation EndLoc) { 11198 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11199 } 11200 11201 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11202 SourceLocation EndLoc) { 11203 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11204 } 11205 11206 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11207 SourceLocation EndLoc) { 11208 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11209 } 11210 11211 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11212 SourceLocation EndLoc) { 11213 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11214 } 11215 11216 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11217 SourceLocation EndLoc) { 11218 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11219 } 11220 11221 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11222 SourceLocation EndLoc) { 11223 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11224 } 11225 11226 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11227 SourceLocation EndLoc) { 11228 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11229 } 11230 11231 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11232 SourceLocation EndLoc) { 11233 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11234 } 11235 11236 OMPClause *Sema::ActOnOpenMPVarListClause( 11237 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11238 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11239 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11240 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11241 OpenMPLinearClauseKind LinKind, 11242 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11243 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11244 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11245 SourceLocation StartLoc = Locs.StartLoc; 11246 SourceLocation LParenLoc = Locs.LParenLoc; 11247 SourceLocation EndLoc = Locs.EndLoc; 11248 OMPClause *Res = nullptr; 11249 switch (Kind) { 11250 case OMPC_private: 11251 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11252 break; 11253 case OMPC_firstprivate: 11254 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11255 break; 11256 case OMPC_lastprivate: 11257 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11258 break; 11259 case OMPC_shared: 11260 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11261 break; 11262 case OMPC_reduction: 11263 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11264 EndLoc, ReductionOrMapperIdScopeSpec, 11265 ReductionOrMapperId); 11266 break; 11267 case OMPC_task_reduction: 11268 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11269 EndLoc, ReductionOrMapperIdScopeSpec, 11270 ReductionOrMapperId); 11271 break; 11272 case OMPC_in_reduction: 11273 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11274 EndLoc, ReductionOrMapperIdScopeSpec, 11275 ReductionOrMapperId); 11276 break; 11277 case OMPC_linear: 11278 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11279 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11280 break; 11281 case OMPC_aligned: 11282 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11283 ColonLoc, EndLoc); 11284 break; 11285 case OMPC_copyin: 11286 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11287 break; 11288 case OMPC_copyprivate: 11289 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11290 break; 11291 case OMPC_flush: 11292 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11293 break; 11294 case OMPC_depend: 11295 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11296 StartLoc, LParenLoc, EndLoc); 11297 break; 11298 case OMPC_map: 11299 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11300 ReductionOrMapperIdScopeSpec, 11301 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11302 DepLinMapLoc, ColonLoc, VarList, Locs); 11303 break; 11304 case OMPC_to: 11305 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11306 ReductionOrMapperId, Locs); 11307 break; 11308 case OMPC_from: 11309 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11310 ReductionOrMapperId, Locs); 11311 break; 11312 case OMPC_use_device_ptr: 11313 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11314 break; 11315 case OMPC_is_device_ptr: 11316 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11317 break; 11318 case OMPC_allocate: 11319 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11320 ColonLoc, EndLoc); 11321 break; 11322 case OMPC_if: 11323 case OMPC_final: 11324 case OMPC_num_threads: 11325 case OMPC_safelen: 11326 case OMPC_simdlen: 11327 case OMPC_allocator: 11328 case OMPC_collapse: 11329 case OMPC_default: 11330 case OMPC_proc_bind: 11331 case OMPC_schedule: 11332 case OMPC_ordered: 11333 case OMPC_nowait: 11334 case OMPC_untied: 11335 case OMPC_mergeable: 11336 case OMPC_threadprivate: 11337 case OMPC_read: 11338 case OMPC_write: 11339 case OMPC_update: 11340 case OMPC_capture: 11341 case OMPC_seq_cst: 11342 case OMPC_device: 11343 case OMPC_threads: 11344 case OMPC_simd: 11345 case OMPC_num_teams: 11346 case OMPC_thread_limit: 11347 case OMPC_priority: 11348 case OMPC_grainsize: 11349 case OMPC_nogroup: 11350 case OMPC_num_tasks: 11351 case OMPC_hint: 11352 case OMPC_dist_schedule: 11353 case OMPC_defaultmap: 11354 case OMPC_unknown: 11355 case OMPC_uniform: 11356 case OMPC_unified_address: 11357 case OMPC_unified_shared_memory: 11358 case OMPC_reverse_offload: 11359 case OMPC_dynamic_allocators: 11360 case OMPC_atomic_default_mem_order: 11361 case OMPC_device_type: 11362 llvm_unreachable("Clause is not allowed."); 11363 } 11364 return Res; 11365 } 11366 11367 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11368 ExprObjectKind OK, SourceLocation Loc) { 11369 ExprResult Res = BuildDeclRefExpr( 11370 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11371 if (!Res.isUsable()) 11372 return ExprError(); 11373 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11374 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11375 if (!Res.isUsable()) 11376 return ExprError(); 11377 } 11378 if (VK != VK_LValue && Res.get()->isGLValue()) { 11379 Res = DefaultLvalueConversion(Res.get()); 11380 if (!Res.isUsable()) 11381 return ExprError(); 11382 } 11383 return Res; 11384 } 11385 11386 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11387 SourceLocation StartLoc, 11388 SourceLocation LParenLoc, 11389 SourceLocation EndLoc) { 11390 SmallVector<Expr *, 8> Vars; 11391 SmallVector<Expr *, 8> PrivateCopies; 11392 for (Expr *RefExpr : VarList) { 11393 assert(RefExpr && "NULL expr in OpenMP private clause."); 11394 SourceLocation ELoc; 11395 SourceRange ERange; 11396 Expr *SimpleRefExpr = RefExpr; 11397 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11398 if (Res.second) { 11399 // It will be analyzed later. 11400 Vars.push_back(RefExpr); 11401 PrivateCopies.push_back(nullptr); 11402 } 11403 ValueDecl *D = Res.first; 11404 if (!D) 11405 continue; 11406 11407 QualType Type = D->getType(); 11408 auto *VD = dyn_cast<VarDecl>(D); 11409 11410 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11411 // A variable that appears in a private clause must not have an incomplete 11412 // type or a reference type. 11413 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11414 continue; 11415 Type = Type.getNonReferenceType(); 11416 11417 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11418 // A variable that is privatized must not have a const-qualified type 11419 // unless it is of class type with a mutable member. This restriction does 11420 // not apply to the firstprivate clause. 11421 // 11422 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11423 // A variable that appears in a private clause must not have a 11424 // const-qualified type unless it is of class type with a mutable member. 11425 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11426 continue; 11427 11428 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11429 // in a Construct] 11430 // Variables with the predetermined data-sharing attributes may not be 11431 // listed in data-sharing attributes clauses, except for the cases 11432 // listed below. For these exceptions only, listing a predetermined 11433 // variable in a data-sharing attribute clause is allowed and overrides 11434 // the variable's predetermined data-sharing attributes. 11435 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11436 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 11437 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11438 << getOpenMPClauseName(OMPC_private); 11439 reportOriginalDsa(*this, DSAStack, D, DVar); 11440 continue; 11441 } 11442 11443 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11444 // Variably modified types are not supported for tasks. 11445 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11446 isOpenMPTaskingDirective(CurrDir)) { 11447 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11448 << getOpenMPClauseName(OMPC_private) << Type 11449 << getOpenMPDirectiveName(CurrDir); 11450 bool IsDecl = 11451 !VD || 11452 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11453 Diag(D->getLocation(), 11454 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11455 << D; 11456 continue; 11457 } 11458 11459 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11460 // A list item cannot appear in both a map clause and a data-sharing 11461 // attribute clause on the same construct 11462 // 11463 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11464 // A list item cannot appear in both a map clause and a data-sharing 11465 // attribute clause on the same construct unless the construct is a 11466 // combined construct. 11467 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 11468 CurrDir == OMPD_target) { 11469 OpenMPClauseKind ConflictKind; 11470 if (DSAStack->checkMappableExprComponentListsForDecl( 11471 VD, /*CurrentRegionOnly=*/true, 11472 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 11473 OpenMPClauseKind WhereFoundClauseKind) -> bool { 11474 ConflictKind = WhereFoundClauseKind; 11475 return true; 11476 })) { 11477 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11478 << getOpenMPClauseName(OMPC_private) 11479 << getOpenMPClauseName(ConflictKind) 11480 << getOpenMPDirectiveName(CurrDir); 11481 reportOriginalDsa(*this, DSAStack, D, DVar); 11482 continue; 11483 } 11484 } 11485 11486 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 11487 // A variable of class type (or array thereof) that appears in a private 11488 // clause requires an accessible, unambiguous default constructor for the 11489 // class type. 11490 // Generate helper private variable and initialize it with the default 11491 // value. The address of the original variable is replaced by the address of 11492 // the new private variable in CodeGen. This new variable is not added to 11493 // IdResolver, so the code in the OpenMP region uses original variable for 11494 // proper diagnostics. 11495 Type = Type.getUnqualifiedType(); 11496 VarDecl *VDPrivate = 11497 buildVarDecl(*this, ELoc, Type, D->getName(), 11498 D->hasAttrs() ? &D->getAttrs() : nullptr, 11499 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11500 ActOnUninitializedDecl(VDPrivate); 11501 if (VDPrivate->isInvalidDecl()) 11502 continue; 11503 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11504 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 11505 11506 DeclRefExpr *Ref = nullptr; 11507 if (!VD && !CurContext->isDependentContext()) 11508 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11509 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 11510 Vars.push_back((VD || CurContext->isDependentContext()) 11511 ? RefExpr->IgnoreParens() 11512 : Ref); 11513 PrivateCopies.push_back(VDPrivateRefExpr); 11514 } 11515 11516 if (Vars.empty()) 11517 return nullptr; 11518 11519 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11520 PrivateCopies); 11521 } 11522 11523 namespace { 11524 class DiagsUninitializedSeveretyRAII { 11525 private: 11526 DiagnosticsEngine &Diags; 11527 SourceLocation SavedLoc; 11528 bool IsIgnored = false; 11529 11530 public: 11531 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 11532 bool IsIgnored) 11533 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 11534 if (!IsIgnored) { 11535 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 11536 /*Map*/ diag::Severity::Ignored, Loc); 11537 } 11538 } 11539 ~DiagsUninitializedSeveretyRAII() { 11540 if (!IsIgnored) 11541 Diags.popMappings(SavedLoc); 11542 } 11543 }; 11544 } 11545 11546 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 11547 SourceLocation StartLoc, 11548 SourceLocation LParenLoc, 11549 SourceLocation EndLoc) { 11550 SmallVector<Expr *, 8> Vars; 11551 SmallVector<Expr *, 8> PrivateCopies; 11552 SmallVector<Expr *, 8> Inits; 11553 SmallVector<Decl *, 4> ExprCaptures; 11554 bool IsImplicitClause = 11555 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 11556 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 11557 11558 for (Expr *RefExpr : VarList) { 11559 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 11560 SourceLocation ELoc; 11561 SourceRange ERange; 11562 Expr *SimpleRefExpr = RefExpr; 11563 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11564 if (Res.second) { 11565 // It will be analyzed later. 11566 Vars.push_back(RefExpr); 11567 PrivateCopies.push_back(nullptr); 11568 Inits.push_back(nullptr); 11569 } 11570 ValueDecl *D = Res.first; 11571 if (!D) 11572 continue; 11573 11574 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 11575 QualType Type = D->getType(); 11576 auto *VD = dyn_cast<VarDecl>(D); 11577 11578 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11579 // A variable that appears in a private clause must not have an incomplete 11580 // type or a reference type. 11581 if (RequireCompleteType(ELoc, Type, 11582 diag::err_omp_firstprivate_incomplete_type)) 11583 continue; 11584 Type = Type.getNonReferenceType(); 11585 11586 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 11587 // A variable of class type (or array thereof) that appears in a private 11588 // clause requires an accessible, unambiguous copy constructor for the 11589 // class type. 11590 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11591 11592 // If an implicit firstprivate variable found it was checked already. 11593 DSAStackTy::DSAVarData TopDVar; 11594 if (!IsImplicitClause) { 11595 DSAStackTy::DSAVarData DVar = 11596 DSAStack->getTopDSA(D, /*FromParent=*/false); 11597 TopDVar = DVar; 11598 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11599 bool IsConstant = ElemType.isConstant(Context); 11600 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 11601 // A list item that specifies a given variable may not appear in more 11602 // than one clause on the same directive, except that a variable may be 11603 // specified in both firstprivate and lastprivate clauses. 11604 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11605 // A list item may appear in a firstprivate or lastprivate clause but not 11606 // both. 11607 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 11608 (isOpenMPDistributeDirective(CurrDir) || 11609 DVar.CKind != OMPC_lastprivate) && 11610 DVar.RefExpr) { 11611 Diag(ELoc, diag::err_omp_wrong_dsa) 11612 << getOpenMPClauseName(DVar.CKind) 11613 << getOpenMPClauseName(OMPC_firstprivate); 11614 reportOriginalDsa(*this, DSAStack, D, DVar); 11615 continue; 11616 } 11617 11618 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11619 // in a Construct] 11620 // Variables with the predetermined data-sharing attributes may not be 11621 // listed in data-sharing attributes clauses, except for the cases 11622 // listed below. For these exceptions only, listing a predetermined 11623 // variable in a data-sharing attribute clause is allowed and overrides 11624 // the variable's predetermined data-sharing attributes. 11625 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11626 // in a Construct, C/C++, p.2] 11627 // Variables with const-qualified type having no mutable member may be 11628 // listed in a firstprivate clause, even if they are static data members. 11629 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11630 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11631 Diag(ELoc, diag::err_omp_wrong_dsa) 11632 << getOpenMPClauseName(DVar.CKind) 11633 << getOpenMPClauseName(OMPC_firstprivate); 11634 reportOriginalDsa(*this, DSAStack, D, DVar); 11635 continue; 11636 } 11637 11638 // OpenMP [2.9.3.4, Restrictions, p.2] 11639 // A list item that is private within a parallel region must not appear 11640 // in a firstprivate clause on a worksharing construct if any of the 11641 // worksharing regions arising from the worksharing construct ever bind 11642 // to any of the parallel regions arising from the parallel construct. 11643 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11644 // A list item that is private within a teams region must not appear in a 11645 // firstprivate clause on a distribute construct if any of the distribute 11646 // regions arising from the distribute construct ever bind to any of the 11647 // teams regions arising from the teams construct. 11648 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11649 // A list item that appears in a reduction clause of a teams construct 11650 // must not appear in a firstprivate clause on a distribute construct if 11651 // any of the distribute regions arising from the distribute construct 11652 // ever bind to any of the teams regions arising from the teams construct. 11653 if ((isOpenMPWorksharingDirective(CurrDir) || 11654 isOpenMPDistributeDirective(CurrDir)) && 11655 !isOpenMPParallelDirective(CurrDir) && 11656 !isOpenMPTeamsDirective(CurrDir)) { 11657 DVar = DSAStack->getImplicitDSA(D, true); 11658 if (DVar.CKind != OMPC_shared && 11659 (isOpenMPParallelDirective(DVar.DKind) || 11660 isOpenMPTeamsDirective(DVar.DKind) || 11661 DVar.DKind == OMPD_unknown)) { 11662 Diag(ELoc, diag::err_omp_required_access) 11663 << getOpenMPClauseName(OMPC_firstprivate) 11664 << getOpenMPClauseName(OMPC_shared); 11665 reportOriginalDsa(*this, DSAStack, D, DVar); 11666 continue; 11667 } 11668 } 11669 // OpenMP [2.9.3.4, Restrictions, p.3] 11670 // A list item that appears in a reduction clause of a parallel construct 11671 // must not appear in a firstprivate clause on a worksharing or task 11672 // construct if any of the worksharing or task regions arising from the 11673 // worksharing or task construct ever bind to any of the parallel regions 11674 // arising from the parallel construct. 11675 // OpenMP [2.9.3.4, Restrictions, p.4] 11676 // A list item that appears in a reduction clause in worksharing 11677 // construct must not appear in a firstprivate clause in a task construct 11678 // encountered during execution of any of the worksharing regions arising 11679 // from the worksharing construct. 11680 if (isOpenMPTaskingDirective(CurrDir)) { 11681 DVar = DSAStack->hasInnermostDSA( 11682 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11683 [](OpenMPDirectiveKind K) { 11684 return isOpenMPParallelDirective(K) || 11685 isOpenMPWorksharingDirective(K) || 11686 isOpenMPTeamsDirective(K); 11687 }, 11688 /*FromParent=*/true); 11689 if (DVar.CKind == OMPC_reduction && 11690 (isOpenMPParallelDirective(DVar.DKind) || 11691 isOpenMPWorksharingDirective(DVar.DKind) || 11692 isOpenMPTeamsDirective(DVar.DKind))) { 11693 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11694 << getOpenMPDirectiveName(DVar.DKind); 11695 reportOriginalDsa(*this, DSAStack, D, DVar); 11696 continue; 11697 } 11698 } 11699 11700 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11701 // A list item cannot appear in both a map clause and a data-sharing 11702 // attribute clause on the same construct 11703 // 11704 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11705 // A list item cannot appear in both a map clause and a data-sharing 11706 // attribute clause on the same construct unless the construct is a 11707 // combined construct. 11708 if ((LangOpts.OpenMP <= 45 && 11709 isOpenMPTargetExecutionDirective(CurrDir)) || 11710 CurrDir == OMPD_target) { 11711 OpenMPClauseKind ConflictKind; 11712 if (DSAStack->checkMappableExprComponentListsForDecl( 11713 VD, /*CurrentRegionOnly=*/true, 11714 [&ConflictKind]( 11715 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11716 OpenMPClauseKind WhereFoundClauseKind) { 11717 ConflictKind = WhereFoundClauseKind; 11718 return true; 11719 })) { 11720 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11721 << getOpenMPClauseName(OMPC_firstprivate) 11722 << getOpenMPClauseName(ConflictKind) 11723 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11724 reportOriginalDsa(*this, DSAStack, D, DVar); 11725 continue; 11726 } 11727 } 11728 } 11729 11730 // Variably modified types are not supported for tasks. 11731 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11732 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11733 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11734 << getOpenMPClauseName(OMPC_firstprivate) << Type 11735 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11736 bool IsDecl = 11737 !VD || 11738 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11739 Diag(D->getLocation(), 11740 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11741 << D; 11742 continue; 11743 } 11744 11745 Type = Type.getUnqualifiedType(); 11746 VarDecl *VDPrivate = 11747 buildVarDecl(*this, ELoc, Type, D->getName(), 11748 D->hasAttrs() ? &D->getAttrs() : nullptr, 11749 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11750 // Generate helper private variable and initialize it with the value of the 11751 // original variable. The address of the original variable is replaced by 11752 // the address of the new private variable in the CodeGen. This new variable 11753 // is not added to IdResolver, so the code in the OpenMP region uses 11754 // original variable for proper diagnostics and variable capturing. 11755 Expr *VDInitRefExpr = nullptr; 11756 // For arrays generate initializer for single element and replace it by the 11757 // original array element in CodeGen. 11758 if (Type->isArrayType()) { 11759 VarDecl *VDInit = 11760 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11761 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11762 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11763 ElemType = ElemType.getUnqualifiedType(); 11764 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11765 ".firstprivate.temp"); 11766 InitializedEntity Entity = 11767 InitializedEntity::InitializeVariable(VDInitTemp); 11768 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11769 11770 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11771 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11772 if (Result.isInvalid()) 11773 VDPrivate->setInvalidDecl(); 11774 else 11775 VDPrivate->setInit(Result.getAs<Expr>()); 11776 // Remove temp variable declaration. 11777 Context.Deallocate(VDInitTemp); 11778 } else { 11779 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11780 ".firstprivate.temp"); 11781 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11782 RefExpr->getExprLoc()); 11783 AddInitializerToDecl(VDPrivate, 11784 DefaultLvalueConversion(VDInitRefExpr).get(), 11785 /*DirectInit=*/false); 11786 } 11787 if (VDPrivate->isInvalidDecl()) { 11788 if (IsImplicitClause) { 11789 Diag(RefExpr->getExprLoc(), 11790 diag::note_omp_task_predetermined_firstprivate_here); 11791 } 11792 continue; 11793 } 11794 CurContext->addDecl(VDPrivate); 11795 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11796 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 11797 RefExpr->getExprLoc()); 11798 DeclRefExpr *Ref = nullptr; 11799 if (!VD && !CurContext->isDependentContext()) { 11800 if (TopDVar.CKind == OMPC_lastprivate) { 11801 Ref = TopDVar.PrivateCopy; 11802 } else { 11803 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11804 if (!isOpenMPCapturedDecl(D)) 11805 ExprCaptures.push_back(Ref->getDecl()); 11806 } 11807 } 11808 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11809 Vars.push_back((VD || CurContext->isDependentContext()) 11810 ? RefExpr->IgnoreParens() 11811 : Ref); 11812 PrivateCopies.push_back(VDPrivateRefExpr); 11813 Inits.push_back(VDInitRefExpr); 11814 } 11815 11816 if (Vars.empty()) 11817 return nullptr; 11818 11819 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11820 Vars, PrivateCopies, Inits, 11821 buildPreInits(Context, ExprCaptures)); 11822 } 11823 11824 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11825 SourceLocation StartLoc, 11826 SourceLocation LParenLoc, 11827 SourceLocation EndLoc) { 11828 SmallVector<Expr *, 8> Vars; 11829 SmallVector<Expr *, 8> SrcExprs; 11830 SmallVector<Expr *, 8> DstExprs; 11831 SmallVector<Expr *, 8> AssignmentOps; 11832 SmallVector<Decl *, 4> ExprCaptures; 11833 SmallVector<Expr *, 4> ExprPostUpdates; 11834 for (Expr *RefExpr : VarList) { 11835 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11836 SourceLocation ELoc; 11837 SourceRange ERange; 11838 Expr *SimpleRefExpr = RefExpr; 11839 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11840 if (Res.second) { 11841 // It will be analyzed later. 11842 Vars.push_back(RefExpr); 11843 SrcExprs.push_back(nullptr); 11844 DstExprs.push_back(nullptr); 11845 AssignmentOps.push_back(nullptr); 11846 } 11847 ValueDecl *D = Res.first; 11848 if (!D) 11849 continue; 11850 11851 QualType Type = D->getType(); 11852 auto *VD = dyn_cast<VarDecl>(D); 11853 11854 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11855 // A variable that appears in a lastprivate clause must not have an 11856 // incomplete type or a reference type. 11857 if (RequireCompleteType(ELoc, Type, 11858 diag::err_omp_lastprivate_incomplete_type)) 11859 continue; 11860 Type = Type.getNonReferenceType(); 11861 11862 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11863 // A variable that is privatized must not have a const-qualified type 11864 // unless it is of class type with a mutable member. This restriction does 11865 // not apply to the firstprivate clause. 11866 // 11867 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11868 // A variable that appears in a lastprivate clause must not have a 11869 // const-qualified type unless it is of class type with a mutable member. 11870 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11871 continue; 11872 11873 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11874 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11875 // in a Construct] 11876 // Variables with the predetermined data-sharing attributes may not be 11877 // listed in data-sharing attributes clauses, except for the cases 11878 // listed below. 11879 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11880 // A list item may appear in a firstprivate or lastprivate clause but not 11881 // both. 11882 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11883 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11884 (isOpenMPDistributeDirective(CurrDir) || 11885 DVar.CKind != OMPC_firstprivate) && 11886 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11887 Diag(ELoc, diag::err_omp_wrong_dsa) 11888 << getOpenMPClauseName(DVar.CKind) 11889 << getOpenMPClauseName(OMPC_lastprivate); 11890 reportOriginalDsa(*this, DSAStack, D, DVar); 11891 continue; 11892 } 11893 11894 // OpenMP [2.14.3.5, Restrictions, p.2] 11895 // A list item that is private within a parallel region, or that appears in 11896 // the reduction clause of a parallel construct, must not appear in a 11897 // lastprivate clause on a worksharing construct if any of the corresponding 11898 // worksharing regions ever binds to any of the corresponding parallel 11899 // regions. 11900 DSAStackTy::DSAVarData TopDVar = DVar; 11901 if (isOpenMPWorksharingDirective(CurrDir) && 11902 !isOpenMPParallelDirective(CurrDir) && 11903 !isOpenMPTeamsDirective(CurrDir)) { 11904 DVar = DSAStack->getImplicitDSA(D, true); 11905 if (DVar.CKind != OMPC_shared) { 11906 Diag(ELoc, diag::err_omp_required_access) 11907 << getOpenMPClauseName(OMPC_lastprivate) 11908 << getOpenMPClauseName(OMPC_shared); 11909 reportOriginalDsa(*this, DSAStack, D, DVar); 11910 continue; 11911 } 11912 } 11913 11914 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11915 // A variable of class type (or array thereof) that appears in a 11916 // lastprivate clause requires an accessible, unambiguous default 11917 // constructor for the class type, unless the list item is also specified 11918 // in a firstprivate clause. 11919 // A variable of class type (or array thereof) that appears in a 11920 // lastprivate clause requires an accessible, unambiguous copy assignment 11921 // operator for the class type. 11922 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11923 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11924 Type.getUnqualifiedType(), ".lastprivate.src", 11925 D->hasAttrs() ? &D->getAttrs() : nullptr); 11926 DeclRefExpr *PseudoSrcExpr = 11927 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11928 VarDecl *DstVD = 11929 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11930 D->hasAttrs() ? &D->getAttrs() : nullptr); 11931 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11932 // For arrays generate assignment operation for single element and replace 11933 // it by the original array element in CodeGen. 11934 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11935 PseudoDstExpr, PseudoSrcExpr); 11936 if (AssignmentOp.isInvalid()) 11937 continue; 11938 AssignmentOp = 11939 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11940 if (AssignmentOp.isInvalid()) 11941 continue; 11942 11943 DeclRefExpr *Ref = nullptr; 11944 if (!VD && !CurContext->isDependentContext()) { 11945 if (TopDVar.CKind == OMPC_firstprivate) { 11946 Ref = TopDVar.PrivateCopy; 11947 } else { 11948 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11949 if (!isOpenMPCapturedDecl(D)) 11950 ExprCaptures.push_back(Ref->getDecl()); 11951 } 11952 if (TopDVar.CKind == OMPC_firstprivate || 11953 (!isOpenMPCapturedDecl(D) && 11954 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11955 ExprResult RefRes = DefaultLvalueConversion(Ref); 11956 if (!RefRes.isUsable()) 11957 continue; 11958 ExprResult PostUpdateRes = 11959 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11960 RefRes.get()); 11961 if (!PostUpdateRes.isUsable()) 11962 continue; 11963 ExprPostUpdates.push_back( 11964 IgnoredValueConversions(PostUpdateRes.get()).get()); 11965 } 11966 } 11967 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11968 Vars.push_back((VD || CurContext->isDependentContext()) 11969 ? RefExpr->IgnoreParens() 11970 : Ref); 11971 SrcExprs.push_back(PseudoSrcExpr); 11972 DstExprs.push_back(PseudoDstExpr); 11973 AssignmentOps.push_back(AssignmentOp.get()); 11974 } 11975 11976 if (Vars.empty()) 11977 return nullptr; 11978 11979 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11980 Vars, SrcExprs, DstExprs, AssignmentOps, 11981 buildPreInits(Context, ExprCaptures), 11982 buildPostUpdate(*this, ExprPostUpdates)); 11983 } 11984 11985 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11986 SourceLocation StartLoc, 11987 SourceLocation LParenLoc, 11988 SourceLocation EndLoc) { 11989 SmallVector<Expr *, 8> Vars; 11990 for (Expr *RefExpr : VarList) { 11991 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11992 SourceLocation ELoc; 11993 SourceRange ERange; 11994 Expr *SimpleRefExpr = RefExpr; 11995 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11996 if (Res.second) { 11997 // It will be analyzed later. 11998 Vars.push_back(RefExpr); 11999 } 12000 ValueDecl *D = Res.first; 12001 if (!D) 12002 continue; 12003 12004 auto *VD = dyn_cast<VarDecl>(D); 12005 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12006 // in a Construct] 12007 // Variables with the predetermined data-sharing attributes may not be 12008 // listed in data-sharing attributes clauses, except for the cases 12009 // listed below. For these exceptions only, listing a predetermined 12010 // variable in a data-sharing attribute clause is allowed and overrides 12011 // the variable's predetermined data-sharing attributes. 12012 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12013 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12014 DVar.RefExpr) { 12015 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12016 << getOpenMPClauseName(OMPC_shared); 12017 reportOriginalDsa(*this, DSAStack, D, DVar); 12018 continue; 12019 } 12020 12021 DeclRefExpr *Ref = nullptr; 12022 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12023 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12024 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12025 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12026 ? RefExpr->IgnoreParens() 12027 : Ref); 12028 } 12029 12030 if (Vars.empty()) 12031 return nullptr; 12032 12033 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12034 } 12035 12036 namespace { 12037 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12038 DSAStackTy *Stack; 12039 12040 public: 12041 bool VisitDeclRefExpr(DeclRefExpr *E) { 12042 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12043 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12044 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12045 return false; 12046 if (DVar.CKind != OMPC_unknown) 12047 return true; 12048 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12049 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12050 /*FromParent=*/true); 12051 return DVarPrivate.CKind != OMPC_unknown; 12052 } 12053 return false; 12054 } 12055 bool VisitStmt(Stmt *S) { 12056 for (Stmt *Child : S->children()) { 12057 if (Child && Visit(Child)) 12058 return true; 12059 } 12060 return false; 12061 } 12062 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12063 }; 12064 } // namespace 12065 12066 namespace { 12067 // Transform MemberExpression for specified FieldDecl of current class to 12068 // DeclRefExpr to specified OMPCapturedExprDecl. 12069 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12070 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12071 ValueDecl *Field = nullptr; 12072 DeclRefExpr *CapturedExpr = nullptr; 12073 12074 public: 12075 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12076 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12077 12078 ExprResult TransformMemberExpr(MemberExpr *E) { 12079 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12080 E->getMemberDecl() == Field) { 12081 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12082 return CapturedExpr; 12083 } 12084 return BaseTransform::TransformMemberExpr(E); 12085 } 12086 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12087 }; 12088 } // namespace 12089 12090 template <typename T, typename U> 12091 static T filterLookupForUDReductionAndMapper( 12092 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12093 for (U &Set : Lookups) { 12094 for (auto *D : Set) { 12095 if (T Res = Gen(cast<ValueDecl>(D))) 12096 return Res; 12097 } 12098 } 12099 return T(); 12100 } 12101 12102 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12103 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12104 12105 for (auto RD : D->redecls()) { 12106 // Don't bother with extra checks if we already know this one isn't visible. 12107 if (RD == D) 12108 continue; 12109 12110 auto ND = cast<NamedDecl>(RD); 12111 if (LookupResult::isVisible(SemaRef, ND)) 12112 return ND; 12113 } 12114 12115 return nullptr; 12116 } 12117 12118 static void 12119 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12120 SourceLocation Loc, QualType Ty, 12121 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12122 // Find all of the associated namespaces and classes based on the 12123 // arguments we have. 12124 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12125 Sema::AssociatedClassSet AssociatedClasses; 12126 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12127 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12128 AssociatedClasses); 12129 12130 // C++ [basic.lookup.argdep]p3: 12131 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12132 // and let Y be the lookup set produced by argument dependent 12133 // lookup (defined as follows). If X contains [...] then Y is 12134 // empty. Otherwise Y is the set of declarations found in the 12135 // namespaces associated with the argument types as described 12136 // below. The set of declarations found by the lookup of the name 12137 // is the union of X and Y. 12138 // 12139 // Here, we compute Y and add its members to the overloaded 12140 // candidate set. 12141 for (auto *NS : AssociatedNamespaces) { 12142 // When considering an associated namespace, the lookup is the 12143 // same as the lookup performed when the associated namespace is 12144 // used as a qualifier (3.4.3.2) except that: 12145 // 12146 // -- Any using-directives in the associated namespace are 12147 // ignored. 12148 // 12149 // -- Any namespace-scope friend functions declared in 12150 // associated classes are visible within their respective 12151 // namespaces even if they are not visible during an ordinary 12152 // lookup (11.4). 12153 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12154 for (auto *D : R) { 12155 auto *Underlying = D; 12156 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12157 Underlying = USD->getTargetDecl(); 12158 12159 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12160 !isa<OMPDeclareMapperDecl>(Underlying)) 12161 continue; 12162 12163 if (!SemaRef.isVisible(D)) { 12164 D = findAcceptableDecl(SemaRef, D); 12165 if (!D) 12166 continue; 12167 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12168 Underlying = USD->getTargetDecl(); 12169 } 12170 Lookups.emplace_back(); 12171 Lookups.back().addDecl(Underlying); 12172 } 12173 } 12174 } 12175 12176 static ExprResult 12177 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12178 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12179 const DeclarationNameInfo &ReductionId, QualType Ty, 12180 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12181 if (ReductionIdScopeSpec.isInvalid()) 12182 return ExprError(); 12183 SmallVector<UnresolvedSet<8>, 4> Lookups; 12184 if (S) { 12185 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12186 Lookup.suppressDiagnostics(); 12187 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12188 NamedDecl *D = Lookup.getRepresentativeDecl(); 12189 do { 12190 S = S->getParent(); 12191 } while (S && !S->isDeclScope(D)); 12192 if (S) 12193 S = S->getParent(); 12194 Lookups.emplace_back(); 12195 Lookups.back().append(Lookup.begin(), Lookup.end()); 12196 Lookup.clear(); 12197 } 12198 } else if (auto *ULE = 12199 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12200 Lookups.push_back(UnresolvedSet<8>()); 12201 Decl *PrevD = nullptr; 12202 for (NamedDecl *D : ULE->decls()) { 12203 if (D == PrevD) 12204 Lookups.push_back(UnresolvedSet<8>()); 12205 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12206 Lookups.back().addDecl(DRD); 12207 PrevD = D; 12208 } 12209 } 12210 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12211 Ty->isInstantiationDependentType() || 12212 Ty->containsUnexpandedParameterPack() || 12213 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12214 return !D->isInvalidDecl() && 12215 (D->getType()->isDependentType() || 12216 D->getType()->isInstantiationDependentType() || 12217 D->getType()->containsUnexpandedParameterPack()); 12218 })) { 12219 UnresolvedSet<8> ResSet; 12220 for (const UnresolvedSet<8> &Set : Lookups) { 12221 if (Set.empty()) 12222 continue; 12223 ResSet.append(Set.begin(), Set.end()); 12224 // The last item marks the end of all declarations at the specified scope. 12225 ResSet.addDecl(Set[Set.size() - 1]); 12226 } 12227 return UnresolvedLookupExpr::Create( 12228 SemaRef.Context, /*NamingClass=*/nullptr, 12229 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12230 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12231 } 12232 // Lookup inside the classes. 12233 // C++ [over.match.oper]p3: 12234 // For a unary operator @ with an operand of a type whose 12235 // cv-unqualified version is T1, and for a binary operator @ with 12236 // a left operand of a type whose cv-unqualified version is T1 and 12237 // a right operand of a type whose cv-unqualified version is T2, 12238 // three sets of candidate functions, designated member 12239 // candidates, non-member candidates and built-in candidates, are 12240 // constructed as follows: 12241 // -- If T1 is a complete class type or a class currently being 12242 // defined, the set of member candidates is the result of the 12243 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12244 // the set of member candidates is empty. 12245 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12246 Lookup.suppressDiagnostics(); 12247 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12248 // Complete the type if it can be completed. 12249 // If the type is neither complete nor being defined, bail out now. 12250 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12251 TyRec->getDecl()->getDefinition()) { 12252 Lookup.clear(); 12253 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12254 if (Lookup.empty()) { 12255 Lookups.emplace_back(); 12256 Lookups.back().append(Lookup.begin(), Lookup.end()); 12257 } 12258 } 12259 } 12260 // Perform ADL. 12261 if (SemaRef.getLangOpts().CPlusPlus) 12262 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12263 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12264 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12265 if (!D->isInvalidDecl() && 12266 SemaRef.Context.hasSameType(D->getType(), Ty)) 12267 return D; 12268 return nullptr; 12269 })) 12270 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12271 VK_LValue, Loc); 12272 if (SemaRef.getLangOpts().CPlusPlus) { 12273 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12274 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12275 if (!D->isInvalidDecl() && 12276 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12277 !Ty.isMoreQualifiedThan(D->getType())) 12278 return D; 12279 return nullptr; 12280 })) { 12281 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12282 /*DetectVirtual=*/false); 12283 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12284 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12285 VD->getType().getUnqualifiedType()))) { 12286 if (SemaRef.CheckBaseClassAccess( 12287 Loc, VD->getType(), Ty, Paths.front(), 12288 /*DiagID=*/0) != Sema::AR_inaccessible) { 12289 SemaRef.BuildBasePathArray(Paths, BasePath); 12290 return SemaRef.BuildDeclRefExpr( 12291 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12292 } 12293 } 12294 } 12295 } 12296 } 12297 if (ReductionIdScopeSpec.isSet()) { 12298 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12299 return ExprError(); 12300 } 12301 return ExprEmpty(); 12302 } 12303 12304 namespace { 12305 /// Data for the reduction-based clauses. 12306 struct ReductionData { 12307 /// List of original reduction items. 12308 SmallVector<Expr *, 8> Vars; 12309 /// List of private copies of the reduction items. 12310 SmallVector<Expr *, 8> Privates; 12311 /// LHS expressions for the reduction_op expressions. 12312 SmallVector<Expr *, 8> LHSs; 12313 /// RHS expressions for the reduction_op expressions. 12314 SmallVector<Expr *, 8> RHSs; 12315 /// Reduction operation expression. 12316 SmallVector<Expr *, 8> ReductionOps; 12317 /// Taskgroup descriptors for the corresponding reduction items in 12318 /// in_reduction clauses. 12319 SmallVector<Expr *, 8> TaskgroupDescriptors; 12320 /// List of captures for clause. 12321 SmallVector<Decl *, 4> ExprCaptures; 12322 /// List of postupdate expressions. 12323 SmallVector<Expr *, 4> ExprPostUpdates; 12324 ReductionData() = delete; 12325 /// Reserves required memory for the reduction data. 12326 ReductionData(unsigned Size) { 12327 Vars.reserve(Size); 12328 Privates.reserve(Size); 12329 LHSs.reserve(Size); 12330 RHSs.reserve(Size); 12331 ReductionOps.reserve(Size); 12332 TaskgroupDescriptors.reserve(Size); 12333 ExprCaptures.reserve(Size); 12334 ExprPostUpdates.reserve(Size); 12335 } 12336 /// Stores reduction item and reduction operation only (required for dependent 12337 /// reduction item). 12338 void push(Expr *Item, Expr *ReductionOp) { 12339 Vars.emplace_back(Item); 12340 Privates.emplace_back(nullptr); 12341 LHSs.emplace_back(nullptr); 12342 RHSs.emplace_back(nullptr); 12343 ReductionOps.emplace_back(ReductionOp); 12344 TaskgroupDescriptors.emplace_back(nullptr); 12345 } 12346 /// Stores reduction data. 12347 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12348 Expr *TaskgroupDescriptor) { 12349 Vars.emplace_back(Item); 12350 Privates.emplace_back(Private); 12351 LHSs.emplace_back(LHS); 12352 RHSs.emplace_back(RHS); 12353 ReductionOps.emplace_back(ReductionOp); 12354 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12355 } 12356 }; 12357 } // namespace 12358 12359 static bool checkOMPArraySectionConstantForReduction( 12360 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12361 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12362 const Expr *Length = OASE->getLength(); 12363 if (Length == nullptr) { 12364 // For array sections of the form [1:] or [:], we would need to analyze 12365 // the lower bound... 12366 if (OASE->getColonLoc().isValid()) 12367 return false; 12368 12369 // This is an array subscript which has implicit length 1! 12370 SingleElement = true; 12371 ArraySizes.push_back(llvm::APSInt::get(1)); 12372 } else { 12373 Expr::EvalResult Result; 12374 if (!Length->EvaluateAsInt(Result, Context)) 12375 return false; 12376 12377 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12378 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12379 ArraySizes.push_back(ConstantLengthValue); 12380 } 12381 12382 // Get the base of this array section and walk up from there. 12383 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12384 12385 // We require length = 1 for all array sections except the right-most to 12386 // guarantee that the memory region is contiguous and has no holes in it. 12387 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12388 Length = TempOASE->getLength(); 12389 if (Length == nullptr) { 12390 // For array sections of the form [1:] or [:], we would need to analyze 12391 // the lower bound... 12392 if (OASE->getColonLoc().isValid()) 12393 return false; 12394 12395 // This is an array subscript which has implicit length 1! 12396 ArraySizes.push_back(llvm::APSInt::get(1)); 12397 } else { 12398 Expr::EvalResult Result; 12399 if (!Length->EvaluateAsInt(Result, Context)) 12400 return false; 12401 12402 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12403 if (ConstantLengthValue.getSExtValue() != 1) 12404 return false; 12405 12406 ArraySizes.push_back(ConstantLengthValue); 12407 } 12408 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12409 } 12410 12411 // If we have a single element, we don't need to add the implicit lengths. 12412 if (!SingleElement) { 12413 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12414 // Has implicit length 1! 12415 ArraySizes.push_back(llvm::APSInt::get(1)); 12416 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12417 } 12418 } 12419 12420 // This array section can be privatized as a single value or as a constant 12421 // sized array. 12422 return true; 12423 } 12424 12425 static bool actOnOMPReductionKindClause( 12426 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12427 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12428 SourceLocation ColonLoc, SourceLocation EndLoc, 12429 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12430 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12431 DeclarationName DN = ReductionId.getName(); 12432 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12433 BinaryOperatorKind BOK = BO_Comma; 12434 12435 ASTContext &Context = S.Context; 12436 // OpenMP [2.14.3.6, reduction clause] 12437 // C 12438 // reduction-identifier is either an identifier or one of the following 12439 // operators: +, -, *, &, |, ^, && and || 12440 // C++ 12441 // reduction-identifier is either an id-expression or one of the following 12442 // operators: +, -, *, &, |, ^, && and || 12443 switch (OOK) { 12444 case OO_Plus: 12445 case OO_Minus: 12446 BOK = BO_Add; 12447 break; 12448 case OO_Star: 12449 BOK = BO_Mul; 12450 break; 12451 case OO_Amp: 12452 BOK = BO_And; 12453 break; 12454 case OO_Pipe: 12455 BOK = BO_Or; 12456 break; 12457 case OO_Caret: 12458 BOK = BO_Xor; 12459 break; 12460 case OO_AmpAmp: 12461 BOK = BO_LAnd; 12462 break; 12463 case OO_PipePipe: 12464 BOK = BO_LOr; 12465 break; 12466 case OO_New: 12467 case OO_Delete: 12468 case OO_Array_New: 12469 case OO_Array_Delete: 12470 case OO_Slash: 12471 case OO_Percent: 12472 case OO_Tilde: 12473 case OO_Exclaim: 12474 case OO_Equal: 12475 case OO_Less: 12476 case OO_Greater: 12477 case OO_LessEqual: 12478 case OO_GreaterEqual: 12479 case OO_PlusEqual: 12480 case OO_MinusEqual: 12481 case OO_StarEqual: 12482 case OO_SlashEqual: 12483 case OO_PercentEqual: 12484 case OO_CaretEqual: 12485 case OO_AmpEqual: 12486 case OO_PipeEqual: 12487 case OO_LessLess: 12488 case OO_GreaterGreater: 12489 case OO_LessLessEqual: 12490 case OO_GreaterGreaterEqual: 12491 case OO_EqualEqual: 12492 case OO_ExclaimEqual: 12493 case OO_Spaceship: 12494 case OO_PlusPlus: 12495 case OO_MinusMinus: 12496 case OO_Comma: 12497 case OO_ArrowStar: 12498 case OO_Arrow: 12499 case OO_Call: 12500 case OO_Subscript: 12501 case OO_Conditional: 12502 case OO_Coawait: 12503 case NUM_OVERLOADED_OPERATORS: 12504 llvm_unreachable("Unexpected reduction identifier"); 12505 case OO_None: 12506 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 12507 if (II->isStr("max")) 12508 BOK = BO_GT; 12509 else if (II->isStr("min")) 12510 BOK = BO_LT; 12511 } 12512 break; 12513 } 12514 SourceRange ReductionIdRange; 12515 if (ReductionIdScopeSpec.isValid()) 12516 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 12517 else 12518 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 12519 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 12520 12521 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 12522 bool FirstIter = true; 12523 for (Expr *RefExpr : VarList) { 12524 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 12525 // OpenMP [2.1, C/C++] 12526 // A list item is a variable or array section, subject to the restrictions 12527 // specified in Section 2.4 on page 42 and in each of the sections 12528 // describing clauses and directives for which a list appears. 12529 // OpenMP [2.14.3.3, Restrictions, p.1] 12530 // A variable that is part of another variable (as an array or 12531 // structure element) cannot appear in a private clause. 12532 if (!FirstIter && IR != ER) 12533 ++IR; 12534 FirstIter = false; 12535 SourceLocation ELoc; 12536 SourceRange ERange; 12537 Expr *SimpleRefExpr = RefExpr; 12538 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 12539 /*AllowArraySection=*/true); 12540 if (Res.second) { 12541 // Try to find 'declare reduction' corresponding construct before using 12542 // builtin/overloaded operators. 12543 QualType Type = Context.DependentTy; 12544 CXXCastPath BasePath; 12545 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12546 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12547 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12548 Expr *ReductionOp = nullptr; 12549 if (S.CurContext->isDependentContext() && 12550 (DeclareReductionRef.isUnset() || 12551 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 12552 ReductionOp = DeclareReductionRef.get(); 12553 // It will be analyzed later. 12554 RD.push(RefExpr, ReductionOp); 12555 } 12556 ValueDecl *D = Res.first; 12557 if (!D) 12558 continue; 12559 12560 Expr *TaskgroupDescriptor = nullptr; 12561 QualType Type; 12562 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 12563 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 12564 if (ASE) { 12565 Type = ASE->getType().getNonReferenceType(); 12566 } else if (OASE) { 12567 QualType BaseType = 12568 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 12569 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 12570 Type = ATy->getElementType(); 12571 else 12572 Type = BaseType->getPointeeType(); 12573 Type = Type.getNonReferenceType(); 12574 } else { 12575 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 12576 } 12577 auto *VD = dyn_cast<VarDecl>(D); 12578 12579 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12580 // A variable that appears in a private clause must not have an incomplete 12581 // type or a reference type. 12582 if (S.RequireCompleteType(ELoc, D->getType(), 12583 diag::err_omp_reduction_incomplete_type)) 12584 continue; 12585 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12586 // A list item that appears in a reduction clause must not be 12587 // const-qualified. 12588 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 12589 /*AcceptIfMutable*/ false, ASE || OASE)) 12590 continue; 12591 12592 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 12593 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 12594 // If a list-item is a reference type then it must bind to the same object 12595 // for all threads of the team. 12596 if (!ASE && !OASE) { 12597 if (VD) { 12598 VarDecl *VDDef = VD->getDefinition(); 12599 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 12600 DSARefChecker Check(Stack); 12601 if (Check.Visit(VDDef->getInit())) { 12602 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 12603 << getOpenMPClauseName(ClauseKind) << ERange; 12604 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 12605 continue; 12606 } 12607 } 12608 } 12609 12610 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12611 // in a Construct] 12612 // Variables with the predetermined data-sharing attributes may not be 12613 // listed in data-sharing attributes clauses, except for the cases 12614 // listed below. For these exceptions only, listing a predetermined 12615 // variable in a data-sharing attribute clause is allowed and overrides 12616 // the variable's predetermined data-sharing attributes. 12617 // OpenMP [2.14.3.6, Restrictions, p.3] 12618 // Any number of reduction clauses can be specified on the directive, 12619 // but a list item can appear only once in the reduction clauses for that 12620 // directive. 12621 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 12622 if (DVar.CKind == OMPC_reduction) { 12623 S.Diag(ELoc, diag::err_omp_once_referenced) 12624 << getOpenMPClauseName(ClauseKind); 12625 if (DVar.RefExpr) 12626 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12627 continue; 12628 } 12629 if (DVar.CKind != OMPC_unknown) { 12630 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12631 << getOpenMPClauseName(DVar.CKind) 12632 << getOpenMPClauseName(OMPC_reduction); 12633 reportOriginalDsa(S, Stack, D, DVar); 12634 continue; 12635 } 12636 12637 // OpenMP [2.14.3.6, Restrictions, p.1] 12638 // A list item that appears in a reduction clause of a worksharing 12639 // construct must be shared in the parallel regions to which any of the 12640 // worksharing regions arising from the worksharing construct bind. 12641 if (isOpenMPWorksharingDirective(CurrDir) && 12642 !isOpenMPParallelDirective(CurrDir) && 12643 !isOpenMPTeamsDirective(CurrDir)) { 12644 DVar = Stack->getImplicitDSA(D, true); 12645 if (DVar.CKind != OMPC_shared) { 12646 S.Diag(ELoc, diag::err_omp_required_access) 12647 << getOpenMPClauseName(OMPC_reduction) 12648 << getOpenMPClauseName(OMPC_shared); 12649 reportOriginalDsa(S, Stack, D, DVar); 12650 continue; 12651 } 12652 } 12653 } 12654 12655 // Try to find 'declare reduction' corresponding construct before using 12656 // builtin/overloaded operators. 12657 CXXCastPath BasePath; 12658 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12659 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12660 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12661 if (DeclareReductionRef.isInvalid()) 12662 continue; 12663 if (S.CurContext->isDependentContext() && 12664 (DeclareReductionRef.isUnset() || 12665 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12666 RD.push(RefExpr, DeclareReductionRef.get()); 12667 continue; 12668 } 12669 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12670 // Not allowed reduction identifier is found. 12671 S.Diag(ReductionId.getBeginLoc(), 12672 diag::err_omp_unknown_reduction_identifier) 12673 << Type << ReductionIdRange; 12674 continue; 12675 } 12676 12677 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12678 // The type of a list item that appears in a reduction clause must be valid 12679 // for the reduction-identifier. For a max or min reduction in C, the type 12680 // of the list item must be an allowed arithmetic data type: char, int, 12681 // float, double, or _Bool, possibly modified with long, short, signed, or 12682 // unsigned. For a max or min reduction in C++, the type of the list item 12683 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12684 // double, or bool, possibly modified with long, short, signed, or unsigned. 12685 if (DeclareReductionRef.isUnset()) { 12686 if ((BOK == BO_GT || BOK == BO_LT) && 12687 !(Type->isScalarType() || 12688 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12689 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12690 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12691 if (!ASE && !OASE) { 12692 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12693 VarDecl::DeclarationOnly; 12694 S.Diag(D->getLocation(), 12695 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12696 << D; 12697 } 12698 continue; 12699 } 12700 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12701 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12702 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12703 << getOpenMPClauseName(ClauseKind); 12704 if (!ASE && !OASE) { 12705 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12706 VarDecl::DeclarationOnly; 12707 S.Diag(D->getLocation(), 12708 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12709 << D; 12710 } 12711 continue; 12712 } 12713 } 12714 12715 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12716 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12717 D->hasAttrs() ? &D->getAttrs() : nullptr); 12718 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12719 D->hasAttrs() ? &D->getAttrs() : nullptr); 12720 QualType PrivateTy = Type; 12721 12722 // Try if we can determine constant lengths for all array sections and avoid 12723 // the VLA. 12724 bool ConstantLengthOASE = false; 12725 if (OASE) { 12726 bool SingleElement; 12727 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12728 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12729 Context, OASE, SingleElement, ArraySizes); 12730 12731 // If we don't have a single element, we must emit a constant array type. 12732 if (ConstantLengthOASE && !SingleElement) { 12733 for (llvm::APSInt &Size : ArraySizes) 12734 PrivateTy = Context.getConstantArrayType( 12735 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12736 } 12737 } 12738 12739 if ((OASE && !ConstantLengthOASE) || 12740 (!OASE && !ASE && 12741 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12742 if (!Context.getTargetInfo().isVLASupported()) { 12743 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 12744 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12745 S.Diag(ELoc, diag::note_vla_unsupported); 12746 } else { 12747 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12748 S.targetDiag(ELoc, diag::note_vla_unsupported); 12749 } 12750 continue; 12751 } 12752 // For arrays/array sections only: 12753 // Create pseudo array type for private copy. The size for this array will 12754 // be generated during codegen. 12755 // For array subscripts or single variables Private Ty is the same as Type 12756 // (type of the variable or single array element). 12757 PrivateTy = Context.getVariableArrayType( 12758 Type, 12759 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12760 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12761 } else if (!ASE && !OASE && 12762 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12763 PrivateTy = D->getType().getNonReferenceType(); 12764 } 12765 // Private copy. 12766 VarDecl *PrivateVD = 12767 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12768 D->hasAttrs() ? &D->getAttrs() : nullptr, 12769 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12770 // Add initializer for private variable. 12771 Expr *Init = nullptr; 12772 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12773 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12774 if (DeclareReductionRef.isUsable()) { 12775 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12776 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12777 if (DRD->getInitializer()) { 12778 Init = DRDRef; 12779 RHSVD->setInit(DRDRef); 12780 RHSVD->setInitStyle(VarDecl::CallInit); 12781 } 12782 } else { 12783 switch (BOK) { 12784 case BO_Add: 12785 case BO_Xor: 12786 case BO_Or: 12787 case BO_LOr: 12788 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12789 if (Type->isScalarType() || Type->isAnyComplexType()) 12790 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 12791 break; 12792 case BO_Mul: 12793 case BO_LAnd: 12794 if (Type->isScalarType() || Type->isAnyComplexType()) { 12795 // '*' and '&&' reduction ops - initializer is '1'. 12796 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 12797 } 12798 break; 12799 case BO_And: { 12800 // '&' reduction op - initializer is '~0'. 12801 QualType OrigType = Type; 12802 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 12803 Type = ComplexTy->getElementType(); 12804 if (Type->isRealFloatingType()) { 12805 llvm::APFloat InitValue = 12806 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 12807 /*isIEEE=*/true); 12808 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12809 Type, ELoc); 12810 } else if (Type->isScalarType()) { 12811 uint64_t Size = Context.getTypeSize(Type); 12812 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 12813 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 12814 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12815 } 12816 if (Init && OrigType->isAnyComplexType()) { 12817 // Init = 0xFFFF + 0xFFFFi; 12818 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 12819 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 12820 } 12821 Type = OrigType; 12822 break; 12823 } 12824 case BO_LT: 12825 case BO_GT: { 12826 // 'min' reduction op - initializer is 'Largest representable number in 12827 // the reduction list item type'. 12828 // 'max' reduction op - initializer is 'Least representable number in 12829 // the reduction list item type'. 12830 if (Type->isIntegerType() || Type->isPointerType()) { 12831 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12832 uint64_t Size = Context.getTypeSize(Type); 12833 QualType IntTy = 12834 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12835 llvm::APInt InitValue = 12836 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12837 : llvm::APInt::getMinValue(Size) 12838 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12839 : llvm::APInt::getMaxValue(Size); 12840 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12841 if (Type->isPointerType()) { 12842 // Cast to pointer type. 12843 ExprResult CastExpr = S.BuildCStyleCastExpr( 12844 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12845 if (CastExpr.isInvalid()) 12846 continue; 12847 Init = CastExpr.get(); 12848 } 12849 } else if (Type->isRealFloatingType()) { 12850 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12851 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12852 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12853 Type, ELoc); 12854 } 12855 break; 12856 } 12857 case BO_PtrMemD: 12858 case BO_PtrMemI: 12859 case BO_MulAssign: 12860 case BO_Div: 12861 case BO_Rem: 12862 case BO_Sub: 12863 case BO_Shl: 12864 case BO_Shr: 12865 case BO_LE: 12866 case BO_GE: 12867 case BO_EQ: 12868 case BO_NE: 12869 case BO_Cmp: 12870 case BO_AndAssign: 12871 case BO_XorAssign: 12872 case BO_OrAssign: 12873 case BO_Assign: 12874 case BO_AddAssign: 12875 case BO_SubAssign: 12876 case BO_DivAssign: 12877 case BO_RemAssign: 12878 case BO_ShlAssign: 12879 case BO_ShrAssign: 12880 case BO_Comma: 12881 llvm_unreachable("Unexpected reduction operation"); 12882 } 12883 } 12884 if (Init && DeclareReductionRef.isUnset()) 12885 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12886 else if (!Init) 12887 S.ActOnUninitializedDecl(RHSVD); 12888 if (RHSVD->isInvalidDecl()) 12889 continue; 12890 if (!RHSVD->hasInit() && 12891 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12892 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12893 << Type << ReductionIdRange; 12894 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12895 VarDecl::DeclarationOnly; 12896 S.Diag(D->getLocation(), 12897 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12898 << D; 12899 continue; 12900 } 12901 // Store initializer for single element in private copy. Will be used during 12902 // codegen. 12903 PrivateVD->setInit(RHSVD->getInit()); 12904 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12905 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12906 ExprResult ReductionOp; 12907 if (DeclareReductionRef.isUsable()) { 12908 QualType RedTy = DeclareReductionRef.get()->getType(); 12909 QualType PtrRedTy = Context.getPointerType(RedTy); 12910 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12911 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12912 if (!BasePath.empty()) { 12913 LHS = S.DefaultLvalueConversion(LHS.get()); 12914 RHS = S.DefaultLvalueConversion(RHS.get()); 12915 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12916 CK_UncheckedDerivedToBase, LHS.get(), 12917 &BasePath, LHS.get()->getValueKind()); 12918 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12919 CK_UncheckedDerivedToBase, RHS.get(), 12920 &BasePath, RHS.get()->getValueKind()); 12921 } 12922 FunctionProtoType::ExtProtoInfo EPI; 12923 QualType Params[] = {PtrRedTy, PtrRedTy}; 12924 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12925 auto *OVE = new (Context) OpaqueValueExpr( 12926 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12927 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12928 Expr *Args[] = {LHS.get(), RHS.get()}; 12929 ReductionOp = 12930 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12931 } else { 12932 ReductionOp = S.BuildBinOp( 12933 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12934 if (ReductionOp.isUsable()) { 12935 if (BOK != BO_LT && BOK != BO_GT) { 12936 ReductionOp = 12937 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12938 BO_Assign, LHSDRE, ReductionOp.get()); 12939 } else { 12940 auto *ConditionalOp = new (Context) 12941 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12942 Type, VK_LValue, OK_Ordinary); 12943 ReductionOp = 12944 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12945 BO_Assign, LHSDRE, ConditionalOp); 12946 } 12947 if (ReductionOp.isUsable()) 12948 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12949 /*DiscardedValue*/ false); 12950 } 12951 if (!ReductionOp.isUsable()) 12952 continue; 12953 } 12954 12955 // OpenMP [2.15.4.6, Restrictions, p.2] 12956 // A list item that appears in an in_reduction clause of a task construct 12957 // must appear in a task_reduction clause of a construct associated with a 12958 // taskgroup region that includes the participating task in its taskgroup 12959 // set. The construct associated with the innermost region that meets this 12960 // condition must specify the same reduction-identifier as the in_reduction 12961 // clause. 12962 if (ClauseKind == OMPC_in_reduction) { 12963 SourceRange ParentSR; 12964 BinaryOperatorKind ParentBOK; 12965 const Expr *ParentReductionOp; 12966 Expr *ParentBOKTD, *ParentReductionOpTD; 12967 DSAStackTy::DSAVarData ParentBOKDSA = 12968 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12969 ParentBOKTD); 12970 DSAStackTy::DSAVarData ParentReductionOpDSA = 12971 Stack->getTopMostTaskgroupReductionData( 12972 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12973 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12974 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12975 if (!IsParentBOK && !IsParentReductionOp) { 12976 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12977 continue; 12978 } 12979 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12980 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12981 IsParentReductionOp) { 12982 bool EmitError = true; 12983 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12984 llvm::FoldingSetNodeID RedId, ParentRedId; 12985 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12986 DeclareReductionRef.get()->Profile(RedId, Context, 12987 /*Canonical=*/true); 12988 EmitError = RedId != ParentRedId; 12989 } 12990 if (EmitError) { 12991 S.Diag(ReductionId.getBeginLoc(), 12992 diag::err_omp_reduction_identifier_mismatch) 12993 << ReductionIdRange << RefExpr->getSourceRange(); 12994 S.Diag(ParentSR.getBegin(), 12995 diag::note_omp_previous_reduction_identifier) 12996 << ParentSR 12997 << (IsParentBOK ? ParentBOKDSA.RefExpr 12998 : ParentReductionOpDSA.RefExpr) 12999 ->getSourceRange(); 13000 continue; 13001 } 13002 } 13003 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13004 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13005 } 13006 13007 DeclRefExpr *Ref = nullptr; 13008 Expr *VarsExpr = RefExpr->IgnoreParens(); 13009 if (!VD && !S.CurContext->isDependentContext()) { 13010 if (ASE || OASE) { 13011 TransformExprToCaptures RebuildToCapture(S, D); 13012 VarsExpr = 13013 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13014 Ref = RebuildToCapture.getCapturedExpr(); 13015 } else { 13016 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13017 } 13018 if (!S.isOpenMPCapturedDecl(D)) { 13019 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13020 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13021 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13022 if (!RefRes.isUsable()) 13023 continue; 13024 ExprResult PostUpdateRes = 13025 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13026 RefRes.get()); 13027 if (!PostUpdateRes.isUsable()) 13028 continue; 13029 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13030 Stack->getCurrentDirective() == OMPD_taskgroup) { 13031 S.Diag(RefExpr->getExprLoc(), 13032 diag::err_omp_reduction_non_addressable_expression) 13033 << RefExpr->getSourceRange(); 13034 continue; 13035 } 13036 RD.ExprPostUpdates.emplace_back( 13037 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13038 } 13039 } 13040 } 13041 // All reduction items are still marked as reduction (to do not increase 13042 // code base size). 13043 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13044 if (CurrDir == OMPD_taskgroup) { 13045 if (DeclareReductionRef.isUsable()) 13046 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13047 DeclareReductionRef.get()); 13048 else 13049 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13050 } 13051 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13052 TaskgroupDescriptor); 13053 } 13054 return RD.Vars.empty(); 13055 } 13056 13057 OMPClause *Sema::ActOnOpenMPReductionClause( 13058 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13059 SourceLocation ColonLoc, SourceLocation EndLoc, 13060 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13061 ArrayRef<Expr *> UnresolvedReductions) { 13062 ReductionData RD(VarList.size()); 13063 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13064 StartLoc, LParenLoc, ColonLoc, EndLoc, 13065 ReductionIdScopeSpec, ReductionId, 13066 UnresolvedReductions, RD)) 13067 return nullptr; 13068 13069 return OMPReductionClause::Create( 13070 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13071 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13072 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13073 buildPreInits(Context, RD.ExprCaptures), 13074 buildPostUpdate(*this, RD.ExprPostUpdates)); 13075 } 13076 13077 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13078 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13079 SourceLocation ColonLoc, SourceLocation EndLoc, 13080 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13081 ArrayRef<Expr *> UnresolvedReductions) { 13082 ReductionData RD(VarList.size()); 13083 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13084 StartLoc, LParenLoc, ColonLoc, EndLoc, 13085 ReductionIdScopeSpec, ReductionId, 13086 UnresolvedReductions, RD)) 13087 return nullptr; 13088 13089 return OMPTaskReductionClause::Create( 13090 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13091 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13092 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13093 buildPreInits(Context, RD.ExprCaptures), 13094 buildPostUpdate(*this, RD.ExprPostUpdates)); 13095 } 13096 13097 OMPClause *Sema::ActOnOpenMPInReductionClause( 13098 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13099 SourceLocation ColonLoc, SourceLocation EndLoc, 13100 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13101 ArrayRef<Expr *> UnresolvedReductions) { 13102 ReductionData RD(VarList.size()); 13103 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13104 StartLoc, LParenLoc, ColonLoc, EndLoc, 13105 ReductionIdScopeSpec, ReductionId, 13106 UnresolvedReductions, RD)) 13107 return nullptr; 13108 13109 return OMPInReductionClause::Create( 13110 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13111 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13112 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13113 buildPreInits(Context, RD.ExprCaptures), 13114 buildPostUpdate(*this, RD.ExprPostUpdates)); 13115 } 13116 13117 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13118 SourceLocation LinLoc) { 13119 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13120 LinKind == OMPC_LINEAR_unknown) { 13121 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13122 return true; 13123 } 13124 return false; 13125 } 13126 13127 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13128 OpenMPLinearClauseKind LinKind, 13129 QualType Type) { 13130 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13131 // A variable must not have an incomplete type or a reference type. 13132 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13133 return true; 13134 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13135 !Type->isReferenceType()) { 13136 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13137 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13138 return true; 13139 } 13140 Type = Type.getNonReferenceType(); 13141 13142 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13143 // A variable that is privatized must not have a const-qualified type 13144 // unless it is of class type with a mutable member. This restriction does 13145 // not apply to the firstprivate clause. 13146 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13147 return true; 13148 13149 // A list item must be of integral or pointer type. 13150 Type = Type.getUnqualifiedType().getCanonicalType(); 13151 const auto *Ty = Type.getTypePtrOrNull(); 13152 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13153 !Ty->isPointerType())) { 13154 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13155 if (D) { 13156 bool IsDecl = 13157 !VD || 13158 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13159 Diag(D->getLocation(), 13160 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13161 << D; 13162 } 13163 return true; 13164 } 13165 return false; 13166 } 13167 13168 OMPClause *Sema::ActOnOpenMPLinearClause( 13169 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13170 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13171 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13172 SmallVector<Expr *, 8> Vars; 13173 SmallVector<Expr *, 8> Privates; 13174 SmallVector<Expr *, 8> Inits; 13175 SmallVector<Decl *, 4> ExprCaptures; 13176 SmallVector<Expr *, 4> ExprPostUpdates; 13177 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13178 LinKind = OMPC_LINEAR_val; 13179 for (Expr *RefExpr : VarList) { 13180 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13181 SourceLocation ELoc; 13182 SourceRange ERange; 13183 Expr *SimpleRefExpr = RefExpr; 13184 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13185 if (Res.second) { 13186 // It will be analyzed later. 13187 Vars.push_back(RefExpr); 13188 Privates.push_back(nullptr); 13189 Inits.push_back(nullptr); 13190 } 13191 ValueDecl *D = Res.first; 13192 if (!D) 13193 continue; 13194 13195 QualType Type = D->getType(); 13196 auto *VD = dyn_cast<VarDecl>(D); 13197 13198 // OpenMP [2.14.3.7, linear clause] 13199 // A list-item cannot appear in more than one linear clause. 13200 // A list-item that appears in a linear clause cannot appear in any 13201 // other data-sharing attribute clause. 13202 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13203 if (DVar.RefExpr) { 13204 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13205 << getOpenMPClauseName(OMPC_linear); 13206 reportOriginalDsa(*this, DSAStack, D, DVar); 13207 continue; 13208 } 13209 13210 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13211 continue; 13212 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13213 13214 // Build private copy of original var. 13215 VarDecl *Private = 13216 buildVarDecl(*this, ELoc, Type, D->getName(), 13217 D->hasAttrs() ? &D->getAttrs() : nullptr, 13218 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13219 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13220 // Build var to save initial value. 13221 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13222 Expr *InitExpr; 13223 DeclRefExpr *Ref = nullptr; 13224 if (!VD && !CurContext->isDependentContext()) { 13225 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13226 if (!isOpenMPCapturedDecl(D)) { 13227 ExprCaptures.push_back(Ref->getDecl()); 13228 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13229 ExprResult RefRes = DefaultLvalueConversion(Ref); 13230 if (!RefRes.isUsable()) 13231 continue; 13232 ExprResult PostUpdateRes = 13233 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13234 SimpleRefExpr, RefRes.get()); 13235 if (!PostUpdateRes.isUsable()) 13236 continue; 13237 ExprPostUpdates.push_back( 13238 IgnoredValueConversions(PostUpdateRes.get()).get()); 13239 } 13240 } 13241 } 13242 if (LinKind == OMPC_LINEAR_uval) 13243 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13244 else 13245 InitExpr = VD ? SimpleRefExpr : Ref; 13246 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13247 /*DirectInit=*/false); 13248 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13249 13250 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13251 Vars.push_back((VD || CurContext->isDependentContext()) 13252 ? RefExpr->IgnoreParens() 13253 : Ref); 13254 Privates.push_back(PrivateRef); 13255 Inits.push_back(InitRef); 13256 } 13257 13258 if (Vars.empty()) 13259 return nullptr; 13260 13261 Expr *StepExpr = Step; 13262 Expr *CalcStepExpr = nullptr; 13263 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13264 !Step->isInstantiationDependent() && 13265 !Step->containsUnexpandedParameterPack()) { 13266 SourceLocation StepLoc = Step->getBeginLoc(); 13267 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13268 if (Val.isInvalid()) 13269 return nullptr; 13270 StepExpr = Val.get(); 13271 13272 // Build var to save the step value. 13273 VarDecl *SaveVar = 13274 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13275 ExprResult SaveRef = 13276 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13277 ExprResult CalcStep = 13278 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13279 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13280 13281 // Warn about zero linear step (it would be probably better specified as 13282 // making corresponding variables 'const'). 13283 llvm::APSInt Result; 13284 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13285 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13286 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13287 << (Vars.size() > 1); 13288 if (!IsConstant && CalcStep.isUsable()) { 13289 // Calculate the step beforehand instead of doing this on each iteration. 13290 // (This is not used if the number of iterations may be kfold-ed). 13291 CalcStepExpr = CalcStep.get(); 13292 } 13293 } 13294 13295 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13296 ColonLoc, EndLoc, Vars, Privates, Inits, 13297 StepExpr, CalcStepExpr, 13298 buildPreInits(Context, ExprCaptures), 13299 buildPostUpdate(*this, ExprPostUpdates)); 13300 } 13301 13302 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13303 Expr *NumIterations, Sema &SemaRef, 13304 Scope *S, DSAStackTy *Stack) { 13305 // Walk the vars and build update/final expressions for the CodeGen. 13306 SmallVector<Expr *, 8> Updates; 13307 SmallVector<Expr *, 8> Finals; 13308 SmallVector<Expr *, 8> UsedExprs; 13309 Expr *Step = Clause.getStep(); 13310 Expr *CalcStep = Clause.getCalcStep(); 13311 // OpenMP [2.14.3.7, linear clause] 13312 // If linear-step is not specified it is assumed to be 1. 13313 if (!Step) 13314 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13315 else if (CalcStep) 13316 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13317 bool HasErrors = false; 13318 auto CurInit = Clause.inits().begin(); 13319 auto CurPrivate = Clause.privates().begin(); 13320 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13321 for (Expr *RefExpr : Clause.varlists()) { 13322 SourceLocation ELoc; 13323 SourceRange ERange; 13324 Expr *SimpleRefExpr = RefExpr; 13325 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13326 ValueDecl *D = Res.first; 13327 if (Res.second || !D) { 13328 Updates.push_back(nullptr); 13329 Finals.push_back(nullptr); 13330 HasErrors = true; 13331 continue; 13332 } 13333 auto &&Info = Stack->isLoopControlVariable(D); 13334 // OpenMP [2.15.11, distribute simd Construct] 13335 // A list item may not appear in a linear clause, unless it is the loop 13336 // iteration variable. 13337 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13338 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13339 SemaRef.Diag(ELoc, 13340 diag::err_omp_linear_distribute_var_non_loop_iteration); 13341 Updates.push_back(nullptr); 13342 Finals.push_back(nullptr); 13343 HasErrors = true; 13344 continue; 13345 } 13346 Expr *InitExpr = *CurInit; 13347 13348 // Build privatized reference to the current linear var. 13349 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13350 Expr *CapturedRef; 13351 if (LinKind == OMPC_LINEAR_uval) 13352 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13353 else 13354 CapturedRef = 13355 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13356 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13357 /*RefersToCapture=*/true); 13358 13359 // Build update: Var = InitExpr + IV * Step 13360 ExprResult Update; 13361 if (!Info.first) 13362 Update = buildCounterUpdate( 13363 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13364 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13365 else 13366 Update = *CurPrivate; 13367 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13368 /*DiscardedValue*/ false); 13369 13370 // Build final: Var = InitExpr + NumIterations * Step 13371 ExprResult Final; 13372 if (!Info.first) 13373 Final = 13374 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13375 InitExpr, NumIterations, Step, /*Subtract=*/false, 13376 /*IsNonRectangularLB=*/false); 13377 else 13378 Final = *CurPrivate; 13379 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13380 /*DiscardedValue*/ false); 13381 13382 if (!Update.isUsable() || !Final.isUsable()) { 13383 Updates.push_back(nullptr); 13384 Finals.push_back(nullptr); 13385 UsedExprs.push_back(nullptr); 13386 HasErrors = true; 13387 } else { 13388 Updates.push_back(Update.get()); 13389 Finals.push_back(Final.get()); 13390 if (!Info.first) 13391 UsedExprs.push_back(SimpleRefExpr); 13392 } 13393 ++CurInit; 13394 ++CurPrivate; 13395 } 13396 if (Expr *S = Clause.getStep()) 13397 UsedExprs.push_back(S); 13398 // Fill the remaining part with the nullptr. 13399 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13400 Clause.setUpdates(Updates); 13401 Clause.setFinals(Finals); 13402 Clause.setUsedExprs(UsedExprs); 13403 return HasErrors; 13404 } 13405 13406 OMPClause *Sema::ActOnOpenMPAlignedClause( 13407 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13408 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13409 SmallVector<Expr *, 8> Vars; 13410 for (Expr *RefExpr : VarList) { 13411 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13412 SourceLocation ELoc; 13413 SourceRange ERange; 13414 Expr *SimpleRefExpr = RefExpr; 13415 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13416 if (Res.second) { 13417 // It will be analyzed later. 13418 Vars.push_back(RefExpr); 13419 } 13420 ValueDecl *D = Res.first; 13421 if (!D) 13422 continue; 13423 13424 QualType QType = D->getType(); 13425 auto *VD = dyn_cast<VarDecl>(D); 13426 13427 // OpenMP [2.8.1, simd construct, Restrictions] 13428 // The type of list items appearing in the aligned clause must be 13429 // array, pointer, reference to array, or reference to pointer. 13430 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13431 const Type *Ty = QType.getTypePtrOrNull(); 13432 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 13433 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 13434 << QType << getLangOpts().CPlusPlus << ERange; 13435 bool IsDecl = 13436 !VD || 13437 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13438 Diag(D->getLocation(), 13439 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13440 << D; 13441 continue; 13442 } 13443 13444 // OpenMP [2.8.1, simd construct, Restrictions] 13445 // A list-item cannot appear in more than one aligned clause. 13446 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 13447 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 13448 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 13449 << getOpenMPClauseName(OMPC_aligned); 13450 continue; 13451 } 13452 13453 DeclRefExpr *Ref = nullptr; 13454 if (!VD && isOpenMPCapturedDecl(D)) 13455 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13456 Vars.push_back(DefaultFunctionArrayConversion( 13457 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 13458 .get()); 13459 } 13460 13461 // OpenMP [2.8.1, simd construct, Description] 13462 // The parameter of the aligned clause, alignment, must be a constant 13463 // positive integer expression. 13464 // If no optional parameter is specified, implementation-defined default 13465 // alignments for SIMD instructions on the target platforms are assumed. 13466 if (Alignment != nullptr) { 13467 ExprResult AlignResult = 13468 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 13469 if (AlignResult.isInvalid()) 13470 return nullptr; 13471 Alignment = AlignResult.get(); 13472 } 13473 if (Vars.empty()) 13474 return nullptr; 13475 13476 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 13477 EndLoc, Vars, Alignment); 13478 } 13479 13480 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 13481 SourceLocation StartLoc, 13482 SourceLocation LParenLoc, 13483 SourceLocation EndLoc) { 13484 SmallVector<Expr *, 8> Vars; 13485 SmallVector<Expr *, 8> SrcExprs; 13486 SmallVector<Expr *, 8> DstExprs; 13487 SmallVector<Expr *, 8> AssignmentOps; 13488 for (Expr *RefExpr : VarList) { 13489 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 13490 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13491 // It will be analyzed later. 13492 Vars.push_back(RefExpr); 13493 SrcExprs.push_back(nullptr); 13494 DstExprs.push_back(nullptr); 13495 AssignmentOps.push_back(nullptr); 13496 continue; 13497 } 13498 13499 SourceLocation ELoc = RefExpr->getExprLoc(); 13500 // OpenMP [2.1, C/C++] 13501 // A list item is a variable name. 13502 // OpenMP [2.14.4.1, Restrictions, p.1] 13503 // A list item that appears in a copyin clause must be threadprivate. 13504 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 13505 if (!DE || !isa<VarDecl>(DE->getDecl())) { 13506 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 13507 << 0 << RefExpr->getSourceRange(); 13508 continue; 13509 } 13510 13511 Decl *D = DE->getDecl(); 13512 auto *VD = cast<VarDecl>(D); 13513 13514 QualType Type = VD->getType(); 13515 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 13516 // It will be analyzed later. 13517 Vars.push_back(DE); 13518 SrcExprs.push_back(nullptr); 13519 DstExprs.push_back(nullptr); 13520 AssignmentOps.push_back(nullptr); 13521 continue; 13522 } 13523 13524 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 13525 // A list item that appears in a copyin clause must be threadprivate. 13526 if (!DSAStack->isThreadPrivate(VD)) { 13527 Diag(ELoc, diag::err_omp_required_access) 13528 << getOpenMPClauseName(OMPC_copyin) 13529 << getOpenMPDirectiveName(OMPD_threadprivate); 13530 continue; 13531 } 13532 13533 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13534 // A variable of class type (or array thereof) that appears in a 13535 // copyin clause requires an accessible, unambiguous copy assignment 13536 // operator for the class type. 13537 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13538 VarDecl *SrcVD = 13539 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 13540 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13541 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 13542 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 13543 VarDecl *DstVD = 13544 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 13545 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13546 DeclRefExpr *PseudoDstExpr = 13547 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 13548 // For arrays generate assignment operation for single element and replace 13549 // it by the original array element in CodeGen. 13550 ExprResult AssignmentOp = 13551 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 13552 PseudoSrcExpr); 13553 if (AssignmentOp.isInvalid()) 13554 continue; 13555 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 13556 /*DiscardedValue*/ false); 13557 if (AssignmentOp.isInvalid()) 13558 continue; 13559 13560 DSAStack->addDSA(VD, DE, OMPC_copyin); 13561 Vars.push_back(DE); 13562 SrcExprs.push_back(PseudoSrcExpr); 13563 DstExprs.push_back(PseudoDstExpr); 13564 AssignmentOps.push_back(AssignmentOp.get()); 13565 } 13566 13567 if (Vars.empty()) 13568 return nullptr; 13569 13570 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13571 SrcExprs, DstExprs, AssignmentOps); 13572 } 13573 13574 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 13575 SourceLocation StartLoc, 13576 SourceLocation LParenLoc, 13577 SourceLocation EndLoc) { 13578 SmallVector<Expr *, 8> Vars; 13579 SmallVector<Expr *, 8> SrcExprs; 13580 SmallVector<Expr *, 8> DstExprs; 13581 SmallVector<Expr *, 8> AssignmentOps; 13582 for (Expr *RefExpr : VarList) { 13583 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13584 SourceLocation ELoc; 13585 SourceRange ERange; 13586 Expr *SimpleRefExpr = RefExpr; 13587 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13588 if (Res.second) { 13589 // It will be analyzed later. 13590 Vars.push_back(RefExpr); 13591 SrcExprs.push_back(nullptr); 13592 DstExprs.push_back(nullptr); 13593 AssignmentOps.push_back(nullptr); 13594 } 13595 ValueDecl *D = Res.first; 13596 if (!D) 13597 continue; 13598 13599 QualType Type = D->getType(); 13600 auto *VD = dyn_cast<VarDecl>(D); 13601 13602 // OpenMP [2.14.4.2, Restrictions, p.2] 13603 // A list item that appears in a copyprivate clause may not appear in a 13604 // private or firstprivate clause on the single construct. 13605 if (!VD || !DSAStack->isThreadPrivate(VD)) { 13606 DSAStackTy::DSAVarData DVar = 13607 DSAStack->getTopDSA(D, /*FromParent=*/false); 13608 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 13609 DVar.RefExpr) { 13610 Diag(ELoc, diag::err_omp_wrong_dsa) 13611 << getOpenMPClauseName(DVar.CKind) 13612 << getOpenMPClauseName(OMPC_copyprivate); 13613 reportOriginalDsa(*this, DSAStack, D, DVar); 13614 continue; 13615 } 13616 13617 // OpenMP [2.11.4.2, Restrictions, p.1] 13618 // All list items that appear in a copyprivate clause must be either 13619 // threadprivate or private in the enclosing context. 13620 if (DVar.CKind == OMPC_unknown) { 13621 DVar = DSAStack->getImplicitDSA(D, false); 13622 if (DVar.CKind == OMPC_shared) { 13623 Diag(ELoc, diag::err_omp_required_access) 13624 << getOpenMPClauseName(OMPC_copyprivate) 13625 << "threadprivate or private in the enclosing context"; 13626 reportOriginalDsa(*this, DSAStack, D, DVar); 13627 continue; 13628 } 13629 } 13630 } 13631 13632 // Variably modified types are not supported. 13633 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 13634 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13635 << getOpenMPClauseName(OMPC_copyprivate) << Type 13636 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13637 bool IsDecl = 13638 !VD || 13639 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13640 Diag(D->getLocation(), 13641 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13642 << D; 13643 continue; 13644 } 13645 13646 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13647 // A variable of class type (or array thereof) that appears in a 13648 // copyin clause requires an accessible, unambiguous copy assignment 13649 // operator for the class type. 13650 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13651 .getUnqualifiedType(); 13652 VarDecl *SrcVD = 13653 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13654 D->hasAttrs() ? &D->getAttrs() : nullptr); 13655 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13656 VarDecl *DstVD = 13657 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13658 D->hasAttrs() ? &D->getAttrs() : nullptr); 13659 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13660 ExprResult AssignmentOp = BuildBinOp( 13661 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13662 if (AssignmentOp.isInvalid()) 13663 continue; 13664 AssignmentOp = 13665 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13666 if (AssignmentOp.isInvalid()) 13667 continue; 13668 13669 // No need to mark vars as copyprivate, they are already threadprivate or 13670 // implicitly private. 13671 assert(VD || isOpenMPCapturedDecl(D)); 13672 Vars.push_back( 13673 VD ? RefExpr->IgnoreParens() 13674 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13675 SrcExprs.push_back(PseudoSrcExpr); 13676 DstExprs.push_back(PseudoDstExpr); 13677 AssignmentOps.push_back(AssignmentOp.get()); 13678 } 13679 13680 if (Vars.empty()) 13681 return nullptr; 13682 13683 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13684 Vars, SrcExprs, DstExprs, AssignmentOps); 13685 } 13686 13687 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13688 SourceLocation StartLoc, 13689 SourceLocation LParenLoc, 13690 SourceLocation EndLoc) { 13691 if (VarList.empty()) 13692 return nullptr; 13693 13694 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13695 } 13696 13697 OMPClause * 13698 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13699 SourceLocation DepLoc, SourceLocation ColonLoc, 13700 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13701 SourceLocation LParenLoc, SourceLocation EndLoc) { 13702 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13703 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13704 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13705 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13706 return nullptr; 13707 } 13708 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13709 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13710 DepKind == OMPC_DEPEND_sink)) { 13711 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13712 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13713 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13714 /*Last=*/OMPC_DEPEND_unknown, Except) 13715 << getOpenMPClauseName(OMPC_depend); 13716 return nullptr; 13717 } 13718 SmallVector<Expr *, 8> Vars; 13719 DSAStackTy::OperatorOffsetTy OpsOffs; 13720 llvm::APSInt DepCounter(/*BitWidth=*/32); 13721 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13722 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13723 if (const Expr *OrderedCountExpr = 13724 DSAStack->getParentOrderedRegionParam().first) { 13725 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13726 TotalDepCount.setIsUnsigned(/*Val=*/true); 13727 } 13728 } 13729 for (Expr *RefExpr : VarList) { 13730 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13731 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13732 // It will be analyzed later. 13733 Vars.push_back(RefExpr); 13734 continue; 13735 } 13736 13737 SourceLocation ELoc = RefExpr->getExprLoc(); 13738 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13739 if (DepKind == OMPC_DEPEND_sink) { 13740 if (DSAStack->getParentOrderedRegionParam().first && 13741 DepCounter >= TotalDepCount) { 13742 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13743 continue; 13744 } 13745 ++DepCounter; 13746 // OpenMP [2.13.9, Summary] 13747 // depend(dependence-type : vec), where dependence-type is: 13748 // 'sink' and where vec is the iteration vector, which has the form: 13749 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13750 // where n is the value specified by the ordered clause in the loop 13751 // directive, xi denotes the loop iteration variable of the i-th nested 13752 // loop associated with the loop directive, and di is a constant 13753 // non-negative integer. 13754 if (CurContext->isDependentContext()) { 13755 // It will be analyzed later. 13756 Vars.push_back(RefExpr); 13757 continue; 13758 } 13759 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13760 OverloadedOperatorKind OOK = OO_None; 13761 SourceLocation OOLoc; 13762 Expr *LHS = SimpleExpr; 13763 Expr *RHS = nullptr; 13764 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13765 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13766 OOLoc = BO->getOperatorLoc(); 13767 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13768 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13769 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13770 OOK = OCE->getOperator(); 13771 OOLoc = OCE->getOperatorLoc(); 13772 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13773 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13774 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13775 OOK = MCE->getMethodDecl() 13776 ->getNameInfo() 13777 .getName() 13778 .getCXXOverloadedOperator(); 13779 OOLoc = MCE->getCallee()->getExprLoc(); 13780 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13781 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13782 } 13783 SourceLocation ELoc; 13784 SourceRange ERange; 13785 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13786 if (Res.second) { 13787 // It will be analyzed later. 13788 Vars.push_back(RefExpr); 13789 } 13790 ValueDecl *D = Res.first; 13791 if (!D) 13792 continue; 13793 13794 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 13795 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 13796 continue; 13797 } 13798 if (RHS) { 13799 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 13800 RHS, OMPC_depend, /*StrictlyPositive=*/false); 13801 if (RHSRes.isInvalid()) 13802 continue; 13803 } 13804 if (!CurContext->isDependentContext() && 13805 DSAStack->getParentOrderedRegionParam().first && 13806 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 13807 const ValueDecl *VD = 13808 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 13809 if (VD) 13810 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 13811 << 1 << VD; 13812 else 13813 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 13814 continue; 13815 } 13816 OpsOffs.emplace_back(RHS, OOK); 13817 } else { 13818 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 13819 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 13820 (ASE && 13821 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 13822 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 13823 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13824 << RefExpr->getSourceRange(); 13825 continue; 13826 } 13827 13828 ExprResult Res; 13829 { 13830 Sema::TentativeAnalysisScope Trap(*this); 13831 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 13832 RefExpr->IgnoreParenImpCasts()); 13833 } 13834 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 13835 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13836 << RefExpr->getSourceRange(); 13837 continue; 13838 } 13839 } 13840 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13841 } 13842 13843 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13844 TotalDepCount > VarList.size() && 13845 DSAStack->getParentOrderedRegionParam().first && 13846 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13847 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13848 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13849 } 13850 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13851 Vars.empty()) 13852 return nullptr; 13853 13854 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13855 DepKind, DepLoc, ColonLoc, Vars, 13856 TotalDepCount.getZExtValue()); 13857 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13858 DSAStack->isParentOrderedRegion()) 13859 DSAStack->addDoacrossDependClause(C, OpsOffs); 13860 return C; 13861 } 13862 13863 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13864 SourceLocation LParenLoc, 13865 SourceLocation EndLoc) { 13866 Expr *ValExpr = Device; 13867 Stmt *HelperValStmt = nullptr; 13868 13869 // OpenMP [2.9.1, Restrictions] 13870 // The device expression must evaluate to a non-negative integer value. 13871 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13872 /*StrictlyPositive=*/false)) 13873 return nullptr; 13874 13875 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13876 OpenMPDirectiveKind CaptureRegion = 13877 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13878 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13879 ValExpr = MakeFullExpr(ValExpr).get(); 13880 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13881 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13882 HelperValStmt = buildPreInits(Context, Captures); 13883 } 13884 13885 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13886 StartLoc, LParenLoc, EndLoc); 13887 } 13888 13889 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13890 DSAStackTy *Stack, QualType QTy, 13891 bool FullCheck = true) { 13892 NamedDecl *ND; 13893 if (QTy->isIncompleteType(&ND)) { 13894 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13895 return false; 13896 } 13897 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13898 !QTy.isTrivialType(SemaRef.Context)) 13899 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13900 return true; 13901 } 13902 13903 /// Return true if it can be proven that the provided array expression 13904 /// (array section or array subscript) does NOT specify the whole size of the 13905 /// array whose base type is \a BaseQTy. 13906 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13907 const Expr *E, 13908 QualType BaseQTy) { 13909 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13910 13911 // If this is an array subscript, it refers to the whole size if the size of 13912 // the dimension is constant and equals 1. Also, an array section assumes the 13913 // format of an array subscript if no colon is used. 13914 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13915 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13916 return ATy->getSize().getSExtValue() != 1; 13917 // Size can't be evaluated statically. 13918 return false; 13919 } 13920 13921 assert(OASE && "Expecting array section if not an array subscript."); 13922 const Expr *LowerBound = OASE->getLowerBound(); 13923 const Expr *Length = OASE->getLength(); 13924 13925 // If there is a lower bound that does not evaluates to zero, we are not 13926 // covering the whole dimension. 13927 if (LowerBound) { 13928 Expr::EvalResult Result; 13929 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13930 return false; // Can't get the integer value as a constant. 13931 13932 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13933 if (ConstLowerBound.getSExtValue()) 13934 return true; 13935 } 13936 13937 // If we don't have a length we covering the whole dimension. 13938 if (!Length) 13939 return false; 13940 13941 // If the base is a pointer, we don't have a way to get the size of the 13942 // pointee. 13943 if (BaseQTy->isPointerType()) 13944 return false; 13945 13946 // We can only check if the length is the same as the size of the dimension 13947 // if we have a constant array. 13948 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13949 if (!CATy) 13950 return false; 13951 13952 Expr::EvalResult Result; 13953 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13954 return false; // Can't get the integer value as a constant. 13955 13956 llvm::APSInt ConstLength = Result.Val.getInt(); 13957 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13958 } 13959 13960 // Return true if it can be proven that the provided array expression (array 13961 // section or array subscript) does NOT specify a single element of the array 13962 // whose base type is \a BaseQTy. 13963 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13964 const Expr *E, 13965 QualType BaseQTy) { 13966 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13967 13968 // An array subscript always refer to a single element. Also, an array section 13969 // assumes the format of an array subscript if no colon is used. 13970 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13971 return false; 13972 13973 assert(OASE && "Expecting array section if not an array subscript."); 13974 const Expr *Length = OASE->getLength(); 13975 13976 // If we don't have a length we have to check if the array has unitary size 13977 // for this dimension. Also, we should always expect a length if the base type 13978 // is pointer. 13979 if (!Length) { 13980 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13981 return ATy->getSize().getSExtValue() != 1; 13982 // We cannot assume anything. 13983 return false; 13984 } 13985 13986 // Check if the length evaluates to 1. 13987 Expr::EvalResult Result; 13988 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13989 return false; // Can't get the integer value as a constant. 13990 13991 llvm::APSInt ConstLength = Result.Val.getInt(); 13992 return ConstLength.getSExtValue() != 1; 13993 } 13994 13995 // Return the expression of the base of the mappable expression or null if it 13996 // cannot be determined and do all the necessary checks to see if the expression 13997 // is valid as a standalone mappable expression. In the process, record all the 13998 // components of the expression. 13999 static const Expr *checkMapClauseExpressionBase( 14000 Sema &SemaRef, Expr *E, 14001 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14002 OpenMPClauseKind CKind, bool NoDiagnose) { 14003 SourceLocation ELoc = E->getExprLoc(); 14004 SourceRange ERange = E->getSourceRange(); 14005 14006 // The base of elements of list in a map clause have to be either: 14007 // - a reference to variable or field. 14008 // - a member expression. 14009 // - an array expression. 14010 // 14011 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14012 // reference to 'r'. 14013 // 14014 // If we have: 14015 // 14016 // struct SS { 14017 // Bla S; 14018 // foo() { 14019 // #pragma omp target map (S.Arr[:12]); 14020 // } 14021 // } 14022 // 14023 // We want to retrieve the member expression 'this->S'; 14024 14025 const Expr *RelevantExpr = nullptr; 14026 14027 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14028 // If a list item is an array section, it must specify contiguous storage. 14029 // 14030 // For this restriction it is sufficient that we make sure only references 14031 // to variables or fields and array expressions, and that no array sections 14032 // exist except in the rightmost expression (unless they cover the whole 14033 // dimension of the array). E.g. these would be invalid: 14034 // 14035 // r.ArrS[3:5].Arr[6:7] 14036 // 14037 // r.ArrS[3:5].x 14038 // 14039 // but these would be valid: 14040 // r.ArrS[3].Arr[6:7] 14041 // 14042 // r.ArrS[3].x 14043 14044 bool AllowUnitySizeArraySection = true; 14045 bool AllowWholeSizeArraySection = true; 14046 14047 while (!RelevantExpr) { 14048 E = E->IgnoreParenImpCasts(); 14049 14050 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14051 if (!isa<VarDecl>(CurE->getDecl())) 14052 return nullptr; 14053 14054 RelevantExpr = CurE; 14055 14056 // If we got a reference to a declaration, we should not expect any array 14057 // section before that. 14058 AllowUnitySizeArraySection = false; 14059 AllowWholeSizeArraySection = false; 14060 14061 // Record the component. 14062 CurComponents.emplace_back(CurE, CurE->getDecl()); 14063 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14064 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14065 14066 if (isa<CXXThisExpr>(BaseE)) 14067 // We found a base expression: this->Val. 14068 RelevantExpr = CurE; 14069 else 14070 E = BaseE; 14071 14072 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14073 if (!NoDiagnose) { 14074 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14075 << CurE->getSourceRange(); 14076 return nullptr; 14077 } 14078 if (RelevantExpr) 14079 return nullptr; 14080 continue; 14081 } 14082 14083 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14084 14085 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14086 // A bit-field cannot appear in a map clause. 14087 // 14088 if (FD->isBitField()) { 14089 if (!NoDiagnose) { 14090 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14091 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14092 return nullptr; 14093 } 14094 if (RelevantExpr) 14095 return nullptr; 14096 continue; 14097 } 14098 14099 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14100 // If the type of a list item is a reference to a type T then the type 14101 // will be considered to be T for all purposes of this clause. 14102 QualType CurType = BaseE->getType().getNonReferenceType(); 14103 14104 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14105 // A list item cannot be a variable that is a member of a structure with 14106 // a union type. 14107 // 14108 if (CurType->isUnionType()) { 14109 if (!NoDiagnose) { 14110 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14111 << CurE->getSourceRange(); 14112 return nullptr; 14113 } 14114 continue; 14115 } 14116 14117 // If we got a member expression, we should not expect any array section 14118 // before that: 14119 // 14120 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14121 // If a list item is an element of a structure, only the rightmost symbol 14122 // of the variable reference can be an array section. 14123 // 14124 AllowUnitySizeArraySection = false; 14125 AllowWholeSizeArraySection = false; 14126 14127 // Record the component. 14128 CurComponents.emplace_back(CurE, FD); 14129 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14130 E = CurE->getBase()->IgnoreParenImpCasts(); 14131 14132 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14133 if (!NoDiagnose) { 14134 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14135 << 0 << CurE->getSourceRange(); 14136 return nullptr; 14137 } 14138 continue; 14139 } 14140 14141 // If we got an array subscript that express the whole dimension we 14142 // can have any array expressions before. If it only expressing part of 14143 // the dimension, we can only have unitary-size array expressions. 14144 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14145 E->getType())) 14146 AllowWholeSizeArraySection = false; 14147 14148 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14149 Expr::EvalResult Result; 14150 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14151 if (!Result.Val.getInt().isNullValue()) { 14152 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14153 diag::err_omp_invalid_map_this_expr); 14154 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14155 diag::note_omp_invalid_subscript_on_this_ptr_map); 14156 } 14157 } 14158 RelevantExpr = TE; 14159 } 14160 14161 // Record the component - we don't have any declaration associated. 14162 CurComponents.emplace_back(CurE, nullptr); 14163 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14164 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14165 E = CurE->getBase()->IgnoreParenImpCasts(); 14166 14167 QualType CurType = 14168 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14169 14170 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14171 // If the type of a list item is a reference to a type T then the type 14172 // will be considered to be T for all purposes of this clause. 14173 if (CurType->isReferenceType()) 14174 CurType = CurType->getPointeeType(); 14175 14176 bool IsPointer = CurType->isAnyPointerType(); 14177 14178 if (!IsPointer && !CurType->isArrayType()) { 14179 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14180 << 0 << CurE->getSourceRange(); 14181 return nullptr; 14182 } 14183 14184 bool NotWhole = 14185 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14186 bool NotUnity = 14187 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14188 14189 if (AllowWholeSizeArraySection) { 14190 // Any array section is currently allowed. Allowing a whole size array 14191 // section implies allowing a unity array section as well. 14192 // 14193 // If this array section refers to the whole dimension we can still 14194 // accept other array sections before this one, except if the base is a 14195 // pointer. Otherwise, only unitary sections are accepted. 14196 if (NotWhole || IsPointer) 14197 AllowWholeSizeArraySection = false; 14198 } else if (AllowUnitySizeArraySection && NotUnity) { 14199 // A unity or whole array section is not allowed and that is not 14200 // compatible with the properties of the current array section. 14201 SemaRef.Diag( 14202 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14203 << CurE->getSourceRange(); 14204 return nullptr; 14205 } 14206 14207 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14208 Expr::EvalResult ResultR; 14209 Expr::EvalResult ResultL; 14210 if (CurE->getLength()->EvaluateAsInt(ResultR, 14211 SemaRef.getASTContext())) { 14212 if (!ResultR.Val.getInt().isOneValue()) { 14213 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14214 diag::err_omp_invalid_map_this_expr); 14215 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14216 diag::note_omp_invalid_length_on_this_ptr_mapping); 14217 } 14218 } 14219 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14220 ResultL, SemaRef.getASTContext())) { 14221 if (!ResultL.Val.getInt().isNullValue()) { 14222 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14223 diag::err_omp_invalid_map_this_expr); 14224 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14225 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14226 } 14227 } 14228 RelevantExpr = TE; 14229 } 14230 14231 // Record the component - we don't have any declaration associated. 14232 CurComponents.emplace_back(CurE, nullptr); 14233 } else { 14234 if (!NoDiagnose) { 14235 // If nothing else worked, this is not a valid map clause expression. 14236 SemaRef.Diag( 14237 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14238 << ERange; 14239 } 14240 return nullptr; 14241 } 14242 } 14243 14244 return RelevantExpr; 14245 } 14246 14247 // Return true if expression E associated with value VD has conflicts with other 14248 // map information. 14249 static bool checkMapConflicts( 14250 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14251 bool CurrentRegionOnly, 14252 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14253 OpenMPClauseKind CKind) { 14254 assert(VD && E); 14255 SourceLocation ELoc = E->getExprLoc(); 14256 SourceRange ERange = E->getSourceRange(); 14257 14258 // In order to easily check the conflicts we need to match each component of 14259 // the expression under test with the components of the expressions that are 14260 // already in the stack. 14261 14262 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14263 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14264 "Map clause expression with unexpected base!"); 14265 14266 // Variables to help detecting enclosing problems in data environment nests. 14267 bool IsEnclosedByDataEnvironmentExpr = false; 14268 const Expr *EnclosingExpr = nullptr; 14269 14270 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14271 VD, CurrentRegionOnly, 14272 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14273 ERange, CKind, &EnclosingExpr, 14274 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14275 StackComponents, 14276 OpenMPClauseKind) { 14277 assert(!StackComponents.empty() && 14278 "Map clause expression with no components!"); 14279 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14280 "Map clause expression with unexpected base!"); 14281 (void)VD; 14282 14283 // The whole expression in the stack. 14284 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14285 14286 // Expressions must start from the same base. Here we detect at which 14287 // point both expressions diverge from each other and see if we can 14288 // detect if the memory referred to both expressions is contiguous and 14289 // do not overlap. 14290 auto CI = CurComponents.rbegin(); 14291 auto CE = CurComponents.rend(); 14292 auto SI = StackComponents.rbegin(); 14293 auto SE = StackComponents.rend(); 14294 for (; CI != CE && SI != SE; ++CI, ++SI) { 14295 14296 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14297 // At most one list item can be an array item derived from a given 14298 // variable in map clauses of the same construct. 14299 if (CurrentRegionOnly && 14300 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14301 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14302 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14303 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14304 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14305 diag::err_omp_multiple_array_items_in_map_clause) 14306 << CI->getAssociatedExpression()->getSourceRange(); 14307 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14308 diag::note_used_here) 14309 << SI->getAssociatedExpression()->getSourceRange(); 14310 return true; 14311 } 14312 14313 // Do both expressions have the same kind? 14314 if (CI->getAssociatedExpression()->getStmtClass() != 14315 SI->getAssociatedExpression()->getStmtClass()) 14316 break; 14317 14318 // Are we dealing with different variables/fields? 14319 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14320 break; 14321 } 14322 // Check if the extra components of the expressions in the enclosing 14323 // data environment are redundant for the current base declaration. 14324 // If they are, the maps completely overlap, which is legal. 14325 for (; SI != SE; ++SI) { 14326 QualType Type; 14327 if (const auto *ASE = 14328 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14329 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14330 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14331 SI->getAssociatedExpression())) { 14332 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14333 Type = 14334 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14335 } 14336 if (Type.isNull() || Type->isAnyPointerType() || 14337 checkArrayExpressionDoesNotReferToWholeSize( 14338 SemaRef, SI->getAssociatedExpression(), Type)) 14339 break; 14340 } 14341 14342 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14343 // List items of map clauses in the same construct must not share 14344 // original storage. 14345 // 14346 // If the expressions are exactly the same or one is a subset of the 14347 // other, it means they are sharing storage. 14348 if (CI == CE && SI == SE) { 14349 if (CurrentRegionOnly) { 14350 if (CKind == OMPC_map) { 14351 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14352 } else { 14353 assert(CKind == OMPC_to || CKind == OMPC_from); 14354 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14355 << ERange; 14356 } 14357 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14358 << RE->getSourceRange(); 14359 return true; 14360 } 14361 // If we find the same expression in the enclosing data environment, 14362 // that is legal. 14363 IsEnclosedByDataEnvironmentExpr = true; 14364 return false; 14365 } 14366 14367 QualType DerivedType = 14368 std::prev(CI)->getAssociatedDeclaration()->getType(); 14369 SourceLocation DerivedLoc = 14370 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14371 14372 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14373 // If the type of a list item is a reference to a type T then the type 14374 // will be considered to be T for all purposes of this clause. 14375 DerivedType = DerivedType.getNonReferenceType(); 14376 14377 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14378 // A variable for which the type is pointer and an array section 14379 // derived from that variable must not appear as list items of map 14380 // clauses of the same construct. 14381 // 14382 // Also, cover one of the cases in: 14383 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14384 // If any part of the original storage of a list item has corresponding 14385 // storage in the device data environment, all of the original storage 14386 // must have corresponding storage in the device data environment. 14387 // 14388 if (DerivedType->isAnyPointerType()) { 14389 if (CI == CE || SI == SE) { 14390 SemaRef.Diag( 14391 DerivedLoc, 14392 diag::err_omp_pointer_mapped_along_with_derived_section) 14393 << DerivedLoc; 14394 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14395 << RE->getSourceRange(); 14396 return true; 14397 } 14398 if (CI->getAssociatedExpression()->getStmtClass() != 14399 SI->getAssociatedExpression()->getStmtClass() || 14400 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14401 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14402 assert(CI != CE && SI != SE); 14403 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14404 << DerivedLoc; 14405 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14406 << RE->getSourceRange(); 14407 return true; 14408 } 14409 } 14410 14411 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14412 // List items of map clauses in the same construct must not share 14413 // original storage. 14414 // 14415 // An expression is a subset of the other. 14416 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14417 if (CKind == OMPC_map) { 14418 if (CI != CE || SI != SE) { 14419 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14420 // a pointer. 14421 auto Begin = 14422 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14423 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14424 auto It = Begin; 14425 while (It != End && !It->getAssociatedDeclaration()) 14426 std::advance(It, 1); 14427 assert(It != End && 14428 "Expected at least one component with the declaration."); 14429 if (It != Begin && It->getAssociatedDeclaration() 14430 ->getType() 14431 .getCanonicalType() 14432 ->isAnyPointerType()) { 14433 IsEnclosedByDataEnvironmentExpr = false; 14434 EnclosingExpr = nullptr; 14435 return false; 14436 } 14437 } 14438 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14439 } else { 14440 assert(CKind == OMPC_to || CKind == OMPC_from); 14441 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14442 << ERange; 14443 } 14444 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14445 << RE->getSourceRange(); 14446 return true; 14447 } 14448 14449 // The current expression uses the same base as other expression in the 14450 // data environment but does not contain it completely. 14451 if (!CurrentRegionOnly && SI != SE) 14452 EnclosingExpr = RE; 14453 14454 // The current expression is a subset of the expression in the data 14455 // environment. 14456 IsEnclosedByDataEnvironmentExpr |= 14457 (!CurrentRegionOnly && CI != CE && SI == SE); 14458 14459 return false; 14460 }); 14461 14462 if (CurrentRegionOnly) 14463 return FoundError; 14464 14465 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14466 // If any part of the original storage of a list item has corresponding 14467 // storage in the device data environment, all of the original storage must 14468 // have corresponding storage in the device data environment. 14469 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 14470 // If a list item is an element of a structure, and a different element of 14471 // the structure has a corresponding list item in the device data environment 14472 // prior to a task encountering the construct associated with the map clause, 14473 // then the list item must also have a corresponding list item in the device 14474 // data environment prior to the task encountering the construct. 14475 // 14476 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 14477 SemaRef.Diag(ELoc, 14478 diag::err_omp_original_storage_is_shared_and_does_not_contain) 14479 << ERange; 14480 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 14481 << EnclosingExpr->getSourceRange(); 14482 return true; 14483 } 14484 14485 return FoundError; 14486 } 14487 14488 // Look up the user-defined mapper given the mapper name and mapped type, and 14489 // build a reference to it. 14490 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 14491 CXXScopeSpec &MapperIdScopeSpec, 14492 const DeclarationNameInfo &MapperId, 14493 QualType Type, 14494 Expr *UnresolvedMapper) { 14495 if (MapperIdScopeSpec.isInvalid()) 14496 return ExprError(); 14497 // Find all user-defined mappers with the given MapperId. 14498 SmallVector<UnresolvedSet<8>, 4> Lookups; 14499 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 14500 Lookup.suppressDiagnostics(); 14501 if (S) { 14502 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 14503 NamedDecl *D = Lookup.getRepresentativeDecl(); 14504 while (S && !S->isDeclScope(D)) 14505 S = S->getParent(); 14506 if (S) 14507 S = S->getParent(); 14508 Lookups.emplace_back(); 14509 Lookups.back().append(Lookup.begin(), Lookup.end()); 14510 Lookup.clear(); 14511 } 14512 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 14513 // Extract the user-defined mappers with the given MapperId. 14514 Lookups.push_back(UnresolvedSet<8>()); 14515 for (NamedDecl *D : ULE->decls()) { 14516 auto *DMD = cast<OMPDeclareMapperDecl>(D); 14517 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 14518 Lookups.back().addDecl(DMD); 14519 } 14520 } 14521 // Defer the lookup for dependent types. The results will be passed through 14522 // UnresolvedMapper on instantiation. 14523 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 14524 Type->isInstantiationDependentType() || 14525 Type->containsUnexpandedParameterPack() || 14526 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14527 return !D->isInvalidDecl() && 14528 (D->getType()->isDependentType() || 14529 D->getType()->isInstantiationDependentType() || 14530 D->getType()->containsUnexpandedParameterPack()); 14531 })) { 14532 UnresolvedSet<8> URS; 14533 for (const UnresolvedSet<8> &Set : Lookups) { 14534 if (Set.empty()) 14535 continue; 14536 URS.append(Set.begin(), Set.end()); 14537 } 14538 return UnresolvedLookupExpr::Create( 14539 SemaRef.Context, /*NamingClass=*/nullptr, 14540 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 14541 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 14542 } 14543 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14544 // The type must be of struct, union or class type in C and C++ 14545 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 14546 return ExprEmpty(); 14547 SourceLocation Loc = MapperId.getLoc(); 14548 // Perform argument dependent lookup. 14549 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 14550 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 14551 // Return the first user-defined mapper with the desired type. 14552 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14553 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 14554 if (!D->isInvalidDecl() && 14555 SemaRef.Context.hasSameType(D->getType(), Type)) 14556 return D; 14557 return nullptr; 14558 })) 14559 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14560 // Find the first user-defined mapper with a type derived from the desired 14561 // type. 14562 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14563 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 14564 if (!D->isInvalidDecl() && 14565 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 14566 !Type.isMoreQualifiedThan(D->getType())) 14567 return D; 14568 return nullptr; 14569 })) { 14570 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14571 /*DetectVirtual=*/false); 14572 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 14573 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14574 VD->getType().getUnqualifiedType()))) { 14575 if (SemaRef.CheckBaseClassAccess( 14576 Loc, VD->getType(), Type, Paths.front(), 14577 /*DiagID=*/0) != Sema::AR_inaccessible) { 14578 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14579 } 14580 } 14581 } 14582 } 14583 // Report error if a mapper is specified, but cannot be found. 14584 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 14585 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 14586 << Type << MapperId.getName(); 14587 return ExprError(); 14588 } 14589 return ExprEmpty(); 14590 } 14591 14592 namespace { 14593 // Utility struct that gathers all the related lists associated with a mappable 14594 // expression. 14595 struct MappableVarListInfo { 14596 // The list of expressions. 14597 ArrayRef<Expr *> VarList; 14598 // The list of processed expressions. 14599 SmallVector<Expr *, 16> ProcessedVarList; 14600 // The mappble components for each expression. 14601 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 14602 // The base declaration of the variable. 14603 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 14604 // The reference to the user-defined mapper associated with every expression. 14605 SmallVector<Expr *, 16> UDMapperList; 14606 14607 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 14608 // We have a list of components and base declarations for each entry in the 14609 // variable list. 14610 VarComponents.reserve(VarList.size()); 14611 VarBaseDeclarations.reserve(VarList.size()); 14612 } 14613 }; 14614 } 14615 14616 // Check the validity of the provided variable list for the provided clause kind 14617 // \a CKind. In the check process the valid expressions, mappable expression 14618 // components, variables, and user-defined mappers are extracted and used to 14619 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 14620 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 14621 // and \a MapperId are expected to be valid if the clause kind is 'map'. 14622 static void checkMappableExpressionList( 14623 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 14624 MappableVarListInfo &MVLI, SourceLocation StartLoc, 14625 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 14626 ArrayRef<Expr *> UnresolvedMappers, 14627 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 14628 bool IsMapTypeImplicit = false) { 14629 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 14630 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 14631 "Unexpected clause kind with mappable expressions!"); 14632 14633 // If the identifier of user-defined mapper is not specified, it is "default". 14634 // We do not change the actual name in this clause to distinguish whether a 14635 // mapper is specified explicitly, i.e., it is not explicitly specified when 14636 // MapperId.getName() is empty. 14637 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 14638 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14639 MapperId.setName(DeclNames.getIdentifier( 14640 &SemaRef.getASTContext().Idents.get("default"))); 14641 } 14642 14643 // Iterators to find the current unresolved mapper expression. 14644 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14645 bool UpdateUMIt = false; 14646 Expr *UnresolvedMapper = nullptr; 14647 14648 // Keep track of the mappable components and base declarations in this clause. 14649 // Each entry in the list is going to have a list of components associated. We 14650 // record each set of the components so that we can build the clause later on. 14651 // In the end we should have the same amount of declarations and component 14652 // lists. 14653 14654 for (Expr *RE : MVLI.VarList) { 14655 assert(RE && "Null expr in omp to/from/map clause"); 14656 SourceLocation ELoc = RE->getExprLoc(); 14657 14658 // Find the current unresolved mapper expression. 14659 if (UpdateUMIt && UMIt != UMEnd) { 14660 UMIt++; 14661 assert( 14662 UMIt != UMEnd && 14663 "Expect the size of UnresolvedMappers to match with that of VarList"); 14664 } 14665 UpdateUMIt = true; 14666 if (UMIt != UMEnd) 14667 UnresolvedMapper = *UMIt; 14668 14669 const Expr *VE = RE->IgnoreParenLValueCasts(); 14670 14671 if (VE->isValueDependent() || VE->isTypeDependent() || 14672 VE->isInstantiationDependent() || 14673 VE->containsUnexpandedParameterPack()) { 14674 // Try to find the associated user-defined mapper. 14675 ExprResult ER = buildUserDefinedMapperRef( 14676 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14677 VE->getType().getCanonicalType(), UnresolvedMapper); 14678 if (ER.isInvalid()) 14679 continue; 14680 MVLI.UDMapperList.push_back(ER.get()); 14681 // We can only analyze this information once the missing information is 14682 // resolved. 14683 MVLI.ProcessedVarList.push_back(RE); 14684 continue; 14685 } 14686 14687 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14688 14689 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14690 SemaRef.Diag(ELoc, 14691 diag::err_omp_expected_named_var_member_or_array_expression) 14692 << RE->getSourceRange(); 14693 continue; 14694 } 14695 14696 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14697 ValueDecl *CurDeclaration = nullptr; 14698 14699 // Obtain the array or member expression bases if required. Also, fill the 14700 // components array with all the components identified in the process. 14701 const Expr *BE = checkMapClauseExpressionBase( 14702 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14703 if (!BE) 14704 continue; 14705 14706 assert(!CurComponents.empty() && 14707 "Invalid mappable expression information."); 14708 14709 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14710 // Add store "this" pointer to class in DSAStackTy for future checking 14711 DSAS->addMappedClassesQualTypes(TE->getType()); 14712 // Try to find the associated user-defined mapper. 14713 ExprResult ER = buildUserDefinedMapperRef( 14714 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14715 VE->getType().getCanonicalType(), UnresolvedMapper); 14716 if (ER.isInvalid()) 14717 continue; 14718 MVLI.UDMapperList.push_back(ER.get()); 14719 // Skip restriction checking for variable or field declarations 14720 MVLI.ProcessedVarList.push_back(RE); 14721 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14722 MVLI.VarComponents.back().append(CurComponents.begin(), 14723 CurComponents.end()); 14724 MVLI.VarBaseDeclarations.push_back(nullptr); 14725 continue; 14726 } 14727 14728 // For the following checks, we rely on the base declaration which is 14729 // expected to be associated with the last component. The declaration is 14730 // expected to be a variable or a field (if 'this' is being mapped). 14731 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14732 assert(CurDeclaration && "Null decl on map clause."); 14733 assert( 14734 CurDeclaration->isCanonicalDecl() && 14735 "Expecting components to have associated only canonical declarations."); 14736 14737 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14738 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14739 14740 assert((VD || FD) && "Only variables or fields are expected here!"); 14741 (void)FD; 14742 14743 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14744 // threadprivate variables cannot appear in a map clause. 14745 // OpenMP 4.5 [2.10.5, target update Construct] 14746 // threadprivate variables cannot appear in a from clause. 14747 if (VD && DSAS->isThreadPrivate(VD)) { 14748 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14749 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14750 << getOpenMPClauseName(CKind); 14751 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14752 continue; 14753 } 14754 14755 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14756 // A list item cannot appear in both a map clause and a data-sharing 14757 // attribute clause on the same construct. 14758 14759 // Check conflicts with other map clause expressions. We check the conflicts 14760 // with the current construct separately from the enclosing data 14761 // environment, because the restrictions are different. We only have to 14762 // check conflicts across regions for the map clauses. 14763 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14764 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14765 break; 14766 if (CKind == OMPC_map && 14767 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14768 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14769 break; 14770 14771 // OpenMP 4.5 [2.10.5, target update Construct] 14772 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14773 // If the type of a list item is a reference to a type T then the type will 14774 // be considered to be T for all purposes of this clause. 14775 auto I = llvm::find_if( 14776 CurComponents, 14777 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14778 return MC.getAssociatedDeclaration(); 14779 }); 14780 assert(I != CurComponents.end() && "Null decl on map clause."); 14781 QualType Type = 14782 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14783 14784 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14785 // A list item in a to or from clause must have a mappable type. 14786 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14787 // A list item must have a mappable type. 14788 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14789 DSAS, Type)) 14790 continue; 14791 14792 if (CKind == OMPC_map) { 14793 // target enter data 14794 // OpenMP [2.10.2, Restrictions, p. 99] 14795 // A map-type must be specified in all map clauses and must be either 14796 // to or alloc. 14797 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 14798 if (DKind == OMPD_target_enter_data && 14799 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 14800 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14801 << (IsMapTypeImplicit ? 1 : 0) 14802 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14803 << getOpenMPDirectiveName(DKind); 14804 continue; 14805 } 14806 14807 // target exit_data 14808 // OpenMP [2.10.3, Restrictions, p. 102] 14809 // A map-type must be specified in all map clauses and must be either 14810 // from, release, or delete. 14811 if (DKind == OMPD_target_exit_data && 14812 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 14813 MapType == OMPC_MAP_delete)) { 14814 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14815 << (IsMapTypeImplicit ? 1 : 0) 14816 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14817 << getOpenMPDirectiveName(DKind); 14818 continue; 14819 } 14820 14821 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14822 // A list item cannot appear in both a map clause and a data-sharing 14823 // attribute clause on the same construct 14824 // 14825 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 14826 // A list item cannot appear in both a map clause and a data-sharing 14827 // attribute clause on the same construct unless the construct is a 14828 // combined construct. 14829 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 14830 isOpenMPTargetExecutionDirective(DKind)) || 14831 DKind == OMPD_target)) { 14832 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14833 if (isOpenMPPrivate(DVar.CKind)) { 14834 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14835 << getOpenMPClauseName(DVar.CKind) 14836 << getOpenMPClauseName(OMPC_map) 14837 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 14838 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 14839 continue; 14840 } 14841 } 14842 } 14843 14844 // Try to find the associated user-defined mapper. 14845 ExprResult ER = buildUserDefinedMapperRef( 14846 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14847 Type.getCanonicalType(), UnresolvedMapper); 14848 if (ER.isInvalid()) 14849 continue; 14850 MVLI.UDMapperList.push_back(ER.get()); 14851 14852 // Save the current expression. 14853 MVLI.ProcessedVarList.push_back(RE); 14854 14855 // Store the components in the stack so that they can be used to check 14856 // against other clauses later on. 14857 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14858 /*WhereFoundClauseKind=*/OMPC_map); 14859 14860 // Save the components and declaration to create the clause. For purposes of 14861 // the clause creation, any component list that has has base 'this' uses 14862 // null as base declaration. 14863 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14864 MVLI.VarComponents.back().append(CurComponents.begin(), 14865 CurComponents.end()); 14866 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14867 : CurDeclaration); 14868 } 14869 } 14870 14871 OMPClause *Sema::ActOnOpenMPMapClause( 14872 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14873 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14874 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14875 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14876 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14877 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14878 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14879 OMPC_MAP_MODIFIER_unknown, 14880 OMPC_MAP_MODIFIER_unknown}; 14881 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14882 14883 // Process map-type-modifiers, flag errors for duplicate modifiers. 14884 unsigned Count = 0; 14885 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14886 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14887 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14888 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14889 continue; 14890 } 14891 assert(Count < OMPMapClause::NumberOfModifiers && 14892 "Modifiers exceed the allowed number of map type modifiers"); 14893 Modifiers[Count] = MapTypeModifiers[I]; 14894 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14895 ++Count; 14896 } 14897 14898 MappableVarListInfo MVLI(VarList); 14899 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14900 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14901 MapType, IsMapTypeImplicit); 14902 14903 // We need to produce a map clause even if we don't have variables so that 14904 // other diagnostics related with non-existing map clauses are accurate. 14905 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14906 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14907 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14908 MapperIdScopeSpec.getWithLocInContext(Context), 14909 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14910 } 14911 14912 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14913 TypeResult ParsedType) { 14914 assert(ParsedType.isUsable()); 14915 14916 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14917 if (ReductionType.isNull()) 14918 return QualType(); 14919 14920 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14921 // A type name in a declare reduction directive cannot be a function type, an 14922 // array type, a reference type, or a type qualified with const, volatile or 14923 // restrict. 14924 if (ReductionType.hasQualifiers()) { 14925 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14926 return QualType(); 14927 } 14928 14929 if (ReductionType->isFunctionType()) { 14930 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14931 return QualType(); 14932 } 14933 if (ReductionType->isReferenceType()) { 14934 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14935 return QualType(); 14936 } 14937 if (ReductionType->isArrayType()) { 14938 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14939 return QualType(); 14940 } 14941 return ReductionType; 14942 } 14943 14944 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14945 Scope *S, DeclContext *DC, DeclarationName Name, 14946 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14947 AccessSpecifier AS, Decl *PrevDeclInScope) { 14948 SmallVector<Decl *, 8> Decls; 14949 Decls.reserve(ReductionTypes.size()); 14950 14951 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14952 forRedeclarationInCurContext()); 14953 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14954 // A reduction-identifier may not be re-declared in the current scope for the 14955 // same type or for a type that is compatible according to the base language 14956 // rules. 14957 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14958 OMPDeclareReductionDecl *PrevDRD = nullptr; 14959 bool InCompoundScope = true; 14960 if (S != nullptr) { 14961 // Find previous declaration with the same name not referenced in other 14962 // declarations. 14963 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14964 InCompoundScope = 14965 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14966 LookupName(Lookup, S); 14967 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14968 /*AllowInlineNamespace=*/false); 14969 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14970 LookupResult::Filter Filter = Lookup.makeFilter(); 14971 while (Filter.hasNext()) { 14972 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14973 if (InCompoundScope) { 14974 auto I = UsedAsPrevious.find(PrevDecl); 14975 if (I == UsedAsPrevious.end()) 14976 UsedAsPrevious[PrevDecl] = false; 14977 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14978 UsedAsPrevious[D] = true; 14979 } 14980 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14981 PrevDecl->getLocation(); 14982 } 14983 Filter.done(); 14984 if (InCompoundScope) { 14985 for (const auto &PrevData : UsedAsPrevious) { 14986 if (!PrevData.second) { 14987 PrevDRD = PrevData.first; 14988 break; 14989 } 14990 } 14991 } 14992 } else if (PrevDeclInScope != nullptr) { 14993 auto *PrevDRDInScope = PrevDRD = 14994 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14995 do { 14996 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14997 PrevDRDInScope->getLocation(); 14998 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14999 } while (PrevDRDInScope != nullptr); 15000 } 15001 for (const auto &TyData : ReductionTypes) { 15002 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15003 bool Invalid = false; 15004 if (I != PreviousRedeclTypes.end()) { 15005 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15006 << TyData.first; 15007 Diag(I->second, diag::note_previous_definition); 15008 Invalid = true; 15009 } 15010 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15011 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15012 Name, TyData.first, PrevDRD); 15013 DC->addDecl(DRD); 15014 DRD->setAccess(AS); 15015 Decls.push_back(DRD); 15016 if (Invalid) 15017 DRD->setInvalidDecl(); 15018 else 15019 PrevDRD = DRD; 15020 } 15021 15022 return DeclGroupPtrTy::make( 15023 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15024 } 15025 15026 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15027 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15028 15029 // Enter new function scope. 15030 PushFunctionScope(); 15031 setFunctionHasBranchProtectedScope(); 15032 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15033 15034 if (S != nullptr) 15035 PushDeclContext(S, DRD); 15036 else 15037 CurContext = DRD; 15038 15039 PushExpressionEvaluationContext( 15040 ExpressionEvaluationContext::PotentiallyEvaluated); 15041 15042 QualType ReductionType = DRD->getType(); 15043 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15044 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15045 // uses semantics of argument handles by value, but it should be passed by 15046 // reference. C lang does not support references, so pass all parameters as 15047 // pointers. 15048 // Create 'T omp_in;' variable. 15049 VarDecl *OmpInParm = 15050 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15051 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15052 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15053 // uses semantics of argument handles by value, but it should be passed by 15054 // reference. C lang does not support references, so pass all parameters as 15055 // pointers. 15056 // Create 'T omp_out;' variable. 15057 VarDecl *OmpOutParm = 15058 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15059 if (S != nullptr) { 15060 PushOnScopeChains(OmpInParm, S); 15061 PushOnScopeChains(OmpOutParm, S); 15062 } else { 15063 DRD->addDecl(OmpInParm); 15064 DRD->addDecl(OmpOutParm); 15065 } 15066 Expr *InE = 15067 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15068 Expr *OutE = 15069 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15070 DRD->setCombinerData(InE, OutE); 15071 } 15072 15073 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15074 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15075 DiscardCleanupsInEvaluationContext(); 15076 PopExpressionEvaluationContext(); 15077 15078 PopDeclContext(); 15079 PopFunctionScopeInfo(); 15080 15081 if (Combiner != nullptr) 15082 DRD->setCombiner(Combiner); 15083 else 15084 DRD->setInvalidDecl(); 15085 } 15086 15087 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15088 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15089 15090 // Enter new function scope. 15091 PushFunctionScope(); 15092 setFunctionHasBranchProtectedScope(); 15093 15094 if (S != nullptr) 15095 PushDeclContext(S, DRD); 15096 else 15097 CurContext = DRD; 15098 15099 PushExpressionEvaluationContext( 15100 ExpressionEvaluationContext::PotentiallyEvaluated); 15101 15102 QualType ReductionType = DRD->getType(); 15103 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15104 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15105 // uses semantics of argument handles by value, but it should be passed by 15106 // reference. C lang does not support references, so pass all parameters as 15107 // pointers. 15108 // Create 'T omp_priv;' variable. 15109 VarDecl *OmpPrivParm = 15110 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15111 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15112 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15113 // uses semantics of argument handles by value, but it should be passed by 15114 // reference. C lang does not support references, so pass all parameters as 15115 // pointers. 15116 // Create 'T omp_orig;' variable. 15117 VarDecl *OmpOrigParm = 15118 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15119 if (S != nullptr) { 15120 PushOnScopeChains(OmpPrivParm, S); 15121 PushOnScopeChains(OmpOrigParm, S); 15122 } else { 15123 DRD->addDecl(OmpPrivParm); 15124 DRD->addDecl(OmpOrigParm); 15125 } 15126 Expr *OrigE = 15127 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15128 Expr *PrivE = 15129 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15130 DRD->setInitializerData(OrigE, PrivE); 15131 return OmpPrivParm; 15132 } 15133 15134 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15135 VarDecl *OmpPrivParm) { 15136 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15137 DiscardCleanupsInEvaluationContext(); 15138 PopExpressionEvaluationContext(); 15139 15140 PopDeclContext(); 15141 PopFunctionScopeInfo(); 15142 15143 if (Initializer != nullptr) { 15144 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15145 } else if (OmpPrivParm->hasInit()) { 15146 DRD->setInitializer(OmpPrivParm->getInit(), 15147 OmpPrivParm->isDirectInit() 15148 ? OMPDeclareReductionDecl::DirectInit 15149 : OMPDeclareReductionDecl::CopyInit); 15150 } else { 15151 DRD->setInvalidDecl(); 15152 } 15153 } 15154 15155 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15156 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15157 for (Decl *D : DeclReductions.get()) { 15158 if (IsValid) { 15159 if (S) 15160 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15161 /*AddToContext=*/false); 15162 } else { 15163 D->setInvalidDecl(); 15164 } 15165 } 15166 return DeclReductions; 15167 } 15168 15169 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15170 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15171 QualType T = TInfo->getType(); 15172 if (D.isInvalidType()) 15173 return true; 15174 15175 if (getLangOpts().CPlusPlus) { 15176 // Check that there are no default arguments (C++ only). 15177 CheckExtraCXXDefaultArguments(D); 15178 } 15179 15180 return CreateParsedType(T, TInfo); 15181 } 15182 15183 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15184 TypeResult ParsedType) { 15185 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15186 15187 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15188 assert(!MapperType.isNull() && "Expect valid mapper type"); 15189 15190 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15191 // The type must be of struct, union or class type in C and C++ 15192 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15193 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15194 return QualType(); 15195 } 15196 return MapperType; 15197 } 15198 15199 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15200 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15201 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15202 Decl *PrevDeclInScope) { 15203 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15204 forRedeclarationInCurContext()); 15205 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15206 // A mapper-identifier may not be redeclared in the current scope for the 15207 // same type or for a type that is compatible according to the base language 15208 // rules. 15209 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15210 OMPDeclareMapperDecl *PrevDMD = nullptr; 15211 bool InCompoundScope = true; 15212 if (S != nullptr) { 15213 // Find previous declaration with the same name not referenced in other 15214 // declarations. 15215 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15216 InCompoundScope = 15217 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15218 LookupName(Lookup, S); 15219 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15220 /*AllowInlineNamespace=*/false); 15221 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15222 LookupResult::Filter Filter = Lookup.makeFilter(); 15223 while (Filter.hasNext()) { 15224 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15225 if (InCompoundScope) { 15226 auto I = UsedAsPrevious.find(PrevDecl); 15227 if (I == UsedAsPrevious.end()) 15228 UsedAsPrevious[PrevDecl] = false; 15229 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15230 UsedAsPrevious[D] = true; 15231 } 15232 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15233 PrevDecl->getLocation(); 15234 } 15235 Filter.done(); 15236 if (InCompoundScope) { 15237 for (const auto &PrevData : UsedAsPrevious) { 15238 if (!PrevData.second) { 15239 PrevDMD = PrevData.first; 15240 break; 15241 } 15242 } 15243 } 15244 } else if (PrevDeclInScope) { 15245 auto *PrevDMDInScope = PrevDMD = 15246 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15247 do { 15248 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15249 PrevDMDInScope->getLocation(); 15250 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15251 } while (PrevDMDInScope != nullptr); 15252 } 15253 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15254 bool Invalid = false; 15255 if (I != PreviousRedeclTypes.end()) { 15256 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15257 << MapperType << Name; 15258 Diag(I->second, diag::note_previous_definition); 15259 Invalid = true; 15260 } 15261 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15262 MapperType, VN, PrevDMD); 15263 DC->addDecl(DMD); 15264 DMD->setAccess(AS); 15265 if (Invalid) 15266 DMD->setInvalidDecl(); 15267 15268 // Enter new function scope. 15269 PushFunctionScope(); 15270 setFunctionHasBranchProtectedScope(); 15271 15272 CurContext = DMD; 15273 15274 return DMD; 15275 } 15276 15277 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15278 Scope *S, 15279 QualType MapperType, 15280 SourceLocation StartLoc, 15281 DeclarationName VN) { 15282 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15283 if (S) 15284 PushOnScopeChains(VD, S); 15285 else 15286 DMD->addDecl(VD); 15287 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15288 DMD->setMapperVarRef(MapperVarRefExpr); 15289 } 15290 15291 Sema::DeclGroupPtrTy 15292 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15293 ArrayRef<OMPClause *> ClauseList) { 15294 PopDeclContext(); 15295 PopFunctionScopeInfo(); 15296 15297 if (D) { 15298 if (S) 15299 PushOnScopeChains(D, S, /*AddToContext=*/false); 15300 D->CreateClauses(Context, ClauseList); 15301 } 15302 15303 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15304 } 15305 15306 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15307 SourceLocation StartLoc, 15308 SourceLocation LParenLoc, 15309 SourceLocation EndLoc) { 15310 Expr *ValExpr = NumTeams; 15311 Stmt *HelperValStmt = nullptr; 15312 15313 // OpenMP [teams Constrcut, Restrictions] 15314 // The num_teams expression must evaluate to a positive integer value. 15315 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15316 /*StrictlyPositive=*/true)) 15317 return nullptr; 15318 15319 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15320 OpenMPDirectiveKind CaptureRegion = 15321 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15322 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15323 ValExpr = MakeFullExpr(ValExpr).get(); 15324 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15325 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15326 HelperValStmt = buildPreInits(Context, Captures); 15327 } 15328 15329 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15330 StartLoc, LParenLoc, EndLoc); 15331 } 15332 15333 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15334 SourceLocation StartLoc, 15335 SourceLocation LParenLoc, 15336 SourceLocation EndLoc) { 15337 Expr *ValExpr = ThreadLimit; 15338 Stmt *HelperValStmt = nullptr; 15339 15340 // OpenMP [teams Constrcut, Restrictions] 15341 // The thread_limit expression must evaluate to a positive integer value. 15342 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15343 /*StrictlyPositive=*/true)) 15344 return nullptr; 15345 15346 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15347 OpenMPDirectiveKind CaptureRegion = 15348 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15349 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15350 ValExpr = MakeFullExpr(ValExpr).get(); 15351 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15352 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15353 HelperValStmt = buildPreInits(Context, Captures); 15354 } 15355 15356 return new (Context) OMPThreadLimitClause( 15357 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15358 } 15359 15360 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15361 SourceLocation StartLoc, 15362 SourceLocation LParenLoc, 15363 SourceLocation EndLoc) { 15364 Expr *ValExpr = Priority; 15365 15366 // OpenMP [2.9.1, task Constrcut] 15367 // The priority-value is a non-negative numerical scalar expression. 15368 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 15369 /*StrictlyPositive=*/false)) 15370 return nullptr; 15371 15372 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15373 } 15374 15375 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15376 SourceLocation StartLoc, 15377 SourceLocation LParenLoc, 15378 SourceLocation EndLoc) { 15379 Expr *ValExpr = Grainsize; 15380 15381 // OpenMP [2.9.2, taskloop Constrcut] 15382 // The parameter of the grainsize clause must be a positive integer 15383 // expression. 15384 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 15385 /*StrictlyPositive=*/true)) 15386 return nullptr; 15387 15388 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15389 } 15390 15391 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15392 SourceLocation StartLoc, 15393 SourceLocation LParenLoc, 15394 SourceLocation EndLoc) { 15395 Expr *ValExpr = NumTasks; 15396 15397 // OpenMP [2.9.2, taskloop Constrcut] 15398 // The parameter of the num_tasks clause must be a positive integer 15399 // expression. 15400 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 15401 /*StrictlyPositive=*/true)) 15402 return nullptr; 15403 15404 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15405 } 15406 15407 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15408 SourceLocation LParenLoc, 15409 SourceLocation EndLoc) { 15410 // OpenMP [2.13.2, critical construct, Description] 15411 // ... where hint-expression is an integer constant expression that evaluates 15412 // to a valid lock hint. 15413 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15414 if (HintExpr.isInvalid()) 15415 return nullptr; 15416 return new (Context) 15417 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 15418 } 15419 15420 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 15421 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 15422 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 15423 SourceLocation EndLoc) { 15424 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 15425 std::string Values; 15426 Values += "'"; 15427 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 15428 Values += "'"; 15429 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 15430 << Values << getOpenMPClauseName(OMPC_dist_schedule); 15431 return nullptr; 15432 } 15433 Expr *ValExpr = ChunkSize; 15434 Stmt *HelperValStmt = nullptr; 15435 if (ChunkSize) { 15436 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 15437 !ChunkSize->isInstantiationDependent() && 15438 !ChunkSize->containsUnexpandedParameterPack()) { 15439 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 15440 ExprResult Val = 15441 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 15442 if (Val.isInvalid()) 15443 return nullptr; 15444 15445 ValExpr = Val.get(); 15446 15447 // OpenMP [2.7.1, Restrictions] 15448 // chunk_size must be a loop invariant integer expression with a positive 15449 // value. 15450 llvm::APSInt Result; 15451 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 15452 if (Result.isSigned() && !Result.isStrictlyPositive()) { 15453 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 15454 << "dist_schedule" << ChunkSize->getSourceRange(); 15455 return nullptr; 15456 } 15457 } else if (getOpenMPCaptureRegionForClause( 15458 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 15459 OMPD_unknown && 15460 !CurContext->isDependentContext()) { 15461 ValExpr = MakeFullExpr(ValExpr).get(); 15462 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15463 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15464 HelperValStmt = buildPreInits(Context, Captures); 15465 } 15466 } 15467 } 15468 15469 return new (Context) 15470 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 15471 Kind, ValExpr, HelperValStmt); 15472 } 15473 15474 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 15475 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 15476 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 15477 SourceLocation KindLoc, SourceLocation EndLoc) { 15478 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 15479 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 15480 std::string Value; 15481 SourceLocation Loc; 15482 Value += "'"; 15483 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 15484 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15485 OMPC_DEFAULTMAP_MODIFIER_tofrom); 15486 Loc = MLoc; 15487 } else { 15488 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15489 OMPC_DEFAULTMAP_scalar); 15490 Loc = KindLoc; 15491 } 15492 Value += "'"; 15493 Diag(Loc, diag::err_omp_unexpected_clause_value) 15494 << Value << getOpenMPClauseName(OMPC_defaultmap); 15495 return nullptr; 15496 } 15497 DSAStack->setDefaultDMAToFromScalar(StartLoc); 15498 15499 return new (Context) 15500 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 15501 } 15502 15503 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 15504 DeclContext *CurLexicalContext = getCurLexicalContext(); 15505 if (!CurLexicalContext->isFileContext() && 15506 !CurLexicalContext->isExternCContext() && 15507 !CurLexicalContext->isExternCXXContext() && 15508 !isa<CXXRecordDecl>(CurLexicalContext) && 15509 !isa<ClassTemplateDecl>(CurLexicalContext) && 15510 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 15511 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 15512 Diag(Loc, diag::err_omp_region_not_file_context); 15513 return false; 15514 } 15515 ++DeclareTargetNestingLevel; 15516 return true; 15517 } 15518 15519 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 15520 assert(DeclareTargetNestingLevel > 0 && 15521 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 15522 --DeclareTargetNestingLevel; 15523 } 15524 15525 NamedDecl * 15526 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 15527 const DeclarationNameInfo &Id, 15528 NamedDeclSetType &SameDirectiveDecls) { 15529 LookupResult Lookup(*this, Id, LookupOrdinaryName); 15530 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 15531 15532 if (Lookup.isAmbiguous()) 15533 return nullptr; 15534 Lookup.suppressDiagnostics(); 15535 15536 if (!Lookup.isSingleResult()) { 15537 VarOrFuncDeclFilterCCC CCC(*this); 15538 if (TypoCorrection Corrected = 15539 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 15540 CTK_ErrorRecovery)) { 15541 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 15542 << Id.getName()); 15543 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 15544 return nullptr; 15545 } 15546 15547 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 15548 return nullptr; 15549 } 15550 15551 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 15552 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 15553 !isa<FunctionTemplateDecl>(ND)) { 15554 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 15555 return nullptr; 15556 } 15557 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 15558 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 15559 return ND; 15560 } 15561 15562 void Sema::ActOnOpenMPDeclareTargetName( 15563 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 15564 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 15565 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 15566 isa<FunctionTemplateDecl>(ND)) && 15567 "Expected variable, function or function template."); 15568 15569 // Diagnose marking after use as it may lead to incorrect diagnosis and 15570 // codegen. 15571 if (LangOpts.OpenMP >= 50 && 15572 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 15573 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 15574 15575 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15576 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 15577 if (DevTy.hasValue() && *DevTy != DT) { 15578 Diag(Loc, diag::err_omp_device_type_mismatch) 15579 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 15580 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 15581 return; 15582 } 15583 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15584 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 15585 if (!Res) { 15586 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 15587 SourceRange(Loc, Loc)); 15588 ND->addAttr(A); 15589 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15590 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 15591 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 15592 } else if (*Res != MT) { 15593 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 15594 } 15595 } 15596 15597 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 15598 Sema &SemaRef, Decl *D) { 15599 if (!D || !isa<VarDecl>(D)) 15600 return; 15601 auto *VD = cast<VarDecl>(D); 15602 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15603 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15604 if (SemaRef.LangOpts.OpenMP >= 50 && 15605 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 15606 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 15607 VD->hasGlobalStorage()) { 15608 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15609 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15610 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 15611 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 15612 // If a lambda declaration and definition appears between a 15613 // declare target directive and the matching end declare target 15614 // directive, all variables that are captured by the lambda 15615 // expression must also appear in a to clause. 15616 SemaRef.Diag(VD->getLocation(), 15617 diag::err_omp_lambda_capture_in_declare_target_not_to); 15618 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 15619 << VD << 0 << SR; 15620 return; 15621 } 15622 } 15623 if (MapTy.hasValue()) 15624 return; 15625 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 15626 SemaRef.Diag(SL, diag::note_used_here) << SR; 15627 } 15628 15629 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 15630 Sema &SemaRef, DSAStackTy *Stack, 15631 ValueDecl *VD) { 15632 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 15633 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 15634 /*FullCheck=*/false); 15635 } 15636 15637 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 15638 SourceLocation IdLoc) { 15639 if (!D || D->isInvalidDecl()) 15640 return; 15641 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 15642 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 15643 if (auto *VD = dyn_cast<VarDecl>(D)) { 15644 // Only global variables can be marked as declare target. 15645 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 15646 !VD->isStaticDataMember()) 15647 return; 15648 // 2.10.6: threadprivate variable cannot appear in a declare target 15649 // directive. 15650 if (DSAStack->isThreadPrivate(VD)) { 15651 Diag(SL, diag::err_omp_threadprivate_in_target); 15652 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 15653 return; 15654 } 15655 } 15656 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 15657 D = FTD->getTemplatedDecl(); 15658 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 15659 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15660 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 15661 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 15662 Diag(IdLoc, diag::err_omp_function_in_link_clause); 15663 Diag(FD->getLocation(), diag::note_defined_here) << FD; 15664 return; 15665 } 15666 // Mark the function as must be emitted for the device. 15667 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15668 OMPDeclareTargetDeclAttr::getDeviceType(FD); 15669 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 15670 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 15671 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 15672 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 15673 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 15674 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 15675 } 15676 if (auto *VD = dyn_cast<ValueDecl>(D)) { 15677 // Problem if any with var declared with incomplete type will be reported 15678 // as normal, so no need to check it here. 15679 if ((E || !VD->getType()->isIncompleteType()) && 15680 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 15681 return; 15682 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 15683 // Checking declaration inside declare target region. 15684 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 15685 isa<FunctionTemplateDecl>(D)) { 15686 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 15687 Context, OMPDeclareTargetDeclAttr::MT_To, 15688 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 15689 D->addAttr(A); 15690 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15691 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 15692 } 15693 return; 15694 } 15695 } 15696 if (!E) 15697 return; 15698 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 15699 } 15700 15701 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15702 CXXScopeSpec &MapperIdScopeSpec, 15703 DeclarationNameInfo &MapperId, 15704 const OMPVarListLocTy &Locs, 15705 ArrayRef<Expr *> UnresolvedMappers) { 15706 MappableVarListInfo MVLI(VarList); 15707 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15708 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15709 if (MVLI.ProcessedVarList.empty()) 15710 return nullptr; 15711 15712 return OMPToClause::Create( 15713 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15714 MVLI.VarComponents, MVLI.UDMapperList, 15715 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15716 } 15717 15718 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15719 CXXScopeSpec &MapperIdScopeSpec, 15720 DeclarationNameInfo &MapperId, 15721 const OMPVarListLocTy &Locs, 15722 ArrayRef<Expr *> UnresolvedMappers) { 15723 MappableVarListInfo MVLI(VarList); 15724 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15725 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15726 if (MVLI.ProcessedVarList.empty()) 15727 return nullptr; 15728 15729 return OMPFromClause::Create( 15730 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15731 MVLI.VarComponents, MVLI.UDMapperList, 15732 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15733 } 15734 15735 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 15736 const OMPVarListLocTy &Locs) { 15737 MappableVarListInfo MVLI(VarList); 15738 SmallVector<Expr *, 8> PrivateCopies; 15739 SmallVector<Expr *, 8> Inits; 15740 15741 for (Expr *RefExpr : VarList) { 15742 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 15743 SourceLocation ELoc; 15744 SourceRange ERange; 15745 Expr *SimpleRefExpr = RefExpr; 15746 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15747 if (Res.second) { 15748 // It will be analyzed later. 15749 MVLI.ProcessedVarList.push_back(RefExpr); 15750 PrivateCopies.push_back(nullptr); 15751 Inits.push_back(nullptr); 15752 } 15753 ValueDecl *D = Res.first; 15754 if (!D) 15755 continue; 15756 15757 QualType Type = D->getType(); 15758 Type = Type.getNonReferenceType().getUnqualifiedType(); 15759 15760 auto *VD = dyn_cast<VarDecl>(D); 15761 15762 // Item should be a pointer or reference to pointer. 15763 if (!Type->isPointerType()) { 15764 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 15765 << 0 << RefExpr->getSourceRange(); 15766 continue; 15767 } 15768 15769 // Build the private variable and the expression that refers to it. 15770 auto VDPrivate = 15771 buildVarDecl(*this, ELoc, Type, D->getName(), 15772 D->hasAttrs() ? &D->getAttrs() : nullptr, 15773 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15774 if (VDPrivate->isInvalidDecl()) 15775 continue; 15776 15777 CurContext->addDecl(VDPrivate); 15778 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15779 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15780 15781 // Add temporary variable to initialize the private copy of the pointer. 15782 VarDecl *VDInit = 15783 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15784 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15785 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15786 AddInitializerToDecl(VDPrivate, 15787 DefaultLvalueConversion(VDInitRefExpr).get(), 15788 /*DirectInit=*/false); 15789 15790 // If required, build a capture to implement the privatization initialized 15791 // with the current list item value. 15792 DeclRefExpr *Ref = nullptr; 15793 if (!VD) 15794 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15795 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 15796 PrivateCopies.push_back(VDPrivateRefExpr); 15797 Inits.push_back(VDInitRefExpr); 15798 15799 // We need to add a data sharing attribute for this variable to make sure it 15800 // is correctly captured. A variable that shows up in a use_device_ptr has 15801 // similar properties of a first private variable. 15802 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15803 15804 // Create a mappable component for the list item. List items in this clause 15805 // only need a component. 15806 MVLI.VarBaseDeclarations.push_back(D); 15807 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15808 MVLI.VarComponents.back().push_back( 15809 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 15810 } 15811 15812 if (MVLI.ProcessedVarList.empty()) 15813 return nullptr; 15814 15815 return OMPUseDevicePtrClause::Create( 15816 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 15817 MVLI.VarBaseDeclarations, MVLI.VarComponents); 15818 } 15819 15820 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 15821 const OMPVarListLocTy &Locs) { 15822 MappableVarListInfo MVLI(VarList); 15823 for (Expr *RefExpr : VarList) { 15824 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 15825 SourceLocation ELoc; 15826 SourceRange ERange; 15827 Expr *SimpleRefExpr = RefExpr; 15828 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15829 if (Res.second) { 15830 // It will be analyzed later. 15831 MVLI.ProcessedVarList.push_back(RefExpr); 15832 } 15833 ValueDecl *D = Res.first; 15834 if (!D) 15835 continue; 15836 15837 QualType Type = D->getType(); 15838 // item should be a pointer or array or reference to pointer or array 15839 if (!Type.getNonReferenceType()->isPointerType() && 15840 !Type.getNonReferenceType()->isArrayType()) { 15841 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 15842 << 0 << RefExpr->getSourceRange(); 15843 continue; 15844 } 15845 15846 // Check if the declaration in the clause does not show up in any data 15847 // sharing attribute. 15848 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15849 if (isOpenMPPrivate(DVar.CKind)) { 15850 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15851 << getOpenMPClauseName(DVar.CKind) 15852 << getOpenMPClauseName(OMPC_is_device_ptr) 15853 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15854 reportOriginalDsa(*this, DSAStack, D, DVar); 15855 continue; 15856 } 15857 15858 const Expr *ConflictExpr; 15859 if (DSAStack->checkMappableExprComponentListsForDecl( 15860 D, /*CurrentRegionOnly=*/true, 15861 [&ConflictExpr]( 15862 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 15863 OpenMPClauseKind) -> bool { 15864 ConflictExpr = R.front().getAssociatedExpression(); 15865 return true; 15866 })) { 15867 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 15868 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 15869 << ConflictExpr->getSourceRange(); 15870 continue; 15871 } 15872 15873 // Store the components in the stack so that they can be used to check 15874 // against other clauses later on. 15875 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 15876 DSAStack->addMappableExpressionComponents( 15877 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 15878 15879 // Record the expression we've just processed. 15880 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 15881 15882 // Create a mappable component for the list item. List items in this clause 15883 // only need a component. We use a null declaration to signal fields in 15884 // 'this'. 15885 assert((isa<DeclRefExpr>(SimpleRefExpr) || 15886 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 15887 "Unexpected device pointer expression!"); 15888 MVLI.VarBaseDeclarations.push_back( 15889 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 15890 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15891 MVLI.VarComponents.back().push_back(MC); 15892 } 15893 15894 if (MVLI.ProcessedVarList.empty()) 15895 return nullptr; 15896 15897 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 15898 MVLI.VarBaseDeclarations, 15899 MVLI.VarComponents); 15900 } 15901 15902 OMPClause *Sema::ActOnOpenMPAllocateClause( 15903 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15904 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15905 if (Allocator) { 15906 // OpenMP [2.11.4 allocate Clause, Description] 15907 // allocator is an expression of omp_allocator_handle_t type. 15908 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15909 return nullptr; 15910 15911 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15912 if (AllocatorRes.isInvalid()) 15913 return nullptr; 15914 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15915 DSAStack->getOMPAllocatorHandleT(), 15916 Sema::AA_Initializing, 15917 /*AllowExplicit=*/true); 15918 if (AllocatorRes.isInvalid()) 15919 return nullptr; 15920 Allocator = AllocatorRes.get(); 15921 } else { 15922 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15923 // allocate clauses that appear on a target construct or on constructs in a 15924 // target region must specify an allocator expression unless a requires 15925 // directive with the dynamic_allocators clause is present in the same 15926 // compilation unit. 15927 if (LangOpts.OpenMPIsDevice && 15928 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15929 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15930 } 15931 // Analyze and build list of variables. 15932 SmallVector<Expr *, 8> Vars; 15933 for (Expr *RefExpr : VarList) { 15934 assert(RefExpr && "NULL expr in OpenMP private clause."); 15935 SourceLocation ELoc; 15936 SourceRange ERange; 15937 Expr *SimpleRefExpr = RefExpr; 15938 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15939 if (Res.second) { 15940 // It will be analyzed later. 15941 Vars.push_back(RefExpr); 15942 } 15943 ValueDecl *D = Res.first; 15944 if (!D) 15945 continue; 15946 15947 auto *VD = dyn_cast<VarDecl>(D); 15948 DeclRefExpr *Ref = nullptr; 15949 if (!VD && !CurContext->isDependentContext()) 15950 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15951 Vars.push_back((VD || CurContext->isDependentContext()) 15952 ? RefExpr->IgnoreParens() 15953 : Ref); 15954 } 15955 15956 if (Vars.empty()) 15957 return nullptr; 15958 15959 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15960 ColonLoc, EndLoc, Vars); 15961 } 15962