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/DiagnosticSema.h" 26 #include "clang/Basic/OpenMPKinds.h" 27 #include "clang/Basic/PartialDiagnostic.h" 28 #include "clang/Sema/Initialization.h" 29 #include "clang/Sema/Lookup.h" 30 #include "clang/Sema/Scope.h" 31 #include "clang/Sema/ScopeInfo.h" 32 #include "clang/Sema/SemaInternal.h" 33 #include "llvm/ADT/IndexedMap.h" 34 #include "llvm/ADT/PointerEmbeddedInt.h" 35 #include "llvm/ADT/STLExtras.h" 36 #include "llvm/Frontend/OpenMP/OMPConstants.h" 37 using namespace clang; 38 using namespace llvm::omp; 39 40 //===----------------------------------------------------------------------===// 41 // Stack of data-sharing attributes for variables 42 //===----------------------------------------------------------------------===// 43 44 static const Expr *checkMapClauseExpressionBase( 45 Sema &SemaRef, Expr *E, 46 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 47 OpenMPClauseKind CKind, bool NoDiagnose); 48 49 namespace { 50 /// Default data sharing attributes, which can be applied to directive. 51 enum DefaultDataSharingAttributes { 52 DSA_unspecified = 0, /// Data sharing attribute not specified. 53 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 54 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 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 UsedRefMapTy = 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 struct DefaultmapInfo { 119 OpenMPDefaultmapClauseModifier ImplicitBehavior = 120 OMPC_DEFAULTMAP_MODIFIER_unknown; 121 SourceLocation SLoc; 122 DefaultmapInfo() = default; 123 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 124 : ImplicitBehavior(M), SLoc(Loc) {} 125 }; 126 127 struct SharingMapTy { 128 DeclSAMapTy SharingMap; 129 DeclReductionMapTy ReductionMap; 130 UsedRefMapTy AlignedMap; 131 UsedRefMapTy NontemporalMap; 132 MappedExprComponentsTy MappedExprComponents; 133 LoopControlVariablesMapTy LCVMap; 134 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 135 SourceLocation DefaultAttrLoc; 136 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 137 OpenMPDirectiveKind Directive = OMPD_unknown; 138 DeclarationNameInfo DirectiveName; 139 Scope *CurScope = nullptr; 140 SourceLocation ConstructLoc; 141 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 142 /// get the data (loop counters etc.) about enclosing loop-based construct. 143 /// This data is required during codegen. 144 DoacrossDependMapTy DoacrossDepends; 145 /// First argument (Expr *) contains optional argument of the 146 /// 'ordered' clause, the second one is true if the regions has 'ordered' 147 /// clause, false otherwise. 148 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 149 unsigned AssociatedLoops = 1; 150 bool HasMutipleLoops = false; 151 const Decl *PossiblyLoopCounter = nullptr; 152 bool NowaitRegion = false; 153 bool CancelRegion = false; 154 bool LoopStart = false; 155 bool BodyComplete = false; 156 SourceLocation InnerTeamsRegionLoc; 157 /// Reference to the taskgroup task_reduction reference expression. 158 Expr *TaskgroupReductionRef = nullptr; 159 llvm::DenseSet<QualType> MappedClassesQualTypes; 160 SmallVector<Expr *, 4> InnerUsedAllocators; 161 /// List of globals marked as declare target link in this target region 162 /// (isOpenMPTargetExecutionDirective(Directive) == true). 163 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 164 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 165 Scope *CurScope, SourceLocation Loc) 166 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 167 ConstructLoc(Loc) {} 168 SharingMapTy() = default; 169 }; 170 171 using StackTy = SmallVector<SharingMapTy, 4>; 172 173 /// Stack of used declaration and their data-sharing attributes. 174 DeclSAMapTy Threadprivates; 175 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 176 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 177 /// true, if check for DSA must be from parent directive, false, if 178 /// from current directive. 179 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 180 Sema &SemaRef; 181 bool ForceCapturing = false; 182 /// true if all the variables in the target executable directives must be 183 /// captured by reference. 184 bool ForceCaptureByReferenceInTargetExecutable = false; 185 CriticalsWithHintsTy Criticals; 186 unsigned IgnoredStackElements = 0; 187 188 /// Iterators over the stack iterate in order from innermost to outermost 189 /// directive. 190 using const_iterator = StackTy::const_reverse_iterator; 191 const_iterator begin() const { 192 return Stack.empty() ? const_iterator() 193 : Stack.back().first.rbegin() + IgnoredStackElements; 194 } 195 const_iterator end() const { 196 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 197 } 198 using iterator = StackTy::reverse_iterator; 199 iterator begin() { 200 return Stack.empty() ? iterator() 201 : Stack.back().first.rbegin() + IgnoredStackElements; 202 } 203 iterator end() { 204 return Stack.empty() ? iterator() : Stack.back().first.rend(); 205 } 206 207 // Convenience operations to get at the elements of the stack. 208 209 bool isStackEmpty() const { 210 return Stack.empty() || 211 Stack.back().second != CurrentNonCapturingFunctionScope || 212 Stack.back().first.size() <= IgnoredStackElements; 213 } 214 size_t getStackSize() const { 215 return isStackEmpty() ? 0 216 : Stack.back().first.size() - IgnoredStackElements; 217 } 218 219 SharingMapTy *getTopOfStackOrNull() { 220 size_t Size = getStackSize(); 221 if (Size == 0) 222 return nullptr; 223 return &Stack.back().first[Size - 1]; 224 } 225 const SharingMapTy *getTopOfStackOrNull() const { 226 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 227 } 228 SharingMapTy &getTopOfStack() { 229 assert(!isStackEmpty() && "no current directive"); 230 return *getTopOfStackOrNull(); 231 } 232 const SharingMapTy &getTopOfStack() const { 233 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 234 } 235 236 SharingMapTy *getSecondOnStackOrNull() { 237 size_t Size = getStackSize(); 238 if (Size <= 1) 239 return nullptr; 240 return &Stack.back().first[Size - 2]; 241 } 242 const SharingMapTy *getSecondOnStackOrNull() const { 243 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 244 } 245 246 /// Get the stack element at a certain level (previously returned by 247 /// \c getNestingLevel). 248 /// 249 /// Note that nesting levels count from outermost to innermost, and this is 250 /// the reverse of our iteration order where new inner levels are pushed at 251 /// the front of the stack. 252 SharingMapTy &getStackElemAtLevel(unsigned Level) { 253 assert(Level < getStackSize() && "no such stack element"); 254 return Stack.back().first[Level]; 255 } 256 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 257 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 258 } 259 260 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 261 262 /// Checks if the variable is a local for OpenMP region. 263 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 264 265 /// Vector of previously declared requires directives 266 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 267 /// omp_allocator_handle_t type. 268 QualType OMPAllocatorHandleT; 269 /// Expression for the predefined allocators. 270 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 271 nullptr}; 272 /// Vector of previously encountered target directives 273 SmallVector<SourceLocation, 2> TargetLocations; 274 275 public: 276 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 277 278 /// Sets omp_allocator_handle_t type. 279 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 280 /// Gets omp_allocator_handle_t type. 281 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 282 /// Sets the given default allocator. 283 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 284 Expr *Allocator) { 285 OMPPredefinedAllocators[AllocatorKind] = Allocator; 286 } 287 /// Returns the specified default allocator. 288 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 289 return OMPPredefinedAllocators[AllocatorKind]; 290 } 291 292 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 293 OpenMPClauseKind getClauseParsingMode() const { 294 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 295 return ClauseKindMode; 296 } 297 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 298 299 bool isBodyComplete() const { 300 const SharingMapTy *Top = getTopOfStackOrNull(); 301 return Top && Top->BodyComplete; 302 } 303 void setBodyComplete() { 304 getTopOfStack().BodyComplete = true; 305 } 306 307 bool isForceVarCapturing() const { return ForceCapturing; } 308 void setForceVarCapturing(bool V) { ForceCapturing = V; } 309 310 void setForceCaptureByReferenceInTargetExecutable(bool V) { 311 ForceCaptureByReferenceInTargetExecutable = V; 312 } 313 bool isForceCaptureByReferenceInTargetExecutable() const { 314 return ForceCaptureByReferenceInTargetExecutable; 315 } 316 317 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 318 Scope *CurScope, SourceLocation Loc) { 319 assert(!IgnoredStackElements && 320 "cannot change stack while ignoring elements"); 321 if (Stack.empty() || 322 Stack.back().second != CurrentNonCapturingFunctionScope) 323 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 324 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 325 Stack.back().first.back().DefaultAttrLoc = Loc; 326 } 327 328 void pop() { 329 assert(!IgnoredStackElements && 330 "cannot change stack while ignoring elements"); 331 assert(!Stack.back().first.empty() && 332 "Data-sharing attributes stack is empty!"); 333 Stack.back().first.pop_back(); 334 } 335 336 /// RAII object to temporarily leave the scope of a directive when we want to 337 /// logically operate in its parent. 338 class ParentDirectiveScope { 339 DSAStackTy &Self; 340 bool Active; 341 public: 342 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 343 : Self(Self), Active(false) { 344 if (Activate) 345 enable(); 346 } 347 ~ParentDirectiveScope() { disable(); } 348 void disable() { 349 if (Active) { 350 --Self.IgnoredStackElements; 351 Active = false; 352 } 353 } 354 void enable() { 355 if (!Active) { 356 ++Self.IgnoredStackElements; 357 Active = true; 358 } 359 } 360 }; 361 362 /// Marks that we're started loop parsing. 363 void loopInit() { 364 assert(isOpenMPLoopDirective(getCurrentDirective()) && 365 "Expected loop-based directive."); 366 getTopOfStack().LoopStart = true; 367 } 368 /// Start capturing of the variables in the loop context. 369 void loopStart() { 370 assert(isOpenMPLoopDirective(getCurrentDirective()) && 371 "Expected loop-based directive."); 372 getTopOfStack().LoopStart = false; 373 } 374 /// true, if variables are captured, false otherwise. 375 bool isLoopStarted() const { 376 assert(isOpenMPLoopDirective(getCurrentDirective()) && 377 "Expected loop-based directive."); 378 return !getTopOfStack().LoopStart; 379 } 380 /// Marks (or clears) declaration as possibly loop counter. 381 void resetPossibleLoopCounter(const Decl *D = nullptr) { 382 getTopOfStack().PossiblyLoopCounter = 383 D ? D->getCanonicalDecl() : D; 384 } 385 /// Gets the possible loop counter decl. 386 const Decl *getPossiblyLoopCunter() const { 387 return getTopOfStack().PossiblyLoopCounter; 388 } 389 /// Start new OpenMP region stack in new non-capturing function. 390 void pushFunction() { 391 assert(!IgnoredStackElements && 392 "cannot change stack while ignoring elements"); 393 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 394 assert(!isa<CapturingScopeInfo>(CurFnScope)); 395 CurrentNonCapturingFunctionScope = CurFnScope; 396 } 397 /// Pop region stack for non-capturing function. 398 void popFunction(const FunctionScopeInfo *OldFSI) { 399 assert(!IgnoredStackElements && 400 "cannot change stack while ignoring elements"); 401 if (!Stack.empty() && Stack.back().second == OldFSI) { 402 assert(Stack.back().first.empty()); 403 Stack.pop_back(); 404 } 405 CurrentNonCapturingFunctionScope = nullptr; 406 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 407 if (!isa<CapturingScopeInfo>(FSI)) { 408 CurrentNonCapturingFunctionScope = FSI; 409 break; 410 } 411 } 412 } 413 414 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 415 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 416 } 417 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 418 getCriticalWithHint(const DeclarationNameInfo &Name) const { 419 auto I = Criticals.find(Name.getAsString()); 420 if (I != Criticals.end()) 421 return I->second; 422 return std::make_pair(nullptr, llvm::APSInt()); 423 } 424 /// If 'aligned' declaration for given variable \a D was not seen yet, 425 /// add it and return NULL; otherwise return previous occurrence's expression 426 /// for diagnostics. 427 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 428 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 429 /// add it and return NULL; otherwise return previous occurrence's expression 430 /// for diagnostics. 431 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 432 433 /// Register specified variable as loop control variable. 434 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 435 /// Check if the specified variable is a loop control variable for 436 /// current region. 437 /// \return The index of the loop control variable in the list of associated 438 /// for-loops (from outer to inner). 439 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 440 /// Check if the specified variable is a loop control variable for 441 /// parent region. 442 /// \return The index of the loop control variable in the list of associated 443 /// for-loops (from outer to inner). 444 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 445 /// Get the loop control variable for the I-th loop (or nullptr) in 446 /// parent directive. 447 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 448 449 /// Adds explicit data sharing attribute to the specified declaration. 450 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 451 DeclRefExpr *PrivateCopy = nullptr); 452 453 /// Adds additional information for the reduction items with the reduction id 454 /// represented as an operator. 455 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 456 BinaryOperatorKind BOK); 457 /// Adds additional information for the reduction items with the reduction id 458 /// represented as reduction identifier. 459 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 460 const Expr *ReductionRef); 461 /// Returns the location and reduction operation from the innermost parent 462 /// region for the given \p D. 463 const DSAVarData 464 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 465 BinaryOperatorKind &BOK, 466 Expr *&TaskgroupDescriptor) const; 467 /// Returns the location and reduction operation from the innermost parent 468 /// region for the given \p D. 469 const DSAVarData 470 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 471 const Expr *&ReductionRef, 472 Expr *&TaskgroupDescriptor) const; 473 /// Return reduction reference expression for the current taskgroup. 474 Expr *getTaskgroupReductionRef() const { 475 assert(getTopOfStack().Directive == OMPD_taskgroup && 476 "taskgroup reference expression requested for non taskgroup " 477 "directive."); 478 return getTopOfStack().TaskgroupReductionRef; 479 } 480 /// Checks if the given \p VD declaration is actually a taskgroup reduction 481 /// descriptor variable at the \p Level of OpenMP regions. 482 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 483 return getStackElemAtLevel(Level).TaskgroupReductionRef && 484 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 485 ->getDecl() == VD; 486 } 487 488 /// Returns data sharing attributes from top of the stack for the 489 /// specified declaration. 490 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 491 /// Returns data-sharing attributes for the specified declaration. 492 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 493 /// Checks if the specified variables has data-sharing attributes which 494 /// match specified \a CPred predicate in any directive which matches \a DPred 495 /// predicate. 496 const DSAVarData 497 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 498 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 499 bool FromParent) const; 500 /// Checks if the specified variables has data-sharing attributes which 501 /// match specified \a CPred predicate in any innermost directive which 502 /// matches \a DPred predicate. 503 const DSAVarData 504 hasInnermostDSA(ValueDecl *D, 505 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 506 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 507 bool FromParent) const; 508 /// Checks if the specified variables has explicit data-sharing 509 /// attributes which match specified \a CPred predicate at the specified 510 /// OpenMP region. 511 bool hasExplicitDSA(const ValueDecl *D, 512 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 513 unsigned Level, bool NotLastprivate = false) const; 514 515 /// Returns true if the directive at level \Level matches in the 516 /// specified \a DPred predicate. 517 bool hasExplicitDirective( 518 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 519 unsigned Level) const; 520 521 /// Finds a directive which matches specified \a DPred predicate. 522 bool hasDirective( 523 const llvm::function_ref<bool( 524 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 525 DPred, 526 bool FromParent) const; 527 528 /// Returns currently analyzed directive. 529 OpenMPDirectiveKind getCurrentDirective() const { 530 const SharingMapTy *Top = getTopOfStackOrNull(); 531 return Top ? Top->Directive : OMPD_unknown; 532 } 533 /// Returns directive kind at specified level. 534 OpenMPDirectiveKind getDirective(unsigned Level) const { 535 assert(!isStackEmpty() && "No directive at specified level."); 536 return getStackElemAtLevel(Level).Directive; 537 } 538 /// Returns the capture region at the specified level. 539 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 540 unsigned OpenMPCaptureLevel) const { 541 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 542 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 543 return CaptureRegions[OpenMPCaptureLevel]; 544 } 545 /// Returns parent directive. 546 OpenMPDirectiveKind getParentDirective() const { 547 const SharingMapTy *Parent = getSecondOnStackOrNull(); 548 return Parent ? Parent->Directive : OMPD_unknown; 549 } 550 551 /// Add requires decl to internal vector 552 void addRequiresDecl(OMPRequiresDecl *RD) { 553 RequiresDecls.push_back(RD); 554 } 555 556 /// Checks if the defined 'requires' directive has specified type of clause. 557 template <typename ClauseType> 558 bool hasRequiresDeclWithClause() { 559 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 560 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 561 return isa<ClauseType>(C); 562 }); 563 }); 564 } 565 566 /// Checks for a duplicate clause amongst previously declared requires 567 /// directives 568 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 569 bool IsDuplicate = false; 570 for (OMPClause *CNew : ClauseList) { 571 for (const OMPRequiresDecl *D : RequiresDecls) { 572 for (const OMPClause *CPrev : D->clauselists()) { 573 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 574 SemaRef.Diag(CNew->getBeginLoc(), 575 diag::err_omp_requires_clause_redeclaration) 576 << getOpenMPClauseName(CNew->getClauseKind()); 577 SemaRef.Diag(CPrev->getBeginLoc(), 578 diag::note_omp_requires_previous_clause) 579 << getOpenMPClauseName(CPrev->getClauseKind()); 580 IsDuplicate = true; 581 } 582 } 583 } 584 } 585 return IsDuplicate; 586 } 587 588 /// Add location of previously encountered target to internal vector 589 void addTargetDirLocation(SourceLocation LocStart) { 590 TargetLocations.push_back(LocStart); 591 } 592 593 // Return previously encountered target region locations. 594 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 595 return TargetLocations; 596 } 597 598 /// Set default data sharing attribute to none. 599 void setDefaultDSANone(SourceLocation Loc) { 600 getTopOfStack().DefaultAttr = DSA_none; 601 getTopOfStack().DefaultAttrLoc = Loc; 602 } 603 /// Set default data sharing attribute to shared. 604 void setDefaultDSAShared(SourceLocation Loc) { 605 getTopOfStack().DefaultAttr = DSA_shared; 606 getTopOfStack().DefaultAttrLoc = Loc; 607 } 608 /// Set default data mapping attribute to Modifier:Kind 609 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 610 OpenMPDefaultmapClauseKind Kind, 611 SourceLocation Loc) { 612 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 613 DMI.ImplicitBehavior = M; 614 DMI.SLoc = Loc; 615 } 616 /// Check whether the implicit-behavior has been set in defaultmap 617 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 618 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 619 OMPC_DEFAULTMAP_MODIFIER_unknown; 620 } 621 622 DefaultDataSharingAttributes getDefaultDSA() const { 623 return isStackEmpty() ? DSA_unspecified 624 : getTopOfStack().DefaultAttr; 625 } 626 SourceLocation getDefaultDSALocation() const { 627 return isStackEmpty() ? SourceLocation() 628 : getTopOfStack().DefaultAttrLoc; 629 } 630 OpenMPDefaultmapClauseModifier 631 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 632 return isStackEmpty() 633 ? OMPC_DEFAULTMAP_MODIFIER_unknown 634 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 635 } 636 OpenMPDefaultmapClauseModifier 637 getDefaultmapModifierAtLevel(unsigned Level, 638 OpenMPDefaultmapClauseKind Kind) const { 639 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 640 } 641 bool isDefaultmapCapturedByRef(unsigned Level, 642 OpenMPDefaultmapClauseKind Kind) const { 643 OpenMPDefaultmapClauseModifier M = 644 getDefaultmapModifierAtLevel(Level, Kind); 645 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 646 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 647 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 648 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 649 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 650 } 651 return true; 652 } 653 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 654 OpenMPDefaultmapClauseKind Kind) { 655 switch (Kind) { 656 case OMPC_DEFAULTMAP_scalar: 657 case OMPC_DEFAULTMAP_pointer: 658 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 659 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 660 (M == OMPC_DEFAULTMAP_MODIFIER_default); 661 case OMPC_DEFAULTMAP_aggregate: 662 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 663 default: 664 break; 665 } 666 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 667 } 668 bool mustBeFirstprivateAtLevel(unsigned Level, 669 OpenMPDefaultmapClauseKind Kind) const { 670 OpenMPDefaultmapClauseModifier M = 671 getDefaultmapModifierAtLevel(Level, Kind); 672 return mustBeFirstprivateBase(M, Kind); 673 } 674 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 675 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 676 return mustBeFirstprivateBase(M, Kind); 677 } 678 679 /// Checks if the specified variable is a threadprivate. 680 bool isThreadPrivate(VarDecl *D) { 681 const DSAVarData DVar = getTopDSA(D, false); 682 return isOpenMPThreadPrivate(DVar.CKind); 683 } 684 685 /// Marks current region as ordered (it has an 'ordered' clause). 686 void setOrderedRegion(bool IsOrdered, const Expr *Param, 687 OMPOrderedClause *Clause) { 688 if (IsOrdered) 689 getTopOfStack().OrderedRegion.emplace(Param, Clause); 690 else 691 getTopOfStack().OrderedRegion.reset(); 692 } 693 /// Returns true, if region is ordered (has associated 'ordered' clause), 694 /// false - otherwise. 695 bool isOrderedRegion() const { 696 if (const SharingMapTy *Top = getTopOfStackOrNull()) 697 return Top->OrderedRegion.hasValue(); 698 return false; 699 } 700 /// Returns optional parameter for the ordered region. 701 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 702 if (const SharingMapTy *Top = getTopOfStackOrNull()) 703 if (Top->OrderedRegion.hasValue()) 704 return Top->OrderedRegion.getValue(); 705 return std::make_pair(nullptr, nullptr); 706 } 707 /// Returns true, if parent region is ordered (has associated 708 /// 'ordered' clause), false - otherwise. 709 bool isParentOrderedRegion() const { 710 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 711 return Parent->OrderedRegion.hasValue(); 712 return false; 713 } 714 /// Returns optional parameter for the ordered region. 715 std::pair<const Expr *, OMPOrderedClause *> 716 getParentOrderedRegionParam() const { 717 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 718 if (Parent->OrderedRegion.hasValue()) 719 return Parent->OrderedRegion.getValue(); 720 return std::make_pair(nullptr, nullptr); 721 } 722 /// Marks current region as nowait (it has a 'nowait' clause). 723 void setNowaitRegion(bool IsNowait = true) { 724 getTopOfStack().NowaitRegion = IsNowait; 725 } 726 /// Returns true, if parent region is nowait (has associated 727 /// 'nowait' clause), false - otherwise. 728 bool isParentNowaitRegion() const { 729 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 730 return Parent->NowaitRegion; 731 return false; 732 } 733 /// Marks parent region as cancel region. 734 void setParentCancelRegion(bool Cancel = true) { 735 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 736 Parent->CancelRegion |= Cancel; 737 } 738 /// Return true if current region has inner cancel construct. 739 bool isCancelRegion() const { 740 const SharingMapTy *Top = getTopOfStackOrNull(); 741 return Top ? Top->CancelRegion : false; 742 } 743 744 /// Set collapse value for the region. 745 void setAssociatedLoops(unsigned Val) { 746 getTopOfStack().AssociatedLoops = Val; 747 if (Val > 1) 748 getTopOfStack().HasMutipleLoops = true; 749 } 750 /// Return collapse value for region. 751 unsigned getAssociatedLoops() const { 752 const SharingMapTy *Top = getTopOfStackOrNull(); 753 return Top ? Top->AssociatedLoops : 0; 754 } 755 /// Returns true if the construct is associated with multiple loops. 756 bool hasMutipleLoops() const { 757 const SharingMapTy *Top = getTopOfStackOrNull(); 758 return Top ? Top->HasMutipleLoops : false; 759 } 760 761 /// Marks current target region as one with closely nested teams 762 /// region. 763 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 764 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 765 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 766 } 767 /// Returns true, if current region has closely nested teams region. 768 bool hasInnerTeamsRegion() const { 769 return getInnerTeamsRegionLoc().isValid(); 770 } 771 /// Returns location of the nested teams region (if any). 772 SourceLocation getInnerTeamsRegionLoc() const { 773 const SharingMapTy *Top = getTopOfStackOrNull(); 774 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 775 } 776 777 Scope *getCurScope() const { 778 const SharingMapTy *Top = getTopOfStackOrNull(); 779 return Top ? Top->CurScope : nullptr; 780 } 781 SourceLocation getConstructLoc() const { 782 const SharingMapTy *Top = getTopOfStackOrNull(); 783 return Top ? Top->ConstructLoc : SourceLocation(); 784 } 785 786 /// Do the check specified in \a Check to all component lists and return true 787 /// if any issue is found. 788 bool checkMappableExprComponentListsForDecl( 789 const ValueDecl *VD, bool CurrentRegionOnly, 790 const llvm::function_ref< 791 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 792 OpenMPClauseKind)> 793 Check) const { 794 if (isStackEmpty()) 795 return false; 796 auto SI = begin(); 797 auto SE = end(); 798 799 if (SI == SE) 800 return false; 801 802 if (CurrentRegionOnly) 803 SE = std::next(SI); 804 else 805 std::advance(SI, 1); 806 807 for (; SI != SE; ++SI) { 808 auto MI = SI->MappedExprComponents.find(VD); 809 if (MI != SI->MappedExprComponents.end()) 810 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 811 MI->second.Components) 812 if (Check(L, MI->second.Kind)) 813 return true; 814 } 815 return false; 816 } 817 818 /// Do the check specified in \a Check to all component lists at a given level 819 /// and return true if any issue is found. 820 bool checkMappableExprComponentListsForDeclAtLevel( 821 const ValueDecl *VD, unsigned Level, 822 const llvm::function_ref< 823 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 824 OpenMPClauseKind)> 825 Check) const { 826 if (getStackSize() <= Level) 827 return false; 828 829 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 830 auto MI = StackElem.MappedExprComponents.find(VD); 831 if (MI != StackElem.MappedExprComponents.end()) 832 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 833 MI->second.Components) 834 if (Check(L, MI->second.Kind)) 835 return true; 836 return false; 837 } 838 839 /// Create a new mappable expression component list associated with a given 840 /// declaration and initialize it with the provided list of components. 841 void addMappableExpressionComponents( 842 const ValueDecl *VD, 843 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 844 OpenMPClauseKind WhereFoundClauseKind) { 845 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 846 // Create new entry and append the new components there. 847 MEC.Components.resize(MEC.Components.size() + 1); 848 MEC.Components.back().append(Components.begin(), Components.end()); 849 MEC.Kind = WhereFoundClauseKind; 850 } 851 852 unsigned getNestingLevel() const { 853 assert(!isStackEmpty()); 854 return getStackSize() - 1; 855 } 856 void addDoacrossDependClause(OMPDependClause *C, 857 const OperatorOffsetTy &OpsOffs) { 858 SharingMapTy *Parent = getSecondOnStackOrNull(); 859 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 860 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 861 } 862 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 863 getDoacrossDependClauses() const { 864 const SharingMapTy &StackElem = getTopOfStack(); 865 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 866 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 867 return llvm::make_range(Ref.begin(), Ref.end()); 868 } 869 return llvm::make_range(StackElem.DoacrossDepends.end(), 870 StackElem.DoacrossDepends.end()); 871 } 872 873 // Store types of classes which have been explicitly mapped 874 void addMappedClassesQualTypes(QualType QT) { 875 SharingMapTy &StackElem = getTopOfStack(); 876 StackElem.MappedClassesQualTypes.insert(QT); 877 } 878 879 // Return set of mapped classes types 880 bool isClassPreviouslyMapped(QualType QT) const { 881 const SharingMapTy &StackElem = getTopOfStack(); 882 return StackElem.MappedClassesQualTypes.count(QT) != 0; 883 } 884 885 /// Adds global declare target to the parent target region. 886 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 887 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 888 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 889 "Expected declare target link global."); 890 for (auto &Elem : *this) { 891 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 892 Elem.DeclareTargetLinkVarDecls.push_back(E); 893 return; 894 } 895 } 896 } 897 898 /// Returns the list of globals with declare target link if current directive 899 /// is target. 900 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 901 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 902 "Expected target executable directive."); 903 return getTopOfStack().DeclareTargetLinkVarDecls; 904 } 905 906 /// Adds list of allocators expressions. 907 void addInnerAllocatorExpr(Expr *E) { 908 getTopOfStack().InnerUsedAllocators.push_back(E); 909 } 910 /// Return list of used allocators. 911 ArrayRef<Expr *> getInnerAllocators() const { 912 return getTopOfStack().InnerUsedAllocators; 913 } 914 }; 915 916 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 917 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 918 } 919 920 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 921 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 922 DKind == OMPD_unknown; 923 } 924 925 } // namespace 926 927 static const Expr *getExprAsWritten(const Expr *E) { 928 if (const auto *FE = dyn_cast<FullExpr>(E)) 929 E = FE->getSubExpr(); 930 931 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 932 E = MTE->getSubExpr(); 933 934 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 935 E = Binder->getSubExpr(); 936 937 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 938 E = ICE->getSubExprAsWritten(); 939 return E->IgnoreParens(); 940 } 941 942 static Expr *getExprAsWritten(Expr *E) { 943 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 944 } 945 946 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 947 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 948 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 949 D = ME->getMemberDecl(); 950 const auto *VD = dyn_cast<VarDecl>(D); 951 const auto *FD = dyn_cast<FieldDecl>(D); 952 if (VD != nullptr) { 953 VD = VD->getCanonicalDecl(); 954 D = VD; 955 } else { 956 assert(FD); 957 FD = FD->getCanonicalDecl(); 958 D = FD; 959 } 960 return D; 961 } 962 963 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 964 return const_cast<ValueDecl *>( 965 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 966 } 967 968 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 969 ValueDecl *D) const { 970 D = getCanonicalDecl(D); 971 auto *VD = dyn_cast<VarDecl>(D); 972 const auto *FD = dyn_cast<FieldDecl>(D); 973 DSAVarData DVar; 974 if (Iter == end()) { 975 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 976 // in a region but not in construct] 977 // File-scope or namespace-scope variables referenced in called routines 978 // in the region are shared unless they appear in a threadprivate 979 // directive. 980 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 981 DVar.CKind = OMPC_shared; 982 983 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 984 // in a region but not in construct] 985 // Variables with static storage duration that are declared in called 986 // routines in the region are shared. 987 if (VD && VD->hasGlobalStorage()) 988 DVar.CKind = OMPC_shared; 989 990 // Non-static data members are shared by default. 991 if (FD) 992 DVar.CKind = OMPC_shared; 993 994 return DVar; 995 } 996 997 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 998 // in a Construct, C/C++, predetermined, p.1] 999 // Variables with automatic storage duration that are declared in a scope 1000 // inside the construct are private. 1001 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1002 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1003 DVar.CKind = OMPC_private; 1004 return DVar; 1005 } 1006 1007 DVar.DKind = Iter->Directive; 1008 // Explicitly specified attributes and local variables with predetermined 1009 // attributes. 1010 if (Iter->SharingMap.count(D)) { 1011 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1012 DVar.RefExpr = Data.RefExpr.getPointer(); 1013 DVar.PrivateCopy = Data.PrivateCopy; 1014 DVar.CKind = Data.Attributes; 1015 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1016 return DVar; 1017 } 1018 1019 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1020 // in a Construct, C/C++, implicitly determined, p.1] 1021 // In a parallel or task construct, the data-sharing attributes of these 1022 // variables are determined by the default clause, if present. 1023 switch (Iter->DefaultAttr) { 1024 case DSA_shared: 1025 DVar.CKind = OMPC_shared; 1026 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1027 return DVar; 1028 case DSA_none: 1029 return DVar; 1030 case DSA_unspecified: 1031 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1032 // in a Construct, implicitly determined, p.2] 1033 // In a parallel construct, if no default clause is present, these 1034 // variables are shared. 1035 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1036 if ((isOpenMPParallelDirective(DVar.DKind) && 1037 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1038 isOpenMPTeamsDirective(DVar.DKind)) { 1039 DVar.CKind = OMPC_shared; 1040 return DVar; 1041 } 1042 1043 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1044 // in a Construct, implicitly determined, p.4] 1045 // In a task construct, if no default clause is present, a variable that in 1046 // the enclosing context is determined to be shared by all implicit tasks 1047 // bound to the current team is shared. 1048 if (isOpenMPTaskingDirective(DVar.DKind)) { 1049 DSAVarData DVarTemp; 1050 const_iterator I = Iter, E = end(); 1051 do { 1052 ++I; 1053 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1054 // Referenced in a Construct, implicitly determined, p.6] 1055 // In a task construct, if no default clause is present, a variable 1056 // whose data-sharing attribute is not determined by the rules above is 1057 // firstprivate. 1058 DVarTemp = getDSA(I, D); 1059 if (DVarTemp.CKind != OMPC_shared) { 1060 DVar.RefExpr = nullptr; 1061 DVar.CKind = OMPC_firstprivate; 1062 return DVar; 1063 } 1064 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1065 DVar.CKind = 1066 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1067 return DVar; 1068 } 1069 } 1070 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1071 // in a Construct, implicitly determined, p.3] 1072 // For constructs other than task, if no default clause is present, these 1073 // variables inherit their data-sharing attributes from the enclosing 1074 // context. 1075 return getDSA(++Iter, D); 1076 } 1077 1078 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1079 const Expr *NewDE) { 1080 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1081 D = getCanonicalDecl(D); 1082 SharingMapTy &StackElem = getTopOfStack(); 1083 auto It = StackElem.AlignedMap.find(D); 1084 if (It == StackElem.AlignedMap.end()) { 1085 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1086 StackElem.AlignedMap[D] = NewDE; 1087 return nullptr; 1088 } 1089 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1090 return It->second; 1091 } 1092 1093 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1094 const Expr *NewDE) { 1095 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1096 D = getCanonicalDecl(D); 1097 SharingMapTy &StackElem = getTopOfStack(); 1098 auto It = StackElem.NontemporalMap.find(D); 1099 if (It == StackElem.NontemporalMap.end()) { 1100 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1101 StackElem.NontemporalMap[D] = NewDE; 1102 return nullptr; 1103 } 1104 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1105 return It->second; 1106 } 1107 1108 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1109 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1110 D = getCanonicalDecl(D); 1111 SharingMapTy &StackElem = getTopOfStack(); 1112 StackElem.LCVMap.try_emplace( 1113 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1114 } 1115 1116 const DSAStackTy::LCDeclInfo 1117 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1118 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1119 D = getCanonicalDecl(D); 1120 const SharingMapTy &StackElem = getTopOfStack(); 1121 auto It = StackElem.LCVMap.find(D); 1122 if (It != StackElem.LCVMap.end()) 1123 return It->second; 1124 return {0, nullptr}; 1125 } 1126 1127 const DSAStackTy::LCDeclInfo 1128 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1129 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1130 assert(Parent && "Data-sharing attributes stack is empty"); 1131 D = getCanonicalDecl(D); 1132 auto It = Parent->LCVMap.find(D); 1133 if (It != Parent->LCVMap.end()) 1134 return It->second; 1135 return {0, nullptr}; 1136 } 1137 1138 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1139 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1140 assert(Parent && "Data-sharing attributes stack is empty"); 1141 if (Parent->LCVMap.size() < I) 1142 return nullptr; 1143 for (const auto &Pair : Parent->LCVMap) 1144 if (Pair.second.first == I) 1145 return Pair.first; 1146 return nullptr; 1147 } 1148 1149 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1150 DeclRefExpr *PrivateCopy) { 1151 D = getCanonicalDecl(D); 1152 if (A == OMPC_threadprivate) { 1153 DSAInfo &Data = Threadprivates[D]; 1154 Data.Attributes = A; 1155 Data.RefExpr.setPointer(E); 1156 Data.PrivateCopy = nullptr; 1157 } else { 1158 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1159 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1160 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1161 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1162 (isLoopControlVariable(D).first && A == OMPC_private)); 1163 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1164 Data.RefExpr.setInt(/*IntVal=*/true); 1165 return; 1166 } 1167 const bool IsLastprivate = 1168 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1169 Data.Attributes = A; 1170 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1171 Data.PrivateCopy = PrivateCopy; 1172 if (PrivateCopy) { 1173 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1174 Data.Attributes = A; 1175 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1176 Data.PrivateCopy = nullptr; 1177 } 1178 } 1179 } 1180 1181 /// Build a variable declaration for OpenMP loop iteration variable. 1182 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1183 StringRef Name, const AttrVec *Attrs = nullptr, 1184 DeclRefExpr *OrigRef = nullptr) { 1185 DeclContext *DC = SemaRef.CurContext; 1186 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1187 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1188 auto *Decl = 1189 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1190 if (Attrs) { 1191 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1192 I != E; ++I) 1193 Decl->addAttr(*I); 1194 } 1195 Decl->setImplicit(); 1196 if (OrigRef) { 1197 Decl->addAttr( 1198 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1199 } 1200 return Decl; 1201 } 1202 1203 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1204 SourceLocation Loc, 1205 bool RefersToCapture = false) { 1206 D->setReferenced(); 1207 D->markUsed(S.Context); 1208 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1209 SourceLocation(), D, RefersToCapture, Loc, Ty, 1210 VK_LValue); 1211 } 1212 1213 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1214 BinaryOperatorKind BOK) { 1215 D = getCanonicalDecl(D); 1216 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1217 assert( 1218 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1219 "Additional reduction info may be specified only for reduction items."); 1220 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1221 assert(ReductionData.ReductionRange.isInvalid() && 1222 getTopOfStack().Directive == OMPD_taskgroup && 1223 "Additional reduction info may be specified only once for reduction " 1224 "items."); 1225 ReductionData.set(BOK, SR); 1226 Expr *&TaskgroupReductionRef = 1227 getTopOfStack().TaskgroupReductionRef; 1228 if (!TaskgroupReductionRef) { 1229 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1230 SemaRef.Context.VoidPtrTy, ".task_red."); 1231 TaskgroupReductionRef = 1232 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1233 } 1234 } 1235 1236 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1237 const Expr *ReductionRef) { 1238 D = getCanonicalDecl(D); 1239 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1240 assert( 1241 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1242 "Additional reduction info may be specified only for reduction items."); 1243 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1244 assert(ReductionData.ReductionRange.isInvalid() && 1245 getTopOfStack().Directive == OMPD_taskgroup && 1246 "Additional reduction info may be specified only once for reduction " 1247 "items."); 1248 ReductionData.set(ReductionRef, SR); 1249 Expr *&TaskgroupReductionRef = 1250 getTopOfStack().TaskgroupReductionRef; 1251 if (!TaskgroupReductionRef) { 1252 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1253 SemaRef.Context.VoidPtrTy, ".task_red."); 1254 TaskgroupReductionRef = 1255 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1256 } 1257 } 1258 1259 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1260 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1261 Expr *&TaskgroupDescriptor) const { 1262 D = getCanonicalDecl(D); 1263 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1264 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1265 const DSAInfo &Data = I->SharingMap.lookup(D); 1266 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1267 continue; 1268 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1269 if (!ReductionData.ReductionOp || 1270 ReductionData.ReductionOp.is<const Expr *>()) 1271 return DSAVarData(); 1272 SR = ReductionData.ReductionRange; 1273 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1274 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1275 "expression for the descriptor is not " 1276 "set."); 1277 TaskgroupDescriptor = I->TaskgroupReductionRef; 1278 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1279 Data.PrivateCopy, I->DefaultAttrLoc); 1280 } 1281 return DSAVarData(); 1282 } 1283 1284 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1285 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1286 Expr *&TaskgroupDescriptor) const { 1287 D = getCanonicalDecl(D); 1288 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1289 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1290 const DSAInfo &Data = I->SharingMap.lookup(D); 1291 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1292 continue; 1293 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1294 if (!ReductionData.ReductionOp || 1295 !ReductionData.ReductionOp.is<const Expr *>()) 1296 return DSAVarData(); 1297 SR = ReductionData.ReductionRange; 1298 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1299 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1300 "expression for the descriptor is not " 1301 "set."); 1302 TaskgroupDescriptor = I->TaskgroupReductionRef; 1303 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1304 Data.PrivateCopy, I->DefaultAttrLoc); 1305 } 1306 return DSAVarData(); 1307 } 1308 1309 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1310 D = D->getCanonicalDecl(); 1311 for (const_iterator E = end(); I != E; ++I) { 1312 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1313 isOpenMPTargetExecutionDirective(I->Directive)) { 1314 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1315 Scope *CurScope = getCurScope(); 1316 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1317 CurScope = CurScope->getParent(); 1318 return CurScope != TopScope; 1319 } 1320 } 1321 return false; 1322 } 1323 1324 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1325 bool AcceptIfMutable = true, 1326 bool *IsClassType = nullptr) { 1327 ASTContext &Context = SemaRef.getASTContext(); 1328 Type = Type.getNonReferenceType().getCanonicalType(); 1329 bool IsConstant = Type.isConstant(Context); 1330 Type = Context.getBaseElementType(Type); 1331 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1332 ? Type->getAsCXXRecordDecl() 1333 : nullptr; 1334 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1335 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1336 RD = CTD->getTemplatedDecl(); 1337 if (IsClassType) 1338 *IsClassType = RD; 1339 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1340 RD->hasDefinition() && RD->hasMutableFields()); 1341 } 1342 1343 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1344 QualType Type, OpenMPClauseKind CKind, 1345 SourceLocation ELoc, 1346 bool AcceptIfMutable = true, 1347 bool ListItemNotVar = false) { 1348 ASTContext &Context = SemaRef.getASTContext(); 1349 bool IsClassType; 1350 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1351 unsigned Diag = ListItemNotVar 1352 ? diag::err_omp_const_list_item 1353 : IsClassType ? diag::err_omp_const_not_mutable_variable 1354 : diag::err_omp_const_variable; 1355 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1356 if (!ListItemNotVar && D) { 1357 const VarDecl *VD = dyn_cast<VarDecl>(D); 1358 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1359 VarDecl::DeclarationOnly; 1360 SemaRef.Diag(D->getLocation(), 1361 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1362 << D; 1363 } 1364 return true; 1365 } 1366 return false; 1367 } 1368 1369 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1370 bool FromParent) { 1371 D = getCanonicalDecl(D); 1372 DSAVarData DVar; 1373 1374 auto *VD = dyn_cast<VarDecl>(D); 1375 auto TI = Threadprivates.find(D); 1376 if (TI != Threadprivates.end()) { 1377 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1378 DVar.CKind = OMPC_threadprivate; 1379 return DVar; 1380 } 1381 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1382 DVar.RefExpr = buildDeclRefExpr( 1383 SemaRef, VD, D->getType().getNonReferenceType(), 1384 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1385 DVar.CKind = OMPC_threadprivate; 1386 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1387 return DVar; 1388 } 1389 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1390 // in a Construct, C/C++, predetermined, p.1] 1391 // Variables appearing in threadprivate directives are threadprivate. 1392 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1393 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1394 SemaRef.getLangOpts().OpenMPUseTLS && 1395 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1396 (VD && VD->getStorageClass() == SC_Register && 1397 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1398 DVar.RefExpr = buildDeclRefExpr( 1399 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1400 DVar.CKind = OMPC_threadprivate; 1401 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1402 return DVar; 1403 } 1404 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1405 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1406 !isLoopControlVariable(D).first) { 1407 const_iterator IterTarget = 1408 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1409 return isOpenMPTargetExecutionDirective(Data.Directive); 1410 }); 1411 if (IterTarget != end()) { 1412 const_iterator ParentIterTarget = IterTarget + 1; 1413 for (const_iterator Iter = begin(); 1414 Iter != ParentIterTarget; ++Iter) { 1415 if (isOpenMPLocal(VD, Iter)) { 1416 DVar.RefExpr = 1417 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1418 D->getLocation()); 1419 DVar.CKind = OMPC_threadprivate; 1420 return DVar; 1421 } 1422 } 1423 if (!isClauseParsingMode() || IterTarget != begin()) { 1424 auto DSAIter = IterTarget->SharingMap.find(D); 1425 if (DSAIter != IterTarget->SharingMap.end() && 1426 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1427 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1428 DVar.CKind = OMPC_threadprivate; 1429 return DVar; 1430 } 1431 const_iterator End = end(); 1432 if (!SemaRef.isOpenMPCapturedByRef( 1433 D, std::distance(ParentIterTarget, End), 1434 /*OpenMPCaptureLevel=*/0)) { 1435 DVar.RefExpr = 1436 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1437 IterTarget->ConstructLoc); 1438 DVar.CKind = OMPC_threadprivate; 1439 return DVar; 1440 } 1441 } 1442 } 1443 } 1444 1445 if (isStackEmpty()) 1446 // Not in OpenMP execution region and top scope was already checked. 1447 return DVar; 1448 1449 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1450 // in a Construct, C/C++, predetermined, p.4] 1451 // Static data members are shared. 1452 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1453 // in a Construct, C/C++, predetermined, p.7] 1454 // Variables with static storage duration that are declared in a scope 1455 // inside the construct are shared. 1456 if (VD && VD->isStaticDataMember()) { 1457 // Check for explicitly specified attributes. 1458 const_iterator I = begin(); 1459 const_iterator EndI = end(); 1460 if (FromParent && I != EndI) 1461 ++I; 1462 auto It = I->SharingMap.find(D); 1463 if (It != I->SharingMap.end()) { 1464 const DSAInfo &Data = It->getSecond(); 1465 DVar.RefExpr = Data.RefExpr.getPointer(); 1466 DVar.PrivateCopy = Data.PrivateCopy; 1467 DVar.CKind = Data.Attributes; 1468 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1469 DVar.DKind = I->Directive; 1470 return DVar; 1471 } 1472 1473 DVar.CKind = OMPC_shared; 1474 return DVar; 1475 } 1476 1477 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1478 // The predetermined shared attribute for const-qualified types having no 1479 // mutable members was removed after OpenMP 3.1. 1480 if (SemaRef.LangOpts.OpenMP <= 31) { 1481 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1482 // in a Construct, C/C++, predetermined, p.6] 1483 // Variables with const qualified type having no mutable member are 1484 // shared. 1485 if (isConstNotMutableType(SemaRef, D->getType())) { 1486 // Variables with const-qualified type having no mutable member may be 1487 // listed in a firstprivate clause, even if they are static data members. 1488 DSAVarData DVarTemp = hasInnermostDSA( 1489 D, 1490 [](OpenMPClauseKind C) { 1491 return C == OMPC_firstprivate || C == OMPC_shared; 1492 }, 1493 MatchesAlways, FromParent); 1494 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1495 return DVarTemp; 1496 1497 DVar.CKind = OMPC_shared; 1498 return DVar; 1499 } 1500 } 1501 1502 // Explicitly specified attributes and local variables with predetermined 1503 // attributes. 1504 const_iterator I = begin(); 1505 const_iterator EndI = end(); 1506 if (FromParent && I != EndI) 1507 ++I; 1508 auto It = I->SharingMap.find(D); 1509 if (It != I->SharingMap.end()) { 1510 const DSAInfo &Data = It->getSecond(); 1511 DVar.RefExpr = Data.RefExpr.getPointer(); 1512 DVar.PrivateCopy = Data.PrivateCopy; 1513 DVar.CKind = Data.Attributes; 1514 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1515 DVar.DKind = I->Directive; 1516 } 1517 1518 return DVar; 1519 } 1520 1521 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1522 bool FromParent) const { 1523 if (isStackEmpty()) { 1524 const_iterator I; 1525 return getDSA(I, D); 1526 } 1527 D = getCanonicalDecl(D); 1528 const_iterator StartI = begin(); 1529 const_iterator EndI = end(); 1530 if (FromParent && StartI != EndI) 1531 ++StartI; 1532 return getDSA(StartI, D); 1533 } 1534 1535 const DSAStackTy::DSAVarData 1536 DSAStackTy::hasDSA(ValueDecl *D, 1537 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1538 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1539 bool FromParent) const { 1540 if (isStackEmpty()) 1541 return {}; 1542 D = getCanonicalDecl(D); 1543 const_iterator I = begin(); 1544 const_iterator EndI = end(); 1545 if (FromParent && I != EndI) 1546 ++I; 1547 for (; I != EndI; ++I) { 1548 if (!DPred(I->Directive) && 1549 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1550 continue; 1551 const_iterator NewI = I; 1552 DSAVarData DVar = getDSA(NewI, D); 1553 if (I == NewI && CPred(DVar.CKind)) 1554 return DVar; 1555 } 1556 return {}; 1557 } 1558 1559 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1560 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1561 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1562 bool FromParent) const { 1563 if (isStackEmpty()) 1564 return {}; 1565 D = getCanonicalDecl(D); 1566 const_iterator StartI = begin(); 1567 const_iterator EndI = end(); 1568 if (FromParent && StartI != EndI) 1569 ++StartI; 1570 if (StartI == EndI || !DPred(StartI->Directive)) 1571 return {}; 1572 const_iterator NewI = StartI; 1573 DSAVarData DVar = getDSA(NewI, D); 1574 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1575 } 1576 1577 bool DSAStackTy::hasExplicitDSA( 1578 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1579 unsigned Level, bool NotLastprivate) const { 1580 if (getStackSize() <= Level) 1581 return false; 1582 D = getCanonicalDecl(D); 1583 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1584 auto I = StackElem.SharingMap.find(D); 1585 if (I != StackElem.SharingMap.end() && 1586 I->getSecond().RefExpr.getPointer() && 1587 CPred(I->getSecond().Attributes) && 1588 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1589 return true; 1590 // Check predetermined rules for the loop control variables. 1591 auto LI = StackElem.LCVMap.find(D); 1592 if (LI != StackElem.LCVMap.end()) 1593 return CPred(OMPC_private); 1594 return false; 1595 } 1596 1597 bool DSAStackTy::hasExplicitDirective( 1598 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1599 unsigned Level) const { 1600 if (getStackSize() <= Level) 1601 return false; 1602 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1603 return DPred(StackElem.Directive); 1604 } 1605 1606 bool DSAStackTy::hasDirective( 1607 const llvm::function_ref<bool(OpenMPDirectiveKind, 1608 const DeclarationNameInfo &, SourceLocation)> 1609 DPred, 1610 bool FromParent) const { 1611 // We look only in the enclosing region. 1612 size_t Skip = FromParent ? 2 : 1; 1613 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1614 I != E; ++I) { 1615 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1616 return true; 1617 } 1618 return false; 1619 } 1620 1621 void Sema::InitDataSharingAttributesStack() { 1622 VarDataSharingAttributesStack = new DSAStackTy(*this); 1623 } 1624 1625 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1626 1627 void Sema::pushOpenMPFunctionRegion() { 1628 DSAStack->pushFunction(); 1629 } 1630 1631 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1632 DSAStack->popFunction(OldFSI); 1633 } 1634 1635 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1636 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1637 "Expected OpenMP device compilation."); 1638 return !S.isInOpenMPTargetExecutionDirective() && 1639 !S.isInOpenMPDeclareTargetContext(); 1640 } 1641 1642 namespace { 1643 /// Status of the function emission on the host/device. 1644 enum class FunctionEmissionStatus { 1645 Emitted, 1646 Discarded, 1647 Unknown, 1648 }; 1649 } // anonymous namespace 1650 1651 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1652 unsigned DiagID) { 1653 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1654 "Expected OpenMP device compilation."); 1655 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1656 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1657 switch (FES) { 1658 case FunctionEmissionStatus::Emitted: 1659 Kind = DeviceDiagBuilder::K_Immediate; 1660 break; 1661 case FunctionEmissionStatus::Unknown: 1662 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1663 : DeviceDiagBuilder::K_Immediate; 1664 break; 1665 case FunctionEmissionStatus::TemplateDiscarded: 1666 case FunctionEmissionStatus::OMPDiscarded: 1667 Kind = DeviceDiagBuilder::K_Nop; 1668 break; 1669 case FunctionEmissionStatus::CUDADiscarded: 1670 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1671 break; 1672 } 1673 1674 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1675 } 1676 1677 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1678 unsigned DiagID) { 1679 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1680 "Expected OpenMP host compilation."); 1681 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1682 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1683 switch (FES) { 1684 case FunctionEmissionStatus::Emitted: 1685 Kind = DeviceDiagBuilder::K_Immediate; 1686 break; 1687 case FunctionEmissionStatus::Unknown: 1688 Kind = DeviceDiagBuilder::K_Deferred; 1689 break; 1690 case FunctionEmissionStatus::TemplateDiscarded: 1691 case FunctionEmissionStatus::OMPDiscarded: 1692 case FunctionEmissionStatus::CUDADiscarded: 1693 Kind = DeviceDiagBuilder::K_Nop; 1694 break; 1695 } 1696 1697 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1698 } 1699 1700 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1701 bool CheckForDelayedContext) { 1702 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1703 "Expected OpenMP device compilation."); 1704 assert(Callee && "Callee may not be null."); 1705 Callee = Callee->getMostRecentDecl(); 1706 FunctionDecl *Caller = getCurFunctionDecl(); 1707 1708 // host only function are not available on the device. 1709 if (Caller) { 1710 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1711 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1712 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1713 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1714 "CUDADiscarded unexpected in OpenMP device function check"); 1715 if ((CallerS == FunctionEmissionStatus::Emitted || 1716 (!isOpenMPDeviceDelayedContext(*this) && 1717 CallerS == FunctionEmissionStatus::Unknown)) && 1718 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1719 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1720 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1721 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1722 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1723 diag::note_omp_marked_device_type_here) 1724 << HostDevTy; 1725 return; 1726 } 1727 } 1728 // If the caller is known-emitted, mark the callee as known-emitted. 1729 // Otherwise, mark the call in our call graph so we can traverse it later. 1730 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1731 (!Caller && !CheckForDelayedContext) || 1732 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1733 markKnownEmitted(*this, Caller, Callee, Loc, 1734 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1735 return CheckForDelayedContext && 1736 S.getEmissionStatus(FD) == 1737 FunctionEmissionStatus::Emitted; 1738 }); 1739 else if (Caller) 1740 DeviceCallGraph[Caller].insert({Callee, Loc}); 1741 } 1742 1743 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1744 bool CheckCaller) { 1745 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1746 "Expected OpenMP host compilation."); 1747 assert(Callee && "Callee may not be null."); 1748 Callee = Callee->getMostRecentDecl(); 1749 FunctionDecl *Caller = getCurFunctionDecl(); 1750 1751 // device only function are not available on the host. 1752 if (Caller) { 1753 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1754 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1755 assert( 1756 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1757 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1758 "CUDADiscarded unexpected in OpenMP host function check"); 1759 if (CallerS == FunctionEmissionStatus::Emitted && 1760 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1761 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1762 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1763 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1764 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1765 diag::note_omp_marked_device_type_here) 1766 << NoHostDevTy; 1767 return; 1768 } 1769 } 1770 // If the caller is known-emitted, mark the callee as known-emitted. 1771 // Otherwise, mark the call in our call graph so we can traverse it later. 1772 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1773 if ((!CheckCaller && !Caller) || 1774 (Caller && 1775 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1776 markKnownEmitted( 1777 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1778 return CheckCaller && 1779 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1780 }); 1781 else if (Caller) 1782 DeviceCallGraph[Caller].insert({Callee, Loc}); 1783 } 1784 } 1785 1786 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1787 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1788 "OpenMP device compilation mode is expected."); 1789 QualType Ty = E->getType(); 1790 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1791 ((Ty->isFloat128Type() || 1792 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1793 !Context.getTargetInfo().hasFloat128Type()) || 1794 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1795 !Context.getTargetInfo().hasInt128Type())) 1796 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1797 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1798 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1799 } 1800 1801 static OpenMPDefaultmapClauseKind 1802 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1803 if (LO.OpenMP <= 45) { 1804 if (VD->getType().getNonReferenceType()->isScalarType()) 1805 return OMPC_DEFAULTMAP_scalar; 1806 return OMPC_DEFAULTMAP_aggregate; 1807 } 1808 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1809 return OMPC_DEFAULTMAP_pointer; 1810 if (VD->getType().getNonReferenceType()->isScalarType()) 1811 return OMPC_DEFAULTMAP_scalar; 1812 return OMPC_DEFAULTMAP_aggregate; 1813 } 1814 1815 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1816 unsigned OpenMPCaptureLevel) const { 1817 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1818 1819 ASTContext &Ctx = getASTContext(); 1820 bool IsByRef = true; 1821 1822 // Find the directive that is associated with the provided scope. 1823 D = cast<ValueDecl>(D->getCanonicalDecl()); 1824 QualType Ty = D->getType(); 1825 1826 bool IsVariableUsedInMapClause = false; 1827 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1828 // This table summarizes how a given variable should be passed to the device 1829 // given its type and the clauses where it appears. This table is based on 1830 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1831 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1832 // 1833 // ========================================================================= 1834 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1835 // | |(tofrom:scalar)| | pvt | | | | 1836 // ========================================================================= 1837 // | scl | | | | - | | bycopy| 1838 // | scl | | - | x | - | - | bycopy| 1839 // | scl | | x | - | - | - | null | 1840 // | scl | x | | | - | | byref | 1841 // | scl | x | - | x | - | - | bycopy| 1842 // | scl | x | x | - | - | - | null | 1843 // | scl | | - | - | - | x | byref | 1844 // | scl | x | - | - | - | x | byref | 1845 // 1846 // | agg | n.a. | | | - | | byref | 1847 // | agg | n.a. | - | x | - | - | byref | 1848 // | agg | n.a. | x | - | - | - | null | 1849 // | agg | n.a. | - | - | - | x | byref | 1850 // | agg | n.a. | - | - | - | x[] | byref | 1851 // 1852 // | ptr | n.a. | | | - | | bycopy| 1853 // | ptr | n.a. | - | x | - | - | bycopy| 1854 // | ptr | n.a. | x | - | - | - | null | 1855 // | ptr | n.a. | - | - | - | x | byref | 1856 // | ptr | n.a. | - | - | - | x[] | bycopy| 1857 // | ptr | n.a. | - | - | x | | bycopy| 1858 // | ptr | n.a. | - | - | x | x | bycopy| 1859 // | ptr | n.a. | - | - | x | x[] | bycopy| 1860 // ========================================================================= 1861 // Legend: 1862 // scl - scalar 1863 // ptr - pointer 1864 // agg - aggregate 1865 // x - applies 1866 // - - invalid in this combination 1867 // [] - mapped with an array section 1868 // byref - should be mapped by reference 1869 // byval - should be mapped by value 1870 // null - initialize a local variable to null on the device 1871 // 1872 // Observations: 1873 // - All scalar declarations that show up in a map clause have to be passed 1874 // by reference, because they may have been mapped in the enclosing data 1875 // environment. 1876 // - If the scalar value does not fit the size of uintptr, it has to be 1877 // passed by reference, regardless the result in the table above. 1878 // - For pointers mapped by value that have either an implicit map or an 1879 // array section, the runtime library may pass the NULL value to the 1880 // device instead of the value passed to it by the compiler. 1881 1882 if (Ty->isReferenceType()) 1883 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1884 1885 // Locate map clauses and see if the variable being captured is referred to 1886 // in any of those clauses. Here we only care about variables, not fields, 1887 // because fields are part of aggregates. 1888 bool IsVariableAssociatedWithSection = false; 1889 1890 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1891 D, Level, 1892 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1893 OMPClauseMappableExprCommon::MappableExprComponentListRef 1894 MapExprComponents, 1895 OpenMPClauseKind WhereFoundClauseKind) { 1896 // Only the map clause information influences how a variable is 1897 // captured. E.g. is_device_ptr does not require changing the default 1898 // behavior. 1899 if (WhereFoundClauseKind != OMPC_map) 1900 return false; 1901 1902 auto EI = MapExprComponents.rbegin(); 1903 auto EE = MapExprComponents.rend(); 1904 1905 assert(EI != EE && "Invalid map expression!"); 1906 1907 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1908 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1909 1910 ++EI; 1911 if (EI == EE) 1912 return false; 1913 1914 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1915 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1916 isa<MemberExpr>(EI->getAssociatedExpression())) { 1917 IsVariableAssociatedWithSection = true; 1918 // There is nothing more we need to know about this variable. 1919 return true; 1920 } 1921 1922 // Keep looking for more map info. 1923 return false; 1924 }); 1925 1926 if (IsVariableUsedInMapClause) { 1927 // If variable is identified in a map clause it is always captured by 1928 // reference except if it is a pointer that is dereferenced somehow. 1929 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1930 } else { 1931 // By default, all the data that has a scalar type is mapped by copy 1932 // (except for reduction variables). 1933 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1934 IsByRef = 1935 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1936 !Ty->isAnyPointerType()) || 1937 !Ty->isScalarType() || 1938 DSAStack->isDefaultmapCapturedByRef( 1939 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1940 DSAStack->hasExplicitDSA( 1941 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1942 } 1943 } 1944 1945 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1946 IsByRef = 1947 ((IsVariableUsedInMapClause && 1948 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1949 OMPD_target) || 1950 !DSAStack->hasExplicitDSA( 1951 D, 1952 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1953 Level, /*NotLastprivate=*/true)) && 1954 // If the variable is artificial and must be captured by value - try to 1955 // capture by value. 1956 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1957 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1958 } 1959 1960 // When passing data by copy, we need to make sure it fits the uintptr size 1961 // and alignment, because the runtime library only deals with uintptr types. 1962 // If it does not fit the uintptr size, we need to pass the data by reference 1963 // instead. 1964 if (!IsByRef && 1965 (Ctx.getTypeSizeInChars(Ty) > 1966 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1967 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1968 IsByRef = true; 1969 } 1970 1971 return IsByRef; 1972 } 1973 1974 unsigned Sema::getOpenMPNestingLevel() const { 1975 assert(getLangOpts().OpenMP); 1976 return DSAStack->getNestingLevel(); 1977 } 1978 1979 bool Sema::isInOpenMPTargetExecutionDirective() const { 1980 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1981 !DSAStack->isClauseParsingMode()) || 1982 DSAStack->hasDirective( 1983 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1984 SourceLocation) -> bool { 1985 return isOpenMPTargetExecutionDirective(K); 1986 }, 1987 false); 1988 } 1989 1990 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1991 unsigned StopAt) { 1992 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1993 D = getCanonicalDecl(D); 1994 1995 auto *VD = dyn_cast<VarDecl>(D); 1996 // Do not capture constexpr variables. 1997 if (VD && VD->isConstexpr()) 1998 return nullptr; 1999 2000 // If we want to determine whether the variable should be captured from the 2001 // perspective of the current capturing scope, and we've already left all the 2002 // capturing scopes of the top directive on the stack, check from the 2003 // perspective of its parent directive (if any) instead. 2004 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2005 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2006 2007 // If we are attempting to capture a global variable in a directive with 2008 // 'target' we return true so that this global is also mapped to the device. 2009 // 2010 if (VD && !VD->hasLocalStorage() && 2011 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2012 if (isInOpenMPDeclareTargetContext()) { 2013 // Try to mark variable as declare target if it is used in capturing 2014 // regions. 2015 if (LangOpts.OpenMP <= 45 && 2016 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2017 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2018 return nullptr; 2019 } else if (isInOpenMPTargetExecutionDirective()) { 2020 // If the declaration is enclosed in a 'declare target' directive, 2021 // then it should not be captured. 2022 // 2023 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2024 return nullptr; 2025 CapturedRegionScopeInfo *CSI = nullptr; 2026 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2027 llvm::reverse(FunctionScopes), 2028 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2029 if (!isa<CapturingScopeInfo>(FSI)) 2030 return nullptr; 2031 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2032 if (RSI->CapRegionKind == CR_OpenMP) { 2033 CSI = RSI; 2034 break; 2035 } 2036 } 2037 SmallVector<OpenMPDirectiveKind, 4> Regions; 2038 getOpenMPCaptureRegions(Regions, 2039 DSAStack->getDirective(CSI->OpenMPLevel)); 2040 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2041 return VD; 2042 } 2043 } 2044 2045 if (CheckScopeInfo) { 2046 bool OpenMPFound = false; 2047 for (unsigned I = StopAt + 1; I > 0; --I) { 2048 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2049 if(!isa<CapturingScopeInfo>(FSI)) 2050 return nullptr; 2051 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2052 if (RSI->CapRegionKind == CR_OpenMP) { 2053 OpenMPFound = true; 2054 break; 2055 } 2056 } 2057 if (!OpenMPFound) 2058 return nullptr; 2059 } 2060 2061 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2062 (!DSAStack->isClauseParsingMode() || 2063 DSAStack->getParentDirective() != OMPD_unknown)) { 2064 auto &&Info = DSAStack->isLoopControlVariable(D); 2065 if (Info.first || 2066 (VD && VD->hasLocalStorage() && 2067 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2068 (VD && DSAStack->isForceVarCapturing())) 2069 return VD ? VD : Info.second; 2070 DSAStackTy::DSAVarData DVarPrivate = 2071 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2072 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 2073 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2074 // Threadprivate variables must not be captured. 2075 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 2076 return nullptr; 2077 // The variable is not private or it is the variable in the directive with 2078 // default(none) clause and not used in any clause. 2079 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 2080 [](OpenMPDirectiveKind) { return true; }, 2081 DSAStack->isClauseParsingMode()); 2082 if (DVarPrivate.CKind != OMPC_unknown || 2083 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2084 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2085 } 2086 return nullptr; 2087 } 2088 2089 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2090 unsigned Level) const { 2091 SmallVector<OpenMPDirectiveKind, 4> Regions; 2092 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2093 FunctionScopesIndex -= Regions.size(); 2094 } 2095 2096 void Sema::startOpenMPLoop() { 2097 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2098 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2099 DSAStack->loopInit(); 2100 } 2101 2102 void Sema::startOpenMPCXXRangeFor() { 2103 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2104 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2105 DSAStack->resetPossibleLoopCounter(); 2106 DSAStack->loopStart(); 2107 } 2108 } 2109 2110 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2111 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2112 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2113 if (DSAStack->getAssociatedLoops() > 0 && 2114 !DSAStack->isLoopStarted()) { 2115 DSAStack->resetPossibleLoopCounter(D); 2116 DSAStack->loopStart(); 2117 return true; 2118 } 2119 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2120 DSAStack->isLoopControlVariable(D).first) && 2121 !DSAStack->hasExplicitDSA( 2122 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2123 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2124 return true; 2125 } 2126 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2127 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2128 DSAStack->isForceVarCapturing() && 2129 !DSAStack->hasExplicitDSA( 2130 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2131 return true; 2132 } 2133 return DSAStack->hasExplicitDSA( 2134 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2135 (DSAStack->isClauseParsingMode() && 2136 DSAStack->getClauseParsingMode() == OMPC_private) || 2137 // Consider taskgroup reduction descriptor variable a private to avoid 2138 // possible capture in the region. 2139 (DSAStack->hasExplicitDirective( 2140 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2141 Level) && 2142 DSAStack->isTaskgroupReductionRef(D, Level)); 2143 } 2144 2145 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2146 unsigned Level) { 2147 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2148 D = getCanonicalDecl(D); 2149 OpenMPClauseKind OMPC = OMPC_unknown; 2150 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2151 const unsigned NewLevel = I - 1; 2152 if (DSAStack->hasExplicitDSA(D, 2153 [&OMPC](const OpenMPClauseKind K) { 2154 if (isOpenMPPrivate(K)) { 2155 OMPC = K; 2156 return true; 2157 } 2158 return false; 2159 }, 2160 NewLevel)) 2161 break; 2162 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2163 D, NewLevel, 2164 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2165 OpenMPClauseKind) { return true; })) { 2166 OMPC = OMPC_map; 2167 break; 2168 } 2169 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2170 NewLevel)) { 2171 OMPC = OMPC_map; 2172 if (DSAStack->mustBeFirstprivateAtLevel( 2173 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2174 OMPC = OMPC_firstprivate; 2175 break; 2176 } 2177 } 2178 if (OMPC != OMPC_unknown) 2179 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2180 } 2181 2182 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2183 unsigned CaptureLevel) const { 2184 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2185 // Return true if the current level is no longer enclosed in a target region. 2186 2187 SmallVector<OpenMPDirectiveKind, 4> Regions; 2188 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2189 const auto *VD = dyn_cast<VarDecl>(D); 2190 return VD && !VD->hasLocalStorage() && 2191 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2192 Level) && 2193 Regions[CaptureLevel] != OMPD_task; 2194 } 2195 2196 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2197 2198 void Sema::finalizeOpenMPDelayedAnalysis() { 2199 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2200 // Diagnose implicit declare target functions and their callees. 2201 for (const auto &CallerCallees : DeviceCallGraph) { 2202 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2203 OMPDeclareTargetDeclAttr::getDeviceType( 2204 CallerCallees.getFirst()->getMostRecentDecl()); 2205 // Ignore host functions during device analyzis. 2206 if (LangOpts.OpenMPIsDevice && DevTy && 2207 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2208 continue; 2209 // Ignore nohost functions during host analyzis. 2210 if (!LangOpts.OpenMPIsDevice && DevTy && 2211 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2212 continue; 2213 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2214 &Callee : CallerCallees.getSecond()) { 2215 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2216 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2217 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2218 if (LangOpts.OpenMPIsDevice && DevTy && 2219 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2220 // Diagnose host function called during device codegen. 2221 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2222 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2223 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2224 << HostDevTy << 0; 2225 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2226 diag::note_omp_marked_device_type_here) 2227 << HostDevTy; 2228 continue; 2229 } 2230 if (!LangOpts.OpenMPIsDevice && DevTy && 2231 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2232 // Diagnose nohost function called during host codegen. 2233 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2234 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2235 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2236 << NoHostDevTy << 1; 2237 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2238 diag::note_omp_marked_device_type_here) 2239 << NoHostDevTy; 2240 continue; 2241 } 2242 } 2243 } 2244 } 2245 2246 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2247 const DeclarationNameInfo &DirName, 2248 Scope *CurScope, SourceLocation Loc) { 2249 DSAStack->push(DKind, DirName, CurScope, Loc); 2250 PushExpressionEvaluationContext( 2251 ExpressionEvaluationContext::PotentiallyEvaluated); 2252 } 2253 2254 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2255 DSAStack->setClauseParsingMode(K); 2256 } 2257 2258 void Sema::EndOpenMPClause() { 2259 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2260 } 2261 2262 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2263 ArrayRef<OMPClause *> Clauses); 2264 static std::pair<ValueDecl *, bool> 2265 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2266 SourceRange &ERange, bool AllowArraySection = false); 2267 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2268 bool WithInit); 2269 2270 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2271 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2272 // A variable of class type (or array thereof) that appears in a lastprivate 2273 // clause requires an accessible, unambiguous default constructor for the 2274 // class type, unless the list item is also specified in a firstprivate 2275 // clause. 2276 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2277 for (OMPClause *C : D->clauses()) { 2278 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2279 SmallVector<Expr *, 8> PrivateCopies; 2280 for (Expr *DE : Clause->varlists()) { 2281 if (DE->isValueDependent() || DE->isTypeDependent()) { 2282 PrivateCopies.push_back(nullptr); 2283 continue; 2284 } 2285 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2286 auto *VD = cast<VarDecl>(DRE->getDecl()); 2287 QualType Type = VD->getType().getNonReferenceType(); 2288 const DSAStackTy::DSAVarData DVar = 2289 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2290 if (DVar.CKind == OMPC_lastprivate) { 2291 // Generate helper private variable and initialize it with the 2292 // default value. The address of the original variable is replaced 2293 // by the address of the new private variable in CodeGen. This new 2294 // variable is not added to IdResolver, so the code in the OpenMP 2295 // region uses original variable for proper diagnostics. 2296 VarDecl *VDPrivate = buildVarDecl( 2297 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2298 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2299 ActOnUninitializedDecl(VDPrivate); 2300 if (VDPrivate->isInvalidDecl()) { 2301 PrivateCopies.push_back(nullptr); 2302 continue; 2303 } 2304 PrivateCopies.push_back(buildDeclRefExpr( 2305 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2306 } else { 2307 // The variable is also a firstprivate, so initialization sequence 2308 // for private copy is generated already. 2309 PrivateCopies.push_back(nullptr); 2310 } 2311 } 2312 Clause->setPrivateCopies(PrivateCopies); 2313 continue; 2314 } 2315 // Finalize nontemporal clause by handling private copies, if any. 2316 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2317 SmallVector<Expr *, 8> PrivateRefs; 2318 for (Expr *RefExpr : Clause->varlists()) { 2319 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2320 SourceLocation ELoc; 2321 SourceRange ERange; 2322 Expr *SimpleRefExpr = RefExpr; 2323 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2324 if (Res.second) 2325 // It will be analyzed later. 2326 PrivateRefs.push_back(RefExpr); 2327 ValueDecl *D = Res.first; 2328 if (!D) 2329 continue; 2330 2331 const DSAStackTy::DSAVarData DVar = 2332 DSAStack->getTopDSA(D, /*FromParent=*/false); 2333 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2334 : SimpleRefExpr); 2335 } 2336 Clause->setPrivateRefs(PrivateRefs); 2337 continue; 2338 } 2339 } 2340 // Check allocate clauses. 2341 if (!CurContext->isDependentContext()) 2342 checkAllocateClauses(*this, DSAStack, D->clauses()); 2343 } 2344 2345 DSAStack->pop(); 2346 DiscardCleanupsInEvaluationContext(); 2347 PopExpressionEvaluationContext(); 2348 } 2349 2350 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2351 Expr *NumIterations, Sema &SemaRef, 2352 Scope *S, DSAStackTy *Stack); 2353 2354 namespace { 2355 2356 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2357 private: 2358 Sema &SemaRef; 2359 2360 public: 2361 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2362 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2363 NamedDecl *ND = Candidate.getCorrectionDecl(); 2364 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2365 return VD->hasGlobalStorage() && 2366 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2367 SemaRef.getCurScope()); 2368 } 2369 return false; 2370 } 2371 2372 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2373 return std::make_unique<VarDeclFilterCCC>(*this); 2374 } 2375 2376 }; 2377 2378 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2379 private: 2380 Sema &SemaRef; 2381 2382 public: 2383 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2384 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2385 NamedDecl *ND = Candidate.getCorrectionDecl(); 2386 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2387 isa<FunctionDecl>(ND))) { 2388 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2389 SemaRef.getCurScope()); 2390 } 2391 return false; 2392 } 2393 2394 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2395 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2396 } 2397 }; 2398 2399 } // namespace 2400 2401 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2402 CXXScopeSpec &ScopeSpec, 2403 const DeclarationNameInfo &Id, 2404 OpenMPDirectiveKind Kind) { 2405 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2406 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2407 2408 if (Lookup.isAmbiguous()) 2409 return ExprError(); 2410 2411 VarDecl *VD; 2412 if (!Lookup.isSingleResult()) { 2413 VarDeclFilterCCC CCC(*this); 2414 if (TypoCorrection Corrected = 2415 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2416 CTK_ErrorRecovery)) { 2417 diagnoseTypo(Corrected, 2418 PDiag(Lookup.empty() 2419 ? diag::err_undeclared_var_use_suggest 2420 : diag::err_omp_expected_var_arg_suggest) 2421 << Id.getName()); 2422 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2423 } else { 2424 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2425 : diag::err_omp_expected_var_arg) 2426 << Id.getName(); 2427 return ExprError(); 2428 } 2429 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2430 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2431 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2432 return ExprError(); 2433 } 2434 Lookup.suppressDiagnostics(); 2435 2436 // OpenMP [2.9.2, Syntax, C/C++] 2437 // Variables must be file-scope, namespace-scope, or static block-scope. 2438 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2439 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2440 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2441 bool IsDecl = 2442 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2443 Diag(VD->getLocation(), 2444 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2445 << VD; 2446 return ExprError(); 2447 } 2448 2449 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2450 NamedDecl *ND = CanonicalVD; 2451 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2452 // A threadprivate directive for file-scope variables must appear outside 2453 // any definition or declaration. 2454 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2455 !getCurLexicalContext()->isTranslationUnit()) { 2456 Diag(Id.getLoc(), diag::err_omp_var_scope) 2457 << getOpenMPDirectiveName(Kind) << VD; 2458 bool IsDecl = 2459 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2460 Diag(VD->getLocation(), 2461 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2462 << VD; 2463 return ExprError(); 2464 } 2465 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2466 // A threadprivate directive for static class member variables must appear 2467 // in the class definition, in the same scope in which the member 2468 // variables are declared. 2469 if (CanonicalVD->isStaticDataMember() && 2470 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2471 Diag(Id.getLoc(), diag::err_omp_var_scope) 2472 << getOpenMPDirectiveName(Kind) << VD; 2473 bool IsDecl = 2474 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2475 Diag(VD->getLocation(), 2476 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2477 << VD; 2478 return ExprError(); 2479 } 2480 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2481 // A threadprivate directive for namespace-scope variables must appear 2482 // outside any definition or declaration other than the namespace 2483 // definition itself. 2484 if (CanonicalVD->getDeclContext()->isNamespace() && 2485 (!getCurLexicalContext()->isFileContext() || 2486 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2487 Diag(Id.getLoc(), diag::err_omp_var_scope) 2488 << getOpenMPDirectiveName(Kind) << VD; 2489 bool IsDecl = 2490 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2491 Diag(VD->getLocation(), 2492 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2493 << VD; 2494 return ExprError(); 2495 } 2496 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2497 // A threadprivate directive for static block-scope variables must appear 2498 // in the scope of the variable and not in a nested scope. 2499 if (CanonicalVD->isLocalVarDecl() && CurScope && 2500 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2501 Diag(Id.getLoc(), diag::err_omp_var_scope) 2502 << getOpenMPDirectiveName(Kind) << VD; 2503 bool IsDecl = 2504 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2505 Diag(VD->getLocation(), 2506 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2507 << VD; 2508 return ExprError(); 2509 } 2510 2511 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2512 // A threadprivate directive must lexically precede all references to any 2513 // of the variables in its list. 2514 if (Kind == OMPD_threadprivate && VD->isUsed() && 2515 !DSAStack->isThreadPrivate(VD)) { 2516 Diag(Id.getLoc(), diag::err_omp_var_used) 2517 << getOpenMPDirectiveName(Kind) << VD; 2518 return ExprError(); 2519 } 2520 2521 QualType ExprType = VD->getType().getNonReferenceType(); 2522 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2523 SourceLocation(), VD, 2524 /*RefersToEnclosingVariableOrCapture=*/false, 2525 Id.getLoc(), ExprType, VK_LValue); 2526 } 2527 2528 Sema::DeclGroupPtrTy 2529 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2530 ArrayRef<Expr *> VarList) { 2531 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2532 CurContext->addDecl(D); 2533 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2534 } 2535 return nullptr; 2536 } 2537 2538 namespace { 2539 class LocalVarRefChecker final 2540 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2541 Sema &SemaRef; 2542 2543 public: 2544 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2545 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2546 if (VD->hasLocalStorage()) { 2547 SemaRef.Diag(E->getBeginLoc(), 2548 diag::err_omp_local_var_in_threadprivate_init) 2549 << E->getSourceRange(); 2550 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2551 << VD << VD->getSourceRange(); 2552 return true; 2553 } 2554 } 2555 return false; 2556 } 2557 bool VisitStmt(const Stmt *S) { 2558 for (const Stmt *Child : S->children()) { 2559 if (Child && Visit(Child)) 2560 return true; 2561 } 2562 return false; 2563 } 2564 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2565 }; 2566 } // namespace 2567 2568 OMPThreadPrivateDecl * 2569 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2570 SmallVector<Expr *, 8> Vars; 2571 for (Expr *RefExpr : VarList) { 2572 auto *DE = cast<DeclRefExpr>(RefExpr); 2573 auto *VD = cast<VarDecl>(DE->getDecl()); 2574 SourceLocation ILoc = DE->getExprLoc(); 2575 2576 // Mark variable as used. 2577 VD->setReferenced(); 2578 VD->markUsed(Context); 2579 2580 QualType QType = VD->getType(); 2581 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2582 // It will be analyzed later. 2583 Vars.push_back(DE); 2584 continue; 2585 } 2586 2587 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2588 // A threadprivate variable must not have an incomplete type. 2589 if (RequireCompleteType(ILoc, VD->getType(), 2590 diag::err_omp_threadprivate_incomplete_type)) { 2591 continue; 2592 } 2593 2594 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2595 // A threadprivate variable must not have a reference type. 2596 if (VD->getType()->isReferenceType()) { 2597 Diag(ILoc, diag::err_omp_ref_type_arg) 2598 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2599 bool IsDecl = 2600 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2601 Diag(VD->getLocation(), 2602 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2603 << VD; 2604 continue; 2605 } 2606 2607 // Check if this is a TLS variable. If TLS is not being supported, produce 2608 // the corresponding diagnostic. 2609 if ((VD->getTLSKind() != VarDecl::TLS_None && 2610 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2611 getLangOpts().OpenMPUseTLS && 2612 getASTContext().getTargetInfo().isTLSSupported())) || 2613 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2614 !VD->isLocalVarDecl())) { 2615 Diag(ILoc, diag::err_omp_var_thread_local) 2616 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2617 bool IsDecl = 2618 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2619 Diag(VD->getLocation(), 2620 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2621 << VD; 2622 continue; 2623 } 2624 2625 // Check if initial value of threadprivate variable reference variable with 2626 // local storage (it is not supported by runtime). 2627 if (const Expr *Init = VD->getAnyInitializer()) { 2628 LocalVarRefChecker Checker(*this); 2629 if (Checker.Visit(Init)) 2630 continue; 2631 } 2632 2633 Vars.push_back(RefExpr); 2634 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2635 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2636 Context, SourceRange(Loc, Loc))); 2637 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2638 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2639 } 2640 OMPThreadPrivateDecl *D = nullptr; 2641 if (!Vars.empty()) { 2642 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2643 Vars); 2644 D->setAccess(AS_public); 2645 } 2646 return D; 2647 } 2648 2649 static OMPAllocateDeclAttr::AllocatorTypeTy 2650 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2651 if (!Allocator) 2652 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2653 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2654 Allocator->isInstantiationDependent() || 2655 Allocator->containsUnexpandedParameterPack()) 2656 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2657 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2658 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2659 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2660 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2661 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2662 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2663 llvm::FoldingSetNodeID AEId, DAEId; 2664 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2665 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2666 if (AEId == DAEId) { 2667 AllocatorKindRes = AllocatorKind; 2668 break; 2669 } 2670 } 2671 return AllocatorKindRes; 2672 } 2673 2674 static bool checkPreviousOMPAllocateAttribute( 2675 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2676 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2677 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2678 return false; 2679 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2680 Expr *PrevAllocator = A->getAllocator(); 2681 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2682 getAllocatorKind(S, Stack, PrevAllocator); 2683 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2684 if (AllocatorsMatch && 2685 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2686 Allocator && PrevAllocator) { 2687 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2688 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2689 llvm::FoldingSetNodeID AEId, PAEId; 2690 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2691 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2692 AllocatorsMatch = AEId == PAEId; 2693 } 2694 if (!AllocatorsMatch) { 2695 SmallString<256> AllocatorBuffer; 2696 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2697 if (Allocator) 2698 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2699 SmallString<256> PrevAllocatorBuffer; 2700 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2701 if (PrevAllocator) 2702 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2703 S.getPrintingPolicy()); 2704 2705 SourceLocation AllocatorLoc = 2706 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2707 SourceRange AllocatorRange = 2708 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2709 SourceLocation PrevAllocatorLoc = 2710 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2711 SourceRange PrevAllocatorRange = 2712 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2713 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2714 << (Allocator ? 1 : 0) << AllocatorStream.str() 2715 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2716 << AllocatorRange; 2717 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2718 << PrevAllocatorRange; 2719 return true; 2720 } 2721 return false; 2722 } 2723 2724 static void 2725 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2726 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2727 Expr *Allocator, SourceRange SR) { 2728 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2729 return; 2730 if (Allocator && 2731 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2732 Allocator->isInstantiationDependent() || 2733 Allocator->containsUnexpandedParameterPack())) 2734 return; 2735 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2736 Allocator, SR); 2737 VD->addAttr(A); 2738 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2739 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2740 } 2741 2742 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2743 SourceLocation Loc, ArrayRef<Expr *> VarList, 2744 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2745 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2746 Expr *Allocator = nullptr; 2747 if (Clauses.empty()) { 2748 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2749 // allocate directives that appear in a target region must specify an 2750 // allocator clause unless a requires directive with the dynamic_allocators 2751 // clause is present in the same compilation unit. 2752 if (LangOpts.OpenMPIsDevice && 2753 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2754 targetDiag(Loc, diag::err_expected_allocator_clause); 2755 } else { 2756 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2757 } 2758 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2759 getAllocatorKind(*this, DSAStack, Allocator); 2760 SmallVector<Expr *, 8> Vars; 2761 for (Expr *RefExpr : VarList) { 2762 auto *DE = cast<DeclRefExpr>(RefExpr); 2763 auto *VD = cast<VarDecl>(DE->getDecl()); 2764 2765 // Check if this is a TLS variable or global register. 2766 if (VD->getTLSKind() != VarDecl::TLS_None || 2767 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2768 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2769 !VD->isLocalVarDecl())) 2770 continue; 2771 2772 // If the used several times in the allocate directive, the same allocator 2773 // must be used. 2774 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2775 AllocatorKind, Allocator)) 2776 continue; 2777 2778 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2779 // If a list item has a static storage type, the allocator expression in the 2780 // allocator clause must be a constant expression that evaluates to one of 2781 // the predefined memory allocator values. 2782 if (Allocator && VD->hasGlobalStorage()) { 2783 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2784 Diag(Allocator->getExprLoc(), 2785 diag::err_omp_expected_predefined_allocator) 2786 << Allocator->getSourceRange(); 2787 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2788 VarDecl::DeclarationOnly; 2789 Diag(VD->getLocation(), 2790 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2791 << VD; 2792 continue; 2793 } 2794 } 2795 2796 Vars.push_back(RefExpr); 2797 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2798 DE->getSourceRange()); 2799 } 2800 if (Vars.empty()) 2801 return nullptr; 2802 if (!Owner) 2803 Owner = getCurLexicalContext(); 2804 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2805 D->setAccess(AS_public); 2806 Owner->addDecl(D); 2807 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2808 } 2809 2810 Sema::DeclGroupPtrTy 2811 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2812 ArrayRef<OMPClause *> ClauseList) { 2813 OMPRequiresDecl *D = nullptr; 2814 if (!CurContext->isFileContext()) { 2815 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2816 } else { 2817 D = CheckOMPRequiresDecl(Loc, ClauseList); 2818 if (D) { 2819 CurContext->addDecl(D); 2820 DSAStack->addRequiresDecl(D); 2821 } 2822 } 2823 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2824 } 2825 2826 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2827 ArrayRef<OMPClause *> ClauseList) { 2828 /// For target specific clauses, the requires directive cannot be 2829 /// specified after the handling of any of the target regions in the 2830 /// current compilation unit. 2831 ArrayRef<SourceLocation> TargetLocations = 2832 DSAStack->getEncounteredTargetLocs(); 2833 if (!TargetLocations.empty()) { 2834 for (const OMPClause *CNew : ClauseList) { 2835 // Check if any of the requires clauses affect target regions. 2836 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2837 isa<OMPUnifiedAddressClause>(CNew) || 2838 isa<OMPReverseOffloadClause>(CNew) || 2839 isa<OMPDynamicAllocatorsClause>(CNew)) { 2840 Diag(Loc, diag::err_omp_target_before_requires) 2841 << getOpenMPClauseName(CNew->getClauseKind()); 2842 for (SourceLocation TargetLoc : TargetLocations) { 2843 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2844 } 2845 } 2846 } 2847 } 2848 2849 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2850 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2851 ClauseList); 2852 return nullptr; 2853 } 2854 2855 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2856 const ValueDecl *D, 2857 const DSAStackTy::DSAVarData &DVar, 2858 bool IsLoopIterVar = false) { 2859 if (DVar.RefExpr) { 2860 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2861 << getOpenMPClauseName(DVar.CKind); 2862 return; 2863 } 2864 enum { 2865 PDSA_StaticMemberShared, 2866 PDSA_StaticLocalVarShared, 2867 PDSA_LoopIterVarPrivate, 2868 PDSA_LoopIterVarLinear, 2869 PDSA_LoopIterVarLastprivate, 2870 PDSA_ConstVarShared, 2871 PDSA_GlobalVarShared, 2872 PDSA_TaskVarFirstprivate, 2873 PDSA_LocalVarPrivate, 2874 PDSA_Implicit 2875 } Reason = PDSA_Implicit; 2876 bool ReportHint = false; 2877 auto ReportLoc = D->getLocation(); 2878 auto *VD = dyn_cast<VarDecl>(D); 2879 if (IsLoopIterVar) { 2880 if (DVar.CKind == OMPC_private) 2881 Reason = PDSA_LoopIterVarPrivate; 2882 else if (DVar.CKind == OMPC_lastprivate) 2883 Reason = PDSA_LoopIterVarLastprivate; 2884 else 2885 Reason = PDSA_LoopIterVarLinear; 2886 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2887 DVar.CKind == OMPC_firstprivate) { 2888 Reason = PDSA_TaskVarFirstprivate; 2889 ReportLoc = DVar.ImplicitDSALoc; 2890 } else if (VD && VD->isStaticLocal()) 2891 Reason = PDSA_StaticLocalVarShared; 2892 else if (VD && VD->isStaticDataMember()) 2893 Reason = PDSA_StaticMemberShared; 2894 else if (VD && VD->isFileVarDecl()) 2895 Reason = PDSA_GlobalVarShared; 2896 else if (D->getType().isConstant(SemaRef.getASTContext())) 2897 Reason = PDSA_ConstVarShared; 2898 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2899 ReportHint = true; 2900 Reason = PDSA_LocalVarPrivate; 2901 } 2902 if (Reason != PDSA_Implicit) { 2903 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2904 << Reason << ReportHint 2905 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2906 } else if (DVar.ImplicitDSALoc.isValid()) { 2907 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2908 << getOpenMPClauseName(DVar.CKind); 2909 } 2910 } 2911 2912 static OpenMPMapClauseKind 2913 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 2914 bool IsAggregateOrDeclareTarget) { 2915 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 2916 switch (M) { 2917 case OMPC_DEFAULTMAP_MODIFIER_alloc: 2918 Kind = OMPC_MAP_alloc; 2919 break; 2920 case OMPC_DEFAULTMAP_MODIFIER_to: 2921 Kind = OMPC_MAP_to; 2922 break; 2923 case OMPC_DEFAULTMAP_MODIFIER_from: 2924 Kind = OMPC_MAP_from; 2925 break; 2926 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 2927 Kind = OMPC_MAP_tofrom; 2928 break; 2929 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 2930 case OMPC_DEFAULTMAP_MODIFIER_last: 2931 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2932 case OMPC_DEFAULTMAP_MODIFIER_none: 2933 case OMPC_DEFAULTMAP_MODIFIER_default: 2934 case OMPC_DEFAULTMAP_MODIFIER_unknown: 2935 // IsAggregateOrDeclareTarget could be true if: 2936 // 1. the implicit behavior for aggregate is tofrom 2937 // 2. it's a declare target link 2938 if (IsAggregateOrDeclareTarget) { 2939 Kind = OMPC_MAP_tofrom; 2940 break; 2941 } 2942 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2943 } 2944 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 2945 return Kind; 2946 } 2947 2948 namespace { 2949 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2950 DSAStackTy *Stack; 2951 Sema &SemaRef; 2952 bool ErrorFound = false; 2953 bool TryCaptureCXXThisMembers = false; 2954 CapturedStmt *CS = nullptr; 2955 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2956 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 2957 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2958 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2959 2960 void VisitSubCaptures(OMPExecutableDirective *S) { 2961 // Check implicitly captured variables. 2962 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2963 return; 2964 visitSubCaptures(S->getInnermostCapturedStmt()); 2965 // Try to capture inner this->member references to generate correct mappings 2966 // and diagnostics. 2967 if (TryCaptureCXXThisMembers || 2968 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2969 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2970 [](const CapturedStmt::Capture &C) { 2971 return C.capturesThis(); 2972 }))) { 2973 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2974 TryCaptureCXXThisMembers = true; 2975 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2976 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2977 } 2978 } 2979 2980 public: 2981 void VisitDeclRefExpr(DeclRefExpr *E) { 2982 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 2983 E->isValueDependent() || E->containsUnexpandedParameterPack() || 2984 E->isInstantiationDependent()) 2985 return; 2986 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2987 // Check the datasharing rules for the expressions in the clauses. 2988 if (!CS) { 2989 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2990 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2991 Visit(CED->getInit()); 2992 return; 2993 } 2994 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2995 // Do not analyze internal variables and do not enclose them into 2996 // implicit clauses. 2997 return; 2998 VD = VD->getCanonicalDecl(); 2999 // Skip internally declared variables. 3000 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 3001 return; 3002 3003 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3004 // Check if the variable has explicit DSA set and stop analysis if it so. 3005 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3006 return; 3007 3008 // Skip internally declared static variables. 3009 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3010 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3011 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3012 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3013 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 3014 return; 3015 3016 SourceLocation ELoc = E->getExprLoc(); 3017 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3018 // The default(none) clause requires that each variable that is referenced 3019 // in the construct, and does not have a predetermined data-sharing 3020 // attribute, must have its data-sharing attribute explicitly determined 3021 // by being listed in a data-sharing attribute clause. 3022 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3023 isImplicitOrExplicitTaskingRegion(DKind) && 3024 VarsWithInheritedDSA.count(VD) == 0) { 3025 VarsWithInheritedDSA[VD] = E; 3026 return; 3027 } 3028 3029 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3030 // If implicit-behavior is none, each variable referenced in the 3031 // construct that does not have a predetermined data-sharing attribute 3032 // and does not appear in a to or link clause on a declare target 3033 // directive must be listed in a data-mapping attribute clause, a 3034 // data-haring attribute clause (including a data-sharing attribute 3035 // clause on a combined construct where target. is one of the 3036 // constituent constructs), or an is_device_ptr clause. 3037 OpenMPDefaultmapClauseKind ClauseKind = 3038 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3039 if (SemaRef.getLangOpts().OpenMP >= 50) { 3040 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3041 OMPC_DEFAULTMAP_MODIFIER_none; 3042 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3043 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3044 // Only check for data-mapping attribute and is_device_ptr here 3045 // since we have already make sure that the declaration does not 3046 // have a data-sharing attribute above 3047 if (!Stack->checkMappableExprComponentListsForDecl( 3048 VD, /*CurrentRegionOnly=*/true, 3049 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3050 MapExprComponents, 3051 OpenMPClauseKind) { 3052 auto MI = MapExprComponents.rbegin(); 3053 auto ME = MapExprComponents.rend(); 3054 return MI != ME && MI->getAssociatedDeclaration() == VD; 3055 })) { 3056 VarsWithInheritedDSA[VD] = E; 3057 return; 3058 } 3059 } 3060 } 3061 3062 if (isOpenMPTargetExecutionDirective(DKind) && 3063 !Stack->isLoopControlVariable(VD).first) { 3064 if (!Stack->checkMappableExprComponentListsForDecl( 3065 VD, /*CurrentRegionOnly=*/true, 3066 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3067 StackComponents, 3068 OpenMPClauseKind) { 3069 // Variable is used if it has been marked as an array, array 3070 // section or the variable iself. 3071 return StackComponents.size() == 1 || 3072 std::all_of( 3073 std::next(StackComponents.rbegin()), 3074 StackComponents.rend(), 3075 [](const OMPClauseMappableExprCommon:: 3076 MappableComponent &MC) { 3077 return MC.getAssociatedDeclaration() == 3078 nullptr && 3079 (isa<OMPArraySectionExpr>( 3080 MC.getAssociatedExpression()) || 3081 isa<ArraySubscriptExpr>( 3082 MC.getAssociatedExpression())); 3083 }); 3084 })) { 3085 bool IsFirstprivate = false; 3086 // By default lambdas are captured as firstprivates. 3087 if (const auto *RD = 3088 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3089 IsFirstprivate = RD->isLambda(); 3090 IsFirstprivate = 3091 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3092 if (IsFirstprivate) { 3093 ImplicitFirstprivate.emplace_back(E); 3094 } else { 3095 OpenMPDefaultmapClauseModifier M = 3096 Stack->getDefaultmapModifier(ClauseKind); 3097 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3098 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3099 ImplicitMap[Kind].emplace_back(E); 3100 } 3101 return; 3102 } 3103 } 3104 3105 // OpenMP [2.9.3.6, Restrictions, p.2] 3106 // A list item that appears in a reduction clause of the innermost 3107 // enclosing worksharing or parallel construct may not be accessed in an 3108 // explicit task. 3109 DVar = Stack->hasInnermostDSA( 3110 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3111 [](OpenMPDirectiveKind K) { 3112 return isOpenMPParallelDirective(K) || 3113 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3114 }, 3115 /*FromParent=*/true); 3116 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3117 ErrorFound = true; 3118 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3119 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3120 return; 3121 } 3122 3123 // Define implicit data-sharing attributes for task. 3124 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3125 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3126 !Stack->isLoopControlVariable(VD).first) { 3127 ImplicitFirstprivate.push_back(E); 3128 return; 3129 } 3130 3131 // Store implicitly used globals with declare target link for parent 3132 // target. 3133 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3134 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3135 Stack->addToParentTargetRegionLinkGlobals(E); 3136 return; 3137 } 3138 } 3139 } 3140 void VisitMemberExpr(MemberExpr *E) { 3141 if (E->isTypeDependent() || E->isValueDependent() || 3142 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3143 return; 3144 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3145 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3146 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 3147 if (!FD) 3148 return; 3149 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3150 // Check if the variable has explicit DSA set and stop analysis if it 3151 // so. 3152 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3153 return; 3154 3155 if (isOpenMPTargetExecutionDirective(DKind) && 3156 !Stack->isLoopControlVariable(FD).first && 3157 !Stack->checkMappableExprComponentListsForDecl( 3158 FD, /*CurrentRegionOnly=*/true, 3159 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3160 StackComponents, 3161 OpenMPClauseKind) { 3162 return isa<CXXThisExpr>( 3163 cast<MemberExpr>( 3164 StackComponents.back().getAssociatedExpression()) 3165 ->getBase() 3166 ->IgnoreParens()); 3167 })) { 3168 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3169 // A bit-field cannot appear in a map clause. 3170 // 3171 if (FD->isBitField()) 3172 return; 3173 3174 // Check to see if the member expression is referencing a class that 3175 // has already been explicitly mapped 3176 if (Stack->isClassPreviouslyMapped(TE->getType())) 3177 return; 3178 3179 OpenMPDefaultmapClauseModifier Modifier = 3180 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3181 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3182 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3183 ImplicitMap[Kind].emplace_back(E); 3184 return; 3185 } 3186 3187 SourceLocation ELoc = E->getExprLoc(); 3188 // OpenMP [2.9.3.6, Restrictions, p.2] 3189 // A list item that appears in a reduction clause of the innermost 3190 // enclosing worksharing or parallel construct may not be accessed in 3191 // an explicit task. 3192 DVar = Stack->hasInnermostDSA( 3193 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3194 [](OpenMPDirectiveKind K) { 3195 return isOpenMPParallelDirective(K) || 3196 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3197 }, 3198 /*FromParent=*/true); 3199 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3200 ErrorFound = true; 3201 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3202 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3203 return; 3204 } 3205 3206 // Define implicit data-sharing attributes for task. 3207 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3208 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3209 !Stack->isLoopControlVariable(FD).first) { 3210 // Check if there is a captured expression for the current field in the 3211 // region. Do not mark it as firstprivate unless there is no captured 3212 // expression. 3213 // TODO: try to make it firstprivate. 3214 if (DVar.CKind != OMPC_unknown) 3215 ImplicitFirstprivate.push_back(E); 3216 } 3217 return; 3218 } 3219 if (isOpenMPTargetExecutionDirective(DKind)) { 3220 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3221 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3222 /*NoDiagnose=*/true)) 3223 return; 3224 const auto *VD = cast<ValueDecl>( 3225 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3226 if (!Stack->checkMappableExprComponentListsForDecl( 3227 VD, /*CurrentRegionOnly=*/true, 3228 [&CurComponents]( 3229 OMPClauseMappableExprCommon::MappableExprComponentListRef 3230 StackComponents, 3231 OpenMPClauseKind) { 3232 auto CCI = CurComponents.rbegin(); 3233 auto CCE = CurComponents.rend(); 3234 for (const auto &SC : llvm::reverse(StackComponents)) { 3235 // Do both expressions have the same kind? 3236 if (CCI->getAssociatedExpression()->getStmtClass() != 3237 SC.getAssociatedExpression()->getStmtClass()) 3238 if (!(isa<OMPArraySectionExpr>( 3239 SC.getAssociatedExpression()) && 3240 isa<ArraySubscriptExpr>( 3241 CCI->getAssociatedExpression()))) 3242 return false; 3243 3244 const Decl *CCD = CCI->getAssociatedDeclaration(); 3245 const Decl *SCD = SC.getAssociatedDeclaration(); 3246 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3247 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3248 if (SCD != CCD) 3249 return false; 3250 std::advance(CCI, 1); 3251 if (CCI == CCE) 3252 break; 3253 } 3254 return true; 3255 })) { 3256 Visit(E->getBase()); 3257 } 3258 } else if (!TryCaptureCXXThisMembers) { 3259 Visit(E->getBase()); 3260 } 3261 } 3262 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3263 for (OMPClause *C : S->clauses()) { 3264 // Skip analysis of arguments of implicitly defined firstprivate clause 3265 // for task|target directives. 3266 // Skip analysis of arguments of implicitly defined map clause for target 3267 // directives. 3268 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3269 C->isImplicit())) { 3270 for (Stmt *CC : C->children()) { 3271 if (CC) 3272 Visit(CC); 3273 } 3274 } 3275 } 3276 // Check implicitly captured variables. 3277 VisitSubCaptures(S); 3278 } 3279 void VisitStmt(Stmt *S) { 3280 for (Stmt *C : S->children()) { 3281 if (C) { 3282 // Check implicitly captured variables in the task-based directives to 3283 // check if they must be firstprivatized. 3284 Visit(C); 3285 } 3286 } 3287 } 3288 3289 void visitSubCaptures(CapturedStmt *S) { 3290 for (const CapturedStmt::Capture &Cap : S->captures()) { 3291 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3292 continue; 3293 VarDecl *VD = Cap.getCapturedVar(); 3294 // Do not try to map the variable if it or its sub-component was mapped 3295 // already. 3296 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3297 Stack->checkMappableExprComponentListsForDecl( 3298 VD, /*CurrentRegionOnly=*/true, 3299 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3300 OpenMPClauseKind) { return true; })) 3301 continue; 3302 DeclRefExpr *DRE = buildDeclRefExpr( 3303 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3304 Cap.getLocation(), /*RefersToCapture=*/true); 3305 Visit(DRE); 3306 } 3307 } 3308 bool isErrorFound() const { return ErrorFound; } 3309 ArrayRef<Expr *> getImplicitFirstprivate() const { 3310 return ImplicitFirstprivate; 3311 } 3312 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3313 return ImplicitMap[Kind]; 3314 } 3315 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3316 return VarsWithInheritedDSA; 3317 } 3318 3319 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3320 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3321 // Process declare target link variables for the target directives. 3322 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3323 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3324 Visit(E); 3325 } 3326 } 3327 }; 3328 } // namespace 3329 3330 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3331 switch (DKind) { 3332 case OMPD_parallel: 3333 case OMPD_parallel_for: 3334 case OMPD_parallel_for_simd: 3335 case OMPD_parallel_sections: 3336 case OMPD_parallel_master: 3337 case OMPD_teams: 3338 case OMPD_teams_distribute: 3339 case OMPD_teams_distribute_simd: { 3340 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3341 QualType KmpInt32PtrTy = 3342 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3343 Sema::CapturedParamNameType Params[] = { 3344 std::make_pair(".global_tid.", KmpInt32PtrTy), 3345 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3346 std::make_pair(StringRef(), QualType()) // __context with shared vars 3347 }; 3348 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3349 Params); 3350 break; 3351 } 3352 case OMPD_target_teams: 3353 case OMPD_target_parallel: 3354 case OMPD_target_parallel_for: 3355 case OMPD_target_parallel_for_simd: 3356 case OMPD_target_teams_distribute: 3357 case OMPD_target_teams_distribute_simd: { 3358 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3359 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3360 QualType KmpInt32PtrTy = 3361 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3362 QualType Args[] = {VoidPtrTy}; 3363 FunctionProtoType::ExtProtoInfo EPI; 3364 EPI.Variadic = true; 3365 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3366 Sema::CapturedParamNameType Params[] = { 3367 std::make_pair(".global_tid.", KmpInt32Ty), 3368 std::make_pair(".part_id.", KmpInt32PtrTy), 3369 std::make_pair(".privates.", VoidPtrTy), 3370 std::make_pair( 3371 ".copy_fn.", 3372 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3373 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3374 std::make_pair(StringRef(), QualType()) // __context with shared vars 3375 }; 3376 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3377 Params, /*OpenMPCaptureLevel=*/0); 3378 // Mark this captured region as inlined, because we don't use outlined 3379 // function directly. 3380 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3381 AlwaysInlineAttr::CreateImplicit( 3382 Context, {}, AttributeCommonInfo::AS_Keyword, 3383 AlwaysInlineAttr::Keyword_forceinline)); 3384 Sema::CapturedParamNameType ParamsTarget[] = { 3385 std::make_pair(StringRef(), QualType()) // __context with shared vars 3386 }; 3387 // Start a captured region for 'target' with no implicit parameters. 3388 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3389 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3390 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3391 std::make_pair(".global_tid.", KmpInt32PtrTy), 3392 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3393 std::make_pair(StringRef(), QualType()) // __context with shared vars 3394 }; 3395 // Start a captured region for 'teams' or 'parallel'. Both regions have 3396 // the same implicit parameters. 3397 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3398 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3399 break; 3400 } 3401 case OMPD_target: 3402 case OMPD_target_simd: { 3403 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3404 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3405 QualType KmpInt32PtrTy = 3406 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3407 QualType Args[] = {VoidPtrTy}; 3408 FunctionProtoType::ExtProtoInfo EPI; 3409 EPI.Variadic = true; 3410 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3411 Sema::CapturedParamNameType Params[] = { 3412 std::make_pair(".global_tid.", KmpInt32Ty), 3413 std::make_pair(".part_id.", KmpInt32PtrTy), 3414 std::make_pair(".privates.", VoidPtrTy), 3415 std::make_pair( 3416 ".copy_fn.", 3417 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3418 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3419 std::make_pair(StringRef(), QualType()) // __context with shared vars 3420 }; 3421 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3422 Params, /*OpenMPCaptureLevel=*/0); 3423 // Mark this captured region as inlined, because we don't use outlined 3424 // function directly. 3425 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3426 AlwaysInlineAttr::CreateImplicit( 3427 Context, {}, AttributeCommonInfo::AS_Keyword, 3428 AlwaysInlineAttr::Keyword_forceinline)); 3429 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3430 std::make_pair(StringRef(), QualType()), 3431 /*OpenMPCaptureLevel=*/1); 3432 break; 3433 } 3434 case OMPD_simd: 3435 case OMPD_for: 3436 case OMPD_for_simd: 3437 case OMPD_sections: 3438 case OMPD_section: 3439 case OMPD_single: 3440 case OMPD_master: 3441 case OMPD_critical: 3442 case OMPD_taskgroup: 3443 case OMPD_distribute: 3444 case OMPD_distribute_simd: 3445 case OMPD_ordered: 3446 case OMPD_atomic: 3447 case OMPD_target_data: { 3448 Sema::CapturedParamNameType Params[] = { 3449 std::make_pair(StringRef(), QualType()) // __context with shared vars 3450 }; 3451 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3452 Params); 3453 break; 3454 } 3455 case OMPD_task: { 3456 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3457 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3458 QualType KmpInt32PtrTy = 3459 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3460 QualType Args[] = {VoidPtrTy}; 3461 FunctionProtoType::ExtProtoInfo EPI; 3462 EPI.Variadic = true; 3463 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3464 Sema::CapturedParamNameType Params[] = { 3465 std::make_pair(".global_tid.", KmpInt32Ty), 3466 std::make_pair(".part_id.", KmpInt32PtrTy), 3467 std::make_pair(".privates.", VoidPtrTy), 3468 std::make_pair( 3469 ".copy_fn.", 3470 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3471 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3472 std::make_pair(StringRef(), QualType()) // __context with shared vars 3473 }; 3474 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3475 Params); 3476 // Mark this captured region as inlined, because we don't use outlined 3477 // function directly. 3478 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3479 AlwaysInlineAttr::CreateImplicit( 3480 Context, {}, AttributeCommonInfo::AS_Keyword, 3481 AlwaysInlineAttr::Keyword_forceinline)); 3482 break; 3483 } 3484 case OMPD_taskloop: 3485 case OMPD_taskloop_simd: 3486 case OMPD_master_taskloop: 3487 case OMPD_master_taskloop_simd: { 3488 QualType KmpInt32Ty = 3489 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3490 .withConst(); 3491 QualType KmpUInt64Ty = 3492 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3493 .withConst(); 3494 QualType KmpInt64Ty = 3495 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3496 .withConst(); 3497 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3498 QualType KmpInt32PtrTy = 3499 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3500 QualType Args[] = {VoidPtrTy}; 3501 FunctionProtoType::ExtProtoInfo EPI; 3502 EPI.Variadic = true; 3503 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3504 Sema::CapturedParamNameType Params[] = { 3505 std::make_pair(".global_tid.", KmpInt32Ty), 3506 std::make_pair(".part_id.", KmpInt32PtrTy), 3507 std::make_pair(".privates.", VoidPtrTy), 3508 std::make_pair( 3509 ".copy_fn.", 3510 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3511 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3512 std::make_pair(".lb.", KmpUInt64Ty), 3513 std::make_pair(".ub.", KmpUInt64Ty), 3514 std::make_pair(".st.", KmpInt64Ty), 3515 std::make_pair(".liter.", KmpInt32Ty), 3516 std::make_pair(".reductions.", VoidPtrTy), 3517 std::make_pair(StringRef(), QualType()) // __context with shared vars 3518 }; 3519 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3520 Params); 3521 // Mark this captured region as inlined, because we don't use outlined 3522 // function directly. 3523 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3524 AlwaysInlineAttr::CreateImplicit( 3525 Context, {}, AttributeCommonInfo::AS_Keyword, 3526 AlwaysInlineAttr::Keyword_forceinline)); 3527 break; 3528 } 3529 case OMPD_parallel_master_taskloop: 3530 case OMPD_parallel_master_taskloop_simd: { 3531 QualType KmpInt32Ty = 3532 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3533 .withConst(); 3534 QualType KmpUInt64Ty = 3535 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3536 .withConst(); 3537 QualType KmpInt64Ty = 3538 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3539 .withConst(); 3540 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3541 QualType KmpInt32PtrTy = 3542 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3543 Sema::CapturedParamNameType ParamsParallel[] = { 3544 std::make_pair(".global_tid.", KmpInt32PtrTy), 3545 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3546 std::make_pair(StringRef(), QualType()) // __context with shared vars 3547 }; 3548 // Start a captured region for 'parallel'. 3549 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3550 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3551 QualType Args[] = {VoidPtrTy}; 3552 FunctionProtoType::ExtProtoInfo EPI; 3553 EPI.Variadic = true; 3554 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3555 Sema::CapturedParamNameType Params[] = { 3556 std::make_pair(".global_tid.", KmpInt32Ty), 3557 std::make_pair(".part_id.", KmpInt32PtrTy), 3558 std::make_pair(".privates.", VoidPtrTy), 3559 std::make_pair( 3560 ".copy_fn.", 3561 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3562 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3563 std::make_pair(".lb.", KmpUInt64Ty), 3564 std::make_pair(".ub.", KmpUInt64Ty), 3565 std::make_pair(".st.", KmpInt64Ty), 3566 std::make_pair(".liter.", KmpInt32Ty), 3567 std::make_pair(".reductions.", VoidPtrTy), 3568 std::make_pair(StringRef(), QualType()) // __context with shared vars 3569 }; 3570 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3571 Params, /*OpenMPCaptureLevel=*/2); 3572 // Mark this captured region as inlined, because we don't use outlined 3573 // function directly. 3574 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3575 AlwaysInlineAttr::CreateImplicit( 3576 Context, {}, AttributeCommonInfo::AS_Keyword, 3577 AlwaysInlineAttr::Keyword_forceinline)); 3578 break; 3579 } 3580 case OMPD_distribute_parallel_for_simd: 3581 case OMPD_distribute_parallel_for: { 3582 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3583 QualType KmpInt32PtrTy = 3584 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3585 Sema::CapturedParamNameType Params[] = { 3586 std::make_pair(".global_tid.", KmpInt32PtrTy), 3587 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3588 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3589 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3590 std::make_pair(StringRef(), QualType()) // __context with shared vars 3591 }; 3592 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3593 Params); 3594 break; 3595 } 3596 case OMPD_target_teams_distribute_parallel_for: 3597 case OMPD_target_teams_distribute_parallel_for_simd: { 3598 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3599 QualType KmpInt32PtrTy = 3600 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3601 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3602 3603 QualType Args[] = {VoidPtrTy}; 3604 FunctionProtoType::ExtProtoInfo EPI; 3605 EPI.Variadic = true; 3606 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3607 Sema::CapturedParamNameType Params[] = { 3608 std::make_pair(".global_tid.", KmpInt32Ty), 3609 std::make_pair(".part_id.", KmpInt32PtrTy), 3610 std::make_pair(".privates.", VoidPtrTy), 3611 std::make_pair( 3612 ".copy_fn.", 3613 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3614 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3615 std::make_pair(StringRef(), QualType()) // __context with shared vars 3616 }; 3617 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3618 Params, /*OpenMPCaptureLevel=*/0); 3619 // Mark this captured region as inlined, because we don't use outlined 3620 // function directly. 3621 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3622 AlwaysInlineAttr::CreateImplicit( 3623 Context, {}, AttributeCommonInfo::AS_Keyword, 3624 AlwaysInlineAttr::Keyword_forceinline)); 3625 Sema::CapturedParamNameType ParamsTarget[] = { 3626 std::make_pair(StringRef(), QualType()) // __context with shared vars 3627 }; 3628 // Start a captured region for 'target' with no implicit parameters. 3629 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3630 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3631 3632 Sema::CapturedParamNameType ParamsTeams[] = { 3633 std::make_pair(".global_tid.", KmpInt32PtrTy), 3634 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3635 std::make_pair(StringRef(), QualType()) // __context with shared vars 3636 }; 3637 // Start a captured region for 'target' with no implicit parameters. 3638 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3639 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3640 3641 Sema::CapturedParamNameType ParamsParallel[] = { 3642 std::make_pair(".global_tid.", KmpInt32PtrTy), 3643 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3644 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3645 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3646 std::make_pair(StringRef(), QualType()) // __context with shared vars 3647 }; 3648 // Start a captured region for 'teams' or 'parallel'. Both regions have 3649 // the same implicit parameters. 3650 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3651 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3652 break; 3653 } 3654 3655 case OMPD_teams_distribute_parallel_for: 3656 case OMPD_teams_distribute_parallel_for_simd: { 3657 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3658 QualType KmpInt32PtrTy = 3659 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3660 3661 Sema::CapturedParamNameType ParamsTeams[] = { 3662 std::make_pair(".global_tid.", KmpInt32PtrTy), 3663 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3664 std::make_pair(StringRef(), QualType()) // __context with shared vars 3665 }; 3666 // Start a captured region for 'target' with no implicit parameters. 3667 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3668 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3669 3670 Sema::CapturedParamNameType ParamsParallel[] = { 3671 std::make_pair(".global_tid.", KmpInt32PtrTy), 3672 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3673 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3674 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3675 std::make_pair(StringRef(), QualType()) // __context with shared vars 3676 }; 3677 // Start a captured region for 'teams' or 'parallel'. Both regions have 3678 // the same implicit parameters. 3679 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3680 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3681 break; 3682 } 3683 case OMPD_target_update: 3684 case OMPD_target_enter_data: 3685 case OMPD_target_exit_data: { 3686 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3687 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3688 QualType KmpInt32PtrTy = 3689 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3690 QualType Args[] = {VoidPtrTy}; 3691 FunctionProtoType::ExtProtoInfo EPI; 3692 EPI.Variadic = true; 3693 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3694 Sema::CapturedParamNameType Params[] = { 3695 std::make_pair(".global_tid.", KmpInt32Ty), 3696 std::make_pair(".part_id.", KmpInt32PtrTy), 3697 std::make_pair(".privates.", VoidPtrTy), 3698 std::make_pair( 3699 ".copy_fn.", 3700 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3701 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3702 std::make_pair(StringRef(), QualType()) // __context with shared vars 3703 }; 3704 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3705 Params); 3706 // Mark this captured region as inlined, because we don't use outlined 3707 // function directly. 3708 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3709 AlwaysInlineAttr::CreateImplicit( 3710 Context, {}, AttributeCommonInfo::AS_Keyword, 3711 AlwaysInlineAttr::Keyword_forceinline)); 3712 break; 3713 } 3714 case OMPD_threadprivate: 3715 case OMPD_allocate: 3716 case OMPD_taskyield: 3717 case OMPD_barrier: 3718 case OMPD_taskwait: 3719 case OMPD_cancellation_point: 3720 case OMPD_cancel: 3721 case OMPD_flush: 3722 case OMPD_declare_reduction: 3723 case OMPD_declare_mapper: 3724 case OMPD_declare_simd: 3725 case OMPD_declare_target: 3726 case OMPD_end_declare_target: 3727 case OMPD_requires: 3728 case OMPD_declare_variant: 3729 llvm_unreachable("OpenMP Directive is not allowed"); 3730 case OMPD_unknown: 3731 llvm_unreachable("Unknown OpenMP directive"); 3732 } 3733 } 3734 3735 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3736 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3737 } 3738 3739 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3740 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3741 getOpenMPCaptureRegions(CaptureRegions, DKind); 3742 return CaptureRegions.size(); 3743 } 3744 3745 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3746 Expr *CaptureExpr, bool WithInit, 3747 bool AsExpression) { 3748 assert(CaptureExpr); 3749 ASTContext &C = S.getASTContext(); 3750 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3751 QualType Ty = Init->getType(); 3752 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3753 if (S.getLangOpts().CPlusPlus) { 3754 Ty = C.getLValueReferenceType(Ty); 3755 } else { 3756 Ty = C.getPointerType(Ty); 3757 ExprResult Res = 3758 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3759 if (!Res.isUsable()) 3760 return nullptr; 3761 Init = Res.get(); 3762 } 3763 WithInit = true; 3764 } 3765 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3766 CaptureExpr->getBeginLoc()); 3767 if (!WithInit) 3768 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3769 S.CurContext->addHiddenDecl(CED); 3770 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3771 return CED; 3772 } 3773 3774 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3775 bool WithInit) { 3776 OMPCapturedExprDecl *CD; 3777 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3778 CD = cast<OMPCapturedExprDecl>(VD); 3779 else 3780 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3781 /*AsExpression=*/false); 3782 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3783 CaptureExpr->getExprLoc()); 3784 } 3785 3786 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3787 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3788 if (!Ref) { 3789 OMPCapturedExprDecl *CD = buildCaptureDecl( 3790 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3791 /*WithInit=*/true, /*AsExpression=*/true); 3792 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3793 CaptureExpr->getExprLoc()); 3794 } 3795 ExprResult Res = Ref; 3796 if (!S.getLangOpts().CPlusPlus && 3797 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3798 Ref->getType()->isPointerType()) { 3799 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3800 if (!Res.isUsable()) 3801 return ExprError(); 3802 } 3803 return S.DefaultLvalueConversion(Res.get()); 3804 } 3805 3806 namespace { 3807 // OpenMP directives parsed in this section are represented as a 3808 // CapturedStatement with an associated statement. If a syntax error 3809 // is detected during the parsing of the associated statement, the 3810 // compiler must abort processing and close the CapturedStatement. 3811 // 3812 // Combined directives such as 'target parallel' have more than one 3813 // nested CapturedStatements. This RAII ensures that we unwind out 3814 // of all the nested CapturedStatements when an error is found. 3815 class CaptureRegionUnwinderRAII { 3816 private: 3817 Sema &S; 3818 bool &ErrorFound; 3819 OpenMPDirectiveKind DKind = OMPD_unknown; 3820 3821 public: 3822 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3823 OpenMPDirectiveKind DKind) 3824 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3825 ~CaptureRegionUnwinderRAII() { 3826 if (ErrorFound) { 3827 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3828 while (--ThisCaptureLevel >= 0) 3829 S.ActOnCapturedRegionError(); 3830 } 3831 } 3832 }; 3833 } // namespace 3834 3835 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3836 // Capture variables captured by reference in lambdas for target-based 3837 // directives. 3838 if (!CurContext->isDependentContext() && 3839 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3840 isOpenMPTargetDataManagementDirective( 3841 DSAStack->getCurrentDirective()))) { 3842 QualType Type = V->getType(); 3843 if (const auto *RD = Type.getCanonicalType() 3844 .getNonReferenceType() 3845 ->getAsCXXRecordDecl()) { 3846 bool SavedForceCaptureByReferenceInTargetExecutable = 3847 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3848 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3849 /*V=*/true); 3850 if (RD->isLambda()) { 3851 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3852 FieldDecl *ThisCapture; 3853 RD->getCaptureFields(Captures, ThisCapture); 3854 for (const LambdaCapture &LC : RD->captures()) { 3855 if (LC.getCaptureKind() == LCK_ByRef) { 3856 VarDecl *VD = LC.getCapturedVar(); 3857 DeclContext *VDC = VD->getDeclContext(); 3858 if (!VDC->Encloses(CurContext)) 3859 continue; 3860 MarkVariableReferenced(LC.getLocation(), VD); 3861 } else if (LC.getCaptureKind() == LCK_This) { 3862 QualType ThisTy = getCurrentThisType(); 3863 if (!ThisTy.isNull() && 3864 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3865 CheckCXXThisCapture(LC.getLocation()); 3866 } 3867 } 3868 } 3869 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3870 SavedForceCaptureByReferenceInTargetExecutable); 3871 } 3872 } 3873 } 3874 3875 static bool checkOrderedOrderSpecified(Sema &S, 3876 const ArrayRef<OMPClause *> Clauses) { 3877 const OMPOrderedClause *Ordered = nullptr; 3878 const OMPOrderClause *Order = nullptr; 3879 3880 for (const OMPClause *Clause : Clauses) { 3881 if (Clause->getClauseKind() == OMPC_ordered) 3882 Ordered = cast<OMPOrderedClause>(Clause); 3883 else if (Clause->getClauseKind() == OMPC_order) { 3884 Order = cast<OMPOrderClause>(Clause); 3885 if (Order->getKind() != OMPC_ORDER_concurrent) 3886 Order = nullptr; 3887 } 3888 if (Ordered && Order) 3889 break; 3890 } 3891 3892 if (Ordered && Order) { 3893 S.Diag(Order->getKindKwLoc(), 3894 diag::err_omp_simple_clause_incompatible_with_ordered) 3895 << getOpenMPClauseName(OMPC_order) 3896 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 3897 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 3898 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 3899 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 3900 return true; 3901 } 3902 return false; 3903 } 3904 3905 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3906 ArrayRef<OMPClause *> Clauses) { 3907 bool ErrorFound = false; 3908 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3909 *this, ErrorFound, DSAStack->getCurrentDirective()); 3910 if (!S.isUsable()) { 3911 ErrorFound = true; 3912 return StmtError(); 3913 } 3914 3915 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3916 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3917 OMPOrderedClause *OC = nullptr; 3918 OMPScheduleClause *SC = nullptr; 3919 SmallVector<const OMPLinearClause *, 4> LCs; 3920 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3921 // This is required for proper codegen. 3922 for (OMPClause *Clause : Clauses) { 3923 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3924 Clause->getClauseKind() == OMPC_in_reduction) { 3925 // Capture taskgroup task_reduction descriptors inside the tasking regions 3926 // with the corresponding in_reduction items. 3927 auto *IRC = cast<OMPInReductionClause>(Clause); 3928 for (Expr *E : IRC->taskgroup_descriptors()) 3929 if (E) 3930 MarkDeclarationsReferencedInExpr(E); 3931 } 3932 if (isOpenMPPrivate(Clause->getClauseKind()) || 3933 Clause->getClauseKind() == OMPC_copyprivate || 3934 (getLangOpts().OpenMPUseTLS && 3935 getASTContext().getTargetInfo().isTLSSupported() && 3936 Clause->getClauseKind() == OMPC_copyin)) { 3937 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3938 // Mark all variables in private list clauses as used in inner region. 3939 for (Stmt *VarRef : Clause->children()) { 3940 if (auto *E = cast_or_null<Expr>(VarRef)) { 3941 MarkDeclarationsReferencedInExpr(E); 3942 } 3943 } 3944 DSAStack->setForceVarCapturing(/*V=*/false); 3945 } else if (CaptureRegions.size() > 1 || 3946 CaptureRegions.back() != OMPD_unknown) { 3947 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3948 PICs.push_back(C); 3949 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3950 if (Expr *E = C->getPostUpdateExpr()) 3951 MarkDeclarationsReferencedInExpr(E); 3952 } 3953 } 3954 if (Clause->getClauseKind() == OMPC_schedule) 3955 SC = cast<OMPScheduleClause>(Clause); 3956 else if (Clause->getClauseKind() == OMPC_ordered) 3957 OC = cast<OMPOrderedClause>(Clause); 3958 else if (Clause->getClauseKind() == OMPC_linear) 3959 LCs.push_back(cast<OMPLinearClause>(Clause)); 3960 } 3961 // Capture allocator expressions if used. 3962 for (Expr *E : DSAStack->getInnerAllocators()) 3963 MarkDeclarationsReferencedInExpr(E); 3964 // OpenMP, 2.7.1 Loop Construct, Restrictions 3965 // The nonmonotonic modifier cannot be specified if an ordered clause is 3966 // specified. 3967 if (SC && 3968 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3969 SC->getSecondScheduleModifier() == 3970 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3971 OC) { 3972 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3973 ? SC->getFirstScheduleModifierLoc() 3974 : SC->getSecondScheduleModifierLoc(), 3975 diag::err_omp_simple_clause_incompatible_with_ordered) 3976 << getOpenMPClauseName(OMPC_schedule) 3977 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 3978 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 3979 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3980 ErrorFound = true; 3981 } 3982 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 3983 // If an order(concurrent) clause is present, an ordered clause may not appear 3984 // on the same directive. 3985 if (checkOrderedOrderSpecified(*this, Clauses)) 3986 ErrorFound = true; 3987 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3988 for (const OMPLinearClause *C : LCs) { 3989 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3990 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3991 } 3992 ErrorFound = true; 3993 } 3994 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3995 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3996 OC->getNumForLoops()) { 3997 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3998 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3999 ErrorFound = true; 4000 } 4001 if (ErrorFound) { 4002 return StmtError(); 4003 } 4004 StmtResult SR = S; 4005 unsigned CompletedRegions = 0; 4006 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4007 // Mark all variables in private list clauses as used in inner region. 4008 // Required for proper codegen of combined directives. 4009 // TODO: add processing for other clauses. 4010 if (ThisCaptureRegion != OMPD_unknown) { 4011 for (const clang::OMPClauseWithPreInit *C : PICs) { 4012 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4013 // Find the particular capture region for the clause if the 4014 // directive is a combined one with multiple capture regions. 4015 // If the directive is not a combined one, the capture region 4016 // associated with the clause is OMPD_unknown and is generated 4017 // only once. 4018 if (CaptureRegion == ThisCaptureRegion || 4019 CaptureRegion == OMPD_unknown) { 4020 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4021 for (Decl *D : DS->decls()) 4022 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4023 } 4024 } 4025 } 4026 } 4027 if (++CompletedRegions == CaptureRegions.size()) 4028 DSAStack->setBodyComplete(); 4029 SR = ActOnCapturedRegionEnd(SR.get()); 4030 } 4031 return SR; 4032 } 4033 4034 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4035 OpenMPDirectiveKind CancelRegion, 4036 SourceLocation StartLoc) { 4037 // CancelRegion is only needed for cancel and cancellation_point. 4038 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4039 return false; 4040 4041 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4042 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4043 return false; 4044 4045 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4046 << getOpenMPDirectiveName(CancelRegion); 4047 return true; 4048 } 4049 4050 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4051 OpenMPDirectiveKind CurrentRegion, 4052 const DeclarationNameInfo &CurrentName, 4053 OpenMPDirectiveKind CancelRegion, 4054 SourceLocation StartLoc) { 4055 if (Stack->getCurScope()) { 4056 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4057 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4058 bool NestingProhibited = false; 4059 bool CloseNesting = true; 4060 bool OrphanSeen = false; 4061 enum { 4062 NoRecommend, 4063 ShouldBeInParallelRegion, 4064 ShouldBeInOrderedRegion, 4065 ShouldBeInTargetRegion, 4066 ShouldBeInTeamsRegion 4067 } Recommend = NoRecommend; 4068 if (isOpenMPSimdDirective(ParentRegion) && 4069 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4070 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4071 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { 4072 // OpenMP [2.16, Nesting of Regions] 4073 // OpenMP constructs may not be nested inside a simd region. 4074 // OpenMP [2.8.1,simd Construct, Restrictions] 4075 // An ordered construct with the simd clause is the only OpenMP 4076 // construct that can appear in the simd region. 4077 // Allowing a SIMD construct nested in another SIMD construct is an 4078 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4079 // message. 4080 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4081 // The only OpenMP constructs that can be encountered during execution of 4082 // a simd region are the atomic construct, the loop construct, the simd 4083 // construct and the ordered construct with the simd clause. 4084 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4085 ? diag::err_omp_prohibited_region_simd 4086 : diag::warn_omp_nesting_simd) 4087 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4088 return CurrentRegion != OMPD_simd; 4089 } 4090 if (ParentRegion == OMPD_atomic) { 4091 // OpenMP [2.16, Nesting of Regions] 4092 // OpenMP constructs may not be nested inside an atomic region. 4093 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4094 return true; 4095 } 4096 if (CurrentRegion == OMPD_section) { 4097 // OpenMP [2.7.2, sections Construct, Restrictions] 4098 // Orphaned section directives are prohibited. That is, the section 4099 // directives must appear within the sections construct and must not be 4100 // encountered elsewhere in the sections region. 4101 if (ParentRegion != OMPD_sections && 4102 ParentRegion != OMPD_parallel_sections) { 4103 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4104 << (ParentRegion != OMPD_unknown) 4105 << getOpenMPDirectiveName(ParentRegion); 4106 return true; 4107 } 4108 return false; 4109 } 4110 // Allow some constructs (except teams and cancellation constructs) to be 4111 // orphaned (they could be used in functions, called from OpenMP regions 4112 // with the required preconditions). 4113 if (ParentRegion == OMPD_unknown && 4114 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4115 CurrentRegion != OMPD_cancellation_point && 4116 CurrentRegion != OMPD_cancel) 4117 return false; 4118 if (CurrentRegion == OMPD_cancellation_point || 4119 CurrentRegion == OMPD_cancel) { 4120 // OpenMP [2.16, Nesting of Regions] 4121 // A cancellation point construct for which construct-type-clause is 4122 // taskgroup must be nested inside a task construct. A cancellation 4123 // point construct for which construct-type-clause is not taskgroup must 4124 // be closely nested inside an OpenMP construct that matches the type 4125 // specified in construct-type-clause. 4126 // A cancel construct for which construct-type-clause is taskgroup must be 4127 // nested inside a task construct. A cancel construct for which 4128 // construct-type-clause is not taskgroup must be closely nested inside an 4129 // OpenMP construct that matches the type specified in 4130 // construct-type-clause. 4131 NestingProhibited = 4132 !((CancelRegion == OMPD_parallel && 4133 (ParentRegion == OMPD_parallel || 4134 ParentRegion == OMPD_target_parallel)) || 4135 (CancelRegion == OMPD_for && 4136 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4137 ParentRegion == OMPD_target_parallel_for || 4138 ParentRegion == OMPD_distribute_parallel_for || 4139 ParentRegion == OMPD_teams_distribute_parallel_for || 4140 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4141 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 4142 (CancelRegion == OMPD_sections && 4143 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4144 ParentRegion == OMPD_parallel_sections))); 4145 OrphanSeen = ParentRegion == OMPD_unknown; 4146 } else if (CurrentRegion == OMPD_master) { 4147 // OpenMP [2.16, Nesting of Regions] 4148 // A master region may not be closely nested inside a worksharing, 4149 // atomic, or explicit task region. 4150 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4151 isOpenMPTaskingDirective(ParentRegion); 4152 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4153 // OpenMP [2.16, Nesting of Regions] 4154 // A critical region may not be nested (closely or otherwise) inside a 4155 // critical region with the same name. Note that this restriction is not 4156 // sufficient to prevent deadlock. 4157 SourceLocation PreviousCriticalLoc; 4158 bool DeadLock = Stack->hasDirective( 4159 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4160 const DeclarationNameInfo &DNI, 4161 SourceLocation Loc) { 4162 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4163 PreviousCriticalLoc = Loc; 4164 return true; 4165 } 4166 return false; 4167 }, 4168 false /* skip top directive */); 4169 if (DeadLock) { 4170 SemaRef.Diag(StartLoc, 4171 diag::err_omp_prohibited_region_critical_same_name) 4172 << CurrentName.getName(); 4173 if (PreviousCriticalLoc.isValid()) 4174 SemaRef.Diag(PreviousCriticalLoc, 4175 diag::note_omp_previous_critical_region); 4176 return true; 4177 } 4178 } else if (CurrentRegion == OMPD_barrier) { 4179 // OpenMP [2.16, Nesting of Regions] 4180 // A barrier region may not be closely nested inside a worksharing, 4181 // explicit task, critical, ordered, atomic, or master region. 4182 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4183 isOpenMPTaskingDirective(ParentRegion) || 4184 ParentRegion == OMPD_master || 4185 ParentRegion == OMPD_parallel_master || 4186 ParentRegion == OMPD_critical || 4187 ParentRegion == OMPD_ordered; 4188 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4189 !isOpenMPParallelDirective(CurrentRegion) && 4190 !isOpenMPTeamsDirective(CurrentRegion)) { 4191 // OpenMP [2.16, Nesting of Regions] 4192 // A worksharing region may not be closely nested inside a worksharing, 4193 // explicit task, critical, ordered, atomic, or master region. 4194 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4195 isOpenMPTaskingDirective(ParentRegion) || 4196 ParentRegion == OMPD_master || 4197 ParentRegion == OMPD_parallel_master || 4198 ParentRegion == OMPD_critical || 4199 ParentRegion == OMPD_ordered; 4200 Recommend = ShouldBeInParallelRegion; 4201 } else if (CurrentRegion == OMPD_ordered) { 4202 // OpenMP [2.16, Nesting of Regions] 4203 // An ordered region may not be closely nested inside a critical, 4204 // atomic, or explicit task region. 4205 // An ordered region must be closely nested inside a loop region (or 4206 // parallel loop region) with an ordered clause. 4207 // OpenMP [2.8.1,simd Construct, Restrictions] 4208 // An ordered construct with the simd clause is the only OpenMP construct 4209 // that can appear in the simd region. 4210 NestingProhibited = ParentRegion == OMPD_critical || 4211 isOpenMPTaskingDirective(ParentRegion) || 4212 !(isOpenMPSimdDirective(ParentRegion) || 4213 Stack->isParentOrderedRegion()); 4214 Recommend = ShouldBeInOrderedRegion; 4215 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4216 // OpenMP [2.16, Nesting of Regions] 4217 // If specified, a teams construct must be contained within a target 4218 // construct. 4219 NestingProhibited = 4220 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4221 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4222 ParentRegion != OMPD_target); 4223 OrphanSeen = ParentRegion == OMPD_unknown; 4224 Recommend = ShouldBeInTargetRegion; 4225 } 4226 if (!NestingProhibited && 4227 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4228 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4229 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4230 // OpenMP [2.16, Nesting of Regions] 4231 // distribute, parallel, parallel sections, parallel workshare, and the 4232 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4233 // constructs that can be closely nested in the teams region. 4234 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4235 !isOpenMPDistributeDirective(CurrentRegion); 4236 Recommend = ShouldBeInParallelRegion; 4237 } 4238 if (!NestingProhibited && 4239 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4240 // OpenMP 4.5 [2.17 Nesting of Regions] 4241 // The region associated with the distribute construct must be strictly 4242 // nested inside a teams region 4243 NestingProhibited = 4244 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4245 Recommend = ShouldBeInTeamsRegion; 4246 } 4247 if (!NestingProhibited && 4248 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4249 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4250 // OpenMP 4.5 [2.17 Nesting of Regions] 4251 // If a target, target update, target data, target enter data, or 4252 // target exit data construct is encountered during execution of a 4253 // target region, the behavior is unspecified. 4254 NestingProhibited = Stack->hasDirective( 4255 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4256 SourceLocation) { 4257 if (isOpenMPTargetExecutionDirective(K)) { 4258 OffendingRegion = K; 4259 return true; 4260 } 4261 return false; 4262 }, 4263 false /* don't skip top directive */); 4264 CloseNesting = false; 4265 } 4266 if (NestingProhibited) { 4267 if (OrphanSeen) { 4268 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4269 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4270 } else { 4271 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4272 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4273 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4274 } 4275 return true; 4276 } 4277 } 4278 return false; 4279 } 4280 4281 struct Kind2Unsigned { 4282 using argument_type = OpenMPDirectiveKind; 4283 unsigned operator()(argument_type DK) { return unsigned(DK); } 4284 }; 4285 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4286 ArrayRef<OMPClause *> Clauses, 4287 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4288 bool ErrorFound = false; 4289 unsigned NamedModifiersNumber = 0; 4290 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4291 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4292 SmallVector<SourceLocation, 4> NameModifierLoc; 4293 for (const OMPClause *C : Clauses) { 4294 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4295 // At most one if clause without a directive-name-modifier can appear on 4296 // the directive. 4297 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4298 if (FoundNameModifiers[CurNM]) { 4299 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4300 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4301 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4302 ErrorFound = true; 4303 } else if (CurNM != OMPD_unknown) { 4304 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4305 ++NamedModifiersNumber; 4306 } 4307 FoundNameModifiers[CurNM] = IC; 4308 if (CurNM == OMPD_unknown) 4309 continue; 4310 // Check if the specified name modifier is allowed for the current 4311 // directive. 4312 // At most one if clause with the particular directive-name-modifier can 4313 // appear on the directive. 4314 bool MatchFound = false; 4315 for (auto NM : AllowedNameModifiers) { 4316 if (CurNM == NM) { 4317 MatchFound = true; 4318 break; 4319 } 4320 } 4321 if (!MatchFound) { 4322 S.Diag(IC->getNameModifierLoc(), 4323 diag::err_omp_wrong_if_directive_name_modifier) 4324 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4325 ErrorFound = true; 4326 } 4327 } 4328 } 4329 // If any if clause on the directive includes a directive-name-modifier then 4330 // all if clauses on the directive must include a directive-name-modifier. 4331 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4332 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4333 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4334 diag::err_omp_no_more_if_clause); 4335 } else { 4336 std::string Values; 4337 std::string Sep(", "); 4338 unsigned AllowedCnt = 0; 4339 unsigned TotalAllowedNum = 4340 AllowedNameModifiers.size() - NamedModifiersNumber; 4341 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4342 ++Cnt) { 4343 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4344 if (!FoundNameModifiers[NM]) { 4345 Values += "'"; 4346 Values += getOpenMPDirectiveName(NM); 4347 Values += "'"; 4348 if (AllowedCnt + 2 == TotalAllowedNum) 4349 Values += " or "; 4350 else if (AllowedCnt + 1 != TotalAllowedNum) 4351 Values += Sep; 4352 ++AllowedCnt; 4353 } 4354 } 4355 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4356 diag::err_omp_unnamed_if_clause) 4357 << (TotalAllowedNum > 1) << Values; 4358 } 4359 for (SourceLocation Loc : NameModifierLoc) { 4360 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4361 } 4362 ErrorFound = true; 4363 } 4364 return ErrorFound; 4365 } 4366 4367 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4368 SourceLocation &ELoc, 4369 SourceRange &ERange, 4370 bool AllowArraySection) { 4371 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4372 RefExpr->containsUnexpandedParameterPack()) 4373 return std::make_pair(nullptr, true); 4374 4375 // OpenMP [3.1, C/C++] 4376 // A list item is a variable name. 4377 // OpenMP [2.9.3.3, Restrictions, p.1] 4378 // A variable that is part of another variable (as an array or 4379 // structure element) cannot appear in a private clause. 4380 RefExpr = RefExpr->IgnoreParens(); 4381 enum { 4382 NoArrayExpr = -1, 4383 ArraySubscript = 0, 4384 OMPArraySection = 1 4385 } IsArrayExpr = NoArrayExpr; 4386 if (AllowArraySection) { 4387 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4388 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4389 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4390 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4391 RefExpr = Base; 4392 IsArrayExpr = ArraySubscript; 4393 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4394 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4395 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4396 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4397 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4398 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4399 RefExpr = Base; 4400 IsArrayExpr = OMPArraySection; 4401 } 4402 } 4403 ELoc = RefExpr->getExprLoc(); 4404 ERange = RefExpr->getSourceRange(); 4405 RefExpr = RefExpr->IgnoreParenImpCasts(); 4406 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4407 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4408 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4409 (S.getCurrentThisType().isNull() || !ME || 4410 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4411 !isa<FieldDecl>(ME->getMemberDecl()))) { 4412 if (IsArrayExpr != NoArrayExpr) { 4413 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4414 << ERange; 4415 } else { 4416 S.Diag(ELoc, 4417 AllowArraySection 4418 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4419 : diag::err_omp_expected_var_name_member_expr) 4420 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4421 } 4422 return std::make_pair(nullptr, false); 4423 } 4424 return std::make_pair( 4425 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4426 } 4427 4428 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4429 ArrayRef<OMPClause *> Clauses) { 4430 assert(!S.CurContext->isDependentContext() && 4431 "Expected non-dependent context."); 4432 auto AllocateRange = 4433 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4434 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4435 DeclToCopy; 4436 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4437 return isOpenMPPrivate(C->getClauseKind()); 4438 }); 4439 for (OMPClause *Cl : PrivateRange) { 4440 MutableArrayRef<Expr *>::iterator I, It, Et; 4441 if (Cl->getClauseKind() == OMPC_private) { 4442 auto *PC = cast<OMPPrivateClause>(Cl); 4443 I = PC->private_copies().begin(); 4444 It = PC->varlist_begin(); 4445 Et = PC->varlist_end(); 4446 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4447 auto *PC = cast<OMPFirstprivateClause>(Cl); 4448 I = PC->private_copies().begin(); 4449 It = PC->varlist_begin(); 4450 Et = PC->varlist_end(); 4451 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4452 auto *PC = cast<OMPLastprivateClause>(Cl); 4453 I = PC->private_copies().begin(); 4454 It = PC->varlist_begin(); 4455 Et = PC->varlist_end(); 4456 } else if (Cl->getClauseKind() == OMPC_linear) { 4457 auto *PC = cast<OMPLinearClause>(Cl); 4458 I = PC->privates().begin(); 4459 It = PC->varlist_begin(); 4460 Et = PC->varlist_end(); 4461 } else if (Cl->getClauseKind() == OMPC_reduction) { 4462 auto *PC = cast<OMPReductionClause>(Cl); 4463 I = PC->privates().begin(); 4464 It = PC->varlist_begin(); 4465 Et = PC->varlist_end(); 4466 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4467 auto *PC = cast<OMPTaskReductionClause>(Cl); 4468 I = PC->privates().begin(); 4469 It = PC->varlist_begin(); 4470 Et = PC->varlist_end(); 4471 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4472 auto *PC = cast<OMPInReductionClause>(Cl); 4473 I = PC->privates().begin(); 4474 It = PC->varlist_begin(); 4475 Et = PC->varlist_end(); 4476 } else { 4477 llvm_unreachable("Expected private clause."); 4478 } 4479 for (Expr *E : llvm::make_range(It, Et)) { 4480 if (!*I) { 4481 ++I; 4482 continue; 4483 } 4484 SourceLocation ELoc; 4485 SourceRange ERange; 4486 Expr *SimpleRefExpr = E; 4487 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4488 /*AllowArraySection=*/true); 4489 DeclToCopy.try_emplace(Res.first, 4490 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4491 ++I; 4492 } 4493 } 4494 for (OMPClause *C : AllocateRange) { 4495 auto *AC = cast<OMPAllocateClause>(C); 4496 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4497 getAllocatorKind(S, Stack, AC->getAllocator()); 4498 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4499 // For task, taskloop or target directives, allocation requests to memory 4500 // allocators with the trait access set to thread result in unspecified 4501 // behavior. 4502 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4503 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4504 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4505 S.Diag(AC->getAllocator()->getExprLoc(), 4506 diag::warn_omp_allocate_thread_on_task_target_directive) 4507 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4508 } 4509 for (Expr *E : AC->varlists()) { 4510 SourceLocation ELoc; 4511 SourceRange ERange; 4512 Expr *SimpleRefExpr = E; 4513 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4514 ValueDecl *VD = Res.first; 4515 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4516 if (!isOpenMPPrivate(Data.CKind)) { 4517 S.Diag(E->getExprLoc(), 4518 diag::err_omp_expected_private_copy_for_allocate); 4519 continue; 4520 } 4521 VarDecl *PrivateVD = DeclToCopy[VD]; 4522 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4523 AllocatorKind, AC->getAllocator())) 4524 continue; 4525 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4526 E->getSourceRange()); 4527 } 4528 } 4529 } 4530 4531 StmtResult Sema::ActOnOpenMPExecutableDirective( 4532 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4533 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4534 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4535 StmtResult Res = StmtError(); 4536 // First check CancelRegion which is then used in checkNestingOfRegions. 4537 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4538 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4539 StartLoc)) 4540 return StmtError(); 4541 4542 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4543 VarsWithInheritedDSAType VarsWithInheritedDSA; 4544 bool ErrorFound = false; 4545 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4546 if (AStmt && !CurContext->isDependentContext()) { 4547 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4548 4549 // Check default data sharing attributes for referenced variables. 4550 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4551 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4552 Stmt *S = AStmt; 4553 while (--ThisCaptureLevel >= 0) 4554 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4555 DSAChecker.Visit(S); 4556 if (!isOpenMPTargetDataManagementDirective(Kind) && 4557 !isOpenMPTaskingDirective(Kind)) { 4558 // Visit subcaptures to generate implicit clauses for captured vars. 4559 auto *CS = cast<CapturedStmt>(AStmt); 4560 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4561 getOpenMPCaptureRegions(CaptureRegions, Kind); 4562 // Ignore outer tasking regions for target directives. 4563 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4564 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4565 DSAChecker.visitSubCaptures(CS); 4566 } 4567 if (DSAChecker.isErrorFound()) 4568 return StmtError(); 4569 // Generate list of implicitly defined firstprivate variables. 4570 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4571 4572 SmallVector<Expr *, 4> ImplicitFirstprivates( 4573 DSAChecker.getImplicitFirstprivate().begin(), 4574 DSAChecker.getImplicitFirstprivate().end()); 4575 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4576 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4577 ArrayRef<Expr *> ImplicitMap = 4578 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4579 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4580 } 4581 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4582 for (OMPClause *C : Clauses) { 4583 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4584 for (Expr *E : IRC->taskgroup_descriptors()) 4585 if (E) 4586 ImplicitFirstprivates.emplace_back(E); 4587 } 4588 } 4589 if (!ImplicitFirstprivates.empty()) { 4590 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4591 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4592 SourceLocation())) { 4593 ClausesWithImplicit.push_back(Implicit); 4594 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4595 ImplicitFirstprivates.size(); 4596 } else { 4597 ErrorFound = true; 4598 } 4599 } 4600 int ClauseKindCnt = -1; 4601 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4602 ++ClauseKindCnt; 4603 if (ImplicitMap.empty()) 4604 continue; 4605 CXXScopeSpec MapperIdScopeSpec; 4606 DeclarationNameInfo MapperId; 4607 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4608 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4609 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4610 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4611 ImplicitMap, OMPVarListLocTy())) { 4612 ClausesWithImplicit.emplace_back(Implicit); 4613 ErrorFound |= 4614 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4615 } else { 4616 ErrorFound = true; 4617 } 4618 } 4619 } 4620 4621 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4622 switch (Kind) { 4623 case OMPD_parallel: 4624 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4625 EndLoc); 4626 AllowedNameModifiers.push_back(OMPD_parallel); 4627 break; 4628 case OMPD_simd: 4629 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4630 VarsWithInheritedDSA); 4631 if (LangOpts.OpenMP >= 50) 4632 AllowedNameModifiers.push_back(OMPD_simd); 4633 break; 4634 case OMPD_for: 4635 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4636 VarsWithInheritedDSA); 4637 break; 4638 case OMPD_for_simd: 4639 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4640 EndLoc, VarsWithInheritedDSA); 4641 if (LangOpts.OpenMP >= 50) 4642 AllowedNameModifiers.push_back(OMPD_simd); 4643 break; 4644 case OMPD_sections: 4645 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4646 EndLoc); 4647 break; 4648 case OMPD_section: 4649 assert(ClausesWithImplicit.empty() && 4650 "No clauses are allowed for 'omp section' directive"); 4651 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4652 break; 4653 case OMPD_single: 4654 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4655 EndLoc); 4656 break; 4657 case OMPD_master: 4658 assert(ClausesWithImplicit.empty() && 4659 "No clauses are allowed for 'omp master' directive"); 4660 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4661 break; 4662 case OMPD_critical: 4663 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4664 StartLoc, EndLoc); 4665 break; 4666 case OMPD_parallel_for: 4667 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4668 EndLoc, VarsWithInheritedDSA); 4669 AllowedNameModifiers.push_back(OMPD_parallel); 4670 break; 4671 case OMPD_parallel_for_simd: 4672 Res = ActOnOpenMPParallelForSimdDirective( 4673 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4674 AllowedNameModifiers.push_back(OMPD_parallel); 4675 if (LangOpts.OpenMP >= 50) 4676 AllowedNameModifiers.push_back(OMPD_simd); 4677 break; 4678 case OMPD_parallel_master: 4679 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4680 StartLoc, EndLoc); 4681 AllowedNameModifiers.push_back(OMPD_parallel); 4682 break; 4683 case OMPD_parallel_sections: 4684 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4685 StartLoc, EndLoc); 4686 AllowedNameModifiers.push_back(OMPD_parallel); 4687 break; 4688 case OMPD_task: 4689 Res = 4690 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4691 AllowedNameModifiers.push_back(OMPD_task); 4692 break; 4693 case OMPD_taskyield: 4694 assert(ClausesWithImplicit.empty() && 4695 "No clauses are allowed for 'omp taskyield' directive"); 4696 assert(AStmt == nullptr && 4697 "No associated statement allowed for 'omp taskyield' directive"); 4698 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4699 break; 4700 case OMPD_barrier: 4701 assert(ClausesWithImplicit.empty() && 4702 "No clauses are allowed for 'omp barrier' directive"); 4703 assert(AStmt == nullptr && 4704 "No associated statement allowed for 'omp barrier' directive"); 4705 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4706 break; 4707 case OMPD_taskwait: 4708 assert(ClausesWithImplicit.empty() && 4709 "No clauses are allowed for 'omp taskwait' directive"); 4710 assert(AStmt == nullptr && 4711 "No associated statement allowed for 'omp taskwait' directive"); 4712 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4713 break; 4714 case OMPD_taskgroup: 4715 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4716 EndLoc); 4717 break; 4718 case OMPD_flush: 4719 assert(AStmt == nullptr && 4720 "No associated statement allowed for 'omp flush' directive"); 4721 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4722 break; 4723 case OMPD_ordered: 4724 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4725 EndLoc); 4726 break; 4727 case OMPD_atomic: 4728 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4729 EndLoc); 4730 break; 4731 case OMPD_teams: 4732 Res = 4733 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4734 break; 4735 case OMPD_target: 4736 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4737 EndLoc); 4738 AllowedNameModifiers.push_back(OMPD_target); 4739 break; 4740 case OMPD_target_parallel: 4741 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4742 StartLoc, EndLoc); 4743 AllowedNameModifiers.push_back(OMPD_target); 4744 AllowedNameModifiers.push_back(OMPD_parallel); 4745 break; 4746 case OMPD_target_parallel_for: 4747 Res = ActOnOpenMPTargetParallelForDirective( 4748 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4749 AllowedNameModifiers.push_back(OMPD_target); 4750 AllowedNameModifiers.push_back(OMPD_parallel); 4751 break; 4752 case OMPD_cancellation_point: 4753 assert(ClausesWithImplicit.empty() && 4754 "No clauses are allowed for 'omp cancellation point' directive"); 4755 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4756 "cancellation point' directive"); 4757 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4758 break; 4759 case OMPD_cancel: 4760 assert(AStmt == nullptr && 4761 "No associated statement allowed for 'omp cancel' directive"); 4762 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4763 CancelRegion); 4764 AllowedNameModifiers.push_back(OMPD_cancel); 4765 break; 4766 case OMPD_target_data: 4767 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4768 EndLoc); 4769 AllowedNameModifiers.push_back(OMPD_target_data); 4770 break; 4771 case OMPD_target_enter_data: 4772 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4773 EndLoc, AStmt); 4774 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4775 break; 4776 case OMPD_target_exit_data: 4777 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4778 EndLoc, AStmt); 4779 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4780 break; 4781 case OMPD_taskloop: 4782 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4783 EndLoc, VarsWithInheritedDSA); 4784 AllowedNameModifiers.push_back(OMPD_taskloop); 4785 break; 4786 case OMPD_taskloop_simd: 4787 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4788 EndLoc, VarsWithInheritedDSA); 4789 AllowedNameModifiers.push_back(OMPD_taskloop); 4790 if (LangOpts.OpenMP >= 50) 4791 AllowedNameModifiers.push_back(OMPD_simd); 4792 break; 4793 case OMPD_master_taskloop: 4794 Res = ActOnOpenMPMasterTaskLoopDirective( 4795 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4796 AllowedNameModifiers.push_back(OMPD_taskloop); 4797 break; 4798 case OMPD_master_taskloop_simd: 4799 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4800 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4801 AllowedNameModifiers.push_back(OMPD_taskloop); 4802 if (LangOpts.OpenMP >= 50) 4803 AllowedNameModifiers.push_back(OMPD_simd); 4804 break; 4805 case OMPD_parallel_master_taskloop: 4806 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4807 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4808 AllowedNameModifiers.push_back(OMPD_taskloop); 4809 AllowedNameModifiers.push_back(OMPD_parallel); 4810 break; 4811 case OMPD_parallel_master_taskloop_simd: 4812 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4813 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4814 AllowedNameModifiers.push_back(OMPD_taskloop); 4815 AllowedNameModifiers.push_back(OMPD_parallel); 4816 if (LangOpts.OpenMP >= 50) 4817 AllowedNameModifiers.push_back(OMPD_simd); 4818 break; 4819 case OMPD_distribute: 4820 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4821 EndLoc, VarsWithInheritedDSA); 4822 break; 4823 case OMPD_target_update: 4824 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4825 EndLoc, AStmt); 4826 AllowedNameModifiers.push_back(OMPD_target_update); 4827 break; 4828 case OMPD_distribute_parallel_for: 4829 Res = ActOnOpenMPDistributeParallelForDirective( 4830 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4831 AllowedNameModifiers.push_back(OMPD_parallel); 4832 break; 4833 case OMPD_distribute_parallel_for_simd: 4834 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4835 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4836 AllowedNameModifiers.push_back(OMPD_parallel); 4837 if (LangOpts.OpenMP >= 50) 4838 AllowedNameModifiers.push_back(OMPD_simd); 4839 break; 4840 case OMPD_distribute_simd: 4841 Res = ActOnOpenMPDistributeSimdDirective( 4842 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4843 if (LangOpts.OpenMP >= 50) 4844 AllowedNameModifiers.push_back(OMPD_simd); 4845 break; 4846 case OMPD_target_parallel_for_simd: 4847 Res = ActOnOpenMPTargetParallelForSimdDirective( 4848 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4849 AllowedNameModifiers.push_back(OMPD_target); 4850 AllowedNameModifiers.push_back(OMPD_parallel); 4851 if (LangOpts.OpenMP >= 50) 4852 AllowedNameModifiers.push_back(OMPD_simd); 4853 break; 4854 case OMPD_target_simd: 4855 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4856 EndLoc, VarsWithInheritedDSA); 4857 AllowedNameModifiers.push_back(OMPD_target); 4858 if (LangOpts.OpenMP >= 50) 4859 AllowedNameModifiers.push_back(OMPD_simd); 4860 break; 4861 case OMPD_teams_distribute: 4862 Res = ActOnOpenMPTeamsDistributeDirective( 4863 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4864 break; 4865 case OMPD_teams_distribute_simd: 4866 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4867 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4868 if (LangOpts.OpenMP >= 50) 4869 AllowedNameModifiers.push_back(OMPD_simd); 4870 break; 4871 case OMPD_teams_distribute_parallel_for_simd: 4872 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4873 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4874 AllowedNameModifiers.push_back(OMPD_parallel); 4875 if (LangOpts.OpenMP >= 50) 4876 AllowedNameModifiers.push_back(OMPD_simd); 4877 break; 4878 case OMPD_teams_distribute_parallel_for: 4879 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4880 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4881 AllowedNameModifiers.push_back(OMPD_parallel); 4882 break; 4883 case OMPD_target_teams: 4884 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4885 EndLoc); 4886 AllowedNameModifiers.push_back(OMPD_target); 4887 break; 4888 case OMPD_target_teams_distribute: 4889 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4890 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4891 AllowedNameModifiers.push_back(OMPD_target); 4892 break; 4893 case OMPD_target_teams_distribute_parallel_for: 4894 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4895 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4896 AllowedNameModifiers.push_back(OMPD_target); 4897 AllowedNameModifiers.push_back(OMPD_parallel); 4898 break; 4899 case OMPD_target_teams_distribute_parallel_for_simd: 4900 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4901 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4902 AllowedNameModifiers.push_back(OMPD_target); 4903 AllowedNameModifiers.push_back(OMPD_parallel); 4904 if (LangOpts.OpenMP >= 50) 4905 AllowedNameModifiers.push_back(OMPD_simd); 4906 break; 4907 case OMPD_target_teams_distribute_simd: 4908 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4909 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4910 AllowedNameModifiers.push_back(OMPD_target); 4911 if (LangOpts.OpenMP >= 50) 4912 AllowedNameModifiers.push_back(OMPD_simd); 4913 break; 4914 case OMPD_declare_target: 4915 case OMPD_end_declare_target: 4916 case OMPD_threadprivate: 4917 case OMPD_allocate: 4918 case OMPD_declare_reduction: 4919 case OMPD_declare_mapper: 4920 case OMPD_declare_simd: 4921 case OMPD_requires: 4922 case OMPD_declare_variant: 4923 llvm_unreachable("OpenMP Directive is not allowed"); 4924 case OMPD_unknown: 4925 llvm_unreachable("Unknown OpenMP directive"); 4926 } 4927 4928 ErrorFound = Res.isInvalid() || ErrorFound; 4929 4930 // Check variables in the clauses if default(none) was specified. 4931 if (DSAStack->getDefaultDSA() == DSA_none) { 4932 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4933 for (OMPClause *C : Clauses) { 4934 switch (C->getClauseKind()) { 4935 case OMPC_num_threads: 4936 case OMPC_dist_schedule: 4937 // Do not analyse if no parent teams directive. 4938 if (isOpenMPTeamsDirective(Kind)) 4939 break; 4940 continue; 4941 case OMPC_if: 4942 if (isOpenMPTeamsDirective(Kind) && 4943 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4944 break; 4945 if (isOpenMPParallelDirective(Kind) && 4946 isOpenMPTaskLoopDirective(Kind) && 4947 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 4948 break; 4949 continue; 4950 case OMPC_schedule: 4951 break; 4952 case OMPC_grainsize: 4953 case OMPC_num_tasks: 4954 case OMPC_final: 4955 case OMPC_priority: 4956 // Do not analyze if no parent parallel directive. 4957 if (isOpenMPParallelDirective(Kind)) 4958 break; 4959 continue; 4960 case OMPC_ordered: 4961 case OMPC_device: 4962 case OMPC_num_teams: 4963 case OMPC_thread_limit: 4964 case OMPC_hint: 4965 case OMPC_collapse: 4966 case OMPC_safelen: 4967 case OMPC_simdlen: 4968 case OMPC_default: 4969 case OMPC_proc_bind: 4970 case OMPC_private: 4971 case OMPC_firstprivate: 4972 case OMPC_lastprivate: 4973 case OMPC_shared: 4974 case OMPC_reduction: 4975 case OMPC_task_reduction: 4976 case OMPC_in_reduction: 4977 case OMPC_linear: 4978 case OMPC_aligned: 4979 case OMPC_copyin: 4980 case OMPC_copyprivate: 4981 case OMPC_nowait: 4982 case OMPC_untied: 4983 case OMPC_mergeable: 4984 case OMPC_allocate: 4985 case OMPC_read: 4986 case OMPC_write: 4987 case OMPC_update: 4988 case OMPC_capture: 4989 case OMPC_seq_cst: 4990 case OMPC_acq_rel: 4991 case OMPC_depend: 4992 case OMPC_threads: 4993 case OMPC_simd: 4994 case OMPC_map: 4995 case OMPC_nogroup: 4996 case OMPC_defaultmap: 4997 case OMPC_to: 4998 case OMPC_from: 4999 case OMPC_use_device_ptr: 5000 case OMPC_is_device_ptr: 5001 case OMPC_nontemporal: 5002 case OMPC_order: 5003 continue; 5004 case OMPC_allocator: 5005 case OMPC_flush: 5006 case OMPC_threadprivate: 5007 case OMPC_uniform: 5008 case OMPC_unknown: 5009 case OMPC_unified_address: 5010 case OMPC_unified_shared_memory: 5011 case OMPC_reverse_offload: 5012 case OMPC_dynamic_allocators: 5013 case OMPC_atomic_default_mem_order: 5014 case OMPC_device_type: 5015 case OMPC_match: 5016 llvm_unreachable("Unexpected clause"); 5017 } 5018 for (Stmt *CC : C->children()) { 5019 if (CC) 5020 DSAChecker.Visit(CC); 5021 } 5022 } 5023 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5024 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5025 } 5026 for (const auto &P : VarsWithInheritedDSA) { 5027 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5028 continue; 5029 ErrorFound = true; 5030 if (DSAStack->getDefaultDSA() == DSA_none) { 5031 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5032 << P.first << P.second->getSourceRange(); 5033 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5034 } else if (getLangOpts().OpenMP >= 50) { 5035 Diag(P.second->getExprLoc(), 5036 diag::err_omp_defaultmap_no_attr_for_variable) 5037 << P.first << P.second->getSourceRange(); 5038 Diag(DSAStack->getDefaultDSALocation(), 5039 diag::note_omp_defaultmap_attr_none); 5040 } 5041 } 5042 5043 if (!AllowedNameModifiers.empty()) 5044 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5045 ErrorFound; 5046 5047 if (ErrorFound) 5048 return StmtError(); 5049 5050 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 5051 Res.getAs<OMPExecutableDirective>() 5052 ->getStructuredBlock() 5053 ->setIsOMPStructuredBlock(true); 5054 } 5055 5056 if (!CurContext->isDependentContext() && 5057 isOpenMPTargetExecutionDirective(Kind) && 5058 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5059 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5060 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5061 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5062 // Register target to DSA Stack. 5063 DSAStack->addTargetDirLocation(StartLoc); 5064 } 5065 5066 return Res; 5067 } 5068 5069 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5070 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5071 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5072 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5073 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5074 assert(Aligneds.size() == Alignments.size()); 5075 assert(Linears.size() == LinModifiers.size()); 5076 assert(Linears.size() == Steps.size()); 5077 if (!DG || DG.get().isNull()) 5078 return DeclGroupPtrTy(); 5079 5080 const int SimdId = 0; 5081 if (!DG.get().isSingleDecl()) { 5082 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5083 << SimdId; 5084 return DG; 5085 } 5086 Decl *ADecl = DG.get().getSingleDecl(); 5087 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5088 ADecl = FTD->getTemplatedDecl(); 5089 5090 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5091 if (!FD) { 5092 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5093 return DeclGroupPtrTy(); 5094 } 5095 5096 // OpenMP [2.8.2, declare simd construct, Description] 5097 // The parameter of the simdlen clause must be a constant positive integer 5098 // expression. 5099 ExprResult SL; 5100 if (Simdlen) 5101 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5102 // OpenMP [2.8.2, declare simd construct, Description] 5103 // The special this pointer can be used as if was one of the arguments to the 5104 // function in any of the linear, aligned, or uniform clauses. 5105 // The uniform clause declares one or more arguments to have an invariant 5106 // value for all concurrent invocations of the function in the execution of a 5107 // single SIMD loop. 5108 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5109 const Expr *UniformedLinearThis = nullptr; 5110 for (const Expr *E : Uniforms) { 5111 E = E->IgnoreParenImpCasts(); 5112 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5113 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5114 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5115 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5116 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5117 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5118 continue; 5119 } 5120 if (isa<CXXThisExpr>(E)) { 5121 UniformedLinearThis = E; 5122 continue; 5123 } 5124 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5125 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5126 } 5127 // OpenMP [2.8.2, declare simd construct, Description] 5128 // The aligned clause declares that the object to which each list item points 5129 // is aligned to the number of bytes expressed in the optional parameter of 5130 // the aligned clause. 5131 // The special this pointer can be used as if was one of the arguments to the 5132 // function in any of the linear, aligned, or uniform clauses. 5133 // The type of list items appearing in the aligned clause must be array, 5134 // pointer, reference to array, or reference to pointer. 5135 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5136 const Expr *AlignedThis = nullptr; 5137 for (const Expr *E : Aligneds) { 5138 E = E->IgnoreParenImpCasts(); 5139 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5140 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5141 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5142 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5143 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5144 ->getCanonicalDecl() == CanonPVD) { 5145 // OpenMP [2.8.1, simd construct, Restrictions] 5146 // A list-item cannot appear in more than one aligned clause. 5147 if (AlignedArgs.count(CanonPVD) > 0) { 5148 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5149 << 1 << getOpenMPClauseName(OMPC_aligned) 5150 << E->getSourceRange(); 5151 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5152 diag::note_omp_explicit_dsa) 5153 << getOpenMPClauseName(OMPC_aligned); 5154 continue; 5155 } 5156 AlignedArgs[CanonPVD] = E; 5157 QualType QTy = PVD->getType() 5158 .getNonReferenceType() 5159 .getUnqualifiedType() 5160 .getCanonicalType(); 5161 const Type *Ty = QTy.getTypePtrOrNull(); 5162 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5163 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5164 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5165 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5166 } 5167 continue; 5168 } 5169 } 5170 if (isa<CXXThisExpr>(E)) { 5171 if (AlignedThis) { 5172 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5173 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5174 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5175 << getOpenMPClauseName(OMPC_aligned); 5176 } 5177 AlignedThis = E; 5178 continue; 5179 } 5180 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5181 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5182 } 5183 // The optional parameter of the aligned clause, alignment, must be a constant 5184 // positive integer expression. If no optional parameter is specified, 5185 // implementation-defined default alignments for SIMD instructions on the 5186 // target platforms are assumed. 5187 SmallVector<const Expr *, 4> NewAligns; 5188 for (Expr *E : Alignments) { 5189 ExprResult Align; 5190 if (E) 5191 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5192 NewAligns.push_back(Align.get()); 5193 } 5194 // OpenMP [2.8.2, declare simd construct, Description] 5195 // The linear clause declares one or more list items to be private to a SIMD 5196 // lane and to have a linear relationship with respect to the iteration space 5197 // of a loop. 5198 // The special this pointer can be used as if was one of the arguments to the 5199 // function in any of the linear, aligned, or uniform clauses. 5200 // When a linear-step expression is specified in a linear clause it must be 5201 // either a constant integer expression or an integer-typed parameter that is 5202 // specified in a uniform clause on the directive. 5203 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5204 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5205 auto MI = LinModifiers.begin(); 5206 for (const Expr *E : Linears) { 5207 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5208 ++MI; 5209 E = E->IgnoreParenImpCasts(); 5210 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5211 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5212 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5213 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5214 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5215 ->getCanonicalDecl() == CanonPVD) { 5216 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5217 // A list-item cannot appear in more than one linear clause. 5218 if (LinearArgs.count(CanonPVD) > 0) { 5219 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5220 << getOpenMPClauseName(OMPC_linear) 5221 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5222 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5223 diag::note_omp_explicit_dsa) 5224 << getOpenMPClauseName(OMPC_linear); 5225 continue; 5226 } 5227 // Each argument can appear in at most one uniform or linear clause. 5228 if (UniformedArgs.count(CanonPVD) > 0) { 5229 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5230 << getOpenMPClauseName(OMPC_linear) 5231 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5232 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5233 diag::note_omp_explicit_dsa) 5234 << getOpenMPClauseName(OMPC_uniform); 5235 continue; 5236 } 5237 LinearArgs[CanonPVD] = E; 5238 if (E->isValueDependent() || E->isTypeDependent() || 5239 E->isInstantiationDependent() || 5240 E->containsUnexpandedParameterPack()) 5241 continue; 5242 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5243 PVD->getOriginalType()); 5244 continue; 5245 } 5246 } 5247 if (isa<CXXThisExpr>(E)) { 5248 if (UniformedLinearThis) { 5249 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5250 << getOpenMPClauseName(OMPC_linear) 5251 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5252 << E->getSourceRange(); 5253 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5254 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5255 : OMPC_linear); 5256 continue; 5257 } 5258 UniformedLinearThis = E; 5259 if (E->isValueDependent() || E->isTypeDependent() || 5260 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5261 continue; 5262 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5263 E->getType()); 5264 continue; 5265 } 5266 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5267 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5268 } 5269 Expr *Step = nullptr; 5270 Expr *NewStep = nullptr; 5271 SmallVector<Expr *, 4> NewSteps; 5272 for (Expr *E : Steps) { 5273 // Skip the same step expression, it was checked already. 5274 if (Step == E || !E) { 5275 NewSteps.push_back(E ? NewStep : nullptr); 5276 continue; 5277 } 5278 Step = E; 5279 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5280 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5281 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5282 if (UniformedArgs.count(CanonPVD) == 0) { 5283 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5284 << Step->getSourceRange(); 5285 } else if (E->isValueDependent() || E->isTypeDependent() || 5286 E->isInstantiationDependent() || 5287 E->containsUnexpandedParameterPack() || 5288 CanonPVD->getType()->hasIntegerRepresentation()) { 5289 NewSteps.push_back(Step); 5290 } else { 5291 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5292 << Step->getSourceRange(); 5293 } 5294 continue; 5295 } 5296 NewStep = Step; 5297 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5298 !Step->isInstantiationDependent() && 5299 !Step->containsUnexpandedParameterPack()) { 5300 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5301 .get(); 5302 if (NewStep) 5303 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5304 } 5305 NewSteps.push_back(NewStep); 5306 } 5307 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5308 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5309 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5310 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5311 const_cast<Expr **>(Linears.data()), Linears.size(), 5312 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5313 NewSteps.data(), NewSteps.size(), SR); 5314 ADecl->addAttr(NewAttr); 5315 return DG; 5316 } 5317 5318 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5319 QualType NewType) { 5320 assert(NewType->isFunctionProtoType() && 5321 "Expected function type with prototype."); 5322 assert(FD->getType()->isFunctionNoProtoType() && 5323 "Expected function with type with no prototype."); 5324 assert(FDWithProto->getType()->isFunctionProtoType() && 5325 "Expected function with prototype."); 5326 // Synthesize parameters with the same types. 5327 FD->setType(NewType); 5328 SmallVector<ParmVarDecl *, 16> Params; 5329 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5330 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5331 SourceLocation(), nullptr, P->getType(), 5332 /*TInfo=*/nullptr, SC_None, nullptr); 5333 Param->setScopeInfo(0, Params.size()); 5334 Param->setImplicit(); 5335 Params.push_back(Param); 5336 } 5337 5338 FD->setParams(Params); 5339 } 5340 5341 Optional<std::pair<FunctionDecl *, Expr *>> 5342 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5343 Expr *VariantRef, SourceRange SR) { 5344 if (!DG || DG.get().isNull()) 5345 return None; 5346 5347 const int VariantId = 1; 5348 // Must be applied only to single decl. 5349 if (!DG.get().isSingleDecl()) { 5350 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5351 << VariantId << SR; 5352 return None; 5353 } 5354 Decl *ADecl = DG.get().getSingleDecl(); 5355 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5356 ADecl = FTD->getTemplatedDecl(); 5357 5358 // Decl must be a function. 5359 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5360 if (!FD) { 5361 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5362 << VariantId << SR; 5363 return None; 5364 } 5365 5366 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5367 return FD->hasAttrs() && 5368 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5369 FD->hasAttr<TargetAttr>()); 5370 }; 5371 // OpenMP is not compatible with CPU-specific attributes. 5372 if (HasMultiVersionAttributes(FD)) { 5373 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5374 << SR; 5375 return None; 5376 } 5377 5378 // Allow #pragma omp declare variant only if the function is not used. 5379 if (FD->isUsed(false)) 5380 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5381 << FD->getLocation(); 5382 5383 // Check if the function was emitted already. 5384 const FunctionDecl *Definition; 5385 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5386 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5387 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5388 << FD->getLocation(); 5389 5390 // The VariantRef must point to function. 5391 if (!VariantRef) { 5392 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5393 return None; 5394 } 5395 5396 // Do not check templates, wait until instantiation. 5397 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5398 VariantRef->containsUnexpandedParameterPack() || 5399 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5400 return std::make_pair(FD, VariantRef); 5401 5402 // Convert VariantRef expression to the type of the original function to 5403 // resolve possible conflicts. 5404 ExprResult VariantRefCast; 5405 if (LangOpts.CPlusPlus) { 5406 QualType FnPtrType; 5407 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5408 if (Method && !Method->isStatic()) { 5409 const Type *ClassType = 5410 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5411 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5412 ExprResult ER; 5413 { 5414 // Build adrr_of unary op to correctly handle type checks for member 5415 // functions. 5416 Sema::TentativeAnalysisScope Trap(*this); 5417 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5418 VariantRef); 5419 } 5420 if (!ER.isUsable()) { 5421 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5422 << VariantId << VariantRef->getSourceRange(); 5423 return None; 5424 } 5425 VariantRef = ER.get(); 5426 } else { 5427 FnPtrType = Context.getPointerType(FD->getType()); 5428 } 5429 ImplicitConversionSequence ICS = 5430 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5431 /*SuppressUserConversions=*/false, 5432 AllowedExplicit::None, 5433 /*InOverloadResolution=*/false, 5434 /*CStyle=*/false, 5435 /*AllowObjCWritebackConversion=*/false); 5436 if (ICS.isFailure()) { 5437 Diag(VariantRef->getExprLoc(), 5438 diag::err_omp_declare_variant_incompat_types) 5439 << VariantRef->getType() 5440 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5441 << VariantRef->getSourceRange(); 5442 return None; 5443 } 5444 VariantRefCast = PerformImplicitConversion( 5445 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5446 if (!VariantRefCast.isUsable()) 5447 return None; 5448 // Drop previously built artificial addr_of unary op for member functions. 5449 if (Method && !Method->isStatic()) { 5450 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5451 if (auto *UO = dyn_cast<UnaryOperator>( 5452 PossibleAddrOfVariantRef->IgnoreImplicit())) 5453 VariantRefCast = UO->getSubExpr(); 5454 } 5455 } else { 5456 VariantRefCast = VariantRef; 5457 } 5458 5459 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5460 if (!ER.isUsable() || 5461 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5462 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5463 << VariantId << VariantRef->getSourceRange(); 5464 return None; 5465 } 5466 5467 // The VariantRef must point to function. 5468 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5469 if (!DRE) { 5470 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5471 << VariantId << VariantRef->getSourceRange(); 5472 return None; 5473 } 5474 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5475 if (!NewFD) { 5476 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5477 << VariantId << VariantRef->getSourceRange(); 5478 return None; 5479 } 5480 5481 // Check if function types are compatible in C. 5482 if (!LangOpts.CPlusPlus) { 5483 QualType NewType = 5484 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5485 if (NewType.isNull()) { 5486 Diag(VariantRef->getExprLoc(), 5487 diag::err_omp_declare_variant_incompat_types) 5488 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5489 return None; 5490 } 5491 if (NewType->isFunctionProtoType()) { 5492 if (FD->getType()->isFunctionNoProtoType()) 5493 setPrototype(*this, FD, NewFD, NewType); 5494 else if (NewFD->getType()->isFunctionNoProtoType()) 5495 setPrototype(*this, NewFD, FD, NewType); 5496 } 5497 } 5498 5499 // Check if variant function is not marked with declare variant directive. 5500 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5501 Diag(VariantRef->getExprLoc(), 5502 diag::warn_omp_declare_variant_marked_as_declare_variant) 5503 << VariantRef->getSourceRange(); 5504 SourceRange SR = 5505 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5506 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5507 return None; 5508 } 5509 5510 enum DoesntSupport { 5511 VirtFuncs = 1, 5512 Constructors = 3, 5513 Destructors = 4, 5514 DeletedFuncs = 5, 5515 DefaultedFuncs = 6, 5516 ConstexprFuncs = 7, 5517 ConstevalFuncs = 8, 5518 }; 5519 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5520 if (CXXFD->isVirtual()) { 5521 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5522 << VirtFuncs; 5523 return None; 5524 } 5525 5526 if (isa<CXXConstructorDecl>(FD)) { 5527 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5528 << Constructors; 5529 return None; 5530 } 5531 5532 if (isa<CXXDestructorDecl>(FD)) { 5533 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5534 << Destructors; 5535 return None; 5536 } 5537 } 5538 5539 if (FD->isDeleted()) { 5540 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5541 << DeletedFuncs; 5542 return None; 5543 } 5544 5545 if (FD->isDefaulted()) { 5546 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5547 << DefaultedFuncs; 5548 return None; 5549 } 5550 5551 if (FD->isConstexpr()) { 5552 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5553 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5554 return None; 5555 } 5556 5557 // Check general compatibility. 5558 if (areMultiversionVariantFunctionsCompatible( 5559 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5560 PartialDiagnosticAt(SourceLocation(), 5561 PartialDiagnostic::NullDiagnostic()), 5562 PartialDiagnosticAt( 5563 VariantRef->getExprLoc(), 5564 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5565 PartialDiagnosticAt(VariantRef->getExprLoc(), 5566 PDiag(diag::err_omp_declare_variant_diff) 5567 << FD->getLocation()), 5568 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5569 /*CLinkageMayDiffer=*/true)) 5570 return None; 5571 return std::make_pair(FD, cast<Expr>(DRE)); 5572 } 5573 5574 void Sema::ActOnOpenMPDeclareVariantDirective( 5575 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5576 ArrayRef<OMPCtxSelectorData> Data) { 5577 if (Data.empty()) 5578 return; 5579 SmallVector<Expr *, 4> CtxScores; 5580 SmallVector<unsigned, 4> CtxSets; 5581 SmallVector<unsigned, 4> Ctxs; 5582 SmallVector<StringRef, 4> ImplVendors, DeviceKinds; 5583 bool IsError = false; 5584 for (const OMPCtxSelectorData &D : Data) { 5585 OpenMPContextSelectorSetKind CtxSet = D.CtxSet; 5586 OpenMPContextSelectorKind Ctx = D.Ctx; 5587 if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown) 5588 return; 5589 Expr *Score = nullptr; 5590 if (D.Score.isUsable()) { 5591 Score = D.Score.get(); 5592 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5593 !Score->isInstantiationDependent() && 5594 !Score->containsUnexpandedParameterPack()) { 5595 Score = 5596 PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score) 5597 .get(); 5598 if (Score) 5599 Score = VerifyIntegerConstantExpression(Score).get(); 5600 } 5601 } else { 5602 // OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors. 5603 // The kind, arch, and isa selectors are given the values 2^l, 2^(l+1) and 5604 // 2^(l+2), respectively, where l is the number of traits in the construct 5605 // set. 5606 // TODO: implement correct logic for isa and arch traits. 5607 // TODO: take the construct context set into account when it is 5608 // implemented. 5609 int L = 0; // Currently set the number of traits in construct set to 0, 5610 // since the construct trait set in not supported yet. 5611 if (CtxSet == OMP_CTX_SET_device && Ctx == OMP_CTX_kind) 5612 Score = ActOnIntegerConstant(SourceLocation(), std::pow(2, L)).get(); 5613 else 5614 Score = ActOnIntegerConstant(SourceLocation(), 0).get(); 5615 } 5616 switch (Ctx) { 5617 case OMP_CTX_vendor: 5618 assert(CtxSet == OMP_CTX_SET_implementation && 5619 "Expected implementation context selector set."); 5620 ImplVendors.append(D.Names.begin(), D.Names.end()); 5621 break; 5622 case OMP_CTX_kind: 5623 assert(CtxSet == OMP_CTX_SET_device && 5624 "Expected device context selector set."); 5625 DeviceKinds.append(D.Names.begin(), D.Names.end()); 5626 break; 5627 case OMP_CTX_unknown: 5628 llvm_unreachable("Unknown context selector kind."); 5629 } 5630 IsError = IsError || !Score; 5631 CtxSets.push_back(CtxSet); 5632 Ctxs.push_back(Ctx); 5633 CtxScores.push_back(Score); 5634 } 5635 if (!IsError) { 5636 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5637 Context, VariantRef, CtxScores.begin(), CtxScores.size(), 5638 CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(), 5639 ImplVendors.begin(), ImplVendors.size(), DeviceKinds.begin(), 5640 DeviceKinds.size(), SR); 5641 FD->addAttr(NewAttr); 5642 } 5643 } 5644 5645 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5646 FunctionDecl *Func, 5647 bool MightBeOdrUse) { 5648 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5649 5650 if (!Func->isDependentContext() && Func->hasAttrs()) { 5651 for (OMPDeclareVariantAttr *A : 5652 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5653 // TODO: add checks for active OpenMP context where possible. 5654 Expr *VariantRef = A->getVariantFuncRef(); 5655 auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5656 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5657 if (!F->isDefined() && F->isTemplateInstantiation()) 5658 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5659 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5660 } 5661 } 5662 } 5663 5664 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5665 Stmt *AStmt, 5666 SourceLocation StartLoc, 5667 SourceLocation EndLoc) { 5668 if (!AStmt) 5669 return StmtError(); 5670 5671 auto *CS = cast<CapturedStmt>(AStmt); 5672 // 1.2.2 OpenMP Language Terminology 5673 // Structured block - An executable statement with a single entry at the 5674 // top and a single exit at the bottom. 5675 // The point of exit cannot be a branch out of the structured block. 5676 // longjmp() and throw() must not violate the entry/exit criteria. 5677 CS->getCapturedDecl()->setNothrow(); 5678 5679 setFunctionHasBranchProtectedScope(); 5680 5681 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5682 DSAStack->isCancelRegion()); 5683 } 5684 5685 namespace { 5686 /// Iteration space of a single for loop. 5687 struct LoopIterationSpace final { 5688 /// True if the condition operator is the strict compare operator (<, > or 5689 /// !=). 5690 bool IsStrictCompare = false; 5691 /// Condition of the loop. 5692 Expr *PreCond = nullptr; 5693 /// This expression calculates the number of iterations in the loop. 5694 /// It is always possible to calculate it before starting the loop. 5695 Expr *NumIterations = nullptr; 5696 /// The loop counter variable. 5697 Expr *CounterVar = nullptr; 5698 /// Private loop counter variable. 5699 Expr *PrivateCounterVar = nullptr; 5700 /// This is initializer for the initial value of #CounterVar. 5701 Expr *CounterInit = nullptr; 5702 /// This is step for the #CounterVar used to generate its update: 5703 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5704 Expr *CounterStep = nullptr; 5705 /// Should step be subtracted? 5706 bool Subtract = false; 5707 /// Source range of the loop init. 5708 SourceRange InitSrcRange; 5709 /// Source range of the loop condition. 5710 SourceRange CondSrcRange; 5711 /// Source range of the loop increment. 5712 SourceRange IncSrcRange; 5713 /// Minimum value that can have the loop control variable. Used to support 5714 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5715 /// since only such variables can be used in non-loop invariant expressions. 5716 Expr *MinValue = nullptr; 5717 /// Maximum value that can have the loop control variable. Used to support 5718 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5719 /// since only such variables can be used in non-loop invariant expressions. 5720 Expr *MaxValue = nullptr; 5721 /// true, if the lower bound depends on the outer loop control var. 5722 bool IsNonRectangularLB = false; 5723 /// true, if the upper bound depends on the outer loop control var. 5724 bool IsNonRectangularUB = false; 5725 /// Index of the loop this loop depends on and forms non-rectangular loop 5726 /// nest. 5727 unsigned LoopDependentIdx = 0; 5728 /// Final condition for the non-rectangular loop nest support. It is used to 5729 /// check that the number of iterations for this particular counter must be 5730 /// finished. 5731 Expr *FinalCondition = nullptr; 5732 }; 5733 5734 /// Helper class for checking canonical form of the OpenMP loops and 5735 /// extracting iteration space of each loop in the loop nest, that will be used 5736 /// for IR generation. 5737 class OpenMPIterationSpaceChecker { 5738 /// Reference to Sema. 5739 Sema &SemaRef; 5740 /// Data-sharing stack. 5741 DSAStackTy &Stack; 5742 /// A location for diagnostics (when there is no some better location). 5743 SourceLocation DefaultLoc; 5744 /// A location for diagnostics (when increment is not compatible). 5745 SourceLocation ConditionLoc; 5746 /// A source location for referring to loop init later. 5747 SourceRange InitSrcRange; 5748 /// A source location for referring to condition later. 5749 SourceRange ConditionSrcRange; 5750 /// A source location for referring to increment later. 5751 SourceRange IncrementSrcRange; 5752 /// Loop variable. 5753 ValueDecl *LCDecl = nullptr; 5754 /// Reference to loop variable. 5755 Expr *LCRef = nullptr; 5756 /// Lower bound (initializer for the var). 5757 Expr *LB = nullptr; 5758 /// Upper bound. 5759 Expr *UB = nullptr; 5760 /// Loop step (increment). 5761 Expr *Step = nullptr; 5762 /// This flag is true when condition is one of: 5763 /// Var < UB 5764 /// Var <= UB 5765 /// UB > Var 5766 /// UB >= Var 5767 /// This will have no value when the condition is != 5768 llvm::Optional<bool> TestIsLessOp; 5769 /// This flag is true when condition is strict ( < or > ). 5770 bool TestIsStrictOp = false; 5771 /// This flag is true when step is subtracted on each iteration. 5772 bool SubtractStep = false; 5773 /// The outer loop counter this loop depends on (if any). 5774 const ValueDecl *DepDecl = nullptr; 5775 /// Contains number of loop (starts from 1) on which loop counter init 5776 /// expression of this loop depends on. 5777 Optional<unsigned> InitDependOnLC; 5778 /// Contains number of loop (starts from 1) on which loop counter condition 5779 /// expression of this loop depends on. 5780 Optional<unsigned> CondDependOnLC; 5781 /// Checks if the provide statement depends on the loop counter. 5782 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5783 /// Original condition required for checking of the exit condition for 5784 /// non-rectangular loop. 5785 Expr *Condition = nullptr; 5786 5787 public: 5788 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5789 SourceLocation DefaultLoc) 5790 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5791 ConditionLoc(DefaultLoc) {} 5792 /// Check init-expr for canonical loop form and save loop counter 5793 /// variable - #Var and its initialization value - #LB. 5794 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5795 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5796 /// for less/greater and for strict/non-strict comparison. 5797 bool checkAndSetCond(Expr *S); 5798 /// Check incr-expr for canonical loop form and return true if it 5799 /// does not conform, otherwise save loop step (#Step). 5800 bool checkAndSetInc(Expr *S); 5801 /// Return the loop counter variable. 5802 ValueDecl *getLoopDecl() const { return LCDecl; } 5803 /// Return the reference expression to loop counter variable. 5804 Expr *getLoopDeclRefExpr() const { return LCRef; } 5805 /// Source range of the loop init. 5806 SourceRange getInitSrcRange() const { return InitSrcRange; } 5807 /// Source range of the loop condition. 5808 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5809 /// Source range of the loop increment. 5810 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5811 /// True if the step should be subtracted. 5812 bool shouldSubtractStep() const { return SubtractStep; } 5813 /// True, if the compare operator is strict (<, > or !=). 5814 bool isStrictTestOp() const { return TestIsStrictOp; } 5815 /// Build the expression to calculate the number of iterations. 5816 Expr *buildNumIterations( 5817 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5818 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5819 /// Build the precondition expression for the loops. 5820 Expr * 5821 buildPreCond(Scope *S, Expr *Cond, 5822 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5823 /// Build reference expression to the counter be used for codegen. 5824 DeclRefExpr * 5825 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5826 DSAStackTy &DSA) const; 5827 /// Build reference expression to the private counter be used for 5828 /// codegen. 5829 Expr *buildPrivateCounterVar() const; 5830 /// Build initialization of the counter be used for codegen. 5831 Expr *buildCounterInit() const; 5832 /// Build step of the counter be used for codegen. 5833 Expr *buildCounterStep() const; 5834 /// Build loop data with counter value for depend clauses in ordered 5835 /// directives. 5836 Expr * 5837 buildOrderedLoopData(Scope *S, Expr *Counter, 5838 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5839 SourceLocation Loc, Expr *Inc = nullptr, 5840 OverloadedOperatorKind OOK = OO_Amp); 5841 /// Builds the minimum value for the loop counter. 5842 std::pair<Expr *, Expr *> buildMinMaxValues( 5843 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5844 /// Builds final condition for the non-rectangular loops. 5845 Expr *buildFinalCondition(Scope *S) const; 5846 /// Return true if any expression is dependent. 5847 bool dependent() const; 5848 /// Returns true if the initializer forms non-rectangular loop. 5849 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5850 /// Returns true if the condition forms non-rectangular loop. 5851 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5852 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5853 unsigned getLoopDependentIdx() const { 5854 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5855 } 5856 5857 private: 5858 /// Check the right-hand side of an assignment in the increment 5859 /// expression. 5860 bool checkAndSetIncRHS(Expr *RHS); 5861 /// Helper to set loop counter variable and its initializer. 5862 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5863 bool EmitDiags); 5864 /// Helper to set upper bound. 5865 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5866 SourceRange SR, SourceLocation SL); 5867 /// Helper to set loop increment. 5868 bool setStep(Expr *NewStep, bool Subtract); 5869 }; 5870 5871 bool OpenMPIterationSpaceChecker::dependent() const { 5872 if (!LCDecl) { 5873 assert(!LB && !UB && !Step); 5874 return false; 5875 } 5876 return LCDecl->getType()->isDependentType() || 5877 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5878 (Step && Step->isValueDependent()); 5879 } 5880 5881 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5882 Expr *NewLCRefExpr, 5883 Expr *NewLB, bool EmitDiags) { 5884 // State consistency checking to ensure correct usage. 5885 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5886 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5887 if (!NewLCDecl || !NewLB) 5888 return true; 5889 LCDecl = getCanonicalDecl(NewLCDecl); 5890 LCRef = NewLCRefExpr; 5891 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5892 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5893 if ((Ctor->isCopyOrMoveConstructor() || 5894 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5895 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5896 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5897 LB = NewLB; 5898 if (EmitDiags) 5899 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5900 return false; 5901 } 5902 5903 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5904 llvm::Optional<bool> LessOp, 5905 bool StrictOp, SourceRange SR, 5906 SourceLocation SL) { 5907 // State consistency checking to ensure correct usage. 5908 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5909 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5910 if (!NewUB) 5911 return true; 5912 UB = NewUB; 5913 if (LessOp) 5914 TestIsLessOp = LessOp; 5915 TestIsStrictOp = StrictOp; 5916 ConditionSrcRange = SR; 5917 ConditionLoc = SL; 5918 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5919 return false; 5920 } 5921 5922 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5923 // State consistency checking to ensure correct usage. 5924 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5925 if (!NewStep) 5926 return true; 5927 if (!NewStep->isValueDependent()) { 5928 // Check that the step is integer expression. 5929 SourceLocation StepLoc = NewStep->getBeginLoc(); 5930 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5931 StepLoc, getExprAsWritten(NewStep)); 5932 if (Val.isInvalid()) 5933 return true; 5934 NewStep = Val.get(); 5935 5936 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5937 // If test-expr is of form var relational-op b and relational-op is < or 5938 // <= then incr-expr must cause var to increase on each iteration of the 5939 // loop. If test-expr is of form var relational-op b and relational-op is 5940 // > or >= then incr-expr must cause var to decrease on each iteration of 5941 // the loop. 5942 // If test-expr is of form b relational-op var and relational-op is < or 5943 // <= then incr-expr must cause var to decrease on each iteration of the 5944 // loop. If test-expr is of form b relational-op var and relational-op is 5945 // > or >= then incr-expr must cause var to increase on each iteration of 5946 // the loop. 5947 llvm::APSInt Result; 5948 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5949 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5950 bool IsConstNeg = 5951 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5952 bool IsConstPos = 5953 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5954 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5955 5956 // != with increment is treated as <; != with decrement is treated as > 5957 if (!TestIsLessOp.hasValue()) 5958 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5959 if (UB && (IsConstZero || 5960 (TestIsLessOp.getValue() ? 5961 (IsConstNeg || (IsUnsigned && Subtract)) : 5962 (IsConstPos || (IsUnsigned && !Subtract))))) { 5963 SemaRef.Diag(NewStep->getExprLoc(), 5964 diag::err_omp_loop_incr_not_compatible) 5965 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5966 SemaRef.Diag(ConditionLoc, 5967 diag::note_omp_loop_cond_requres_compatible_incr) 5968 << TestIsLessOp.getValue() << ConditionSrcRange; 5969 return true; 5970 } 5971 if (TestIsLessOp.getValue() == Subtract) { 5972 NewStep = 5973 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5974 .get(); 5975 Subtract = !Subtract; 5976 } 5977 } 5978 5979 Step = NewStep; 5980 SubtractStep = Subtract; 5981 return false; 5982 } 5983 5984 namespace { 5985 /// Checker for the non-rectangular loops. Checks if the initializer or 5986 /// condition expression references loop counter variable. 5987 class LoopCounterRefChecker final 5988 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5989 Sema &SemaRef; 5990 DSAStackTy &Stack; 5991 const ValueDecl *CurLCDecl = nullptr; 5992 const ValueDecl *DepDecl = nullptr; 5993 const ValueDecl *PrevDepDecl = nullptr; 5994 bool IsInitializer = true; 5995 unsigned BaseLoopId = 0; 5996 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5997 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5998 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5999 << (IsInitializer ? 0 : 1); 6000 return false; 6001 } 6002 const auto &&Data = Stack.isLoopControlVariable(VD); 6003 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6004 // The type of the loop iterator on which we depend may not have a random 6005 // access iterator type. 6006 if (Data.first && VD->getType()->isRecordType()) { 6007 SmallString<128> Name; 6008 llvm::raw_svector_ostream OS(Name); 6009 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6010 /*Qualified=*/true); 6011 SemaRef.Diag(E->getExprLoc(), 6012 diag::err_omp_wrong_dependency_iterator_type) 6013 << OS.str(); 6014 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6015 return false; 6016 } 6017 if (Data.first && 6018 (DepDecl || (PrevDepDecl && 6019 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6020 if (!DepDecl && PrevDepDecl) 6021 DepDecl = PrevDepDecl; 6022 SmallString<128> Name; 6023 llvm::raw_svector_ostream OS(Name); 6024 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6025 /*Qualified=*/true); 6026 SemaRef.Diag(E->getExprLoc(), 6027 diag::err_omp_invariant_or_linear_dependency) 6028 << OS.str(); 6029 return false; 6030 } 6031 if (Data.first) { 6032 DepDecl = VD; 6033 BaseLoopId = Data.first; 6034 } 6035 return Data.first; 6036 } 6037 6038 public: 6039 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6040 const ValueDecl *VD = E->getDecl(); 6041 if (isa<VarDecl>(VD)) 6042 return checkDecl(E, VD); 6043 return false; 6044 } 6045 bool VisitMemberExpr(const MemberExpr *E) { 6046 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6047 const ValueDecl *VD = E->getMemberDecl(); 6048 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6049 return checkDecl(E, VD); 6050 } 6051 return false; 6052 } 6053 bool VisitStmt(const Stmt *S) { 6054 bool Res = false; 6055 for (const Stmt *Child : S->children()) 6056 Res = (Child && Visit(Child)) || Res; 6057 return Res; 6058 } 6059 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6060 const ValueDecl *CurLCDecl, bool IsInitializer, 6061 const ValueDecl *PrevDepDecl = nullptr) 6062 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6063 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6064 unsigned getBaseLoopId() const { 6065 assert(CurLCDecl && "Expected loop dependency."); 6066 return BaseLoopId; 6067 } 6068 const ValueDecl *getDepDecl() const { 6069 assert(CurLCDecl && "Expected loop dependency."); 6070 return DepDecl; 6071 } 6072 }; 6073 } // namespace 6074 6075 Optional<unsigned> 6076 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6077 bool IsInitializer) { 6078 // Check for the non-rectangular loops. 6079 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6080 DepDecl); 6081 if (LoopStmtChecker.Visit(S)) { 6082 DepDecl = LoopStmtChecker.getDepDecl(); 6083 return LoopStmtChecker.getBaseLoopId(); 6084 } 6085 return llvm::None; 6086 } 6087 6088 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6089 // Check init-expr for canonical loop form and save loop counter 6090 // variable - #Var and its initialization value - #LB. 6091 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6092 // var = lb 6093 // integer-type var = lb 6094 // random-access-iterator-type var = lb 6095 // pointer-type var = lb 6096 // 6097 if (!S) { 6098 if (EmitDiags) { 6099 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6100 } 6101 return true; 6102 } 6103 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6104 if (!ExprTemp->cleanupsHaveSideEffects()) 6105 S = ExprTemp->getSubExpr(); 6106 6107 InitSrcRange = S->getSourceRange(); 6108 if (Expr *E = dyn_cast<Expr>(S)) 6109 S = E->IgnoreParens(); 6110 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6111 if (BO->getOpcode() == BO_Assign) { 6112 Expr *LHS = BO->getLHS()->IgnoreParens(); 6113 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6114 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6115 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6116 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6117 EmitDiags); 6118 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6119 } 6120 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6121 if (ME->isArrow() && 6122 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6123 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6124 EmitDiags); 6125 } 6126 } 6127 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6128 if (DS->isSingleDecl()) { 6129 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6130 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6131 // Accept non-canonical init form here but emit ext. warning. 6132 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6133 SemaRef.Diag(S->getBeginLoc(), 6134 diag::ext_omp_loop_not_canonical_init) 6135 << S->getSourceRange(); 6136 return setLCDeclAndLB( 6137 Var, 6138 buildDeclRefExpr(SemaRef, Var, 6139 Var->getType().getNonReferenceType(), 6140 DS->getBeginLoc()), 6141 Var->getInit(), EmitDiags); 6142 } 6143 } 6144 } 6145 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6146 if (CE->getOperator() == OO_Equal) { 6147 Expr *LHS = CE->getArg(0); 6148 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6149 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6150 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6151 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6152 EmitDiags); 6153 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6154 } 6155 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6156 if (ME->isArrow() && 6157 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6158 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6159 EmitDiags); 6160 } 6161 } 6162 } 6163 6164 if (dependent() || SemaRef.CurContext->isDependentContext()) 6165 return false; 6166 if (EmitDiags) { 6167 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6168 << S->getSourceRange(); 6169 } 6170 return true; 6171 } 6172 6173 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6174 /// variable (which may be the loop variable) if possible. 6175 static const ValueDecl *getInitLCDecl(const Expr *E) { 6176 if (!E) 6177 return nullptr; 6178 E = getExprAsWritten(E); 6179 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6180 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6181 if ((Ctor->isCopyOrMoveConstructor() || 6182 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6183 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6184 E = CE->getArg(0)->IgnoreParenImpCasts(); 6185 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6186 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6187 return getCanonicalDecl(VD); 6188 } 6189 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6190 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6191 return getCanonicalDecl(ME->getMemberDecl()); 6192 return nullptr; 6193 } 6194 6195 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6196 // Check test-expr for canonical form, save upper-bound UB, flags for 6197 // less/greater and for strict/non-strict comparison. 6198 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6199 // var relational-op b 6200 // b relational-op var 6201 // 6202 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6203 if (!S) { 6204 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6205 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6206 return true; 6207 } 6208 Condition = S; 6209 S = getExprAsWritten(S); 6210 SourceLocation CondLoc = S->getBeginLoc(); 6211 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6212 if (BO->isRelationalOp()) { 6213 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6214 return setUB(BO->getRHS(), 6215 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6216 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6217 BO->getSourceRange(), BO->getOperatorLoc()); 6218 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6219 return setUB(BO->getLHS(), 6220 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6221 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6222 BO->getSourceRange(), BO->getOperatorLoc()); 6223 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6224 return setUB( 6225 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6226 /*LessOp=*/llvm::None, 6227 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6228 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6229 if (CE->getNumArgs() == 2) { 6230 auto Op = CE->getOperator(); 6231 switch (Op) { 6232 case OO_Greater: 6233 case OO_GreaterEqual: 6234 case OO_Less: 6235 case OO_LessEqual: 6236 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6237 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6238 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6239 CE->getOperatorLoc()); 6240 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6241 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6242 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6243 CE->getOperatorLoc()); 6244 break; 6245 case OO_ExclaimEqual: 6246 if (IneqCondIsCanonical) 6247 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6248 : CE->getArg(0), 6249 /*LessOp=*/llvm::None, 6250 /*StrictOp=*/true, CE->getSourceRange(), 6251 CE->getOperatorLoc()); 6252 break; 6253 default: 6254 break; 6255 } 6256 } 6257 } 6258 if (dependent() || SemaRef.CurContext->isDependentContext()) 6259 return false; 6260 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6261 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6262 return true; 6263 } 6264 6265 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6266 // RHS of canonical loop form increment can be: 6267 // var + incr 6268 // incr + var 6269 // var - incr 6270 // 6271 RHS = RHS->IgnoreParenImpCasts(); 6272 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6273 if (BO->isAdditiveOp()) { 6274 bool IsAdd = BO->getOpcode() == BO_Add; 6275 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6276 return setStep(BO->getRHS(), !IsAdd); 6277 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6278 return setStep(BO->getLHS(), /*Subtract=*/false); 6279 } 6280 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6281 bool IsAdd = CE->getOperator() == OO_Plus; 6282 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6283 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6284 return setStep(CE->getArg(1), !IsAdd); 6285 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6286 return setStep(CE->getArg(0), /*Subtract=*/false); 6287 } 6288 } 6289 if (dependent() || SemaRef.CurContext->isDependentContext()) 6290 return false; 6291 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6292 << RHS->getSourceRange() << LCDecl; 6293 return true; 6294 } 6295 6296 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6297 // Check incr-expr for canonical loop form and return true if it 6298 // does not conform. 6299 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6300 // ++var 6301 // var++ 6302 // --var 6303 // var-- 6304 // var += incr 6305 // var -= incr 6306 // var = var + incr 6307 // var = incr + var 6308 // var = var - incr 6309 // 6310 if (!S) { 6311 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6312 return true; 6313 } 6314 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6315 if (!ExprTemp->cleanupsHaveSideEffects()) 6316 S = ExprTemp->getSubExpr(); 6317 6318 IncrementSrcRange = S->getSourceRange(); 6319 S = S->IgnoreParens(); 6320 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6321 if (UO->isIncrementDecrementOp() && 6322 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6323 return setStep(SemaRef 6324 .ActOnIntegerConstant(UO->getBeginLoc(), 6325 (UO->isDecrementOp() ? -1 : 1)) 6326 .get(), 6327 /*Subtract=*/false); 6328 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6329 switch (BO->getOpcode()) { 6330 case BO_AddAssign: 6331 case BO_SubAssign: 6332 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6333 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6334 break; 6335 case BO_Assign: 6336 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6337 return checkAndSetIncRHS(BO->getRHS()); 6338 break; 6339 default: 6340 break; 6341 } 6342 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6343 switch (CE->getOperator()) { 6344 case OO_PlusPlus: 6345 case OO_MinusMinus: 6346 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6347 return setStep(SemaRef 6348 .ActOnIntegerConstant( 6349 CE->getBeginLoc(), 6350 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6351 .get(), 6352 /*Subtract=*/false); 6353 break; 6354 case OO_PlusEqual: 6355 case OO_MinusEqual: 6356 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6357 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6358 break; 6359 case OO_Equal: 6360 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6361 return checkAndSetIncRHS(CE->getArg(1)); 6362 break; 6363 default: 6364 break; 6365 } 6366 } 6367 if (dependent() || SemaRef.CurContext->isDependentContext()) 6368 return false; 6369 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6370 << S->getSourceRange() << LCDecl; 6371 return true; 6372 } 6373 6374 static ExprResult 6375 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6376 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6377 if (SemaRef.CurContext->isDependentContext()) 6378 return ExprResult(Capture); 6379 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6380 return SemaRef.PerformImplicitConversion( 6381 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6382 /*AllowExplicit=*/true); 6383 auto I = Captures.find(Capture); 6384 if (I != Captures.end()) 6385 return buildCapture(SemaRef, Capture, I->second); 6386 DeclRefExpr *Ref = nullptr; 6387 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6388 Captures[Capture] = Ref; 6389 return Res; 6390 } 6391 6392 /// Build the expression to calculate the number of iterations. 6393 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6394 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6395 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6396 ExprResult Diff; 6397 QualType VarType = LCDecl->getType().getNonReferenceType(); 6398 if (VarType->isIntegerType() || VarType->isPointerType() || 6399 SemaRef.getLangOpts().CPlusPlus) { 6400 Expr *LBVal = LB; 6401 Expr *UBVal = UB; 6402 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6403 // max(LB(MinVal), LB(MaxVal)) 6404 if (InitDependOnLC) { 6405 const LoopIterationSpace &IS = 6406 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6407 InitDependOnLC.getValueOr( 6408 CondDependOnLC.getValueOr(0))]; 6409 if (!IS.MinValue || !IS.MaxValue) 6410 return nullptr; 6411 // OuterVar = Min 6412 ExprResult MinValue = 6413 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6414 if (!MinValue.isUsable()) 6415 return nullptr; 6416 6417 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6418 IS.CounterVar, MinValue.get()); 6419 if (!LBMinVal.isUsable()) 6420 return nullptr; 6421 // OuterVar = Min, LBVal 6422 LBMinVal = 6423 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6424 if (!LBMinVal.isUsable()) 6425 return nullptr; 6426 // (OuterVar = Min, LBVal) 6427 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6428 if (!LBMinVal.isUsable()) 6429 return nullptr; 6430 6431 // OuterVar = Max 6432 ExprResult MaxValue = 6433 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6434 if (!MaxValue.isUsable()) 6435 return nullptr; 6436 6437 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6438 IS.CounterVar, MaxValue.get()); 6439 if (!LBMaxVal.isUsable()) 6440 return nullptr; 6441 // OuterVar = Max, LBVal 6442 LBMaxVal = 6443 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6444 if (!LBMaxVal.isUsable()) 6445 return nullptr; 6446 // (OuterVar = Max, LBVal) 6447 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6448 if (!LBMaxVal.isUsable()) 6449 return nullptr; 6450 6451 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6452 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6453 if (!LBMin || !LBMax) 6454 return nullptr; 6455 // LB(MinVal) < LB(MaxVal) 6456 ExprResult MinLessMaxRes = 6457 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6458 if (!MinLessMaxRes.isUsable()) 6459 return nullptr; 6460 Expr *MinLessMax = 6461 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6462 if (!MinLessMax) 6463 return nullptr; 6464 if (TestIsLessOp.getValue()) { 6465 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6466 // LB(MaxVal)) 6467 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6468 MinLessMax, LBMin, LBMax); 6469 if (!MinLB.isUsable()) 6470 return nullptr; 6471 LBVal = MinLB.get(); 6472 } else { 6473 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6474 // LB(MaxVal)) 6475 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6476 MinLessMax, LBMax, LBMin); 6477 if (!MaxLB.isUsable()) 6478 return nullptr; 6479 LBVal = MaxLB.get(); 6480 } 6481 } 6482 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6483 // min(UB(MinVal), UB(MaxVal)) 6484 if (CondDependOnLC) { 6485 const LoopIterationSpace &IS = 6486 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6487 InitDependOnLC.getValueOr( 6488 CondDependOnLC.getValueOr(0))]; 6489 if (!IS.MinValue || !IS.MaxValue) 6490 return nullptr; 6491 // OuterVar = Min 6492 ExprResult MinValue = 6493 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6494 if (!MinValue.isUsable()) 6495 return nullptr; 6496 6497 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6498 IS.CounterVar, MinValue.get()); 6499 if (!UBMinVal.isUsable()) 6500 return nullptr; 6501 // OuterVar = Min, UBVal 6502 UBMinVal = 6503 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6504 if (!UBMinVal.isUsable()) 6505 return nullptr; 6506 // (OuterVar = Min, UBVal) 6507 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6508 if (!UBMinVal.isUsable()) 6509 return nullptr; 6510 6511 // OuterVar = Max 6512 ExprResult MaxValue = 6513 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6514 if (!MaxValue.isUsable()) 6515 return nullptr; 6516 6517 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6518 IS.CounterVar, MaxValue.get()); 6519 if (!UBMaxVal.isUsable()) 6520 return nullptr; 6521 // OuterVar = Max, UBVal 6522 UBMaxVal = 6523 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6524 if (!UBMaxVal.isUsable()) 6525 return nullptr; 6526 // (OuterVar = Max, UBVal) 6527 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6528 if (!UBMaxVal.isUsable()) 6529 return nullptr; 6530 6531 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6532 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6533 if (!UBMin || !UBMax) 6534 return nullptr; 6535 // UB(MinVal) > UB(MaxVal) 6536 ExprResult MinGreaterMaxRes = 6537 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6538 if (!MinGreaterMaxRes.isUsable()) 6539 return nullptr; 6540 Expr *MinGreaterMax = 6541 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6542 if (!MinGreaterMax) 6543 return nullptr; 6544 if (TestIsLessOp.getValue()) { 6545 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6546 // UB(MaxVal)) 6547 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6548 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6549 if (!MaxUB.isUsable()) 6550 return nullptr; 6551 UBVal = MaxUB.get(); 6552 } else { 6553 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6554 // UB(MaxVal)) 6555 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6556 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6557 if (!MinUB.isUsable()) 6558 return nullptr; 6559 UBVal = MinUB.get(); 6560 } 6561 } 6562 // Upper - Lower 6563 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6564 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6565 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6566 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6567 if (!Upper || !Lower) 6568 return nullptr; 6569 6570 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6571 6572 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6573 // BuildBinOp already emitted error, this one is to point user to upper 6574 // and lower bound, and to tell what is passed to 'operator-'. 6575 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6576 << Upper->getSourceRange() << Lower->getSourceRange(); 6577 return nullptr; 6578 } 6579 } 6580 6581 if (!Diff.isUsable()) 6582 return nullptr; 6583 6584 // Upper - Lower [- 1] 6585 if (TestIsStrictOp) 6586 Diff = SemaRef.BuildBinOp( 6587 S, DefaultLoc, BO_Sub, Diff.get(), 6588 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6589 if (!Diff.isUsable()) 6590 return nullptr; 6591 6592 // Upper - Lower [- 1] + Step 6593 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6594 if (!NewStep.isUsable()) 6595 return nullptr; 6596 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6597 if (!Diff.isUsable()) 6598 return nullptr; 6599 6600 // Parentheses (for dumping/debugging purposes only). 6601 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6602 if (!Diff.isUsable()) 6603 return nullptr; 6604 6605 // (Upper - Lower [- 1] + Step) / Step 6606 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6607 if (!Diff.isUsable()) 6608 return nullptr; 6609 6610 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6611 QualType Type = Diff.get()->getType(); 6612 ASTContext &C = SemaRef.Context; 6613 bool UseVarType = VarType->hasIntegerRepresentation() && 6614 C.getTypeSize(Type) > C.getTypeSize(VarType); 6615 if (!Type->isIntegerType() || UseVarType) { 6616 unsigned NewSize = 6617 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6618 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6619 : Type->hasSignedIntegerRepresentation(); 6620 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6621 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6622 Diff = SemaRef.PerformImplicitConversion( 6623 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6624 if (!Diff.isUsable()) 6625 return nullptr; 6626 } 6627 } 6628 if (LimitedType) { 6629 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6630 if (NewSize != C.getTypeSize(Type)) { 6631 if (NewSize < C.getTypeSize(Type)) { 6632 assert(NewSize == 64 && "incorrect loop var size"); 6633 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6634 << InitSrcRange << ConditionSrcRange; 6635 } 6636 QualType NewType = C.getIntTypeForBitwidth( 6637 NewSize, Type->hasSignedIntegerRepresentation() || 6638 C.getTypeSize(Type) < NewSize); 6639 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6640 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6641 Sema::AA_Converting, true); 6642 if (!Diff.isUsable()) 6643 return nullptr; 6644 } 6645 } 6646 } 6647 6648 return Diff.get(); 6649 } 6650 6651 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6652 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6653 // Do not build for iterators, they cannot be used in non-rectangular loop 6654 // nests. 6655 if (LCDecl->getType()->isRecordType()) 6656 return std::make_pair(nullptr, nullptr); 6657 // If we subtract, the min is in the condition, otherwise the min is in the 6658 // init value. 6659 Expr *MinExpr = nullptr; 6660 Expr *MaxExpr = nullptr; 6661 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6662 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6663 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6664 : CondDependOnLC.hasValue(); 6665 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6666 : InitDependOnLC.hasValue(); 6667 Expr *Lower = 6668 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6669 Expr *Upper = 6670 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6671 if (!Upper || !Lower) 6672 return std::make_pair(nullptr, nullptr); 6673 6674 if (TestIsLessOp.getValue()) 6675 MinExpr = Lower; 6676 else 6677 MaxExpr = Upper; 6678 6679 // Build minimum/maximum value based on number of iterations. 6680 ExprResult Diff; 6681 QualType VarType = LCDecl->getType().getNonReferenceType(); 6682 6683 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6684 if (!Diff.isUsable()) 6685 return std::make_pair(nullptr, nullptr); 6686 6687 // Upper - Lower [- 1] 6688 if (TestIsStrictOp) 6689 Diff = SemaRef.BuildBinOp( 6690 S, DefaultLoc, BO_Sub, Diff.get(), 6691 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6692 if (!Diff.isUsable()) 6693 return std::make_pair(nullptr, nullptr); 6694 6695 // Upper - Lower [- 1] + Step 6696 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6697 if (!NewStep.isUsable()) 6698 return std::make_pair(nullptr, nullptr); 6699 6700 // Parentheses (for dumping/debugging purposes only). 6701 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6702 if (!Diff.isUsable()) 6703 return std::make_pair(nullptr, nullptr); 6704 6705 // (Upper - Lower [- 1]) / Step 6706 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6707 if (!Diff.isUsable()) 6708 return std::make_pair(nullptr, nullptr); 6709 6710 // ((Upper - Lower [- 1]) / Step) * Step 6711 // Parentheses (for dumping/debugging purposes only). 6712 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6713 if (!Diff.isUsable()) 6714 return std::make_pair(nullptr, nullptr); 6715 6716 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6717 if (!Diff.isUsable()) 6718 return std::make_pair(nullptr, nullptr); 6719 6720 // Convert to the original type or ptrdiff_t, if original type is pointer. 6721 if (!VarType->isAnyPointerType() && 6722 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6723 Diff = SemaRef.PerformImplicitConversion( 6724 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6725 } else if (VarType->isAnyPointerType() && 6726 !SemaRef.Context.hasSameType( 6727 Diff.get()->getType(), 6728 SemaRef.Context.getUnsignedPointerDiffType())) { 6729 Diff = SemaRef.PerformImplicitConversion( 6730 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6731 Sema::AA_Converting, /*AllowExplicit=*/true); 6732 } 6733 if (!Diff.isUsable()) 6734 return std::make_pair(nullptr, nullptr); 6735 6736 // Parentheses (for dumping/debugging purposes only). 6737 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6738 if (!Diff.isUsable()) 6739 return std::make_pair(nullptr, nullptr); 6740 6741 if (TestIsLessOp.getValue()) { 6742 // MinExpr = Lower; 6743 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6744 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6745 if (!Diff.isUsable()) 6746 return std::make_pair(nullptr, nullptr); 6747 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6748 if (!Diff.isUsable()) 6749 return std::make_pair(nullptr, nullptr); 6750 MaxExpr = Diff.get(); 6751 } else { 6752 // MaxExpr = Upper; 6753 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6754 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6755 if (!Diff.isUsable()) 6756 return std::make_pair(nullptr, nullptr); 6757 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6758 if (!Diff.isUsable()) 6759 return std::make_pair(nullptr, nullptr); 6760 MinExpr = Diff.get(); 6761 } 6762 6763 return std::make_pair(MinExpr, MaxExpr); 6764 } 6765 6766 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6767 if (InitDependOnLC || CondDependOnLC) 6768 return Condition; 6769 return nullptr; 6770 } 6771 6772 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6773 Scope *S, Expr *Cond, 6774 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6775 // Do not build a precondition when the condition/initialization is dependent 6776 // to prevent pessimistic early loop exit. 6777 // TODO: this can be improved by calculating min/max values but not sure that 6778 // it will be very effective. 6779 if (CondDependOnLC || InitDependOnLC) 6780 return SemaRef.PerformImplicitConversion( 6781 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6782 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6783 /*AllowExplicit=*/true).get(); 6784 6785 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6786 Sema::TentativeAnalysisScope Trap(SemaRef); 6787 6788 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6789 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6790 if (!NewLB.isUsable() || !NewUB.isUsable()) 6791 return nullptr; 6792 6793 ExprResult CondExpr = 6794 SemaRef.BuildBinOp(S, DefaultLoc, 6795 TestIsLessOp.getValue() ? 6796 (TestIsStrictOp ? BO_LT : BO_LE) : 6797 (TestIsStrictOp ? BO_GT : BO_GE), 6798 NewLB.get(), NewUB.get()); 6799 if (CondExpr.isUsable()) { 6800 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6801 SemaRef.Context.BoolTy)) 6802 CondExpr = SemaRef.PerformImplicitConversion( 6803 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6804 /*AllowExplicit=*/true); 6805 } 6806 6807 // Otherwise use original loop condition and evaluate it in runtime. 6808 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6809 } 6810 6811 /// Build reference expression to the counter be used for codegen. 6812 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6813 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6814 DSAStackTy &DSA) const { 6815 auto *VD = dyn_cast<VarDecl>(LCDecl); 6816 if (!VD) { 6817 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6818 DeclRefExpr *Ref = buildDeclRefExpr( 6819 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6820 const DSAStackTy::DSAVarData Data = 6821 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6822 // If the loop control decl is explicitly marked as private, do not mark it 6823 // as captured again. 6824 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6825 Captures.insert(std::make_pair(LCRef, Ref)); 6826 return Ref; 6827 } 6828 return cast<DeclRefExpr>(LCRef); 6829 } 6830 6831 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6832 if (LCDecl && !LCDecl->isInvalidDecl()) { 6833 QualType Type = LCDecl->getType().getNonReferenceType(); 6834 VarDecl *PrivateVar = buildVarDecl( 6835 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6836 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6837 isa<VarDecl>(LCDecl) 6838 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6839 : nullptr); 6840 if (PrivateVar->isInvalidDecl()) 6841 return nullptr; 6842 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6843 } 6844 return nullptr; 6845 } 6846 6847 /// Build initialization of the counter to be used for codegen. 6848 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6849 6850 /// Build step of the counter be used for codegen. 6851 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6852 6853 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6854 Scope *S, Expr *Counter, 6855 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6856 Expr *Inc, OverloadedOperatorKind OOK) { 6857 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6858 if (!Cnt) 6859 return nullptr; 6860 if (Inc) { 6861 assert((OOK == OO_Plus || OOK == OO_Minus) && 6862 "Expected only + or - operations for depend clauses."); 6863 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6864 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6865 if (!Cnt) 6866 return nullptr; 6867 } 6868 ExprResult Diff; 6869 QualType VarType = LCDecl->getType().getNonReferenceType(); 6870 if (VarType->isIntegerType() || VarType->isPointerType() || 6871 SemaRef.getLangOpts().CPlusPlus) { 6872 // Upper - Lower 6873 Expr *Upper = TestIsLessOp.getValue() 6874 ? Cnt 6875 : tryBuildCapture(SemaRef, UB, Captures).get(); 6876 Expr *Lower = TestIsLessOp.getValue() 6877 ? tryBuildCapture(SemaRef, LB, Captures).get() 6878 : Cnt; 6879 if (!Upper || !Lower) 6880 return nullptr; 6881 6882 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6883 6884 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6885 // BuildBinOp already emitted error, this one is to point user to upper 6886 // and lower bound, and to tell what is passed to 'operator-'. 6887 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6888 << Upper->getSourceRange() << Lower->getSourceRange(); 6889 return nullptr; 6890 } 6891 } 6892 6893 if (!Diff.isUsable()) 6894 return nullptr; 6895 6896 // Parentheses (for dumping/debugging purposes only). 6897 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6898 if (!Diff.isUsable()) 6899 return nullptr; 6900 6901 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6902 if (!NewStep.isUsable()) 6903 return nullptr; 6904 // (Upper - Lower) / Step 6905 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6906 if (!Diff.isUsable()) 6907 return nullptr; 6908 6909 return Diff.get(); 6910 } 6911 } // namespace 6912 6913 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6914 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6915 assert(Init && "Expected loop in canonical form."); 6916 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6917 if (AssociatedLoops > 0 && 6918 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6919 DSAStack->loopStart(); 6920 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6921 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6922 if (ValueDecl *D = ISC.getLoopDecl()) { 6923 auto *VD = dyn_cast<VarDecl>(D); 6924 DeclRefExpr *PrivateRef = nullptr; 6925 if (!VD) { 6926 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6927 VD = Private; 6928 } else { 6929 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6930 /*WithInit=*/false); 6931 VD = cast<VarDecl>(PrivateRef->getDecl()); 6932 } 6933 } 6934 DSAStack->addLoopControlVariable(D, VD); 6935 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6936 if (LD != D->getCanonicalDecl()) { 6937 DSAStack->resetPossibleLoopCounter(); 6938 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6939 MarkDeclarationsReferencedInExpr( 6940 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6941 Var->getType().getNonLValueExprType(Context), 6942 ForLoc, /*RefersToCapture=*/true)); 6943 } 6944 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6945 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6946 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6947 // associated for-loop of a simd construct with just one associated 6948 // for-loop may be listed in a linear clause with a constant-linear-step 6949 // that is the increment of the associated for-loop. The loop iteration 6950 // variable(s) in the associated for-loop(s) of a for or parallel for 6951 // construct may be listed in a private or lastprivate clause. 6952 DSAStackTy::DSAVarData DVar = 6953 DSAStack->getTopDSA(D, /*FromParent=*/false); 6954 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6955 // is declared in the loop and it is predetermined as a private. 6956 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6957 OpenMPClauseKind PredeterminedCKind = 6958 isOpenMPSimdDirective(DKind) 6959 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6960 : OMPC_private; 6961 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6962 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6963 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6964 DVar.CKind != OMPC_private))) || 6965 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6966 DKind == OMPD_master_taskloop || 6967 DKind == OMPD_parallel_master_taskloop || 6968 isOpenMPDistributeDirective(DKind)) && 6969 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6970 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6971 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6972 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6973 << getOpenMPClauseName(DVar.CKind) 6974 << getOpenMPDirectiveName(DKind) 6975 << getOpenMPClauseName(PredeterminedCKind); 6976 if (DVar.RefExpr == nullptr) 6977 DVar.CKind = PredeterminedCKind; 6978 reportOriginalDsa(*this, DSAStack, D, DVar, 6979 /*IsLoopIterVar=*/true); 6980 } else if (LoopDeclRefExpr) { 6981 // Make the loop iteration variable private (for worksharing 6982 // constructs), linear (for simd directives with the only one 6983 // associated loop) or lastprivate (for simd directives with several 6984 // collapsed or ordered loops). 6985 if (DVar.CKind == OMPC_unknown) 6986 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6987 PrivateRef); 6988 } 6989 } 6990 } 6991 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6992 } 6993 } 6994 6995 /// Called on a for stmt to check and extract its iteration space 6996 /// for further processing (such as collapsing). 6997 static bool checkOpenMPIterationSpace( 6998 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6999 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7000 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7001 Expr *OrderedLoopCountExpr, 7002 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7003 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7004 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7005 // OpenMP [2.9.1, Canonical Loop Form] 7006 // for (init-expr; test-expr; incr-expr) structured-block 7007 // for (range-decl: range-expr) structured-block 7008 auto *For = dyn_cast_or_null<ForStmt>(S); 7009 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7010 // Ranged for is supported only in OpenMP 5.0. 7011 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7012 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7013 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7014 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7015 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7016 if (TotalNestedLoopCount > 1) { 7017 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7018 SemaRef.Diag(DSA.getConstructLoc(), 7019 diag::note_omp_collapse_ordered_expr) 7020 << 2 << CollapseLoopCountExpr->getSourceRange() 7021 << OrderedLoopCountExpr->getSourceRange(); 7022 else if (CollapseLoopCountExpr) 7023 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7024 diag::note_omp_collapse_ordered_expr) 7025 << 0 << CollapseLoopCountExpr->getSourceRange(); 7026 else 7027 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7028 diag::note_omp_collapse_ordered_expr) 7029 << 1 << OrderedLoopCountExpr->getSourceRange(); 7030 } 7031 return true; 7032 } 7033 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7034 "No loop body."); 7035 7036 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7037 For ? For->getForLoc() : CXXFor->getForLoc()); 7038 7039 // Check init. 7040 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7041 if (ISC.checkAndSetInit(Init)) 7042 return true; 7043 7044 bool HasErrors = false; 7045 7046 // Check loop variable's type. 7047 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7048 // OpenMP [2.6, Canonical Loop Form] 7049 // Var is one of the following: 7050 // A variable of signed or unsigned integer type. 7051 // For C++, a variable of a random access iterator type. 7052 // For C, a variable of a pointer type. 7053 QualType VarType = LCDecl->getType().getNonReferenceType(); 7054 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7055 !VarType->isPointerType() && 7056 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7057 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7058 << SemaRef.getLangOpts().CPlusPlus; 7059 HasErrors = true; 7060 } 7061 7062 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7063 // a Construct 7064 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7065 // parallel for construct is (are) private. 7066 // The loop iteration variable in the associated for-loop of a simd 7067 // construct with just one associated for-loop is linear with a 7068 // constant-linear-step that is the increment of the associated for-loop. 7069 // Exclude loop var from the list of variables with implicitly defined data 7070 // sharing attributes. 7071 VarsWithImplicitDSA.erase(LCDecl); 7072 7073 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7074 7075 // Check test-expr. 7076 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7077 7078 // Check incr-expr. 7079 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7080 } 7081 7082 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7083 return HasErrors; 7084 7085 // Build the loop's iteration space representation. 7086 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7087 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7088 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7089 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7090 (isOpenMPWorksharingDirective(DKind) || 7091 isOpenMPTaskLoopDirective(DKind) || 7092 isOpenMPDistributeDirective(DKind)), 7093 Captures); 7094 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7095 ISC.buildCounterVar(Captures, DSA); 7096 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7097 ISC.buildPrivateCounterVar(); 7098 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7099 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7100 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7101 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7102 ISC.getConditionSrcRange(); 7103 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7104 ISC.getIncrementSrcRange(); 7105 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7106 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7107 ISC.isStrictTestOp(); 7108 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7109 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7110 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7111 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7112 ISC.buildFinalCondition(DSA.getCurScope()); 7113 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7114 ISC.doesInitDependOnLC(); 7115 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7116 ISC.doesCondDependOnLC(); 7117 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7118 ISC.getLoopDependentIdx(); 7119 7120 HasErrors |= 7121 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7122 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7123 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7124 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7125 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7126 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7127 if (!HasErrors && DSA.isOrderedRegion()) { 7128 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7129 if (CurrentNestedLoopCount < 7130 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7131 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7132 CurrentNestedLoopCount, 7133 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7134 DSA.getOrderedRegionParam().second->setLoopCounter( 7135 CurrentNestedLoopCount, 7136 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7137 } 7138 } 7139 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7140 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7141 // Erroneous case - clause has some problems. 7142 continue; 7143 } 7144 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7145 Pair.second.size() <= CurrentNestedLoopCount) { 7146 // Erroneous case - clause has some problems. 7147 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7148 continue; 7149 } 7150 Expr *CntValue; 7151 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7152 CntValue = ISC.buildOrderedLoopData( 7153 DSA.getCurScope(), 7154 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7155 Pair.first->getDependencyLoc()); 7156 else 7157 CntValue = ISC.buildOrderedLoopData( 7158 DSA.getCurScope(), 7159 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7160 Pair.first->getDependencyLoc(), 7161 Pair.second[CurrentNestedLoopCount].first, 7162 Pair.second[CurrentNestedLoopCount].second); 7163 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7164 } 7165 } 7166 7167 return HasErrors; 7168 } 7169 7170 /// Build 'VarRef = Start. 7171 static ExprResult 7172 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7173 ExprResult Start, bool IsNonRectangularLB, 7174 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7175 // Build 'VarRef = Start. 7176 ExprResult NewStart = IsNonRectangularLB 7177 ? Start.get() 7178 : tryBuildCapture(SemaRef, Start.get(), Captures); 7179 if (!NewStart.isUsable()) 7180 return ExprError(); 7181 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7182 VarRef.get()->getType())) { 7183 NewStart = SemaRef.PerformImplicitConversion( 7184 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7185 /*AllowExplicit=*/true); 7186 if (!NewStart.isUsable()) 7187 return ExprError(); 7188 } 7189 7190 ExprResult Init = 7191 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7192 return Init; 7193 } 7194 7195 /// Build 'VarRef = Start + Iter * Step'. 7196 static ExprResult buildCounterUpdate( 7197 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7198 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7199 bool IsNonRectangularLB, 7200 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7201 // Add parentheses (for debugging purposes only). 7202 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7203 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7204 !Step.isUsable()) 7205 return ExprError(); 7206 7207 ExprResult NewStep = Step; 7208 if (Captures) 7209 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7210 if (NewStep.isInvalid()) 7211 return ExprError(); 7212 ExprResult Update = 7213 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7214 if (!Update.isUsable()) 7215 return ExprError(); 7216 7217 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7218 // 'VarRef = Start (+|-) Iter * Step'. 7219 if (!Start.isUsable()) 7220 return ExprError(); 7221 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7222 if (!NewStart.isUsable()) 7223 return ExprError(); 7224 if (Captures && !IsNonRectangularLB) 7225 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7226 if (NewStart.isInvalid()) 7227 return ExprError(); 7228 7229 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7230 ExprResult SavedUpdate = Update; 7231 ExprResult UpdateVal; 7232 if (VarRef.get()->getType()->isOverloadableType() || 7233 NewStart.get()->getType()->isOverloadableType() || 7234 Update.get()->getType()->isOverloadableType()) { 7235 Sema::TentativeAnalysisScope Trap(SemaRef); 7236 7237 Update = 7238 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7239 if (Update.isUsable()) { 7240 UpdateVal = 7241 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7242 VarRef.get(), SavedUpdate.get()); 7243 if (UpdateVal.isUsable()) { 7244 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7245 UpdateVal.get()); 7246 } 7247 } 7248 } 7249 7250 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7251 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7252 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7253 NewStart.get(), SavedUpdate.get()); 7254 if (!Update.isUsable()) 7255 return ExprError(); 7256 7257 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7258 VarRef.get()->getType())) { 7259 Update = SemaRef.PerformImplicitConversion( 7260 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7261 if (!Update.isUsable()) 7262 return ExprError(); 7263 } 7264 7265 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7266 } 7267 return Update; 7268 } 7269 7270 /// Convert integer expression \a E to make it have at least \a Bits 7271 /// bits. 7272 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7273 if (E == nullptr) 7274 return ExprError(); 7275 ASTContext &C = SemaRef.Context; 7276 QualType OldType = E->getType(); 7277 unsigned HasBits = C.getTypeSize(OldType); 7278 if (HasBits >= Bits) 7279 return ExprResult(E); 7280 // OK to convert to signed, because new type has more bits than old. 7281 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7282 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7283 true); 7284 } 7285 7286 /// Check if the given expression \a E is a constant integer that fits 7287 /// into \a Bits bits. 7288 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7289 if (E == nullptr) 7290 return false; 7291 llvm::APSInt Result; 7292 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7293 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7294 return false; 7295 } 7296 7297 /// Build preinits statement for the given declarations. 7298 static Stmt *buildPreInits(ASTContext &Context, 7299 MutableArrayRef<Decl *> PreInits) { 7300 if (!PreInits.empty()) { 7301 return new (Context) DeclStmt( 7302 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7303 SourceLocation(), SourceLocation()); 7304 } 7305 return nullptr; 7306 } 7307 7308 /// Build preinits statement for the given declarations. 7309 static Stmt * 7310 buildPreInits(ASTContext &Context, 7311 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7312 if (!Captures.empty()) { 7313 SmallVector<Decl *, 16> PreInits; 7314 for (const auto &Pair : Captures) 7315 PreInits.push_back(Pair.second->getDecl()); 7316 return buildPreInits(Context, PreInits); 7317 } 7318 return nullptr; 7319 } 7320 7321 /// Build postupdate expression for the given list of postupdates expressions. 7322 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7323 Expr *PostUpdate = nullptr; 7324 if (!PostUpdates.empty()) { 7325 for (Expr *E : PostUpdates) { 7326 Expr *ConvE = S.BuildCStyleCastExpr( 7327 E->getExprLoc(), 7328 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7329 E->getExprLoc(), E) 7330 .get(); 7331 PostUpdate = PostUpdate 7332 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7333 PostUpdate, ConvE) 7334 .get() 7335 : ConvE; 7336 } 7337 } 7338 return PostUpdate; 7339 } 7340 7341 /// Called on a for stmt to check itself and nested loops (if any). 7342 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7343 /// number of collapsed loops otherwise. 7344 static unsigned 7345 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7346 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7347 DSAStackTy &DSA, 7348 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7349 OMPLoopDirective::HelperExprs &Built) { 7350 unsigned NestedLoopCount = 1; 7351 if (CollapseLoopCountExpr) { 7352 // Found 'collapse' clause - calculate collapse number. 7353 Expr::EvalResult Result; 7354 if (!CollapseLoopCountExpr->isValueDependent() && 7355 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7356 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7357 } else { 7358 Built.clear(/*Size=*/1); 7359 return 1; 7360 } 7361 } 7362 unsigned OrderedLoopCount = 1; 7363 if (OrderedLoopCountExpr) { 7364 // Found 'ordered' clause - calculate collapse number. 7365 Expr::EvalResult EVResult; 7366 if (!OrderedLoopCountExpr->isValueDependent() && 7367 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7368 SemaRef.getASTContext())) { 7369 llvm::APSInt Result = EVResult.Val.getInt(); 7370 if (Result.getLimitedValue() < NestedLoopCount) { 7371 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7372 diag::err_omp_wrong_ordered_loop_count) 7373 << OrderedLoopCountExpr->getSourceRange(); 7374 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7375 diag::note_collapse_loop_count) 7376 << CollapseLoopCountExpr->getSourceRange(); 7377 } 7378 OrderedLoopCount = Result.getLimitedValue(); 7379 } else { 7380 Built.clear(/*Size=*/1); 7381 return 1; 7382 } 7383 } 7384 // This is helper routine for loop directives (e.g., 'for', 'simd', 7385 // 'for simd', etc.). 7386 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7387 SmallVector<LoopIterationSpace, 4> IterSpaces( 7388 std::max(OrderedLoopCount, NestedLoopCount)); 7389 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7390 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7391 if (checkOpenMPIterationSpace( 7392 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7393 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7394 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7395 return 0; 7396 // Move on to the next nested for loop, or to the loop body. 7397 // OpenMP [2.8.1, simd construct, Restrictions] 7398 // All loops associated with the construct must be perfectly nested; that 7399 // is, there must be no intervening code nor any OpenMP directive between 7400 // any two loops. 7401 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7402 CurStmt = For->getBody(); 7403 } else { 7404 assert(isa<CXXForRangeStmt>(CurStmt) && 7405 "Expected canonical for or range-based for loops."); 7406 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7407 } 7408 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7409 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7410 } 7411 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7412 if (checkOpenMPIterationSpace( 7413 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7414 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7415 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7416 return 0; 7417 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7418 // Handle initialization of captured loop iterator variables. 7419 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7420 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7421 Captures[DRE] = DRE; 7422 } 7423 } 7424 // Move on to the next nested for loop, or to the loop body. 7425 // OpenMP [2.8.1, simd construct, Restrictions] 7426 // All loops associated with the construct must be perfectly nested; that 7427 // is, there must be no intervening code nor any OpenMP directive between 7428 // any two loops. 7429 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7430 CurStmt = For->getBody(); 7431 } else { 7432 assert(isa<CXXForRangeStmt>(CurStmt) && 7433 "Expected canonical for or range-based for loops."); 7434 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7435 } 7436 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7437 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7438 } 7439 7440 Built.clear(/* size */ NestedLoopCount); 7441 7442 if (SemaRef.CurContext->isDependentContext()) 7443 return NestedLoopCount; 7444 7445 // An example of what is generated for the following code: 7446 // 7447 // #pragma omp simd collapse(2) ordered(2) 7448 // for (i = 0; i < NI; ++i) 7449 // for (k = 0; k < NK; ++k) 7450 // for (j = J0; j < NJ; j+=2) { 7451 // <loop body> 7452 // } 7453 // 7454 // We generate the code below. 7455 // Note: the loop body may be outlined in CodeGen. 7456 // Note: some counters may be C++ classes, operator- is used to find number of 7457 // iterations and operator+= to calculate counter value. 7458 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7459 // or i64 is currently supported). 7460 // 7461 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7462 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7463 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7464 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7465 // // similar updates for vars in clauses (e.g. 'linear') 7466 // <loop body (using local i and j)> 7467 // } 7468 // i = NI; // assign final values of counters 7469 // j = NJ; 7470 // 7471 7472 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7473 // the iteration counts of the collapsed for loops. 7474 // Precondition tests if there is at least one iteration (all conditions are 7475 // true). 7476 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7477 Expr *N0 = IterSpaces[0].NumIterations; 7478 ExprResult LastIteration32 = 7479 widenIterationCount(/*Bits=*/32, 7480 SemaRef 7481 .PerformImplicitConversion( 7482 N0->IgnoreImpCasts(), N0->getType(), 7483 Sema::AA_Converting, /*AllowExplicit=*/true) 7484 .get(), 7485 SemaRef); 7486 ExprResult LastIteration64 = widenIterationCount( 7487 /*Bits=*/64, 7488 SemaRef 7489 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7490 Sema::AA_Converting, 7491 /*AllowExplicit=*/true) 7492 .get(), 7493 SemaRef); 7494 7495 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7496 return NestedLoopCount; 7497 7498 ASTContext &C = SemaRef.Context; 7499 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7500 7501 Scope *CurScope = DSA.getCurScope(); 7502 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7503 if (PreCond.isUsable()) { 7504 PreCond = 7505 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7506 PreCond.get(), IterSpaces[Cnt].PreCond); 7507 } 7508 Expr *N = IterSpaces[Cnt].NumIterations; 7509 SourceLocation Loc = N->getExprLoc(); 7510 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7511 if (LastIteration32.isUsable()) 7512 LastIteration32 = SemaRef.BuildBinOp( 7513 CurScope, Loc, BO_Mul, LastIteration32.get(), 7514 SemaRef 7515 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7516 Sema::AA_Converting, 7517 /*AllowExplicit=*/true) 7518 .get()); 7519 if (LastIteration64.isUsable()) 7520 LastIteration64 = SemaRef.BuildBinOp( 7521 CurScope, Loc, BO_Mul, LastIteration64.get(), 7522 SemaRef 7523 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7524 Sema::AA_Converting, 7525 /*AllowExplicit=*/true) 7526 .get()); 7527 } 7528 7529 // Choose either the 32-bit or 64-bit version. 7530 ExprResult LastIteration = LastIteration64; 7531 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7532 (LastIteration32.isUsable() && 7533 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7534 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7535 fitsInto( 7536 /*Bits=*/32, 7537 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7538 LastIteration64.get(), SemaRef)))) 7539 LastIteration = LastIteration32; 7540 QualType VType = LastIteration.get()->getType(); 7541 QualType RealVType = VType; 7542 QualType StrideVType = VType; 7543 if (isOpenMPTaskLoopDirective(DKind)) { 7544 VType = 7545 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7546 StrideVType = 7547 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7548 } 7549 7550 if (!LastIteration.isUsable()) 7551 return 0; 7552 7553 // Save the number of iterations. 7554 ExprResult NumIterations = LastIteration; 7555 { 7556 LastIteration = SemaRef.BuildBinOp( 7557 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7558 LastIteration.get(), 7559 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7560 if (!LastIteration.isUsable()) 7561 return 0; 7562 } 7563 7564 // Calculate the last iteration number beforehand instead of doing this on 7565 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7566 llvm::APSInt Result; 7567 bool IsConstant = 7568 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7569 ExprResult CalcLastIteration; 7570 if (!IsConstant) { 7571 ExprResult SaveRef = 7572 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7573 LastIteration = SaveRef; 7574 7575 // Prepare SaveRef + 1. 7576 NumIterations = SemaRef.BuildBinOp( 7577 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7578 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7579 if (!NumIterations.isUsable()) 7580 return 0; 7581 } 7582 7583 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7584 7585 // Build variables passed into runtime, necessary for worksharing directives. 7586 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7587 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7588 isOpenMPDistributeDirective(DKind)) { 7589 // Lower bound variable, initialized with zero. 7590 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7591 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7592 SemaRef.AddInitializerToDecl(LBDecl, 7593 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7594 /*DirectInit*/ false); 7595 7596 // Upper bound variable, initialized with last iteration number. 7597 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7598 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7599 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7600 /*DirectInit*/ false); 7601 7602 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7603 // This will be used to implement clause 'lastprivate'. 7604 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7605 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7606 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7607 SemaRef.AddInitializerToDecl(ILDecl, 7608 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7609 /*DirectInit*/ false); 7610 7611 // Stride variable returned by runtime (we initialize it to 1 by default). 7612 VarDecl *STDecl = 7613 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7614 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7615 SemaRef.AddInitializerToDecl(STDecl, 7616 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7617 /*DirectInit*/ false); 7618 7619 // Build expression: UB = min(UB, LastIteration) 7620 // It is necessary for CodeGen of directives with static scheduling. 7621 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7622 UB.get(), LastIteration.get()); 7623 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7624 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7625 LastIteration.get(), UB.get()); 7626 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7627 CondOp.get()); 7628 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7629 7630 // If we have a combined directive that combines 'distribute', 'for' or 7631 // 'simd' we need to be able to access the bounds of the schedule of the 7632 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7633 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7634 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7635 // Lower bound variable, initialized with zero. 7636 VarDecl *CombLBDecl = 7637 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7638 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7639 SemaRef.AddInitializerToDecl( 7640 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7641 /*DirectInit*/ false); 7642 7643 // Upper bound variable, initialized with last iteration number. 7644 VarDecl *CombUBDecl = 7645 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7646 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7647 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7648 /*DirectInit*/ false); 7649 7650 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7651 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7652 ExprResult CombCondOp = 7653 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7654 LastIteration.get(), CombUB.get()); 7655 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7656 CombCondOp.get()); 7657 CombEUB = 7658 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7659 7660 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7661 // We expect to have at least 2 more parameters than the 'parallel' 7662 // directive does - the lower and upper bounds of the previous schedule. 7663 assert(CD->getNumParams() >= 4 && 7664 "Unexpected number of parameters in loop combined directive"); 7665 7666 // Set the proper type for the bounds given what we learned from the 7667 // enclosed loops. 7668 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7669 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7670 7671 // Previous lower and upper bounds are obtained from the region 7672 // parameters. 7673 PrevLB = 7674 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7675 PrevUB = 7676 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7677 } 7678 } 7679 7680 // Build the iteration variable and its initialization before loop. 7681 ExprResult IV; 7682 ExprResult Init, CombInit; 7683 { 7684 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7685 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7686 Expr *RHS = 7687 (isOpenMPWorksharingDirective(DKind) || 7688 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7689 ? LB.get() 7690 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7691 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7692 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7693 7694 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7695 Expr *CombRHS = 7696 (isOpenMPWorksharingDirective(DKind) || 7697 isOpenMPTaskLoopDirective(DKind) || 7698 isOpenMPDistributeDirective(DKind)) 7699 ? CombLB.get() 7700 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7701 CombInit = 7702 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7703 CombInit = 7704 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7705 } 7706 } 7707 7708 bool UseStrictCompare = 7709 RealVType->hasUnsignedIntegerRepresentation() && 7710 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7711 return LIS.IsStrictCompare; 7712 }); 7713 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7714 // unsigned IV)) for worksharing loops. 7715 SourceLocation CondLoc = AStmt->getBeginLoc(); 7716 Expr *BoundUB = UB.get(); 7717 if (UseStrictCompare) { 7718 BoundUB = 7719 SemaRef 7720 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7721 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7722 .get(); 7723 BoundUB = 7724 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7725 } 7726 ExprResult Cond = 7727 (isOpenMPWorksharingDirective(DKind) || 7728 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7729 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7730 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7731 BoundUB) 7732 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7733 NumIterations.get()); 7734 ExprResult CombDistCond; 7735 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7736 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7737 NumIterations.get()); 7738 } 7739 7740 ExprResult CombCond; 7741 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7742 Expr *BoundCombUB = CombUB.get(); 7743 if (UseStrictCompare) { 7744 BoundCombUB = 7745 SemaRef 7746 .BuildBinOp( 7747 CurScope, CondLoc, BO_Add, BoundCombUB, 7748 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7749 .get(); 7750 BoundCombUB = 7751 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7752 .get(); 7753 } 7754 CombCond = 7755 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7756 IV.get(), BoundCombUB); 7757 } 7758 // Loop increment (IV = IV + 1) 7759 SourceLocation IncLoc = AStmt->getBeginLoc(); 7760 ExprResult Inc = 7761 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7762 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7763 if (!Inc.isUsable()) 7764 return 0; 7765 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7766 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7767 if (!Inc.isUsable()) 7768 return 0; 7769 7770 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7771 // Used for directives with static scheduling. 7772 // In combined construct, add combined version that use CombLB and CombUB 7773 // base variables for the update 7774 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7775 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7776 isOpenMPDistributeDirective(DKind)) { 7777 // LB + ST 7778 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7779 if (!NextLB.isUsable()) 7780 return 0; 7781 // LB = LB + ST 7782 NextLB = 7783 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7784 NextLB = 7785 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7786 if (!NextLB.isUsable()) 7787 return 0; 7788 // UB + ST 7789 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7790 if (!NextUB.isUsable()) 7791 return 0; 7792 // UB = UB + ST 7793 NextUB = 7794 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7795 NextUB = 7796 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7797 if (!NextUB.isUsable()) 7798 return 0; 7799 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7800 CombNextLB = 7801 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7802 if (!NextLB.isUsable()) 7803 return 0; 7804 // LB = LB + ST 7805 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7806 CombNextLB.get()); 7807 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7808 /*DiscardedValue*/ false); 7809 if (!CombNextLB.isUsable()) 7810 return 0; 7811 // UB + ST 7812 CombNextUB = 7813 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7814 if (!CombNextUB.isUsable()) 7815 return 0; 7816 // UB = UB + ST 7817 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7818 CombNextUB.get()); 7819 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7820 /*DiscardedValue*/ false); 7821 if (!CombNextUB.isUsable()) 7822 return 0; 7823 } 7824 } 7825 7826 // Create increment expression for distribute loop when combined in a same 7827 // directive with for as IV = IV + ST; ensure upper bound expression based 7828 // on PrevUB instead of NumIterations - used to implement 'for' when found 7829 // in combination with 'distribute', like in 'distribute parallel for' 7830 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7831 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7832 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7833 DistCond = SemaRef.BuildBinOp( 7834 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7835 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7836 7837 DistInc = 7838 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7839 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7840 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7841 DistInc.get()); 7842 DistInc = 7843 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7844 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7845 7846 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7847 // construct 7848 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7849 ExprResult IsUBGreater = 7850 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7851 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7852 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7853 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7854 CondOp.get()); 7855 PrevEUB = 7856 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7857 7858 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7859 // parallel for is in combination with a distribute directive with 7860 // schedule(static, 1) 7861 Expr *BoundPrevUB = PrevUB.get(); 7862 if (UseStrictCompare) { 7863 BoundPrevUB = 7864 SemaRef 7865 .BuildBinOp( 7866 CurScope, CondLoc, BO_Add, BoundPrevUB, 7867 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7868 .get(); 7869 BoundPrevUB = 7870 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7871 .get(); 7872 } 7873 ParForInDistCond = 7874 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7875 IV.get(), BoundPrevUB); 7876 } 7877 7878 // Build updates and final values of the loop counters. 7879 bool HasErrors = false; 7880 Built.Counters.resize(NestedLoopCount); 7881 Built.Inits.resize(NestedLoopCount); 7882 Built.Updates.resize(NestedLoopCount); 7883 Built.Finals.resize(NestedLoopCount); 7884 Built.DependentCounters.resize(NestedLoopCount); 7885 Built.DependentInits.resize(NestedLoopCount); 7886 Built.FinalsConditions.resize(NestedLoopCount); 7887 { 7888 // We implement the following algorithm for obtaining the 7889 // original loop iteration variable values based on the 7890 // value of the collapsed loop iteration variable IV. 7891 // 7892 // Let n+1 be the number of collapsed loops in the nest. 7893 // Iteration variables (I0, I1, .... In) 7894 // Iteration counts (N0, N1, ... Nn) 7895 // 7896 // Acc = IV; 7897 // 7898 // To compute Ik for loop k, 0 <= k <= n, generate: 7899 // Prod = N(k+1) * N(k+2) * ... * Nn; 7900 // Ik = Acc / Prod; 7901 // Acc -= Ik * Prod; 7902 // 7903 ExprResult Acc = IV; 7904 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7905 LoopIterationSpace &IS = IterSpaces[Cnt]; 7906 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7907 ExprResult Iter; 7908 7909 // Compute prod 7910 ExprResult Prod = 7911 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7912 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7913 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7914 IterSpaces[K].NumIterations); 7915 7916 // Iter = Acc / Prod 7917 // If there is at least one more inner loop to avoid 7918 // multiplication by 1. 7919 if (Cnt + 1 < NestedLoopCount) 7920 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7921 Acc.get(), Prod.get()); 7922 else 7923 Iter = Acc; 7924 if (!Iter.isUsable()) { 7925 HasErrors = true; 7926 break; 7927 } 7928 7929 // Update Acc: 7930 // Acc -= Iter * Prod 7931 // Check if there is at least one more inner loop to avoid 7932 // multiplication by 1. 7933 if (Cnt + 1 < NestedLoopCount) 7934 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7935 Iter.get(), Prod.get()); 7936 else 7937 Prod = Iter; 7938 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7939 Acc.get(), Prod.get()); 7940 7941 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7942 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7943 DeclRefExpr *CounterVar = buildDeclRefExpr( 7944 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7945 /*RefersToCapture=*/true); 7946 ExprResult Init = 7947 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7948 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7949 if (!Init.isUsable()) { 7950 HasErrors = true; 7951 break; 7952 } 7953 ExprResult Update = buildCounterUpdate( 7954 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7955 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7956 if (!Update.isUsable()) { 7957 HasErrors = true; 7958 break; 7959 } 7960 7961 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7962 ExprResult Final = 7963 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7964 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7965 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7966 if (!Final.isUsable()) { 7967 HasErrors = true; 7968 break; 7969 } 7970 7971 if (!Update.isUsable() || !Final.isUsable()) { 7972 HasErrors = true; 7973 break; 7974 } 7975 // Save results 7976 Built.Counters[Cnt] = IS.CounterVar; 7977 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7978 Built.Inits[Cnt] = Init.get(); 7979 Built.Updates[Cnt] = Update.get(); 7980 Built.Finals[Cnt] = Final.get(); 7981 Built.DependentCounters[Cnt] = nullptr; 7982 Built.DependentInits[Cnt] = nullptr; 7983 Built.FinalsConditions[Cnt] = nullptr; 7984 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7985 Built.DependentCounters[Cnt] = 7986 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7987 Built.DependentInits[Cnt] = 7988 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7989 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7990 } 7991 } 7992 } 7993 7994 if (HasErrors) 7995 return 0; 7996 7997 // Save results 7998 Built.IterationVarRef = IV.get(); 7999 Built.LastIteration = LastIteration.get(); 8000 Built.NumIterations = NumIterations.get(); 8001 Built.CalcLastIteration = SemaRef 8002 .ActOnFinishFullExpr(CalcLastIteration.get(), 8003 /*DiscardedValue=*/false) 8004 .get(); 8005 Built.PreCond = PreCond.get(); 8006 Built.PreInits = buildPreInits(C, Captures); 8007 Built.Cond = Cond.get(); 8008 Built.Init = Init.get(); 8009 Built.Inc = Inc.get(); 8010 Built.LB = LB.get(); 8011 Built.UB = UB.get(); 8012 Built.IL = IL.get(); 8013 Built.ST = ST.get(); 8014 Built.EUB = EUB.get(); 8015 Built.NLB = NextLB.get(); 8016 Built.NUB = NextUB.get(); 8017 Built.PrevLB = PrevLB.get(); 8018 Built.PrevUB = PrevUB.get(); 8019 Built.DistInc = DistInc.get(); 8020 Built.PrevEUB = PrevEUB.get(); 8021 Built.DistCombinedFields.LB = CombLB.get(); 8022 Built.DistCombinedFields.UB = CombUB.get(); 8023 Built.DistCombinedFields.EUB = CombEUB.get(); 8024 Built.DistCombinedFields.Init = CombInit.get(); 8025 Built.DistCombinedFields.Cond = CombCond.get(); 8026 Built.DistCombinedFields.NLB = CombNextLB.get(); 8027 Built.DistCombinedFields.NUB = CombNextUB.get(); 8028 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8029 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8030 8031 return NestedLoopCount; 8032 } 8033 8034 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8035 auto CollapseClauses = 8036 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8037 if (CollapseClauses.begin() != CollapseClauses.end()) 8038 return (*CollapseClauses.begin())->getNumForLoops(); 8039 return nullptr; 8040 } 8041 8042 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8043 auto OrderedClauses = 8044 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8045 if (OrderedClauses.begin() != OrderedClauses.end()) 8046 return (*OrderedClauses.begin())->getNumForLoops(); 8047 return nullptr; 8048 } 8049 8050 static bool checkSimdlenSafelenSpecified(Sema &S, 8051 const ArrayRef<OMPClause *> Clauses) { 8052 const OMPSafelenClause *Safelen = nullptr; 8053 const OMPSimdlenClause *Simdlen = nullptr; 8054 8055 for (const OMPClause *Clause : Clauses) { 8056 if (Clause->getClauseKind() == OMPC_safelen) 8057 Safelen = cast<OMPSafelenClause>(Clause); 8058 else if (Clause->getClauseKind() == OMPC_simdlen) 8059 Simdlen = cast<OMPSimdlenClause>(Clause); 8060 if (Safelen && Simdlen) 8061 break; 8062 } 8063 8064 if (Simdlen && Safelen) { 8065 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8066 const Expr *SafelenLength = Safelen->getSafelen(); 8067 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8068 SimdlenLength->isInstantiationDependent() || 8069 SimdlenLength->containsUnexpandedParameterPack()) 8070 return false; 8071 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8072 SafelenLength->isInstantiationDependent() || 8073 SafelenLength->containsUnexpandedParameterPack()) 8074 return false; 8075 Expr::EvalResult SimdlenResult, SafelenResult; 8076 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8077 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8078 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8079 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8080 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8081 // If both simdlen and safelen clauses are specified, the value of the 8082 // simdlen parameter must be less than or equal to the value of the safelen 8083 // parameter. 8084 if (SimdlenRes > SafelenRes) { 8085 S.Diag(SimdlenLength->getExprLoc(), 8086 diag::err_omp_wrong_simdlen_safelen_values) 8087 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8088 return true; 8089 } 8090 } 8091 return false; 8092 } 8093 8094 StmtResult 8095 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8096 SourceLocation StartLoc, SourceLocation EndLoc, 8097 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8098 if (!AStmt) 8099 return StmtError(); 8100 8101 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8102 OMPLoopDirective::HelperExprs B; 8103 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8104 // define the nested loops number. 8105 unsigned NestedLoopCount = checkOpenMPLoop( 8106 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8107 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8108 if (NestedLoopCount == 0) 8109 return StmtError(); 8110 8111 assert((CurContext->isDependentContext() || B.builtAll()) && 8112 "omp simd loop exprs were not built"); 8113 8114 if (!CurContext->isDependentContext()) { 8115 // Finalize the clauses that need pre-built expressions for CodeGen. 8116 for (OMPClause *C : Clauses) { 8117 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8118 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8119 B.NumIterations, *this, CurScope, 8120 DSAStack)) 8121 return StmtError(); 8122 } 8123 } 8124 8125 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8126 return StmtError(); 8127 8128 setFunctionHasBranchProtectedScope(); 8129 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8130 Clauses, AStmt, B); 8131 } 8132 8133 StmtResult 8134 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8135 SourceLocation StartLoc, SourceLocation EndLoc, 8136 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8137 if (!AStmt) 8138 return StmtError(); 8139 8140 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8141 OMPLoopDirective::HelperExprs B; 8142 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8143 // define the nested loops number. 8144 unsigned NestedLoopCount = checkOpenMPLoop( 8145 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8146 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8147 if (NestedLoopCount == 0) 8148 return StmtError(); 8149 8150 assert((CurContext->isDependentContext() || B.builtAll()) && 8151 "omp for loop exprs were not built"); 8152 8153 if (!CurContext->isDependentContext()) { 8154 // Finalize the clauses that need pre-built expressions for CodeGen. 8155 for (OMPClause *C : Clauses) { 8156 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8157 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8158 B.NumIterations, *this, CurScope, 8159 DSAStack)) 8160 return StmtError(); 8161 } 8162 } 8163 8164 setFunctionHasBranchProtectedScope(); 8165 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8166 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8167 } 8168 8169 StmtResult Sema::ActOnOpenMPForSimdDirective( 8170 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8171 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8172 if (!AStmt) 8173 return StmtError(); 8174 8175 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8176 OMPLoopDirective::HelperExprs B; 8177 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8178 // define the nested loops number. 8179 unsigned NestedLoopCount = 8180 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8181 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8182 VarsWithImplicitDSA, B); 8183 if (NestedLoopCount == 0) 8184 return StmtError(); 8185 8186 assert((CurContext->isDependentContext() || B.builtAll()) && 8187 "omp for simd loop exprs were not built"); 8188 8189 if (!CurContext->isDependentContext()) { 8190 // Finalize the clauses that need pre-built expressions for CodeGen. 8191 for (OMPClause *C : Clauses) { 8192 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8193 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8194 B.NumIterations, *this, CurScope, 8195 DSAStack)) 8196 return StmtError(); 8197 } 8198 } 8199 8200 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8201 return StmtError(); 8202 8203 setFunctionHasBranchProtectedScope(); 8204 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8205 Clauses, AStmt, B); 8206 } 8207 8208 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8209 Stmt *AStmt, 8210 SourceLocation StartLoc, 8211 SourceLocation EndLoc) { 8212 if (!AStmt) 8213 return StmtError(); 8214 8215 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8216 auto BaseStmt = AStmt; 8217 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8218 BaseStmt = CS->getCapturedStmt(); 8219 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8220 auto S = C->children(); 8221 if (S.begin() == S.end()) 8222 return StmtError(); 8223 // All associated statements must be '#pragma omp section' except for 8224 // the first one. 8225 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8226 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8227 if (SectionStmt) 8228 Diag(SectionStmt->getBeginLoc(), 8229 diag::err_omp_sections_substmt_not_section); 8230 return StmtError(); 8231 } 8232 cast<OMPSectionDirective>(SectionStmt) 8233 ->setHasCancel(DSAStack->isCancelRegion()); 8234 } 8235 } else { 8236 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8237 return StmtError(); 8238 } 8239 8240 setFunctionHasBranchProtectedScope(); 8241 8242 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8243 DSAStack->isCancelRegion()); 8244 } 8245 8246 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8247 SourceLocation StartLoc, 8248 SourceLocation EndLoc) { 8249 if (!AStmt) 8250 return StmtError(); 8251 8252 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8253 8254 setFunctionHasBranchProtectedScope(); 8255 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8256 8257 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8258 DSAStack->isCancelRegion()); 8259 } 8260 8261 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8262 Stmt *AStmt, 8263 SourceLocation StartLoc, 8264 SourceLocation EndLoc) { 8265 if (!AStmt) 8266 return StmtError(); 8267 8268 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8269 8270 setFunctionHasBranchProtectedScope(); 8271 8272 // OpenMP [2.7.3, single Construct, Restrictions] 8273 // The copyprivate clause must not be used with the nowait clause. 8274 const OMPClause *Nowait = nullptr; 8275 const OMPClause *Copyprivate = nullptr; 8276 for (const OMPClause *Clause : Clauses) { 8277 if (Clause->getClauseKind() == OMPC_nowait) 8278 Nowait = Clause; 8279 else if (Clause->getClauseKind() == OMPC_copyprivate) 8280 Copyprivate = Clause; 8281 if (Copyprivate && Nowait) { 8282 Diag(Copyprivate->getBeginLoc(), 8283 diag::err_omp_single_copyprivate_with_nowait); 8284 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8285 return StmtError(); 8286 } 8287 } 8288 8289 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8290 } 8291 8292 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8293 SourceLocation StartLoc, 8294 SourceLocation EndLoc) { 8295 if (!AStmt) 8296 return StmtError(); 8297 8298 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8299 8300 setFunctionHasBranchProtectedScope(); 8301 8302 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8303 } 8304 8305 StmtResult Sema::ActOnOpenMPCriticalDirective( 8306 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8307 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8308 if (!AStmt) 8309 return StmtError(); 8310 8311 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8312 8313 bool ErrorFound = false; 8314 llvm::APSInt Hint; 8315 SourceLocation HintLoc; 8316 bool DependentHint = false; 8317 for (const OMPClause *C : Clauses) { 8318 if (C->getClauseKind() == OMPC_hint) { 8319 if (!DirName.getName()) { 8320 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8321 ErrorFound = true; 8322 } 8323 Expr *E = cast<OMPHintClause>(C)->getHint(); 8324 if (E->isTypeDependent() || E->isValueDependent() || 8325 E->isInstantiationDependent()) { 8326 DependentHint = true; 8327 } else { 8328 Hint = E->EvaluateKnownConstInt(Context); 8329 HintLoc = C->getBeginLoc(); 8330 } 8331 } 8332 } 8333 if (ErrorFound) 8334 return StmtError(); 8335 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8336 if (Pair.first && DirName.getName() && !DependentHint) { 8337 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8338 Diag(StartLoc, diag::err_omp_critical_with_hint); 8339 if (HintLoc.isValid()) 8340 Diag(HintLoc, diag::note_omp_critical_hint_here) 8341 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8342 else 8343 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8344 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8345 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8346 << 1 8347 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8348 /*Radix=*/10, /*Signed=*/false); 8349 } else { 8350 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8351 } 8352 } 8353 } 8354 8355 setFunctionHasBranchProtectedScope(); 8356 8357 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8358 Clauses, AStmt); 8359 if (!Pair.first && DirName.getName() && !DependentHint) 8360 DSAStack->addCriticalWithHint(Dir, Hint); 8361 return Dir; 8362 } 8363 8364 StmtResult Sema::ActOnOpenMPParallelForDirective( 8365 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8366 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8367 if (!AStmt) 8368 return StmtError(); 8369 8370 auto *CS = cast<CapturedStmt>(AStmt); 8371 // 1.2.2 OpenMP Language Terminology 8372 // Structured block - An executable statement with a single entry at the 8373 // top and a single exit at the bottom. 8374 // The point of exit cannot be a branch out of the structured block. 8375 // longjmp() and throw() must not violate the entry/exit criteria. 8376 CS->getCapturedDecl()->setNothrow(); 8377 8378 OMPLoopDirective::HelperExprs B; 8379 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8380 // define the nested loops number. 8381 unsigned NestedLoopCount = 8382 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8383 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8384 VarsWithImplicitDSA, B); 8385 if (NestedLoopCount == 0) 8386 return StmtError(); 8387 8388 assert((CurContext->isDependentContext() || B.builtAll()) && 8389 "omp parallel for loop exprs were not built"); 8390 8391 if (!CurContext->isDependentContext()) { 8392 // Finalize the clauses that need pre-built expressions for CodeGen. 8393 for (OMPClause *C : Clauses) { 8394 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8395 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8396 B.NumIterations, *this, CurScope, 8397 DSAStack)) 8398 return StmtError(); 8399 } 8400 } 8401 8402 setFunctionHasBranchProtectedScope(); 8403 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8404 NestedLoopCount, Clauses, AStmt, B, 8405 DSAStack->isCancelRegion()); 8406 } 8407 8408 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8409 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8410 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8411 if (!AStmt) 8412 return StmtError(); 8413 8414 auto *CS = cast<CapturedStmt>(AStmt); 8415 // 1.2.2 OpenMP Language Terminology 8416 // Structured block - An executable statement with a single entry at the 8417 // top and a single exit at the bottom. 8418 // The point of exit cannot be a branch out of the structured block. 8419 // longjmp() and throw() must not violate the entry/exit criteria. 8420 CS->getCapturedDecl()->setNothrow(); 8421 8422 OMPLoopDirective::HelperExprs B; 8423 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8424 // define the nested loops number. 8425 unsigned NestedLoopCount = 8426 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8427 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8428 VarsWithImplicitDSA, B); 8429 if (NestedLoopCount == 0) 8430 return StmtError(); 8431 8432 if (!CurContext->isDependentContext()) { 8433 // Finalize the clauses that need pre-built expressions for CodeGen. 8434 for (OMPClause *C : Clauses) { 8435 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8436 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8437 B.NumIterations, *this, CurScope, 8438 DSAStack)) 8439 return StmtError(); 8440 } 8441 } 8442 8443 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8444 return StmtError(); 8445 8446 setFunctionHasBranchProtectedScope(); 8447 return OMPParallelForSimdDirective::Create( 8448 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8449 } 8450 8451 StmtResult 8452 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8453 Stmt *AStmt, SourceLocation StartLoc, 8454 SourceLocation EndLoc) { 8455 if (!AStmt) 8456 return StmtError(); 8457 8458 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8459 auto *CS = cast<CapturedStmt>(AStmt); 8460 // 1.2.2 OpenMP Language Terminology 8461 // Structured block - An executable statement with a single entry at the 8462 // top and a single exit at the bottom. 8463 // The point of exit cannot be a branch out of the structured block. 8464 // longjmp() and throw() must not violate the entry/exit criteria. 8465 CS->getCapturedDecl()->setNothrow(); 8466 8467 setFunctionHasBranchProtectedScope(); 8468 8469 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8470 AStmt); 8471 } 8472 8473 StmtResult 8474 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8475 Stmt *AStmt, SourceLocation StartLoc, 8476 SourceLocation EndLoc) { 8477 if (!AStmt) 8478 return StmtError(); 8479 8480 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8481 auto BaseStmt = AStmt; 8482 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8483 BaseStmt = CS->getCapturedStmt(); 8484 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8485 auto S = C->children(); 8486 if (S.begin() == S.end()) 8487 return StmtError(); 8488 // All associated statements must be '#pragma omp section' except for 8489 // the first one. 8490 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8491 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8492 if (SectionStmt) 8493 Diag(SectionStmt->getBeginLoc(), 8494 diag::err_omp_parallel_sections_substmt_not_section); 8495 return StmtError(); 8496 } 8497 cast<OMPSectionDirective>(SectionStmt) 8498 ->setHasCancel(DSAStack->isCancelRegion()); 8499 } 8500 } else { 8501 Diag(AStmt->getBeginLoc(), 8502 diag::err_omp_parallel_sections_not_compound_stmt); 8503 return StmtError(); 8504 } 8505 8506 setFunctionHasBranchProtectedScope(); 8507 8508 return OMPParallelSectionsDirective::Create( 8509 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8510 } 8511 8512 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8513 Stmt *AStmt, SourceLocation StartLoc, 8514 SourceLocation EndLoc) { 8515 if (!AStmt) 8516 return StmtError(); 8517 8518 auto *CS = cast<CapturedStmt>(AStmt); 8519 // 1.2.2 OpenMP Language Terminology 8520 // Structured block - An executable statement with a single entry at the 8521 // top and a single exit at the bottom. 8522 // The point of exit cannot be a branch out of the structured block. 8523 // longjmp() and throw() must not violate the entry/exit criteria. 8524 CS->getCapturedDecl()->setNothrow(); 8525 8526 setFunctionHasBranchProtectedScope(); 8527 8528 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8529 DSAStack->isCancelRegion()); 8530 } 8531 8532 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8533 SourceLocation EndLoc) { 8534 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8535 } 8536 8537 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8538 SourceLocation EndLoc) { 8539 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8540 } 8541 8542 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8543 SourceLocation EndLoc) { 8544 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8545 } 8546 8547 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8548 Stmt *AStmt, 8549 SourceLocation StartLoc, 8550 SourceLocation EndLoc) { 8551 if (!AStmt) 8552 return StmtError(); 8553 8554 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8555 8556 setFunctionHasBranchProtectedScope(); 8557 8558 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8559 AStmt, 8560 DSAStack->getTaskgroupReductionRef()); 8561 } 8562 8563 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8564 SourceLocation StartLoc, 8565 SourceLocation EndLoc) { 8566 OMPFlushClause *FC = nullptr; 8567 OMPClause *OrderClause = nullptr; 8568 for (OMPClause *C : Clauses) { 8569 if (C->getClauseKind() == OMPC_flush) 8570 FC = cast<OMPFlushClause>(C); 8571 else 8572 OrderClause = C; 8573 } 8574 if (FC && OrderClause) { 8575 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 8576 << getOpenMPClauseName(OrderClause->getClauseKind()); 8577 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 8578 << getOpenMPClauseName(OrderClause->getClauseKind()); 8579 return StmtError(); 8580 } 8581 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8582 } 8583 8584 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8585 Stmt *AStmt, 8586 SourceLocation StartLoc, 8587 SourceLocation EndLoc) { 8588 const OMPClause *DependFound = nullptr; 8589 const OMPClause *DependSourceClause = nullptr; 8590 const OMPClause *DependSinkClause = nullptr; 8591 bool ErrorFound = false; 8592 const OMPThreadsClause *TC = nullptr; 8593 const OMPSIMDClause *SC = nullptr; 8594 for (const OMPClause *C : Clauses) { 8595 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8596 DependFound = C; 8597 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8598 if (DependSourceClause) { 8599 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8600 << getOpenMPDirectiveName(OMPD_ordered) 8601 << getOpenMPClauseName(OMPC_depend) << 2; 8602 ErrorFound = true; 8603 } else { 8604 DependSourceClause = C; 8605 } 8606 if (DependSinkClause) { 8607 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8608 << 0; 8609 ErrorFound = true; 8610 } 8611 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8612 if (DependSourceClause) { 8613 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8614 << 1; 8615 ErrorFound = true; 8616 } 8617 DependSinkClause = C; 8618 } 8619 } else if (C->getClauseKind() == OMPC_threads) { 8620 TC = cast<OMPThreadsClause>(C); 8621 } else if (C->getClauseKind() == OMPC_simd) { 8622 SC = cast<OMPSIMDClause>(C); 8623 } 8624 } 8625 if (!ErrorFound && !SC && 8626 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8627 // OpenMP [2.8.1,simd Construct, Restrictions] 8628 // An ordered construct with the simd clause is the only OpenMP construct 8629 // that can appear in the simd region. 8630 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8631 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8632 ErrorFound = true; 8633 } else if (DependFound && (TC || SC)) { 8634 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8635 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8636 ErrorFound = true; 8637 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8638 Diag(DependFound->getBeginLoc(), 8639 diag::err_omp_ordered_directive_without_param); 8640 ErrorFound = true; 8641 } else if (TC || Clauses.empty()) { 8642 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8643 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8644 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8645 << (TC != nullptr); 8646 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 8647 ErrorFound = true; 8648 } 8649 } 8650 if ((!AStmt && !DependFound) || ErrorFound) 8651 return StmtError(); 8652 8653 if (AStmt) { 8654 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8655 8656 setFunctionHasBranchProtectedScope(); 8657 } 8658 8659 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8660 } 8661 8662 namespace { 8663 /// Helper class for checking expression in 'omp atomic [update]' 8664 /// construct. 8665 class OpenMPAtomicUpdateChecker { 8666 /// Error results for atomic update expressions. 8667 enum ExprAnalysisErrorCode { 8668 /// A statement is not an expression statement. 8669 NotAnExpression, 8670 /// Expression is not builtin binary or unary operation. 8671 NotABinaryOrUnaryExpression, 8672 /// Unary operation is not post-/pre- increment/decrement operation. 8673 NotAnUnaryIncDecExpression, 8674 /// An expression is not of scalar type. 8675 NotAScalarType, 8676 /// A binary operation is not an assignment operation. 8677 NotAnAssignmentOp, 8678 /// RHS part of the binary operation is not a binary expression. 8679 NotABinaryExpression, 8680 /// RHS part is not additive/multiplicative/shift/biwise binary 8681 /// expression. 8682 NotABinaryOperator, 8683 /// RHS binary operation does not have reference to the updated LHS 8684 /// part. 8685 NotAnUpdateExpression, 8686 /// No errors is found. 8687 NoError 8688 }; 8689 /// Reference to Sema. 8690 Sema &SemaRef; 8691 /// A location for note diagnostics (when error is found). 8692 SourceLocation NoteLoc; 8693 /// 'x' lvalue part of the source atomic expression. 8694 Expr *X; 8695 /// 'expr' rvalue part of the source atomic expression. 8696 Expr *E; 8697 /// Helper expression of the form 8698 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8699 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8700 Expr *UpdateExpr; 8701 /// Is 'x' a LHS in a RHS part of full update expression. It is 8702 /// important for non-associative operations. 8703 bool IsXLHSInRHSPart; 8704 BinaryOperatorKind Op; 8705 SourceLocation OpLoc; 8706 /// true if the source expression is a postfix unary operation, false 8707 /// if it is a prefix unary operation. 8708 bool IsPostfixUpdate; 8709 8710 public: 8711 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8712 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8713 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8714 /// Check specified statement that it is suitable for 'atomic update' 8715 /// constructs and extract 'x', 'expr' and Operation from the original 8716 /// expression. If DiagId and NoteId == 0, then only check is performed 8717 /// without error notification. 8718 /// \param DiagId Diagnostic which should be emitted if error is found. 8719 /// \param NoteId Diagnostic note for the main error message. 8720 /// \return true if statement is not an update expression, false otherwise. 8721 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8722 /// Return the 'x' lvalue part of the source atomic expression. 8723 Expr *getX() const { return X; } 8724 /// Return the 'expr' rvalue part of the source atomic expression. 8725 Expr *getExpr() const { return E; } 8726 /// Return the update expression used in calculation of the updated 8727 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8728 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8729 Expr *getUpdateExpr() const { return UpdateExpr; } 8730 /// Return true if 'x' is LHS in RHS part of full update expression, 8731 /// false otherwise. 8732 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8733 8734 /// true if the source expression is a postfix unary operation, false 8735 /// if it is a prefix unary operation. 8736 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8737 8738 private: 8739 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8740 unsigned NoteId = 0); 8741 }; 8742 } // namespace 8743 8744 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8745 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8746 ExprAnalysisErrorCode ErrorFound = NoError; 8747 SourceLocation ErrorLoc, NoteLoc; 8748 SourceRange ErrorRange, NoteRange; 8749 // Allowed constructs are: 8750 // x = x binop expr; 8751 // x = expr binop x; 8752 if (AtomicBinOp->getOpcode() == BO_Assign) { 8753 X = AtomicBinOp->getLHS(); 8754 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8755 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8756 if (AtomicInnerBinOp->isMultiplicativeOp() || 8757 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8758 AtomicInnerBinOp->isBitwiseOp()) { 8759 Op = AtomicInnerBinOp->getOpcode(); 8760 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8761 Expr *LHS = AtomicInnerBinOp->getLHS(); 8762 Expr *RHS = AtomicInnerBinOp->getRHS(); 8763 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8764 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8765 /*Canonical=*/true); 8766 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8767 /*Canonical=*/true); 8768 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8769 /*Canonical=*/true); 8770 if (XId == LHSId) { 8771 E = RHS; 8772 IsXLHSInRHSPart = true; 8773 } else if (XId == RHSId) { 8774 E = LHS; 8775 IsXLHSInRHSPart = false; 8776 } else { 8777 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8778 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8779 NoteLoc = X->getExprLoc(); 8780 NoteRange = X->getSourceRange(); 8781 ErrorFound = NotAnUpdateExpression; 8782 } 8783 } else { 8784 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8785 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8786 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8787 NoteRange = SourceRange(NoteLoc, NoteLoc); 8788 ErrorFound = NotABinaryOperator; 8789 } 8790 } else { 8791 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8792 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8793 ErrorFound = NotABinaryExpression; 8794 } 8795 } else { 8796 ErrorLoc = AtomicBinOp->getExprLoc(); 8797 ErrorRange = AtomicBinOp->getSourceRange(); 8798 NoteLoc = AtomicBinOp->getOperatorLoc(); 8799 NoteRange = SourceRange(NoteLoc, NoteLoc); 8800 ErrorFound = NotAnAssignmentOp; 8801 } 8802 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8803 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8804 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8805 return true; 8806 } 8807 if (SemaRef.CurContext->isDependentContext()) 8808 E = X = UpdateExpr = nullptr; 8809 return ErrorFound != NoError; 8810 } 8811 8812 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8813 unsigned NoteId) { 8814 ExprAnalysisErrorCode ErrorFound = NoError; 8815 SourceLocation ErrorLoc, NoteLoc; 8816 SourceRange ErrorRange, NoteRange; 8817 // Allowed constructs are: 8818 // x++; 8819 // x--; 8820 // ++x; 8821 // --x; 8822 // x binop= expr; 8823 // x = x binop expr; 8824 // x = expr binop x; 8825 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8826 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8827 if (AtomicBody->getType()->isScalarType() || 8828 AtomicBody->isInstantiationDependent()) { 8829 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8830 AtomicBody->IgnoreParenImpCasts())) { 8831 // Check for Compound Assignment Operation 8832 Op = BinaryOperator::getOpForCompoundAssignment( 8833 AtomicCompAssignOp->getOpcode()); 8834 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8835 E = AtomicCompAssignOp->getRHS(); 8836 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8837 IsXLHSInRHSPart = true; 8838 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8839 AtomicBody->IgnoreParenImpCasts())) { 8840 // Check for Binary Operation 8841 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8842 return true; 8843 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8844 AtomicBody->IgnoreParenImpCasts())) { 8845 // Check for Unary Operation 8846 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8847 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8848 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8849 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8850 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8851 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8852 IsXLHSInRHSPart = true; 8853 } else { 8854 ErrorFound = NotAnUnaryIncDecExpression; 8855 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8856 ErrorRange = AtomicUnaryOp->getSourceRange(); 8857 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8858 NoteRange = SourceRange(NoteLoc, NoteLoc); 8859 } 8860 } else if (!AtomicBody->isInstantiationDependent()) { 8861 ErrorFound = NotABinaryOrUnaryExpression; 8862 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8863 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8864 } 8865 } else { 8866 ErrorFound = NotAScalarType; 8867 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8868 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8869 } 8870 } else { 8871 ErrorFound = NotAnExpression; 8872 NoteLoc = ErrorLoc = S->getBeginLoc(); 8873 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8874 } 8875 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8876 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8877 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8878 return true; 8879 } 8880 if (SemaRef.CurContext->isDependentContext()) 8881 E = X = UpdateExpr = nullptr; 8882 if (ErrorFound == NoError && E && X) { 8883 // Build an update expression of form 'OpaqueValueExpr(x) binop 8884 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8885 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8886 auto *OVEX = new (SemaRef.getASTContext()) 8887 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8888 auto *OVEExpr = new (SemaRef.getASTContext()) 8889 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8890 ExprResult Update = 8891 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8892 IsXLHSInRHSPart ? OVEExpr : OVEX); 8893 if (Update.isInvalid()) 8894 return true; 8895 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8896 Sema::AA_Casting); 8897 if (Update.isInvalid()) 8898 return true; 8899 UpdateExpr = Update.get(); 8900 } 8901 return ErrorFound != NoError; 8902 } 8903 8904 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8905 Stmt *AStmt, 8906 SourceLocation StartLoc, 8907 SourceLocation EndLoc) { 8908 if (!AStmt) 8909 return StmtError(); 8910 8911 auto *CS = cast<CapturedStmt>(AStmt); 8912 // 1.2.2 OpenMP Language Terminology 8913 // Structured block - An executable statement with a single entry at the 8914 // top and a single exit at the bottom. 8915 // The point of exit cannot be a branch out of the structured block. 8916 // longjmp() and throw() must not violate the entry/exit criteria. 8917 OpenMPClauseKind AtomicKind = OMPC_unknown; 8918 SourceLocation AtomicKindLoc; 8919 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8920 SourceLocation MemOrderLoc; 8921 for (const OMPClause *C : Clauses) { 8922 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8923 C->getClauseKind() == OMPC_update || 8924 C->getClauseKind() == OMPC_capture) { 8925 if (AtomicKind != OMPC_unknown) { 8926 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8927 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8928 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8929 << getOpenMPClauseName(AtomicKind); 8930 } else { 8931 AtomicKind = C->getClauseKind(); 8932 AtomicKindLoc = C->getBeginLoc(); 8933 } 8934 } 8935 if (C->getClauseKind() == OMPC_seq_cst || 8936 C->getClauseKind() == OMPC_acq_rel) { 8937 if (MemOrderKind != OMPC_unknown) { 8938 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_mem_order_clauses) 8939 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8940 Diag(MemOrderLoc, diag::note_omp_atomic_previous_clause) 8941 << getOpenMPClauseName(MemOrderKind); 8942 } else { 8943 MemOrderKind = C->getClauseKind(); 8944 MemOrderLoc = C->getBeginLoc(); 8945 } 8946 } 8947 } 8948 8949 Stmt *Body = CS->getCapturedStmt(); 8950 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8951 Body = EWC->getSubExpr(); 8952 8953 Expr *X = nullptr; 8954 Expr *V = nullptr; 8955 Expr *E = nullptr; 8956 Expr *UE = nullptr; 8957 bool IsXLHSInRHSPart = false; 8958 bool IsPostfixUpdate = false; 8959 // OpenMP [2.12.6, atomic Construct] 8960 // In the next expressions: 8961 // * x and v (as applicable) are both l-value expressions with scalar type. 8962 // * During the execution of an atomic region, multiple syntactic 8963 // occurrences of x must designate the same storage location. 8964 // * Neither of v and expr (as applicable) may access the storage location 8965 // designated by x. 8966 // * Neither of x and expr (as applicable) may access the storage location 8967 // designated by v. 8968 // * expr is an expression with scalar type. 8969 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8970 // * binop, binop=, ++, and -- are not overloaded operators. 8971 // * The expression x binop expr must be numerically equivalent to x binop 8972 // (expr). This requirement is satisfied if the operators in expr have 8973 // precedence greater than binop, or by using parentheses around expr or 8974 // subexpressions of expr. 8975 // * The expression expr binop x must be numerically equivalent to (expr) 8976 // binop x. This requirement is satisfied if the operators in expr have 8977 // precedence equal to or greater than binop, or by using parentheses around 8978 // expr or subexpressions of expr. 8979 // * For forms that allow multiple occurrences of x, the number of times 8980 // that x is evaluated is unspecified. 8981 if (AtomicKind == OMPC_read) { 8982 enum { 8983 NotAnExpression, 8984 NotAnAssignmentOp, 8985 NotAScalarType, 8986 NotAnLValue, 8987 NoError 8988 } ErrorFound = NoError; 8989 SourceLocation ErrorLoc, NoteLoc; 8990 SourceRange ErrorRange, NoteRange; 8991 // If clause is read: 8992 // v = x; 8993 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8994 const auto *AtomicBinOp = 8995 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8996 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8997 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8998 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8999 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9000 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9001 if (!X->isLValue() || !V->isLValue()) { 9002 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9003 ErrorFound = NotAnLValue; 9004 ErrorLoc = AtomicBinOp->getExprLoc(); 9005 ErrorRange = AtomicBinOp->getSourceRange(); 9006 NoteLoc = NotLValueExpr->getExprLoc(); 9007 NoteRange = NotLValueExpr->getSourceRange(); 9008 } 9009 } else if (!X->isInstantiationDependent() || 9010 !V->isInstantiationDependent()) { 9011 const Expr *NotScalarExpr = 9012 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9013 ? V 9014 : X; 9015 ErrorFound = NotAScalarType; 9016 ErrorLoc = AtomicBinOp->getExprLoc(); 9017 ErrorRange = AtomicBinOp->getSourceRange(); 9018 NoteLoc = NotScalarExpr->getExprLoc(); 9019 NoteRange = NotScalarExpr->getSourceRange(); 9020 } 9021 } else if (!AtomicBody->isInstantiationDependent()) { 9022 ErrorFound = NotAnAssignmentOp; 9023 ErrorLoc = AtomicBody->getExprLoc(); 9024 ErrorRange = AtomicBody->getSourceRange(); 9025 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9026 : AtomicBody->getExprLoc(); 9027 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9028 : AtomicBody->getSourceRange(); 9029 } 9030 } else { 9031 ErrorFound = NotAnExpression; 9032 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9033 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9034 } 9035 if (ErrorFound != NoError) { 9036 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9037 << ErrorRange; 9038 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9039 << NoteRange; 9040 return StmtError(); 9041 } 9042 if (CurContext->isDependentContext()) 9043 V = X = nullptr; 9044 } else if (AtomicKind == OMPC_write) { 9045 enum { 9046 NotAnExpression, 9047 NotAnAssignmentOp, 9048 NotAScalarType, 9049 NotAnLValue, 9050 NoError 9051 } ErrorFound = NoError; 9052 SourceLocation ErrorLoc, NoteLoc; 9053 SourceRange ErrorRange, NoteRange; 9054 // If clause is write: 9055 // x = expr; 9056 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9057 const auto *AtomicBinOp = 9058 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9059 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9060 X = AtomicBinOp->getLHS(); 9061 E = AtomicBinOp->getRHS(); 9062 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9063 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9064 if (!X->isLValue()) { 9065 ErrorFound = NotAnLValue; 9066 ErrorLoc = AtomicBinOp->getExprLoc(); 9067 ErrorRange = AtomicBinOp->getSourceRange(); 9068 NoteLoc = X->getExprLoc(); 9069 NoteRange = X->getSourceRange(); 9070 } 9071 } else if (!X->isInstantiationDependent() || 9072 !E->isInstantiationDependent()) { 9073 const Expr *NotScalarExpr = 9074 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9075 ? E 9076 : X; 9077 ErrorFound = NotAScalarType; 9078 ErrorLoc = AtomicBinOp->getExprLoc(); 9079 ErrorRange = AtomicBinOp->getSourceRange(); 9080 NoteLoc = NotScalarExpr->getExprLoc(); 9081 NoteRange = NotScalarExpr->getSourceRange(); 9082 } 9083 } else if (!AtomicBody->isInstantiationDependent()) { 9084 ErrorFound = NotAnAssignmentOp; 9085 ErrorLoc = AtomicBody->getExprLoc(); 9086 ErrorRange = AtomicBody->getSourceRange(); 9087 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9088 : AtomicBody->getExprLoc(); 9089 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9090 : AtomicBody->getSourceRange(); 9091 } 9092 } else { 9093 ErrorFound = NotAnExpression; 9094 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9095 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9096 } 9097 if (ErrorFound != NoError) { 9098 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9099 << ErrorRange; 9100 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9101 << NoteRange; 9102 return StmtError(); 9103 } 9104 if (CurContext->isDependentContext()) 9105 E = X = nullptr; 9106 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9107 // If clause is update: 9108 // x++; 9109 // x--; 9110 // ++x; 9111 // --x; 9112 // x binop= expr; 9113 // x = x binop expr; 9114 // x = expr binop x; 9115 OpenMPAtomicUpdateChecker Checker(*this); 9116 if (Checker.checkStatement( 9117 Body, (AtomicKind == OMPC_update) 9118 ? diag::err_omp_atomic_update_not_expression_statement 9119 : diag::err_omp_atomic_not_expression_statement, 9120 diag::note_omp_atomic_update)) 9121 return StmtError(); 9122 if (!CurContext->isDependentContext()) { 9123 E = Checker.getExpr(); 9124 X = Checker.getX(); 9125 UE = Checker.getUpdateExpr(); 9126 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9127 } 9128 } else if (AtomicKind == OMPC_capture) { 9129 enum { 9130 NotAnAssignmentOp, 9131 NotACompoundStatement, 9132 NotTwoSubstatements, 9133 NotASpecificExpression, 9134 NoError 9135 } ErrorFound = NoError; 9136 SourceLocation ErrorLoc, NoteLoc; 9137 SourceRange ErrorRange, NoteRange; 9138 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9139 // If clause is a capture: 9140 // v = x++; 9141 // v = x--; 9142 // v = ++x; 9143 // v = --x; 9144 // v = x binop= expr; 9145 // v = x = x binop expr; 9146 // v = x = expr binop x; 9147 const auto *AtomicBinOp = 9148 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9149 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9150 V = AtomicBinOp->getLHS(); 9151 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9152 OpenMPAtomicUpdateChecker Checker(*this); 9153 if (Checker.checkStatement( 9154 Body, diag::err_omp_atomic_capture_not_expression_statement, 9155 diag::note_omp_atomic_update)) 9156 return StmtError(); 9157 E = Checker.getExpr(); 9158 X = Checker.getX(); 9159 UE = Checker.getUpdateExpr(); 9160 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9161 IsPostfixUpdate = Checker.isPostfixUpdate(); 9162 } else if (!AtomicBody->isInstantiationDependent()) { 9163 ErrorLoc = AtomicBody->getExprLoc(); 9164 ErrorRange = AtomicBody->getSourceRange(); 9165 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9166 : AtomicBody->getExprLoc(); 9167 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9168 : AtomicBody->getSourceRange(); 9169 ErrorFound = NotAnAssignmentOp; 9170 } 9171 if (ErrorFound != NoError) { 9172 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9173 << ErrorRange; 9174 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9175 return StmtError(); 9176 } 9177 if (CurContext->isDependentContext()) 9178 UE = V = E = X = nullptr; 9179 } else { 9180 // If clause is a capture: 9181 // { v = x; x = expr; } 9182 // { v = x; x++; } 9183 // { v = x; x--; } 9184 // { v = x; ++x; } 9185 // { v = x; --x; } 9186 // { v = x; x binop= expr; } 9187 // { v = x; x = x binop expr; } 9188 // { v = x; x = expr binop x; } 9189 // { x++; v = x; } 9190 // { x--; v = x; } 9191 // { ++x; v = x; } 9192 // { --x; v = x; } 9193 // { x binop= expr; v = x; } 9194 // { x = x binop expr; v = x; } 9195 // { x = expr binop x; v = x; } 9196 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9197 // Check that this is { expr1; expr2; } 9198 if (CS->size() == 2) { 9199 Stmt *First = CS->body_front(); 9200 Stmt *Second = CS->body_back(); 9201 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9202 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9203 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9204 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9205 // Need to find what subexpression is 'v' and what is 'x'. 9206 OpenMPAtomicUpdateChecker Checker(*this); 9207 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9208 BinaryOperator *BinOp = nullptr; 9209 if (IsUpdateExprFound) { 9210 BinOp = dyn_cast<BinaryOperator>(First); 9211 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9212 } 9213 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9214 // { v = x; x++; } 9215 // { v = x; x--; } 9216 // { v = x; ++x; } 9217 // { v = x; --x; } 9218 // { v = x; x binop= expr; } 9219 // { v = x; x = x binop expr; } 9220 // { v = x; x = expr binop x; } 9221 // Check that the first expression has form v = x. 9222 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9223 llvm::FoldingSetNodeID XId, PossibleXId; 9224 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9225 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9226 IsUpdateExprFound = XId == PossibleXId; 9227 if (IsUpdateExprFound) { 9228 V = BinOp->getLHS(); 9229 X = Checker.getX(); 9230 E = Checker.getExpr(); 9231 UE = Checker.getUpdateExpr(); 9232 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9233 IsPostfixUpdate = true; 9234 } 9235 } 9236 if (!IsUpdateExprFound) { 9237 IsUpdateExprFound = !Checker.checkStatement(First); 9238 BinOp = nullptr; 9239 if (IsUpdateExprFound) { 9240 BinOp = dyn_cast<BinaryOperator>(Second); 9241 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9242 } 9243 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9244 // { x++; v = x; } 9245 // { x--; v = x; } 9246 // { ++x; v = x; } 9247 // { --x; v = x; } 9248 // { x binop= expr; v = x; } 9249 // { x = x binop expr; v = x; } 9250 // { x = expr binop x; v = x; } 9251 // Check that the second expression has form v = x. 9252 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9253 llvm::FoldingSetNodeID XId, PossibleXId; 9254 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9255 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9256 IsUpdateExprFound = XId == PossibleXId; 9257 if (IsUpdateExprFound) { 9258 V = BinOp->getLHS(); 9259 X = Checker.getX(); 9260 E = Checker.getExpr(); 9261 UE = Checker.getUpdateExpr(); 9262 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9263 IsPostfixUpdate = false; 9264 } 9265 } 9266 } 9267 if (!IsUpdateExprFound) { 9268 // { v = x; x = expr; } 9269 auto *FirstExpr = dyn_cast<Expr>(First); 9270 auto *SecondExpr = dyn_cast<Expr>(Second); 9271 if (!FirstExpr || !SecondExpr || 9272 !(FirstExpr->isInstantiationDependent() || 9273 SecondExpr->isInstantiationDependent())) { 9274 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9275 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9276 ErrorFound = NotAnAssignmentOp; 9277 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9278 : First->getBeginLoc(); 9279 NoteRange = ErrorRange = FirstBinOp 9280 ? FirstBinOp->getSourceRange() 9281 : SourceRange(ErrorLoc, ErrorLoc); 9282 } else { 9283 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9284 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9285 ErrorFound = NotAnAssignmentOp; 9286 NoteLoc = ErrorLoc = SecondBinOp 9287 ? SecondBinOp->getOperatorLoc() 9288 : Second->getBeginLoc(); 9289 NoteRange = ErrorRange = 9290 SecondBinOp ? SecondBinOp->getSourceRange() 9291 : SourceRange(ErrorLoc, ErrorLoc); 9292 } else { 9293 Expr *PossibleXRHSInFirst = 9294 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9295 Expr *PossibleXLHSInSecond = 9296 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9297 llvm::FoldingSetNodeID X1Id, X2Id; 9298 PossibleXRHSInFirst->Profile(X1Id, Context, 9299 /*Canonical=*/true); 9300 PossibleXLHSInSecond->Profile(X2Id, Context, 9301 /*Canonical=*/true); 9302 IsUpdateExprFound = X1Id == X2Id; 9303 if (IsUpdateExprFound) { 9304 V = FirstBinOp->getLHS(); 9305 X = SecondBinOp->getLHS(); 9306 E = SecondBinOp->getRHS(); 9307 UE = nullptr; 9308 IsXLHSInRHSPart = false; 9309 IsPostfixUpdate = true; 9310 } else { 9311 ErrorFound = NotASpecificExpression; 9312 ErrorLoc = FirstBinOp->getExprLoc(); 9313 ErrorRange = FirstBinOp->getSourceRange(); 9314 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9315 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9316 } 9317 } 9318 } 9319 } 9320 } 9321 } else { 9322 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9323 NoteRange = ErrorRange = 9324 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9325 ErrorFound = NotTwoSubstatements; 9326 } 9327 } else { 9328 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9329 NoteRange = ErrorRange = 9330 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9331 ErrorFound = NotACompoundStatement; 9332 } 9333 if (ErrorFound != NoError) { 9334 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9335 << ErrorRange; 9336 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9337 return StmtError(); 9338 } 9339 if (CurContext->isDependentContext()) 9340 UE = V = E = X = nullptr; 9341 } 9342 } 9343 9344 setFunctionHasBranchProtectedScope(); 9345 9346 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9347 X, V, E, UE, IsXLHSInRHSPart, 9348 IsPostfixUpdate); 9349 } 9350 9351 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9352 Stmt *AStmt, 9353 SourceLocation StartLoc, 9354 SourceLocation EndLoc) { 9355 if (!AStmt) 9356 return StmtError(); 9357 9358 auto *CS = cast<CapturedStmt>(AStmt); 9359 // 1.2.2 OpenMP Language Terminology 9360 // Structured block - An executable statement with a single entry at the 9361 // top and a single exit at the bottom. 9362 // The point of exit cannot be a branch out of the structured block. 9363 // longjmp() and throw() must not violate the entry/exit criteria. 9364 CS->getCapturedDecl()->setNothrow(); 9365 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9366 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9367 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9368 // 1.2.2 OpenMP Language Terminology 9369 // Structured block - An executable statement with a single entry at the 9370 // top and a single exit at the bottom. 9371 // The point of exit cannot be a branch out of the structured block. 9372 // longjmp() and throw() must not violate the entry/exit criteria. 9373 CS->getCapturedDecl()->setNothrow(); 9374 } 9375 9376 // OpenMP [2.16, Nesting of Regions] 9377 // If specified, a teams construct must be contained within a target 9378 // construct. That target construct must contain no statements or directives 9379 // outside of the teams construct. 9380 if (DSAStack->hasInnerTeamsRegion()) { 9381 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9382 bool OMPTeamsFound = true; 9383 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9384 auto I = CS->body_begin(); 9385 while (I != CS->body_end()) { 9386 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9387 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9388 OMPTeamsFound) { 9389 9390 OMPTeamsFound = false; 9391 break; 9392 } 9393 ++I; 9394 } 9395 assert(I != CS->body_end() && "Not found statement"); 9396 S = *I; 9397 } else { 9398 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9399 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9400 } 9401 if (!OMPTeamsFound) { 9402 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9403 Diag(DSAStack->getInnerTeamsRegionLoc(), 9404 diag::note_omp_nested_teams_construct_here); 9405 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9406 << isa<OMPExecutableDirective>(S); 9407 return StmtError(); 9408 } 9409 } 9410 9411 setFunctionHasBranchProtectedScope(); 9412 9413 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9414 } 9415 9416 StmtResult 9417 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9418 Stmt *AStmt, SourceLocation StartLoc, 9419 SourceLocation EndLoc) { 9420 if (!AStmt) 9421 return StmtError(); 9422 9423 auto *CS = cast<CapturedStmt>(AStmt); 9424 // 1.2.2 OpenMP Language Terminology 9425 // Structured block - An executable statement with a single entry at the 9426 // top and a single exit at the bottom. 9427 // The point of exit cannot be a branch out of the structured block. 9428 // longjmp() and throw() must not violate the entry/exit criteria. 9429 CS->getCapturedDecl()->setNothrow(); 9430 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9431 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9432 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9433 // 1.2.2 OpenMP Language Terminology 9434 // Structured block - An executable statement with a single entry at the 9435 // top and a single exit at the bottom. 9436 // The point of exit cannot be a branch out of the structured block. 9437 // longjmp() and throw() must not violate the entry/exit criteria. 9438 CS->getCapturedDecl()->setNothrow(); 9439 } 9440 9441 setFunctionHasBranchProtectedScope(); 9442 9443 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9444 AStmt); 9445 } 9446 9447 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9448 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9449 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9450 if (!AStmt) 9451 return StmtError(); 9452 9453 auto *CS = cast<CapturedStmt>(AStmt); 9454 // 1.2.2 OpenMP Language Terminology 9455 // Structured block - An executable statement with a single entry at the 9456 // top and a single exit at the bottom. 9457 // The point of exit cannot be a branch out of the structured block. 9458 // longjmp() and throw() must not violate the entry/exit criteria. 9459 CS->getCapturedDecl()->setNothrow(); 9460 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9461 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9462 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9463 // 1.2.2 OpenMP Language Terminology 9464 // Structured block - An executable statement with a single entry at the 9465 // top and a single exit at the bottom. 9466 // The point of exit cannot be a branch out of the structured block. 9467 // longjmp() and throw() must not violate the entry/exit criteria. 9468 CS->getCapturedDecl()->setNothrow(); 9469 } 9470 9471 OMPLoopDirective::HelperExprs B; 9472 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9473 // define the nested loops number. 9474 unsigned NestedLoopCount = 9475 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9476 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9477 VarsWithImplicitDSA, B); 9478 if (NestedLoopCount == 0) 9479 return StmtError(); 9480 9481 assert((CurContext->isDependentContext() || B.builtAll()) && 9482 "omp target parallel for loop exprs were not built"); 9483 9484 if (!CurContext->isDependentContext()) { 9485 // Finalize the clauses that need pre-built expressions for CodeGen. 9486 for (OMPClause *C : Clauses) { 9487 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9488 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9489 B.NumIterations, *this, CurScope, 9490 DSAStack)) 9491 return StmtError(); 9492 } 9493 } 9494 9495 setFunctionHasBranchProtectedScope(); 9496 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9497 NestedLoopCount, Clauses, AStmt, 9498 B, DSAStack->isCancelRegion()); 9499 } 9500 9501 /// Check for existence of a map clause in the list of clauses. 9502 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9503 const OpenMPClauseKind K) { 9504 return llvm::any_of( 9505 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9506 } 9507 9508 template <typename... Params> 9509 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9510 const Params... ClauseTypes) { 9511 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9512 } 9513 9514 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9515 Stmt *AStmt, 9516 SourceLocation StartLoc, 9517 SourceLocation EndLoc) { 9518 if (!AStmt) 9519 return StmtError(); 9520 9521 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9522 9523 // OpenMP [2.10.1, Restrictions, p. 97] 9524 // At least one map clause must appear on the directive. 9525 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9526 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9527 << "'map' or 'use_device_ptr'" 9528 << getOpenMPDirectiveName(OMPD_target_data); 9529 return StmtError(); 9530 } 9531 9532 setFunctionHasBranchProtectedScope(); 9533 9534 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9535 AStmt); 9536 } 9537 9538 StmtResult 9539 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9540 SourceLocation StartLoc, 9541 SourceLocation EndLoc, Stmt *AStmt) { 9542 if (!AStmt) 9543 return StmtError(); 9544 9545 auto *CS = cast<CapturedStmt>(AStmt); 9546 // 1.2.2 OpenMP Language Terminology 9547 // Structured block - An executable statement with a single entry at the 9548 // top and a single exit at the bottom. 9549 // The point of exit cannot be a branch out of the structured block. 9550 // longjmp() and throw() must not violate the entry/exit criteria. 9551 CS->getCapturedDecl()->setNothrow(); 9552 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9553 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9554 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9555 // 1.2.2 OpenMP Language Terminology 9556 // Structured block - An executable statement with a single entry at the 9557 // top and a single exit at the bottom. 9558 // The point of exit cannot be a branch out of the structured block. 9559 // longjmp() and throw() must not violate the entry/exit criteria. 9560 CS->getCapturedDecl()->setNothrow(); 9561 } 9562 9563 // OpenMP [2.10.2, Restrictions, p. 99] 9564 // At least one map clause must appear on the directive. 9565 if (!hasClauses(Clauses, OMPC_map)) { 9566 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9567 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9568 return StmtError(); 9569 } 9570 9571 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9572 AStmt); 9573 } 9574 9575 StmtResult 9576 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9577 SourceLocation StartLoc, 9578 SourceLocation EndLoc, Stmt *AStmt) { 9579 if (!AStmt) 9580 return StmtError(); 9581 9582 auto *CS = cast<CapturedStmt>(AStmt); 9583 // 1.2.2 OpenMP Language Terminology 9584 // Structured block - An executable statement with a single entry at the 9585 // top and a single exit at the bottom. 9586 // The point of exit cannot be a branch out of the structured block. 9587 // longjmp() and throw() must not violate the entry/exit criteria. 9588 CS->getCapturedDecl()->setNothrow(); 9589 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9590 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9591 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9592 // 1.2.2 OpenMP Language Terminology 9593 // Structured block - An executable statement with a single entry at the 9594 // top and a single exit at the bottom. 9595 // The point of exit cannot be a branch out of the structured block. 9596 // longjmp() and throw() must not violate the entry/exit criteria. 9597 CS->getCapturedDecl()->setNothrow(); 9598 } 9599 9600 // OpenMP [2.10.3, Restrictions, p. 102] 9601 // At least one map clause must appear on the directive. 9602 if (!hasClauses(Clauses, OMPC_map)) { 9603 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9604 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9605 return StmtError(); 9606 } 9607 9608 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9609 AStmt); 9610 } 9611 9612 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9613 SourceLocation StartLoc, 9614 SourceLocation EndLoc, 9615 Stmt *AStmt) { 9616 if (!AStmt) 9617 return StmtError(); 9618 9619 auto *CS = cast<CapturedStmt>(AStmt); 9620 // 1.2.2 OpenMP Language Terminology 9621 // Structured block - An executable statement with a single entry at the 9622 // top and a single exit at the bottom. 9623 // The point of exit cannot be a branch out of the structured block. 9624 // longjmp() and throw() must not violate the entry/exit criteria. 9625 CS->getCapturedDecl()->setNothrow(); 9626 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9627 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9628 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9629 // 1.2.2 OpenMP Language Terminology 9630 // Structured block - An executable statement with a single entry at the 9631 // top and a single exit at the bottom. 9632 // The point of exit cannot be a branch out of the structured block. 9633 // longjmp() and throw() must not violate the entry/exit criteria. 9634 CS->getCapturedDecl()->setNothrow(); 9635 } 9636 9637 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9638 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9639 return StmtError(); 9640 } 9641 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9642 AStmt); 9643 } 9644 9645 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9646 Stmt *AStmt, SourceLocation StartLoc, 9647 SourceLocation EndLoc) { 9648 if (!AStmt) 9649 return StmtError(); 9650 9651 auto *CS = cast<CapturedStmt>(AStmt); 9652 // 1.2.2 OpenMP Language Terminology 9653 // Structured block - An executable statement with a single entry at the 9654 // top and a single exit at the bottom. 9655 // The point of exit cannot be a branch out of the structured block. 9656 // longjmp() and throw() must not violate the entry/exit criteria. 9657 CS->getCapturedDecl()->setNothrow(); 9658 9659 setFunctionHasBranchProtectedScope(); 9660 9661 DSAStack->setParentTeamsRegionLoc(StartLoc); 9662 9663 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9664 } 9665 9666 StmtResult 9667 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9668 SourceLocation EndLoc, 9669 OpenMPDirectiveKind CancelRegion) { 9670 if (DSAStack->isParentNowaitRegion()) { 9671 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9672 return StmtError(); 9673 } 9674 if (DSAStack->isParentOrderedRegion()) { 9675 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9676 return StmtError(); 9677 } 9678 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9679 CancelRegion); 9680 } 9681 9682 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9683 SourceLocation StartLoc, 9684 SourceLocation EndLoc, 9685 OpenMPDirectiveKind CancelRegion) { 9686 if (DSAStack->isParentNowaitRegion()) { 9687 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9688 return StmtError(); 9689 } 9690 if (DSAStack->isParentOrderedRegion()) { 9691 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9692 return StmtError(); 9693 } 9694 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9695 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9696 CancelRegion); 9697 } 9698 9699 static bool checkGrainsizeNumTasksClauses(Sema &S, 9700 ArrayRef<OMPClause *> Clauses) { 9701 const OMPClause *PrevClause = nullptr; 9702 bool ErrorFound = false; 9703 for (const OMPClause *C : Clauses) { 9704 if (C->getClauseKind() == OMPC_grainsize || 9705 C->getClauseKind() == OMPC_num_tasks) { 9706 if (!PrevClause) 9707 PrevClause = C; 9708 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9709 S.Diag(C->getBeginLoc(), 9710 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9711 << getOpenMPClauseName(C->getClauseKind()) 9712 << getOpenMPClauseName(PrevClause->getClauseKind()); 9713 S.Diag(PrevClause->getBeginLoc(), 9714 diag::note_omp_previous_grainsize_num_tasks) 9715 << getOpenMPClauseName(PrevClause->getClauseKind()); 9716 ErrorFound = true; 9717 } 9718 } 9719 } 9720 return ErrorFound; 9721 } 9722 9723 static bool checkReductionClauseWithNogroup(Sema &S, 9724 ArrayRef<OMPClause *> Clauses) { 9725 const OMPClause *ReductionClause = nullptr; 9726 const OMPClause *NogroupClause = nullptr; 9727 for (const OMPClause *C : Clauses) { 9728 if (C->getClauseKind() == OMPC_reduction) { 9729 ReductionClause = C; 9730 if (NogroupClause) 9731 break; 9732 continue; 9733 } 9734 if (C->getClauseKind() == OMPC_nogroup) { 9735 NogroupClause = C; 9736 if (ReductionClause) 9737 break; 9738 continue; 9739 } 9740 } 9741 if (ReductionClause && NogroupClause) { 9742 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9743 << SourceRange(NogroupClause->getBeginLoc(), 9744 NogroupClause->getEndLoc()); 9745 return true; 9746 } 9747 return false; 9748 } 9749 9750 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9751 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9752 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9753 if (!AStmt) 9754 return StmtError(); 9755 9756 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9757 OMPLoopDirective::HelperExprs B; 9758 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9759 // define the nested loops number. 9760 unsigned NestedLoopCount = 9761 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9762 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9763 VarsWithImplicitDSA, B); 9764 if (NestedLoopCount == 0) 9765 return StmtError(); 9766 9767 assert((CurContext->isDependentContext() || B.builtAll()) && 9768 "omp for loop exprs were not built"); 9769 9770 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9771 // The grainsize clause and num_tasks clause are mutually exclusive and may 9772 // not appear on the same taskloop directive. 9773 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9774 return StmtError(); 9775 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9776 // If a reduction clause is present on the taskloop directive, the nogroup 9777 // clause must not be specified. 9778 if (checkReductionClauseWithNogroup(*this, Clauses)) 9779 return StmtError(); 9780 9781 setFunctionHasBranchProtectedScope(); 9782 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9783 NestedLoopCount, Clauses, AStmt, B); 9784 } 9785 9786 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9787 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9788 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9789 if (!AStmt) 9790 return StmtError(); 9791 9792 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9793 OMPLoopDirective::HelperExprs B; 9794 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9795 // define the nested loops number. 9796 unsigned NestedLoopCount = 9797 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9798 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9799 VarsWithImplicitDSA, B); 9800 if (NestedLoopCount == 0) 9801 return StmtError(); 9802 9803 assert((CurContext->isDependentContext() || B.builtAll()) && 9804 "omp for loop exprs were not built"); 9805 9806 if (!CurContext->isDependentContext()) { 9807 // Finalize the clauses that need pre-built expressions for CodeGen. 9808 for (OMPClause *C : Clauses) { 9809 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9810 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9811 B.NumIterations, *this, CurScope, 9812 DSAStack)) 9813 return StmtError(); 9814 } 9815 } 9816 9817 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9818 // The grainsize clause and num_tasks clause are mutually exclusive and may 9819 // not appear on the same taskloop directive. 9820 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9821 return StmtError(); 9822 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9823 // If a reduction clause is present on the taskloop directive, the nogroup 9824 // clause must not be specified. 9825 if (checkReductionClauseWithNogroup(*this, Clauses)) 9826 return StmtError(); 9827 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9828 return StmtError(); 9829 9830 setFunctionHasBranchProtectedScope(); 9831 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9832 NestedLoopCount, Clauses, AStmt, B); 9833 } 9834 9835 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9836 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9837 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9838 if (!AStmt) 9839 return StmtError(); 9840 9841 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9842 OMPLoopDirective::HelperExprs B; 9843 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9844 // define the nested loops number. 9845 unsigned NestedLoopCount = 9846 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9847 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9848 VarsWithImplicitDSA, B); 9849 if (NestedLoopCount == 0) 9850 return StmtError(); 9851 9852 assert((CurContext->isDependentContext() || B.builtAll()) && 9853 "omp for loop exprs were not built"); 9854 9855 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9856 // The grainsize clause and num_tasks clause are mutually exclusive and may 9857 // not appear on the same taskloop directive. 9858 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9859 return StmtError(); 9860 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9861 // If a reduction clause is present on the taskloop directive, the nogroup 9862 // clause must not be specified. 9863 if (checkReductionClauseWithNogroup(*this, Clauses)) 9864 return StmtError(); 9865 9866 setFunctionHasBranchProtectedScope(); 9867 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9868 NestedLoopCount, Clauses, AStmt, B); 9869 } 9870 9871 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9872 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9873 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9874 if (!AStmt) 9875 return StmtError(); 9876 9877 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9878 OMPLoopDirective::HelperExprs B; 9879 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9880 // define the nested loops number. 9881 unsigned NestedLoopCount = 9882 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9883 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9884 VarsWithImplicitDSA, B); 9885 if (NestedLoopCount == 0) 9886 return StmtError(); 9887 9888 assert((CurContext->isDependentContext() || B.builtAll()) && 9889 "omp for loop exprs were not built"); 9890 9891 if (!CurContext->isDependentContext()) { 9892 // Finalize the clauses that need pre-built expressions for CodeGen. 9893 for (OMPClause *C : Clauses) { 9894 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9895 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9896 B.NumIterations, *this, CurScope, 9897 DSAStack)) 9898 return StmtError(); 9899 } 9900 } 9901 9902 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9903 // The grainsize clause and num_tasks clause are mutually exclusive and may 9904 // not appear on the same taskloop directive. 9905 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9906 return StmtError(); 9907 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9908 // If a reduction clause is present on the taskloop directive, the nogroup 9909 // clause must not be specified. 9910 if (checkReductionClauseWithNogroup(*this, Clauses)) 9911 return StmtError(); 9912 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9913 return StmtError(); 9914 9915 setFunctionHasBranchProtectedScope(); 9916 return OMPMasterTaskLoopSimdDirective::Create( 9917 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9918 } 9919 9920 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9921 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9922 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9923 if (!AStmt) 9924 return StmtError(); 9925 9926 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9927 auto *CS = cast<CapturedStmt>(AStmt); 9928 // 1.2.2 OpenMP Language Terminology 9929 // Structured block - An executable statement with a single entry at the 9930 // top and a single exit at the bottom. 9931 // The point of exit cannot be a branch out of the structured block. 9932 // longjmp() and throw() must not violate the entry/exit criteria. 9933 CS->getCapturedDecl()->setNothrow(); 9934 for (int ThisCaptureLevel = 9935 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9936 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9937 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9938 // 1.2.2 OpenMP Language Terminology 9939 // Structured block - An executable statement with a single entry at the 9940 // top and a single exit at the bottom. 9941 // The point of exit cannot be a branch out of the structured block. 9942 // longjmp() and throw() must not violate the entry/exit criteria. 9943 CS->getCapturedDecl()->setNothrow(); 9944 } 9945 9946 OMPLoopDirective::HelperExprs B; 9947 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9948 // define the nested loops number. 9949 unsigned NestedLoopCount = checkOpenMPLoop( 9950 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9951 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9952 VarsWithImplicitDSA, B); 9953 if (NestedLoopCount == 0) 9954 return StmtError(); 9955 9956 assert((CurContext->isDependentContext() || B.builtAll()) && 9957 "omp for loop exprs were not built"); 9958 9959 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9960 // The grainsize clause and num_tasks clause are mutually exclusive and may 9961 // not appear on the same taskloop directive. 9962 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9963 return StmtError(); 9964 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9965 // If a reduction clause is present on the taskloop directive, the nogroup 9966 // clause must not be specified. 9967 if (checkReductionClauseWithNogroup(*this, Clauses)) 9968 return StmtError(); 9969 9970 setFunctionHasBranchProtectedScope(); 9971 return OMPParallelMasterTaskLoopDirective::Create( 9972 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9973 } 9974 9975 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 9976 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9977 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9978 if (!AStmt) 9979 return StmtError(); 9980 9981 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9982 auto *CS = cast<CapturedStmt>(AStmt); 9983 // 1.2.2 OpenMP Language Terminology 9984 // Structured block - An executable statement with a single entry at the 9985 // top and a single exit at the bottom. 9986 // The point of exit cannot be a branch out of the structured block. 9987 // longjmp() and throw() must not violate the entry/exit criteria. 9988 CS->getCapturedDecl()->setNothrow(); 9989 for (int ThisCaptureLevel = 9990 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 9991 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9992 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9993 // 1.2.2 OpenMP Language Terminology 9994 // Structured block - An executable statement with a single entry at the 9995 // top and a single exit at the bottom. 9996 // The point of exit cannot be a branch out of the structured block. 9997 // longjmp() and throw() must not violate the entry/exit criteria. 9998 CS->getCapturedDecl()->setNothrow(); 9999 } 10000 10001 OMPLoopDirective::HelperExprs B; 10002 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10003 // define the nested loops number. 10004 unsigned NestedLoopCount = checkOpenMPLoop( 10005 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10006 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10007 VarsWithImplicitDSA, B); 10008 if (NestedLoopCount == 0) 10009 return StmtError(); 10010 10011 assert((CurContext->isDependentContext() || B.builtAll()) && 10012 "omp for loop exprs were not built"); 10013 10014 if (!CurContext->isDependentContext()) { 10015 // Finalize the clauses that need pre-built expressions for CodeGen. 10016 for (OMPClause *C : Clauses) { 10017 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10018 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10019 B.NumIterations, *this, CurScope, 10020 DSAStack)) 10021 return StmtError(); 10022 } 10023 } 10024 10025 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10026 // The grainsize clause and num_tasks clause are mutually exclusive and may 10027 // not appear on the same taskloop directive. 10028 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10029 return StmtError(); 10030 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10031 // If a reduction clause is present on the taskloop directive, the nogroup 10032 // clause must not be specified. 10033 if (checkReductionClauseWithNogroup(*this, Clauses)) 10034 return StmtError(); 10035 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10036 return StmtError(); 10037 10038 setFunctionHasBranchProtectedScope(); 10039 return OMPParallelMasterTaskLoopSimdDirective::Create( 10040 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10041 } 10042 10043 StmtResult Sema::ActOnOpenMPDistributeDirective( 10044 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10045 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10046 if (!AStmt) 10047 return StmtError(); 10048 10049 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10050 OMPLoopDirective::HelperExprs B; 10051 // In presence of clause 'collapse' with number of loops, it will 10052 // define the nested loops number. 10053 unsigned NestedLoopCount = 10054 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10055 nullptr /*ordered not a clause on distribute*/, AStmt, 10056 *this, *DSAStack, VarsWithImplicitDSA, B); 10057 if (NestedLoopCount == 0) 10058 return StmtError(); 10059 10060 assert((CurContext->isDependentContext() || B.builtAll()) && 10061 "omp for loop exprs were not built"); 10062 10063 setFunctionHasBranchProtectedScope(); 10064 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10065 NestedLoopCount, Clauses, AStmt, B); 10066 } 10067 10068 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10069 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10070 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10071 if (!AStmt) 10072 return StmtError(); 10073 10074 auto *CS = cast<CapturedStmt>(AStmt); 10075 // 1.2.2 OpenMP Language Terminology 10076 // Structured block - An executable statement with a single entry at the 10077 // top and a single exit at the bottom. 10078 // The point of exit cannot be a branch out of the structured block. 10079 // longjmp() and throw() must not violate the entry/exit criteria. 10080 CS->getCapturedDecl()->setNothrow(); 10081 for (int ThisCaptureLevel = 10082 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10083 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10084 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10085 // 1.2.2 OpenMP Language Terminology 10086 // Structured block - An executable statement with a single entry at the 10087 // top and a single exit at the bottom. 10088 // The point of exit cannot be a branch out of the structured block. 10089 // longjmp() and throw() must not violate the entry/exit criteria. 10090 CS->getCapturedDecl()->setNothrow(); 10091 } 10092 10093 OMPLoopDirective::HelperExprs B; 10094 // In presence of clause 'collapse' with number of loops, it will 10095 // define the nested loops number. 10096 unsigned NestedLoopCount = checkOpenMPLoop( 10097 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10098 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10099 VarsWithImplicitDSA, B); 10100 if (NestedLoopCount == 0) 10101 return StmtError(); 10102 10103 assert((CurContext->isDependentContext() || B.builtAll()) && 10104 "omp for loop exprs were not built"); 10105 10106 setFunctionHasBranchProtectedScope(); 10107 return OMPDistributeParallelForDirective::Create( 10108 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10109 DSAStack->isCancelRegion()); 10110 } 10111 10112 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10113 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10114 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10115 if (!AStmt) 10116 return StmtError(); 10117 10118 auto *CS = cast<CapturedStmt>(AStmt); 10119 // 1.2.2 OpenMP Language Terminology 10120 // Structured block - An executable statement with a single entry at the 10121 // top and a single exit at the bottom. 10122 // The point of exit cannot be a branch out of the structured block. 10123 // longjmp() and throw() must not violate the entry/exit criteria. 10124 CS->getCapturedDecl()->setNothrow(); 10125 for (int ThisCaptureLevel = 10126 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10127 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10128 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10129 // 1.2.2 OpenMP Language Terminology 10130 // Structured block - An executable statement with a single entry at the 10131 // top and a single exit at the bottom. 10132 // The point of exit cannot be a branch out of the structured block. 10133 // longjmp() and throw() must not violate the entry/exit criteria. 10134 CS->getCapturedDecl()->setNothrow(); 10135 } 10136 10137 OMPLoopDirective::HelperExprs B; 10138 // In presence of clause 'collapse' with number of loops, it will 10139 // define the nested loops number. 10140 unsigned NestedLoopCount = checkOpenMPLoop( 10141 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10142 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10143 VarsWithImplicitDSA, B); 10144 if (NestedLoopCount == 0) 10145 return StmtError(); 10146 10147 assert((CurContext->isDependentContext() || B.builtAll()) && 10148 "omp for loop exprs were not built"); 10149 10150 if (!CurContext->isDependentContext()) { 10151 // Finalize the clauses that need pre-built expressions for CodeGen. 10152 for (OMPClause *C : Clauses) { 10153 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10154 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10155 B.NumIterations, *this, CurScope, 10156 DSAStack)) 10157 return StmtError(); 10158 } 10159 } 10160 10161 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10162 return StmtError(); 10163 10164 setFunctionHasBranchProtectedScope(); 10165 return OMPDistributeParallelForSimdDirective::Create( 10166 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10167 } 10168 10169 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10170 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10171 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10172 if (!AStmt) 10173 return StmtError(); 10174 10175 auto *CS = cast<CapturedStmt>(AStmt); 10176 // 1.2.2 OpenMP Language Terminology 10177 // Structured block - An executable statement with a single entry at the 10178 // top and a single exit at the bottom. 10179 // The point of exit cannot be a branch out of the structured block. 10180 // longjmp() and throw() must not violate the entry/exit criteria. 10181 CS->getCapturedDecl()->setNothrow(); 10182 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10183 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10184 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10185 // 1.2.2 OpenMP Language Terminology 10186 // Structured block - An executable statement with a single entry at the 10187 // top and a single exit at the bottom. 10188 // The point of exit cannot be a branch out of the structured block. 10189 // longjmp() and throw() must not violate the entry/exit criteria. 10190 CS->getCapturedDecl()->setNothrow(); 10191 } 10192 10193 OMPLoopDirective::HelperExprs B; 10194 // In presence of clause 'collapse' with number of loops, it will 10195 // define the nested loops number. 10196 unsigned NestedLoopCount = 10197 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10198 nullptr /*ordered not a clause on distribute*/, CS, *this, 10199 *DSAStack, VarsWithImplicitDSA, B); 10200 if (NestedLoopCount == 0) 10201 return StmtError(); 10202 10203 assert((CurContext->isDependentContext() || B.builtAll()) && 10204 "omp for loop exprs were not built"); 10205 10206 if (!CurContext->isDependentContext()) { 10207 // Finalize the clauses that need pre-built expressions for CodeGen. 10208 for (OMPClause *C : Clauses) { 10209 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10210 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10211 B.NumIterations, *this, CurScope, 10212 DSAStack)) 10213 return StmtError(); 10214 } 10215 } 10216 10217 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10218 return StmtError(); 10219 10220 setFunctionHasBranchProtectedScope(); 10221 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10222 NestedLoopCount, Clauses, AStmt, B); 10223 } 10224 10225 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10226 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10227 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10228 if (!AStmt) 10229 return StmtError(); 10230 10231 auto *CS = cast<CapturedStmt>(AStmt); 10232 // 1.2.2 OpenMP Language Terminology 10233 // Structured block - An executable statement with a single entry at the 10234 // top and a single exit at the bottom. 10235 // The point of exit cannot be a branch out of the structured block. 10236 // longjmp() and throw() must not violate the entry/exit criteria. 10237 CS->getCapturedDecl()->setNothrow(); 10238 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10239 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10240 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10241 // 1.2.2 OpenMP Language Terminology 10242 // Structured block - An executable statement with a single entry at the 10243 // top and a single exit at the bottom. 10244 // The point of exit cannot be a branch out of the structured block. 10245 // longjmp() and throw() must not violate the entry/exit criteria. 10246 CS->getCapturedDecl()->setNothrow(); 10247 } 10248 10249 OMPLoopDirective::HelperExprs B; 10250 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10251 // define the nested loops number. 10252 unsigned NestedLoopCount = checkOpenMPLoop( 10253 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10254 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10255 VarsWithImplicitDSA, B); 10256 if (NestedLoopCount == 0) 10257 return StmtError(); 10258 10259 assert((CurContext->isDependentContext() || B.builtAll()) && 10260 "omp target parallel for simd loop exprs were not built"); 10261 10262 if (!CurContext->isDependentContext()) { 10263 // Finalize the clauses that need pre-built expressions for CodeGen. 10264 for (OMPClause *C : Clauses) { 10265 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10266 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10267 B.NumIterations, *this, CurScope, 10268 DSAStack)) 10269 return StmtError(); 10270 } 10271 } 10272 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10273 return StmtError(); 10274 10275 setFunctionHasBranchProtectedScope(); 10276 return OMPTargetParallelForSimdDirective::Create( 10277 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10278 } 10279 10280 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10281 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10282 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10283 if (!AStmt) 10284 return StmtError(); 10285 10286 auto *CS = cast<CapturedStmt>(AStmt); 10287 // 1.2.2 OpenMP Language Terminology 10288 // Structured block - An executable statement with a single entry at the 10289 // top and a single exit at the bottom. 10290 // The point of exit cannot be a branch out of the structured block. 10291 // longjmp() and throw() must not violate the entry/exit criteria. 10292 CS->getCapturedDecl()->setNothrow(); 10293 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10294 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10295 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10296 // 1.2.2 OpenMP Language Terminology 10297 // Structured block - An executable statement with a single entry at the 10298 // top and a single exit at the bottom. 10299 // The point of exit cannot be a branch out of the structured block. 10300 // longjmp() and throw() must not violate the entry/exit criteria. 10301 CS->getCapturedDecl()->setNothrow(); 10302 } 10303 10304 OMPLoopDirective::HelperExprs B; 10305 // In presence of clause 'collapse' with number of loops, it will define the 10306 // nested loops number. 10307 unsigned NestedLoopCount = 10308 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10309 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10310 VarsWithImplicitDSA, B); 10311 if (NestedLoopCount == 0) 10312 return StmtError(); 10313 10314 assert((CurContext->isDependentContext() || B.builtAll()) && 10315 "omp target simd loop exprs were not built"); 10316 10317 if (!CurContext->isDependentContext()) { 10318 // Finalize the clauses that need pre-built expressions for CodeGen. 10319 for (OMPClause *C : Clauses) { 10320 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10321 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10322 B.NumIterations, *this, CurScope, 10323 DSAStack)) 10324 return StmtError(); 10325 } 10326 } 10327 10328 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10329 return StmtError(); 10330 10331 setFunctionHasBranchProtectedScope(); 10332 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10333 NestedLoopCount, Clauses, AStmt, B); 10334 } 10335 10336 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10337 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10338 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10339 if (!AStmt) 10340 return StmtError(); 10341 10342 auto *CS = cast<CapturedStmt>(AStmt); 10343 // 1.2.2 OpenMP Language Terminology 10344 // Structured block - An executable statement with a single entry at the 10345 // top and a single exit at the bottom. 10346 // The point of exit cannot be a branch out of the structured block. 10347 // longjmp() and throw() must not violate the entry/exit criteria. 10348 CS->getCapturedDecl()->setNothrow(); 10349 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10350 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10351 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10352 // 1.2.2 OpenMP Language Terminology 10353 // Structured block - An executable statement with a single entry at the 10354 // top and a single exit at the bottom. 10355 // The point of exit cannot be a branch out of the structured block. 10356 // longjmp() and throw() must not violate the entry/exit criteria. 10357 CS->getCapturedDecl()->setNothrow(); 10358 } 10359 10360 OMPLoopDirective::HelperExprs B; 10361 // In presence of clause 'collapse' with number of loops, it will 10362 // define the nested loops number. 10363 unsigned NestedLoopCount = 10364 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10365 nullptr /*ordered not a clause on distribute*/, CS, *this, 10366 *DSAStack, VarsWithImplicitDSA, B); 10367 if (NestedLoopCount == 0) 10368 return StmtError(); 10369 10370 assert((CurContext->isDependentContext() || B.builtAll()) && 10371 "omp teams distribute loop exprs were not built"); 10372 10373 setFunctionHasBranchProtectedScope(); 10374 10375 DSAStack->setParentTeamsRegionLoc(StartLoc); 10376 10377 return OMPTeamsDistributeDirective::Create( 10378 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10379 } 10380 10381 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10382 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10383 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10384 if (!AStmt) 10385 return StmtError(); 10386 10387 auto *CS = cast<CapturedStmt>(AStmt); 10388 // 1.2.2 OpenMP Language Terminology 10389 // Structured block - An executable statement with a single entry at the 10390 // top and a single exit at the bottom. 10391 // The point of exit cannot be a branch out of the structured block. 10392 // longjmp() and throw() must not violate the entry/exit criteria. 10393 CS->getCapturedDecl()->setNothrow(); 10394 for (int ThisCaptureLevel = 10395 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10396 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10397 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10398 // 1.2.2 OpenMP Language Terminology 10399 // Structured block - An executable statement with a single entry at the 10400 // top and a single exit at the bottom. 10401 // The point of exit cannot be a branch out of the structured block. 10402 // longjmp() and throw() must not violate the entry/exit criteria. 10403 CS->getCapturedDecl()->setNothrow(); 10404 } 10405 10406 10407 OMPLoopDirective::HelperExprs B; 10408 // In presence of clause 'collapse' with number of loops, it will 10409 // define the nested loops number. 10410 unsigned NestedLoopCount = checkOpenMPLoop( 10411 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10412 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10413 VarsWithImplicitDSA, B); 10414 10415 if (NestedLoopCount == 0) 10416 return StmtError(); 10417 10418 assert((CurContext->isDependentContext() || B.builtAll()) && 10419 "omp teams distribute simd loop exprs were not built"); 10420 10421 if (!CurContext->isDependentContext()) { 10422 // Finalize the clauses that need pre-built expressions for CodeGen. 10423 for (OMPClause *C : Clauses) { 10424 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10425 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10426 B.NumIterations, *this, CurScope, 10427 DSAStack)) 10428 return StmtError(); 10429 } 10430 } 10431 10432 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10433 return StmtError(); 10434 10435 setFunctionHasBranchProtectedScope(); 10436 10437 DSAStack->setParentTeamsRegionLoc(StartLoc); 10438 10439 return OMPTeamsDistributeSimdDirective::Create( 10440 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10441 } 10442 10443 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10444 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10445 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10446 if (!AStmt) 10447 return StmtError(); 10448 10449 auto *CS = cast<CapturedStmt>(AStmt); 10450 // 1.2.2 OpenMP Language Terminology 10451 // Structured block - An executable statement with a single entry at the 10452 // top and a single exit at the bottom. 10453 // The point of exit cannot be a branch out of the structured block. 10454 // longjmp() and throw() must not violate the entry/exit criteria. 10455 CS->getCapturedDecl()->setNothrow(); 10456 10457 for (int ThisCaptureLevel = 10458 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10459 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10460 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10461 // 1.2.2 OpenMP Language Terminology 10462 // Structured block - An executable statement with a single entry at the 10463 // top and a single exit at the bottom. 10464 // The point of exit cannot be a branch out of the structured block. 10465 // longjmp() and throw() must not violate the entry/exit criteria. 10466 CS->getCapturedDecl()->setNothrow(); 10467 } 10468 10469 OMPLoopDirective::HelperExprs B; 10470 // In presence of clause 'collapse' with number of loops, it will 10471 // define the nested loops number. 10472 unsigned NestedLoopCount = checkOpenMPLoop( 10473 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10474 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10475 VarsWithImplicitDSA, B); 10476 10477 if (NestedLoopCount == 0) 10478 return StmtError(); 10479 10480 assert((CurContext->isDependentContext() || B.builtAll()) && 10481 "omp for loop exprs were not built"); 10482 10483 if (!CurContext->isDependentContext()) { 10484 // Finalize the clauses that need pre-built expressions for CodeGen. 10485 for (OMPClause *C : Clauses) { 10486 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10487 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10488 B.NumIterations, *this, CurScope, 10489 DSAStack)) 10490 return StmtError(); 10491 } 10492 } 10493 10494 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10495 return StmtError(); 10496 10497 setFunctionHasBranchProtectedScope(); 10498 10499 DSAStack->setParentTeamsRegionLoc(StartLoc); 10500 10501 return OMPTeamsDistributeParallelForSimdDirective::Create( 10502 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10503 } 10504 10505 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10506 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10507 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10508 if (!AStmt) 10509 return StmtError(); 10510 10511 auto *CS = cast<CapturedStmt>(AStmt); 10512 // 1.2.2 OpenMP Language Terminology 10513 // Structured block - An executable statement with a single entry at the 10514 // top and a single exit at the bottom. 10515 // The point of exit cannot be a branch out of the structured block. 10516 // longjmp() and throw() must not violate the entry/exit criteria. 10517 CS->getCapturedDecl()->setNothrow(); 10518 10519 for (int ThisCaptureLevel = 10520 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10521 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10522 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10523 // 1.2.2 OpenMP Language Terminology 10524 // Structured block - An executable statement with a single entry at the 10525 // top and a single exit at the bottom. 10526 // The point of exit cannot be a branch out of the structured block. 10527 // longjmp() and throw() must not violate the entry/exit criteria. 10528 CS->getCapturedDecl()->setNothrow(); 10529 } 10530 10531 OMPLoopDirective::HelperExprs B; 10532 // In presence of clause 'collapse' with number of loops, it will 10533 // define the nested loops number. 10534 unsigned NestedLoopCount = checkOpenMPLoop( 10535 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10536 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10537 VarsWithImplicitDSA, B); 10538 10539 if (NestedLoopCount == 0) 10540 return StmtError(); 10541 10542 assert((CurContext->isDependentContext() || B.builtAll()) && 10543 "omp for loop exprs were not built"); 10544 10545 setFunctionHasBranchProtectedScope(); 10546 10547 DSAStack->setParentTeamsRegionLoc(StartLoc); 10548 10549 return OMPTeamsDistributeParallelForDirective::Create( 10550 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10551 DSAStack->isCancelRegion()); 10552 } 10553 10554 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10555 Stmt *AStmt, 10556 SourceLocation StartLoc, 10557 SourceLocation EndLoc) { 10558 if (!AStmt) 10559 return StmtError(); 10560 10561 auto *CS = cast<CapturedStmt>(AStmt); 10562 // 1.2.2 OpenMP Language Terminology 10563 // Structured block - An executable statement with a single entry at the 10564 // top and a single exit at the bottom. 10565 // The point of exit cannot be a branch out of the structured block. 10566 // longjmp() and throw() must not violate the entry/exit criteria. 10567 CS->getCapturedDecl()->setNothrow(); 10568 10569 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10570 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10571 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10572 // 1.2.2 OpenMP Language Terminology 10573 // Structured block - An executable statement with a single entry at the 10574 // top and a single exit at the bottom. 10575 // The point of exit cannot be a branch out of the structured block. 10576 // longjmp() and throw() must not violate the entry/exit criteria. 10577 CS->getCapturedDecl()->setNothrow(); 10578 } 10579 setFunctionHasBranchProtectedScope(); 10580 10581 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10582 AStmt); 10583 } 10584 10585 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10586 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10587 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10588 if (!AStmt) 10589 return StmtError(); 10590 10591 auto *CS = cast<CapturedStmt>(AStmt); 10592 // 1.2.2 OpenMP Language Terminology 10593 // Structured block - An executable statement with a single entry at the 10594 // top and a single exit at the bottom. 10595 // The point of exit cannot be a branch out of the structured block. 10596 // longjmp() and throw() must not violate the entry/exit criteria. 10597 CS->getCapturedDecl()->setNothrow(); 10598 for (int ThisCaptureLevel = 10599 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10600 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10601 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10602 // 1.2.2 OpenMP Language Terminology 10603 // Structured block - An executable statement with a single entry at the 10604 // top and a single exit at the bottom. 10605 // The point of exit cannot be a branch out of the structured block. 10606 // longjmp() and throw() must not violate the entry/exit criteria. 10607 CS->getCapturedDecl()->setNothrow(); 10608 } 10609 10610 OMPLoopDirective::HelperExprs B; 10611 // In presence of clause 'collapse' with number of loops, it will 10612 // define the nested loops number. 10613 unsigned NestedLoopCount = checkOpenMPLoop( 10614 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10615 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10616 VarsWithImplicitDSA, B); 10617 if (NestedLoopCount == 0) 10618 return StmtError(); 10619 10620 assert((CurContext->isDependentContext() || B.builtAll()) && 10621 "omp target teams distribute loop exprs were not built"); 10622 10623 setFunctionHasBranchProtectedScope(); 10624 return OMPTargetTeamsDistributeDirective::Create( 10625 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10626 } 10627 10628 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10629 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10630 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10631 if (!AStmt) 10632 return StmtError(); 10633 10634 auto *CS = cast<CapturedStmt>(AStmt); 10635 // 1.2.2 OpenMP Language Terminology 10636 // Structured block - An executable statement with a single entry at the 10637 // top and a single exit at the bottom. 10638 // The point of exit cannot be a branch out of the structured block. 10639 // longjmp() and throw() must not violate the entry/exit criteria. 10640 CS->getCapturedDecl()->setNothrow(); 10641 for (int ThisCaptureLevel = 10642 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10643 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10644 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10645 // 1.2.2 OpenMP Language Terminology 10646 // Structured block - An executable statement with a single entry at the 10647 // top and a single exit at the bottom. 10648 // The point of exit cannot be a branch out of the structured block. 10649 // longjmp() and throw() must not violate the entry/exit criteria. 10650 CS->getCapturedDecl()->setNothrow(); 10651 } 10652 10653 OMPLoopDirective::HelperExprs B; 10654 // In presence of clause 'collapse' with number of loops, it will 10655 // define the nested loops number. 10656 unsigned NestedLoopCount = checkOpenMPLoop( 10657 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10658 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10659 VarsWithImplicitDSA, B); 10660 if (NestedLoopCount == 0) 10661 return StmtError(); 10662 10663 assert((CurContext->isDependentContext() || B.builtAll()) && 10664 "omp target teams distribute parallel for loop exprs were not built"); 10665 10666 if (!CurContext->isDependentContext()) { 10667 // Finalize the clauses that need pre-built expressions for CodeGen. 10668 for (OMPClause *C : Clauses) { 10669 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10670 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10671 B.NumIterations, *this, CurScope, 10672 DSAStack)) 10673 return StmtError(); 10674 } 10675 } 10676 10677 setFunctionHasBranchProtectedScope(); 10678 return OMPTargetTeamsDistributeParallelForDirective::Create( 10679 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10680 DSAStack->isCancelRegion()); 10681 } 10682 10683 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10684 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10685 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10686 if (!AStmt) 10687 return StmtError(); 10688 10689 auto *CS = cast<CapturedStmt>(AStmt); 10690 // 1.2.2 OpenMP Language Terminology 10691 // Structured block - An executable statement with a single entry at the 10692 // top and a single exit at the bottom. 10693 // The point of exit cannot be a branch out of the structured block. 10694 // longjmp() and throw() must not violate the entry/exit criteria. 10695 CS->getCapturedDecl()->setNothrow(); 10696 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10697 OMPD_target_teams_distribute_parallel_for_simd); 10698 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10699 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10700 // 1.2.2 OpenMP Language Terminology 10701 // Structured block - An executable statement with a single entry at the 10702 // top and a single exit at the bottom. 10703 // The point of exit cannot be a branch out of the structured block. 10704 // longjmp() and throw() must not violate the entry/exit criteria. 10705 CS->getCapturedDecl()->setNothrow(); 10706 } 10707 10708 OMPLoopDirective::HelperExprs B; 10709 // In presence of clause 'collapse' with number of loops, it will 10710 // define the nested loops number. 10711 unsigned NestedLoopCount = 10712 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10713 getCollapseNumberExpr(Clauses), 10714 nullptr /*ordered not a clause on distribute*/, CS, *this, 10715 *DSAStack, VarsWithImplicitDSA, B); 10716 if (NestedLoopCount == 0) 10717 return StmtError(); 10718 10719 assert((CurContext->isDependentContext() || B.builtAll()) && 10720 "omp target teams distribute parallel for simd loop exprs were not " 10721 "built"); 10722 10723 if (!CurContext->isDependentContext()) { 10724 // Finalize the clauses that need pre-built expressions for CodeGen. 10725 for (OMPClause *C : Clauses) { 10726 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10727 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10728 B.NumIterations, *this, CurScope, 10729 DSAStack)) 10730 return StmtError(); 10731 } 10732 } 10733 10734 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10735 return StmtError(); 10736 10737 setFunctionHasBranchProtectedScope(); 10738 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10739 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10740 } 10741 10742 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10743 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10744 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10745 if (!AStmt) 10746 return StmtError(); 10747 10748 auto *CS = cast<CapturedStmt>(AStmt); 10749 // 1.2.2 OpenMP Language Terminology 10750 // Structured block - An executable statement with a single entry at the 10751 // top and a single exit at the bottom. 10752 // The point of exit cannot be a branch out of the structured block. 10753 // longjmp() and throw() must not violate the entry/exit criteria. 10754 CS->getCapturedDecl()->setNothrow(); 10755 for (int ThisCaptureLevel = 10756 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10757 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10758 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10759 // 1.2.2 OpenMP Language Terminology 10760 // Structured block - An executable statement with a single entry at the 10761 // top and a single exit at the bottom. 10762 // The point of exit cannot be a branch out of the structured block. 10763 // longjmp() and throw() must not violate the entry/exit criteria. 10764 CS->getCapturedDecl()->setNothrow(); 10765 } 10766 10767 OMPLoopDirective::HelperExprs B; 10768 // In presence of clause 'collapse' with number of loops, it will 10769 // define the nested loops number. 10770 unsigned NestedLoopCount = checkOpenMPLoop( 10771 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10772 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10773 VarsWithImplicitDSA, B); 10774 if (NestedLoopCount == 0) 10775 return StmtError(); 10776 10777 assert((CurContext->isDependentContext() || B.builtAll()) && 10778 "omp target teams distribute simd loop exprs were not built"); 10779 10780 if (!CurContext->isDependentContext()) { 10781 // Finalize the clauses that need pre-built expressions for CodeGen. 10782 for (OMPClause *C : Clauses) { 10783 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10784 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10785 B.NumIterations, *this, CurScope, 10786 DSAStack)) 10787 return StmtError(); 10788 } 10789 } 10790 10791 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10792 return StmtError(); 10793 10794 setFunctionHasBranchProtectedScope(); 10795 return OMPTargetTeamsDistributeSimdDirective::Create( 10796 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10797 } 10798 10799 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10800 SourceLocation StartLoc, 10801 SourceLocation LParenLoc, 10802 SourceLocation EndLoc) { 10803 OMPClause *Res = nullptr; 10804 switch (Kind) { 10805 case OMPC_final: 10806 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10807 break; 10808 case OMPC_num_threads: 10809 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10810 break; 10811 case OMPC_safelen: 10812 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10813 break; 10814 case OMPC_simdlen: 10815 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10816 break; 10817 case OMPC_allocator: 10818 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10819 break; 10820 case OMPC_collapse: 10821 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10822 break; 10823 case OMPC_ordered: 10824 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10825 break; 10826 case OMPC_device: 10827 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10828 break; 10829 case OMPC_num_teams: 10830 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10831 break; 10832 case OMPC_thread_limit: 10833 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10834 break; 10835 case OMPC_priority: 10836 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10837 break; 10838 case OMPC_grainsize: 10839 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10840 break; 10841 case OMPC_num_tasks: 10842 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10843 break; 10844 case OMPC_hint: 10845 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10846 break; 10847 case OMPC_if: 10848 case OMPC_default: 10849 case OMPC_proc_bind: 10850 case OMPC_schedule: 10851 case OMPC_private: 10852 case OMPC_firstprivate: 10853 case OMPC_lastprivate: 10854 case OMPC_shared: 10855 case OMPC_reduction: 10856 case OMPC_task_reduction: 10857 case OMPC_in_reduction: 10858 case OMPC_linear: 10859 case OMPC_aligned: 10860 case OMPC_copyin: 10861 case OMPC_copyprivate: 10862 case OMPC_nowait: 10863 case OMPC_untied: 10864 case OMPC_mergeable: 10865 case OMPC_threadprivate: 10866 case OMPC_allocate: 10867 case OMPC_flush: 10868 case OMPC_read: 10869 case OMPC_write: 10870 case OMPC_update: 10871 case OMPC_capture: 10872 case OMPC_seq_cst: 10873 case OMPC_acq_rel: 10874 case OMPC_depend: 10875 case OMPC_threads: 10876 case OMPC_simd: 10877 case OMPC_map: 10878 case OMPC_nogroup: 10879 case OMPC_dist_schedule: 10880 case OMPC_defaultmap: 10881 case OMPC_unknown: 10882 case OMPC_uniform: 10883 case OMPC_to: 10884 case OMPC_from: 10885 case OMPC_use_device_ptr: 10886 case OMPC_is_device_ptr: 10887 case OMPC_unified_address: 10888 case OMPC_unified_shared_memory: 10889 case OMPC_reverse_offload: 10890 case OMPC_dynamic_allocators: 10891 case OMPC_atomic_default_mem_order: 10892 case OMPC_device_type: 10893 case OMPC_match: 10894 case OMPC_nontemporal: 10895 case OMPC_order: 10896 llvm_unreachable("Clause is not allowed."); 10897 } 10898 return Res; 10899 } 10900 10901 // An OpenMP directive such as 'target parallel' has two captured regions: 10902 // for the 'target' and 'parallel' respectively. This function returns 10903 // the region in which to capture expressions associated with a clause. 10904 // A return value of OMPD_unknown signifies that the expression should not 10905 // be captured. 10906 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10907 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 10908 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10909 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10910 switch (CKind) { 10911 case OMPC_if: 10912 switch (DKind) { 10913 case OMPD_target_parallel_for_simd: 10914 if (OpenMPVersion >= 50 && 10915 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10916 CaptureRegion = OMPD_parallel; 10917 break; 10918 } 10919 LLVM_FALLTHROUGH; 10920 case OMPD_target_parallel: 10921 case OMPD_target_parallel_for: 10922 // If this clause applies to the nested 'parallel' region, capture within 10923 // the 'target' region, otherwise do not capture. 10924 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10925 CaptureRegion = OMPD_target; 10926 break; 10927 case OMPD_target_teams_distribute_parallel_for_simd: 10928 if (OpenMPVersion >= 50 && 10929 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10930 CaptureRegion = OMPD_parallel; 10931 break; 10932 } 10933 LLVM_FALLTHROUGH; 10934 case OMPD_target_teams_distribute_parallel_for: 10935 // If this clause applies to the nested 'parallel' region, capture within 10936 // the 'teams' region, otherwise do not capture. 10937 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10938 CaptureRegion = OMPD_teams; 10939 break; 10940 case OMPD_teams_distribute_parallel_for_simd: 10941 if (OpenMPVersion >= 50 && 10942 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10943 CaptureRegion = OMPD_parallel; 10944 break; 10945 } 10946 LLVM_FALLTHROUGH; 10947 case OMPD_teams_distribute_parallel_for: 10948 CaptureRegion = OMPD_teams; 10949 break; 10950 case OMPD_target_update: 10951 case OMPD_target_enter_data: 10952 case OMPD_target_exit_data: 10953 CaptureRegion = OMPD_task; 10954 break; 10955 case OMPD_parallel_master_taskloop: 10956 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10957 CaptureRegion = OMPD_parallel; 10958 break; 10959 case OMPD_parallel_master_taskloop_simd: 10960 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 10961 NameModifier == OMPD_taskloop) { 10962 CaptureRegion = OMPD_parallel; 10963 break; 10964 } 10965 if (OpenMPVersion <= 45) 10966 break; 10967 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10968 CaptureRegion = OMPD_taskloop; 10969 break; 10970 case OMPD_parallel_for_simd: 10971 if (OpenMPVersion <= 45) 10972 break; 10973 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10974 CaptureRegion = OMPD_parallel; 10975 break; 10976 case OMPD_taskloop_simd: 10977 case OMPD_master_taskloop_simd: 10978 if (OpenMPVersion <= 45) 10979 break; 10980 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10981 CaptureRegion = OMPD_taskloop; 10982 break; 10983 case OMPD_distribute_parallel_for_simd: 10984 if (OpenMPVersion <= 45) 10985 break; 10986 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10987 CaptureRegion = OMPD_parallel; 10988 break; 10989 case OMPD_target_simd: 10990 if (OpenMPVersion >= 50 && 10991 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10992 CaptureRegion = OMPD_target; 10993 break; 10994 case OMPD_teams_distribute_simd: 10995 case OMPD_target_teams_distribute_simd: 10996 if (OpenMPVersion >= 50 && 10997 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10998 CaptureRegion = OMPD_teams; 10999 break; 11000 case OMPD_cancel: 11001 case OMPD_parallel: 11002 case OMPD_parallel_master: 11003 case OMPD_parallel_sections: 11004 case OMPD_parallel_for: 11005 case OMPD_target: 11006 case OMPD_target_teams: 11007 case OMPD_target_teams_distribute: 11008 case OMPD_distribute_parallel_for: 11009 case OMPD_task: 11010 case OMPD_taskloop: 11011 case OMPD_master_taskloop: 11012 case OMPD_target_data: 11013 case OMPD_simd: 11014 case OMPD_for_simd: 11015 case OMPD_distribute_simd: 11016 // Do not capture if-clause expressions. 11017 break; 11018 case OMPD_threadprivate: 11019 case OMPD_allocate: 11020 case OMPD_taskyield: 11021 case OMPD_barrier: 11022 case OMPD_taskwait: 11023 case OMPD_cancellation_point: 11024 case OMPD_flush: 11025 case OMPD_declare_reduction: 11026 case OMPD_declare_mapper: 11027 case OMPD_declare_simd: 11028 case OMPD_declare_variant: 11029 case OMPD_declare_target: 11030 case OMPD_end_declare_target: 11031 case OMPD_teams: 11032 case OMPD_for: 11033 case OMPD_sections: 11034 case OMPD_section: 11035 case OMPD_single: 11036 case OMPD_master: 11037 case OMPD_critical: 11038 case OMPD_taskgroup: 11039 case OMPD_distribute: 11040 case OMPD_ordered: 11041 case OMPD_atomic: 11042 case OMPD_teams_distribute: 11043 case OMPD_requires: 11044 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11045 case OMPD_unknown: 11046 llvm_unreachable("Unknown OpenMP directive"); 11047 } 11048 break; 11049 case OMPC_num_threads: 11050 switch (DKind) { 11051 case OMPD_target_parallel: 11052 case OMPD_target_parallel_for: 11053 case OMPD_target_parallel_for_simd: 11054 CaptureRegion = OMPD_target; 11055 break; 11056 case OMPD_teams_distribute_parallel_for: 11057 case OMPD_teams_distribute_parallel_for_simd: 11058 case OMPD_target_teams_distribute_parallel_for: 11059 case OMPD_target_teams_distribute_parallel_for_simd: 11060 CaptureRegion = OMPD_teams; 11061 break; 11062 case OMPD_parallel: 11063 case OMPD_parallel_master: 11064 case OMPD_parallel_sections: 11065 case OMPD_parallel_for: 11066 case OMPD_parallel_for_simd: 11067 case OMPD_distribute_parallel_for: 11068 case OMPD_distribute_parallel_for_simd: 11069 case OMPD_parallel_master_taskloop: 11070 case OMPD_parallel_master_taskloop_simd: 11071 // Do not capture num_threads-clause expressions. 11072 break; 11073 case OMPD_target_data: 11074 case OMPD_target_enter_data: 11075 case OMPD_target_exit_data: 11076 case OMPD_target_update: 11077 case OMPD_target: 11078 case OMPD_target_simd: 11079 case OMPD_target_teams: 11080 case OMPD_target_teams_distribute: 11081 case OMPD_target_teams_distribute_simd: 11082 case OMPD_cancel: 11083 case OMPD_task: 11084 case OMPD_taskloop: 11085 case OMPD_taskloop_simd: 11086 case OMPD_master_taskloop: 11087 case OMPD_master_taskloop_simd: 11088 case OMPD_threadprivate: 11089 case OMPD_allocate: 11090 case OMPD_taskyield: 11091 case OMPD_barrier: 11092 case OMPD_taskwait: 11093 case OMPD_cancellation_point: 11094 case OMPD_flush: 11095 case OMPD_declare_reduction: 11096 case OMPD_declare_mapper: 11097 case OMPD_declare_simd: 11098 case OMPD_declare_variant: 11099 case OMPD_declare_target: 11100 case OMPD_end_declare_target: 11101 case OMPD_teams: 11102 case OMPD_simd: 11103 case OMPD_for: 11104 case OMPD_for_simd: 11105 case OMPD_sections: 11106 case OMPD_section: 11107 case OMPD_single: 11108 case OMPD_master: 11109 case OMPD_critical: 11110 case OMPD_taskgroup: 11111 case OMPD_distribute: 11112 case OMPD_ordered: 11113 case OMPD_atomic: 11114 case OMPD_distribute_simd: 11115 case OMPD_teams_distribute: 11116 case OMPD_teams_distribute_simd: 11117 case OMPD_requires: 11118 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11119 case OMPD_unknown: 11120 llvm_unreachable("Unknown OpenMP directive"); 11121 } 11122 break; 11123 case OMPC_num_teams: 11124 switch (DKind) { 11125 case OMPD_target_teams: 11126 case OMPD_target_teams_distribute: 11127 case OMPD_target_teams_distribute_simd: 11128 case OMPD_target_teams_distribute_parallel_for: 11129 case OMPD_target_teams_distribute_parallel_for_simd: 11130 CaptureRegion = OMPD_target; 11131 break; 11132 case OMPD_teams_distribute_parallel_for: 11133 case OMPD_teams_distribute_parallel_for_simd: 11134 case OMPD_teams: 11135 case OMPD_teams_distribute: 11136 case OMPD_teams_distribute_simd: 11137 // Do not capture num_teams-clause expressions. 11138 break; 11139 case OMPD_distribute_parallel_for: 11140 case OMPD_distribute_parallel_for_simd: 11141 case OMPD_task: 11142 case OMPD_taskloop: 11143 case OMPD_taskloop_simd: 11144 case OMPD_master_taskloop: 11145 case OMPD_master_taskloop_simd: 11146 case OMPD_parallel_master_taskloop: 11147 case OMPD_parallel_master_taskloop_simd: 11148 case OMPD_target_data: 11149 case OMPD_target_enter_data: 11150 case OMPD_target_exit_data: 11151 case OMPD_target_update: 11152 case OMPD_cancel: 11153 case OMPD_parallel: 11154 case OMPD_parallel_master: 11155 case OMPD_parallel_sections: 11156 case OMPD_parallel_for: 11157 case OMPD_parallel_for_simd: 11158 case OMPD_target: 11159 case OMPD_target_simd: 11160 case OMPD_target_parallel: 11161 case OMPD_target_parallel_for: 11162 case OMPD_target_parallel_for_simd: 11163 case OMPD_threadprivate: 11164 case OMPD_allocate: 11165 case OMPD_taskyield: 11166 case OMPD_barrier: 11167 case OMPD_taskwait: 11168 case OMPD_cancellation_point: 11169 case OMPD_flush: 11170 case OMPD_declare_reduction: 11171 case OMPD_declare_mapper: 11172 case OMPD_declare_simd: 11173 case OMPD_declare_variant: 11174 case OMPD_declare_target: 11175 case OMPD_end_declare_target: 11176 case OMPD_simd: 11177 case OMPD_for: 11178 case OMPD_for_simd: 11179 case OMPD_sections: 11180 case OMPD_section: 11181 case OMPD_single: 11182 case OMPD_master: 11183 case OMPD_critical: 11184 case OMPD_taskgroup: 11185 case OMPD_distribute: 11186 case OMPD_ordered: 11187 case OMPD_atomic: 11188 case OMPD_distribute_simd: 11189 case OMPD_requires: 11190 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11191 case OMPD_unknown: 11192 llvm_unreachable("Unknown OpenMP directive"); 11193 } 11194 break; 11195 case OMPC_thread_limit: 11196 switch (DKind) { 11197 case OMPD_target_teams: 11198 case OMPD_target_teams_distribute: 11199 case OMPD_target_teams_distribute_simd: 11200 case OMPD_target_teams_distribute_parallel_for: 11201 case OMPD_target_teams_distribute_parallel_for_simd: 11202 CaptureRegion = OMPD_target; 11203 break; 11204 case OMPD_teams_distribute_parallel_for: 11205 case OMPD_teams_distribute_parallel_for_simd: 11206 case OMPD_teams: 11207 case OMPD_teams_distribute: 11208 case OMPD_teams_distribute_simd: 11209 // Do not capture thread_limit-clause expressions. 11210 break; 11211 case OMPD_distribute_parallel_for: 11212 case OMPD_distribute_parallel_for_simd: 11213 case OMPD_task: 11214 case OMPD_taskloop: 11215 case OMPD_taskloop_simd: 11216 case OMPD_master_taskloop: 11217 case OMPD_master_taskloop_simd: 11218 case OMPD_parallel_master_taskloop: 11219 case OMPD_parallel_master_taskloop_simd: 11220 case OMPD_target_data: 11221 case OMPD_target_enter_data: 11222 case OMPD_target_exit_data: 11223 case OMPD_target_update: 11224 case OMPD_cancel: 11225 case OMPD_parallel: 11226 case OMPD_parallel_master: 11227 case OMPD_parallel_sections: 11228 case OMPD_parallel_for: 11229 case OMPD_parallel_for_simd: 11230 case OMPD_target: 11231 case OMPD_target_simd: 11232 case OMPD_target_parallel: 11233 case OMPD_target_parallel_for: 11234 case OMPD_target_parallel_for_simd: 11235 case OMPD_threadprivate: 11236 case OMPD_allocate: 11237 case OMPD_taskyield: 11238 case OMPD_barrier: 11239 case OMPD_taskwait: 11240 case OMPD_cancellation_point: 11241 case OMPD_flush: 11242 case OMPD_declare_reduction: 11243 case OMPD_declare_mapper: 11244 case OMPD_declare_simd: 11245 case OMPD_declare_variant: 11246 case OMPD_declare_target: 11247 case OMPD_end_declare_target: 11248 case OMPD_simd: 11249 case OMPD_for: 11250 case OMPD_for_simd: 11251 case OMPD_sections: 11252 case OMPD_section: 11253 case OMPD_single: 11254 case OMPD_master: 11255 case OMPD_critical: 11256 case OMPD_taskgroup: 11257 case OMPD_distribute: 11258 case OMPD_ordered: 11259 case OMPD_atomic: 11260 case OMPD_distribute_simd: 11261 case OMPD_requires: 11262 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11263 case OMPD_unknown: 11264 llvm_unreachable("Unknown OpenMP directive"); 11265 } 11266 break; 11267 case OMPC_schedule: 11268 switch (DKind) { 11269 case OMPD_parallel_for: 11270 case OMPD_parallel_for_simd: 11271 case OMPD_distribute_parallel_for: 11272 case OMPD_distribute_parallel_for_simd: 11273 case OMPD_teams_distribute_parallel_for: 11274 case OMPD_teams_distribute_parallel_for_simd: 11275 case OMPD_target_parallel_for: 11276 case OMPD_target_parallel_for_simd: 11277 case OMPD_target_teams_distribute_parallel_for: 11278 case OMPD_target_teams_distribute_parallel_for_simd: 11279 CaptureRegion = OMPD_parallel; 11280 break; 11281 case OMPD_for: 11282 case OMPD_for_simd: 11283 // Do not capture schedule-clause expressions. 11284 break; 11285 case OMPD_task: 11286 case OMPD_taskloop: 11287 case OMPD_taskloop_simd: 11288 case OMPD_master_taskloop: 11289 case OMPD_master_taskloop_simd: 11290 case OMPD_parallel_master_taskloop: 11291 case OMPD_parallel_master_taskloop_simd: 11292 case OMPD_target_data: 11293 case OMPD_target_enter_data: 11294 case OMPD_target_exit_data: 11295 case OMPD_target_update: 11296 case OMPD_teams: 11297 case OMPD_teams_distribute: 11298 case OMPD_teams_distribute_simd: 11299 case OMPD_target_teams_distribute: 11300 case OMPD_target_teams_distribute_simd: 11301 case OMPD_target: 11302 case OMPD_target_simd: 11303 case OMPD_target_parallel: 11304 case OMPD_cancel: 11305 case OMPD_parallel: 11306 case OMPD_parallel_master: 11307 case OMPD_parallel_sections: 11308 case OMPD_threadprivate: 11309 case OMPD_allocate: 11310 case OMPD_taskyield: 11311 case OMPD_barrier: 11312 case OMPD_taskwait: 11313 case OMPD_cancellation_point: 11314 case OMPD_flush: 11315 case OMPD_declare_reduction: 11316 case OMPD_declare_mapper: 11317 case OMPD_declare_simd: 11318 case OMPD_declare_variant: 11319 case OMPD_declare_target: 11320 case OMPD_end_declare_target: 11321 case OMPD_simd: 11322 case OMPD_sections: 11323 case OMPD_section: 11324 case OMPD_single: 11325 case OMPD_master: 11326 case OMPD_critical: 11327 case OMPD_taskgroup: 11328 case OMPD_distribute: 11329 case OMPD_ordered: 11330 case OMPD_atomic: 11331 case OMPD_distribute_simd: 11332 case OMPD_target_teams: 11333 case OMPD_requires: 11334 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11335 case OMPD_unknown: 11336 llvm_unreachable("Unknown OpenMP directive"); 11337 } 11338 break; 11339 case OMPC_dist_schedule: 11340 switch (DKind) { 11341 case OMPD_teams_distribute_parallel_for: 11342 case OMPD_teams_distribute_parallel_for_simd: 11343 case OMPD_teams_distribute: 11344 case OMPD_teams_distribute_simd: 11345 case OMPD_target_teams_distribute_parallel_for: 11346 case OMPD_target_teams_distribute_parallel_for_simd: 11347 case OMPD_target_teams_distribute: 11348 case OMPD_target_teams_distribute_simd: 11349 CaptureRegion = OMPD_teams; 11350 break; 11351 case OMPD_distribute_parallel_for: 11352 case OMPD_distribute_parallel_for_simd: 11353 case OMPD_distribute: 11354 case OMPD_distribute_simd: 11355 // Do not capture thread_limit-clause expressions. 11356 break; 11357 case OMPD_parallel_for: 11358 case OMPD_parallel_for_simd: 11359 case OMPD_target_parallel_for_simd: 11360 case OMPD_target_parallel_for: 11361 case OMPD_task: 11362 case OMPD_taskloop: 11363 case OMPD_taskloop_simd: 11364 case OMPD_master_taskloop: 11365 case OMPD_master_taskloop_simd: 11366 case OMPD_parallel_master_taskloop: 11367 case OMPD_parallel_master_taskloop_simd: 11368 case OMPD_target_data: 11369 case OMPD_target_enter_data: 11370 case OMPD_target_exit_data: 11371 case OMPD_target_update: 11372 case OMPD_teams: 11373 case OMPD_target: 11374 case OMPD_target_simd: 11375 case OMPD_target_parallel: 11376 case OMPD_cancel: 11377 case OMPD_parallel: 11378 case OMPD_parallel_master: 11379 case OMPD_parallel_sections: 11380 case OMPD_threadprivate: 11381 case OMPD_allocate: 11382 case OMPD_taskyield: 11383 case OMPD_barrier: 11384 case OMPD_taskwait: 11385 case OMPD_cancellation_point: 11386 case OMPD_flush: 11387 case OMPD_declare_reduction: 11388 case OMPD_declare_mapper: 11389 case OMPD_declare_simd: 11390 case OMPD_declare_variant: 11391 case OMPD_declare_target: 11392 case OMPD_end_declare_target: 11393 case OMPD_simd: 11394 case OMPD_for: 11395 case OMPD_for_simd: 11396 case OMPD_sections: 11397 case OMPD_section: 11398 case OMPD_single: 11399 case OMPD_master: 11400 case OMPD_critical: 11401 case OMPD_taskgroup: 11402 case OMPD_ordered: 11403 case OMPD_atomic: 11404 case OMPD_target_teams: 11405 case OMPD_requires: 11406 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11407 case OMPD_unknown: 11408 llvm_unreachable("Unknown OpenMP directive"); 11409 } 11410 break; 11411 case OMPC_device: 11412 switch (DKind) { 11413 case OMPD_target_update: 11414 case OMPD_target_enter_data: 11415 case OMPD_target_exit_data: 11416 case OMPD_target: 11417 case OMPD_target_simd: 11418 case OMPD_target_teams: 11419 case OMPD_target_parallel: 11420 case OMPD_target_teams_distribute: 11421 case OMPD_target_teams_distribute_simd: 11422 case OMPD_target_parallel_for: 11423 case OMPD_target_parallel_for_simd: 11424 case OMPD_target_teams_distribute_parallel_for: 11425 case OMPD_target_teams_distribute_parallel_for_simd: 11426 CaptureRegion = OMPD_task; 11427 break; 11428 case OMPD_target_data: 11429 // Do not capture device-clause expressions. 11430 break; 11431 case OMPD_teams_distribute_parallel_for: 11432 case OMPD_teams_distribute_parallel_for_simd: 11433 case OMPD_teams: 11434 case OMPD_teams_distribute: 11435 case OMPD_teams_distribute_simd: 11436 case OMPD_distribute_parallel_for: 11437 case OMPD_distribute_parallel_for_simd: 11438 case OMPD_task: 11439 case OMPD_taskloop: 11440 case OMPD_taskloop_simd: 11441 case OMPD_master_taskloop: 11442 case OMPD_master_taskloop_simd: 11443 case OMPD_parallel_master_taskloop: 11444 case OMPD_parallel_master_taskloop_simd: 11445 case OMPD_cancel: 11446 case OMPD_parallel: 11447 case OMPD_parallel_master: 11448 case OMPD_parallel_sections: 11449 case OMPD_parallel_for: 11450 case OMPD_parallel_for_simd: 11451 case OMPD_threadprivate: 11452 case OMPD_allocate: 11453 case OMPD_taskyield: 11454 case OMPD_barrier: 11455 case OMPD_taskwait: 11456 case OMPD_cancellation_point: 11457 case OMPD_flush: 11458 case OMPD_declare_reduction: 11459 case OMPD_declare_mapper: 11460 case OMPD_declare_simd: 11461 case OMPD_declare_variant: 11462 case OMPD_declare_target: 11463 case OMPD_end_declare_target: 11464 case OMPD_simd: 11465 case OMPD_for: 11466 case OMPD_for_simd: 11467 case OMPD_sections: 11468 case OMPD_section: 11469 case OMPD_single: 11470 case OMPD_master: 11471 case OMPD_critical: 11472 case OMPD_taskgroup: 11473 case OMPD_distribute: 11474 case OMPD_ordered: 11475 case OMPD_atomic: 11476 case OMPD_distribute_simd: 11477 case OMPD_requires: 11478 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11479 case OMPD_unknown: 11480 llvm_unreachable("Unknown OpenMP directive"); 11481 } 11482 break; 11483 case OMPC_grainsize: 11484 case OMPC_num_tasks: 11485 case OMPC_final: 11486 case OMPC_priority: 11487 switch (DKind) { 11488 case OMPD_task: 11489 case OMPD_taskloop: 11490 case OMPD_taskloop_simd: 11491 case OMPD_master_taskloop: 11492 case OMPD_master_taskloop_simd: 11493 break; 11494 case OMPD_parallel_master_taskloop: 11495 case OMPD_parallel_master_taskloop_simd: 11496 CaptureRegion = OMPD_parallel; 11497 break; 11498 case OMPD_target_update: 11499 case OMPD_target_enter_data: 11500 case OMPD_target_exit_data: 11501 case OMPD_target: 11502 case OMPD_target_simd: 11503 case OMPD_target_teams: 11504 case OMPD_target_parallel: 11505 case OMPD_target_teams_distribute: 11506 case OMPD_target_teams_distribute_simd: 11507 case OMPD_target_parallel_for: 11508 case OMPD_target_parallel_for_simd: 11509 case OMPD_target_teams_distribute_parallel_for: 11510 case OMPD_target_teams_distribute_parallel_for_simd: 11511 case OMPD_target_data: 11512 case OMPD_teams_distribute_parallel_for: 11513 case OMPD_teams_distribute_parallel_for_simd: 11514 case OMPD_teams: 11515 case OMPD_teams_distribute: 11516 case OMPD_teams_distribute_simd: 11517 case OMPD_distribute_parallel_for: 11518 case OMPD_distribute_parallel_for_simd: 11519 case OMPD_cancel: 11520 case OMPD_parallel: 11521 case OMPD_parallel_master: 11522 case OMPD_parallel_sections: 11523 case OMPD_parallel_for: 11524 case OMPD_parallel_for_simd: 11525 case OMPD_threadprivate: 11526 case OMPD_allocate: 11527 case OMPD_taskyield: 11528 case OMPD_barrier: 11529 case OMPD_taskwait: 11530 case OMPD_cancellation_point: 11531 case OMPD_flush: 11532 case OMPD_declare_reduction: 11533 case OMPD_declare_mapper: 11534 case OMPD_declare_simd: 11535 case OMPD_declare_variant: 11536 case OMPD_declare_target: 11537 case OMPD_end_declare_target: 11538 case OMPD_simd: 11539 case OMPD_for: 11540 case OMPD_for_simd: 11541 case OMPD_sections: 11542 case OMPD_section: 11543 case OMPD_single: 11544 case OMPD_master: 11545 case OMPD_critical: 11546 case OMPD_taskgroup: 11547 case OMPD_distribute: 11548 case OMPD_ordered: 11549 case OMPD_atomic: 11550 case OMPD_distribute_simd: 11551 case OMPD_requires: 11552 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11553 case OMPD_unknown: 11554 llvm_unreachable("Unknown OpenMP directive"); 11555 } 11556 break; 11557 case OMPC_firstprivate: 11558 case OMPC_lastprivate: 11559 case OMPC_reduction: 11560 case OMPC_task_reduction: 11561 case OMPC_in_reduction: 11562 case OMPC_linear: 11563 case OMPC_default: 11564 case OMPC_proc_bind: 11565 case OMPC_safelen: 11566 case OMPC_simdlen: 11567 case OMPC_allocator: 11568 case OMPC_collapse: 11569 case OMPC_private: 11570 case OMPC_shared: 11571 case OMPC_aligned: 11572 case OMPC_copyin: 11573 case OMPC_copyprivate: 11574 case OMPC_ordered: 11575 case OMPC_nowait: 11576 case OMPC_untied: 11577 case OMPC_mergeable: 11578 case OMPC_threadprivate: 11579 case OMPC_allocate: 11580 case OMPC_flush: 11581 case OMPC_read: 11582 case OMPC_write: 11583 case OMPC_update: 11584 case OMPC_capture: 11585 case OMPC_seq_cst: 11586 case OMPC_acq_rel: 11587 case OMPC_depend: 11588 case OMPC_threads: 11589 case OMPC_simd: 11590 case OMPC_map: 11591 case OMPC_nogroup: 11592 case OMPC_hint: 11593 case OMPC_defaultmap: 11594 case OMPC_unknown: 11595 case OMPC_uniform: 11596 case OMPC_to: 11597 case OMPC_from: 11598 case OMPC_use_device_ptr: 11599 case OMPC_is_device_ptr: 11600 case OMPC_unified_address: 11601 case OMPC_unified_shared_memory: 11602 case OMPC_reverse_offload: 11603 case OMPC_dynamic_allocators: 11604 case OMPC_atomic_default_mem_order: 11605 case OMPC_device_type: 11606 case OMPC_match: 11607 case OMPC_nontemporal: 11608 case OMPC_order: 11609 llvm_unreachable("Unexpected OpenMP clause."); 11610 } 11611 return CaptureRegion; 11612 } 11613 11614 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11615 Expr *Condition, SourceLocation StartLoc, 11616 SourceLocation LParenLoc, 11617 SourceLocation NameModifierLoc, 11618 SourceLocation ColonLoc, 11619 SourceLocation EndLoc) { 11620 Expr *ValExpr = Condition; 11621 Stmt *HelperValStmt = nullptr; 11622 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11623 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11624 !Condition->isInstantiationDependent() && 11625 !Condition->containsUnexpandedParameterPack()) { 11626 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11627 if (Val.isInvalid()) 11628 return nullptr; 11629 11630 ValExpr = Val.get(); 11631 11632 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11633 CaptureRegion = getOpenMPCaptureRegionForClause( 11634 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 11635 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11636 ValExpr = MakeFullExpr(ValExpr).get(); 11637 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11638 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11639 HelperValStmt = buildPreInits(Context, Captures); 11640 } 11641 } 11642 11643 return new (Context) 11644 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11645 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11646 } 11647 11648 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11649 SourceLocation StartLoc, 11650 SourceLocation LParenLoc, 11651 SourceLocation EndLoc) { 11652 Expr *ValExpr = Condition; 11653 Stmt *HelperValStmt = nullptr; 11654 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11655 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11656 !Condition->isInstantiationDependent() && 11657 !Condition->containsUnexpandedParameterPack()) { 11658 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11659 if (Val.isInvalid()) 11660 return nullptr; 11661 11662 ValExpr = MakeFullExpr(Val.get()).get(); 11663 11664 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11665 CaptureRegion = 11666 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 11667 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11668 ValExpr = MakeFullExpr(ValExpr).get(); 11669 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11670 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11671 HelperValStmt = buildPreInits(Context, Captures); 11672 } 11673 } 11674 11675 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11676 StartLoc, LParenLoc, EndLoc); 11677 } 11678 11679 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11680 Expr *Op) { 11681 if (!Op) 11682 return ExprError(); 11683 11684 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11685 public: 11686 IntConvertDiagnoser() 11687 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11688 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11689 QualType T) override { 11690 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11691 } 11692 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11693 QualType T) override { 11694 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11695 } 11696 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11697 QualType T, 11698 QualType ConvTy) override { 11699 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11700 } 11701 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11702 QualType ConvTy) override { 11703 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11704 << ConvTy->isEnumeralType() << ConvTy; 11705 } 11706 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11707 QualType T) override { 11708 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11709 } 11710 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11711 QualType ConvTy) override { 11712 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11713 << ConvTy->isEnumeralType() << ConvTy; 11714 } 11715 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11716 QualType) override { 11717 llvm_unreachable("conversion functions are permitted"); 11718 } 11719 } ConvertDiagnoser; 11720 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11721 } 11722 11723 static bool 11724 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11725 bool StrictlyPositive, bool BuildCapture = false, 11726 OpenMPDirectiveKind DKind = OMPD_unknown, 11727 OpenMPDirectiveKind *CaptureRegion = nullptr, 11728 Stmt **HelperValStmt = nullptr) { 11729 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11730 !ValExpr->isInstantiationDependent()) { 11731 SourceLocation Loc = ValExpr->getExprLoc(); 11732 ExprResult Value = 11733 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11734 if (Value.isInvalid()) 11735 return false; 11736 11737 ValExpr = Value.get(); 11738 // The expression must evaluate to a non-negative integer value. 11739 llvm::APSInt Result; 11740 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11741 Result.isSigned() && 11742 !((!StrictlyPositive && Result.isNonNegative()) || 11743 (StrictlyPositive && Result.isStrictlyPositive()))) { 11744 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11745 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11746 << ValExpr->getSourceRange(); 11747 return false; 11748 } 11749 if (!BuildCapture) 11750 return true; 11751 *CaptureRegion = 11752 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 11753 if (*CaptureRegion != OMPD_unknown && 11754 !SemaRef.CurContext->isDependentContext()) { 11755 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11756 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11757 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11758 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11759 } 11760 } 11761 return true; 11762 } 11763 11764 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11765 SourceLocation StartLoc, 11766 SourceLocation LParenLoc, 11767 SourceLocation EndLoc) { 11768 Expr *ValExpr = NumThreads; 11769 Stmt *HelperValStmt = nullptr; 11770 11771 // OpenMP [2.5, Restrictions] 11772 // The num_threads expression must evaluate to a positive integer value. 11773 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11774 /*StrictlyPositive=*/true)) 11775 return nullptr; 11776 11777 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11778 OpenMPDirectiveKind CaptureRegion = 11779 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 11780 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11781 ValExpr = MakeFullExpr(ValExpr).get(); 11782 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11783 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11784 HelperValStmt = buildPreInits(Context, Captures); 11785 } 11786 11787 return new (Context) OMPNumThreadsClause( 11788 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11789 } 11790 11791 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11792 OpenMPClauseKind CKind, 11793 bool StrictlyPositive) { 11794 if (!E) 11795 return ExprError(); 11796 if (E->isValueDependent() || E->isTypeDependent() || 11797 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11798 return E; 11799 llvm::APSInt Result; 11800 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11801 if (ICE.isInvalid()) 11802 return ExprError(); 11803 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11804 (!StrictlyPositive && !Result.isNonNegative())) { 11805 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11806 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11807 << E->getSourceRange(); 11808 return ExprError(); 11809 } 11810 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11811 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11812 << E->getSourceRange(); 11813 return ExprError(); 11814 } 11815 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11816 DSAStack->setAssociatedLoops(Result.getExtValue()); 11817 else if (CKind == OMPC_ordered) 11818 DSAStack->setAssociatedLoops(Result.getExtValue()); 11819 return ICE; 11820 } 11821 11822 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11823 SourceLocation LParenLoc, 11824 SourceLocation EndLoc) { 11825 // OpenMP [2.8.1, simd construct, Description] 11826 // The parameter of the safelen clause must be a constant 11827 // positive integer expression. 11828 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11829 if (Safelen.isInvalid()) 11830 return nullptr; 11831 return new (Context) 11832 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11833 } 11834 11835 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11836 SourceLocation LParenLoc, 11837 SourceLocation EndLoc) { 11838 // OpenMP [2.8.1, simd construct, Description] 11839 // The parameter of the simdlen clause must be a constant 11840 // positive integer expression. 11841 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11842 if (Simdlen.isInvalid()) 11843 return nullptr; 11844 return new (Context) 11845 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11846 } 11847 11848 /// Tries to find omp_allocator_handle_t type. 11849 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11850 DSAStackTy *Stack) { 11851 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11852 if (!OMPAllocatorHandleT.isNull()) 11853 return true; 11854 // Build the predefined allocator expressions. 11855 bool ErrorFound = false; 11856 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11857 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11858 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11859 StringRef Allocator = 11860 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11861 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11862 auto *VD = dyn_cast_or_null<ValueDecl>( 11863 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11864 if (!VD) { 11865 ErrorFound = true; 11866 break; 11867 } 11868 QualType AllocatorType = 11869 VD->getType().getNonLValueExprType(S.getASTContext()); 11870 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11871 if (!Res.isUsable()) { 11872 ErrorFound = true; 11873 break; 11874 } 11875 if (OMPAllocatorHandleT.isNull()) 11876 OMPAllocatorHandleT = AllocatorType; 11877 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11878 ErrorFound = true; 11879 break; 11880 } 11881 Stack->setAllocator(AllocatorKind, Res.get()); 11882 } 11883 if (ErrorFound) { 11884 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11885 return false; 11886 } 11887 OMPAllocatorHandleT.addConst(); 11888 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11889 return true; 11890 } 11891 11892 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11893 SourceLocation LParenLoc, 11894 SourceLocation EndLoc) { 11895 // OpenMP [2.11.3, allocate Directive, Description] 11896 // allocator is an expression of omp_allocator_handle_t type. 11897 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11898 return nullptr; 11899 11900 ExprResult Allocator = DefaultLvalueConversion(A); 11901 if (Allocator.isInvalid()) 11902 return nullptr; 11903 Allocator = PerformImplicitConversion(Allocator.get(), 11904 DSAStack->getOMPAllocatorHandleT(), 11905 Sema::AA_Initializing, 11906 /*AllowExplicit=*/true); 11907 if (Allocator.isInvalid()) 11908 return nullptr; 11909 return new (Context) 11910 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11911 } 11912 11913 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11914 SourceLocation StartLoc, 11915 SourceLocation LParenLoc, 11916 SourceLocation EndLoc) { 11917 // OpenMP [2.7.1, loop construct, Description] 11918 // OpenMP [2.8.1, simd construct, Description] 11919 // OpenMP [2.9.6, distribute construct, Description] 11920 // The parameter of the collapse clause must be a constant 11921 // positive integer expression. 11922 ExprResult NumForLoopsResult = 11923 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11924 if (NumForLoopsResult.isInvalid()) 11925 return nullptr; 11926 return new (Context) 11927 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11928 } 11929 11930 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11931 SourceLocation EndLoc, 11932 SourceLocation LParenLoc, 11933 Expr *NumForLoops) { 11934 // OpenMP [2.7.1, loop construct, Description] 11935 // OpenMP [2.8.1, simd construct, Description] 11936 // OpenMP [2.9.6, distribute construct, Description] 11937 // The parameter of the ordered clause must be a constant 11938 // positive integer expression if any. 11939 if (NumForLoops && LParenLoc.isValid()) { 11940 ExprResult NumForLoopsResult = 11941 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11942 if (NumForLoopsResult.isInvalid()) 11943 return nullptr; 11944 NumForLoops = NumForLoopsResult.get(); 11945 } else { 11946 NumForLoops = nullptr; 11947 } 11948 auto *Clause = OMPOrderedClause::Create( 11949 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11950 StartLoc, LParenLoc, EndLoc); 11951 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11952 return Clause; 11953 } 11954 11955 OMPClause *Sema::ActOnOpenMPSimpleClause( 11956 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11957 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11958 OMPClause *Res = nullptr; 11959 switch (Kind) { 11960 case OMPC_default: 11961 Res = 11962 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11963 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11964 break; 11965 case OMPC_proc_bind: 11966 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 11967 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11968 break; 11969 case OMPC_atomic_default_mem_order: 11970 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11971 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11972 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11973 break; 11974 case OMPC_order: 11975 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 11976 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11977 break; 11978 case OMPC_if: 11979 case OMPC_final: 11980 case OMPC_num_threads: 11981 case OMPC_safelen: 11982 case OMPC_simdlen: 11983 case OMPC_allocator: 11984 case OMPC_collapse: 11985 case OMPC_schedule: 11986 case OMPC_private: 11987 case OMPC_firstprivate: 11988 case OMPC_lastprivate: 11989 case OMPC_shared: 11990 case OMPC_reduction: 11991 case OMPC_task_reduction: 11992 case OMPC_in_reduction: 11993 case OMPC_linear: 11994 case OMPC_aligned: 11995 case OMPC_copyin: 11996 case OMPC_copyprivate: 11997 case OMPC_ordered: 11998 case OMPC_nowait: 11999 case OMPC_untied: 12000 case OMPC_mergeable: 12001 case OMPC_threadprivate: 12002 case OMPC_allocate: 12003 case OMPC_flush: 12004 case OMPC_read: 12005 case OMPC_write: 12006 case OMPC_update: 12007 case OMPC_capture: 12008 case OMPC_seq_cst: 12009 case OMPC_acq_rel: 12010 case OMPC_depend: 12011 case OMPC_device: 12012 case OMPC_threads: 12013 case OMPC_simd: 12014 case OMPC_map: 12015 case OMPC_num_teams: 12016 case OMPC_thread_limit: 12017 case OMPC_priority: 12018 case OMPC_grainsize: 12019 case OMPC_nogroup: 12020 case OMPC_num_tasks: 12021 case OMPC_hint: 12022 case OMPC_dist_schedule: 12023 case OMPC_defaultmap: 12024 case OMPC_unknown: 12025 case OMPC_uniform: 12026 case OMPC_to: 12027 case OMPC_from: 12028 case OMPC_use_device_ptr: 12029 case OMPC_is_device_ptr: 12030 case OMPC_unified_address: 12031 case OMPC_unified_shared_memory: 12032 case OMPC_reverse_offload: 12033 case OMPC_dynamic_allocators: 12034 case OMPC_device_type: 12035 case OMPC_match: 12036 case OMPC_nontemporal: 12037 llvm_unreachable("Clause is not allowed."); 12038 } 12039 return Res; 12040 } 12041 12042 static std::string 12043 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12044 ArrayRef<unsigned> Exclude = llvm::None) { 12045 SmallString<256> Buffer; 12046 llvm::raw_svector_ostream Out(Buffer); 12047 unsigned Skipped = Exclude.size(); 12048 auto S = Exclude.begin(), E = Exclude.end(); 12049 for (unsigned I = First; I < Last; ++I) { 12050 if (std::find(S, E, I) != E) { 12051 --Skipped; 12052 continue; 12053 } 12054 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12055 if (I + Skipped + 2 == Last) 12056 Out << " or "; 12057 else if (I + Skipped + 1 != Last) 12058 Out << ", "; 12059 } 12060 return std::string(Out.str()); 12061 } 12062 12063 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 12064 SourceLocation KindKwLoc, 12065 SourceLocation StartLoc, 12066 SourceLocation LParenLoc, 12067 SourceLocation EndLoc) { 12068 if (Kind == OMPC_DEFAULT_unknown) { 12069 static_assert(OMPC_DEFAULT_unknown > 0, 12070 "OMPC_DEFAULT_unknown not greater than 0"); 12071 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12072 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12073 /*Last=*/OMPC_DEFAULT_unknown) 12074 << getOpenMPClauseName(OMPC_default); 12075 return nullptr; 12076 } 12077 switch (Kind) { 12078 case OMPC_DEFAULT_none: 12079 DSAStack->setDefaultDSANone(KindKwLoc); 12080 break; 12081 case OMPC_DEFAULT_shared: 12082 DSAStack->setDefaultDSAShared(KindKwLoc); 12083 break; 12084 case OMPC_DEFAULT_unknown: 12085 llvm_unreachable("Clause kind is not allowed."); 12086 break; 12087 } 12088 return new (Context) 12089 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12090 } 12091 12092 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12093 SourceLocation KindKwLoc, 12094 SourceLocation StartLoc, 12095 SourceLocation LParenLoc, 12096 SourceLocation EndLoc) { 12097 if (Kind == OMP_PROC_BIND_unknown) { 12098 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12099 << getListOfPossibleValues(OMPC_proc_bind, 12100 /*First=*/unsigned(OMP_PROC_BIND_master), 12101 /*Last=*/5) 12102 << getOpenMPClauseName(OMPC_proc_bind); 12103 return nullptr; 12104 } 12105 return new (Context) 12106 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12107 } 12108 12109 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12110 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12111 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12112 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12113 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12114 << getListOfPossibleValues( 12115 OMPC_atomic_default_mem_order, /*First=*/0, 12116 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12117 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12118 return nullptr; 12119 } 12120 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12121 LParenLoc, EndLoc); 12122 } 12123 12124 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12125 SourceLocation KindKwLoc, 12126 SourceLocation StartLoc, 12127 SourceLocation LParenLoc, 12128 SourceLocation EndLoc) { 12129 if (Kind == OMPC_ORDER_unknown) { 12130 static_assert(OMPC_ORDER_unknown > 0, 12131 "OMPC_ORDER_unknown not greater than 0"); 12132 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12133 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12134 /*Last=*/OMPC_ORDER_unknown) 12135 << getOpenMPClauseName(OMPC_order); 12136 return nullptr; 12137 } 12138 return new (Context) 12139 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12140 } 12141 12142 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12143 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12144 SourceLocation StartLoc, SourceLocation LParenLoc, 12145 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12146 SourceLocation EndLoc) { 12147 OMPClause *Res = nullptr; 12148 switch (Kind) { 12149 case OMPC_schedule: 12150 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12151 assert(Argument.size() == NumberOfElements && 12152 ArgumentLoc.size() == NumberOfElements); 12153 Res = ActOnOpenMPScheduleClause( 12154 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12155 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12156 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12157 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12158 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12159 break; 12160 case OMPC_if: 12161 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12162 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12163 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12164 DelimLoc, EndLoc); 12165 break; 12166 case OMPC_dist_schedule: 12167 Res = ActOnOpenMPDistScheduleClause( 12168 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12169 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12170 break; 12171 case OMPC_defaultmap: 12172 enum { Modifier, DefaultmapKind }; 12173 Res = ActOnOpenMPDefaultmapClause( 12174 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12175 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12176 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12177 EndLoc); 12178 break; 12179 case OMPC_final: 12180 case OMPC_num_threads: 12181 case OMPC_safelen: 12182 case OMPC_simdlen: 12183 case OMPC_allocator: 12184 case OMPC_collapse: 12185 case OMPC_default: 12186 case OMPC_proc_bind: 12187 case OMPC_private: 12188 case OMPC_firstprivate: 12189 case OMPC_lastprivate: 12190 case OMPC_shared: 12191 case OMPC_reduction: 12192 case OMPC_task_reduction: 12193 case OMPC_in_reduction: 12194 case OMPC_linear: 12195 case OMPC_aligned: 12196 case OMPC_copyin: 12197 case OMPC_copyprivate: 12198 case OMPC_ordered: 12199 case OMPC_nowait: 12200 case OMPC_untied: 12201 case OMPC_mergeable: 12202 case OMPC_threadprivate: 12203 case OMPC_allocate: 12204 case OMPC_flush: 12205 case OMPC_read: 12206 case OMPC_write: 12207 case OMPC_update: 12208 case OMPC_capture: 12209 case OMPC_seq_cst: 12210 case OMPC_acq_rel: 12211 case OMPC_depend: 12212 case OMPC_device: 12213 case OMPC_threads: 12214 case OMPC_simd: 12215 case OMPC_map: 12216 case OMPC_num_teams: 12217 case OMPC_thread_limit: 12218 case OMPC_priority: 12219 case OMPC_grainsize: 12220 case OMPC_nogroup: 12221 case OMPC_num_tasks: 12222 case OMPC_hint: 12223 case OMPC_unknown: 12224 case OMPC_uniform: 12225 case OMPC_to: 12226 case OMPC_from: 12227 case OMPC_use_device_ptr: 12228 case OMPC_is_device_ptr: 12229 case OMPC_unified_address: 12230 case OMPC_unified_shared_memory: 12231 case OMPC_reverse_offload: 12232 case OMPC_dynamic_allocators: 12233 case OMPC_atomic_default_mem_order: 12234 case OMPC_device_type: 12235 case OMPC_match: 12236 case OMPC_nontemporal: 12237 case OMPC_order: 12238 llvm_unreachable("Clause is not allowed."); 12239 } 12240 return Res; 12241 } 12242 12243 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12244 OpenMPScheduleClauseModifier M2, 12245 SourceLocation M1Loc, SourceLocation M2Loc) { 12246 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12247 SmallVector<unsigned, 2> Excluded; 12248 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12249 Excluded.push_back(M2); 12250 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12251 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12252 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12253 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12254 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12255 << getListOfPossibleValues(OMPC_schedule, 12256 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12257 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12258 Excluded) 12259 << getOpenMPClauseName(OMPC_schedule); 12260 return true; 12261 } 12262 return false; 12263 } 12264 12265 OMPClause *Sema::ActOnOpenMPScheduleClause( 12266 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12267 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12268 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12269 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12270 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12271 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12272 return nullptr; 12273 // OpenMP, 2.7.1, Loop Construct, Restrictions 12274 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12275 // but not both. 12276 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12277 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12278 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12279 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12280 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12281 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12282 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12283 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12284 return nullptr; 12285 } 12286 if (Kind == OMPC_SCHEDULE_unknown) { 12287 std::string Values; 12288 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12289 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12290 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12291 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12292 Exclude); 12293 } else { 12294 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12295 /*Last=*/OMPC_SCHEDULE_unknown); 12296 } 12297 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12298 << Values << getOpenMPClauseName(OMPC_schedule); 12299 return nullptr; 12300 } 12301 // OpenMP, 2.7.1, Loop Construct, Restrictions 12302 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12303 // schedule(guided). 12304 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12305 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12306 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12307 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12308 diag::err_omp_schedule_nonmonotonic_static); 12309 return nullptr; 12310 } 12311 Expr *ValExpr = ChunkSize; 12312 Stmt *HelperValStmt = nullptr; 12313 if (ChunkSize) { 12314 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12315 !ChunkSize->isInstantiationDependent() && 12316 !ChunkSize->containsUnexpandedParameterPack()) { 12317 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12318 ExprResult Val = 12319 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12320 if (Val.isInvalid()) 12321 return nullptr; 12322 12323 ValExpr = Val.get(); 12324 12325 // OpenMP [2.7.1, Restrictions] 12326 // chunk_size must be a loop invariant integer expression with a positive 12327 // value. 12328 llvm::APSInt Result; 12329 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12330 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12331 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12332 << "schedule" << 1 << ChunkSize->getSourceRange(); 12333 return nullptr; 12334 } 12335 } else if (getOpenMPCaptureRegionForClause( 12336 DSAStack->getCurrentDirective(), OMPC_schedule, 12337 LangOpts.OpenMP) != OMPD_unknown && 12338 !CurContext->isDependentContext()) { 12339 ValExpr = MakeFullExpr(ValExpr).get(); 12340 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12341 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12342 HelperValStmt = buildPreInits(Context, Captures); 12343 } 12344 } 12345 } 12346 12347 return new (Context) 12348 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12349 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12350 } 12351 12352 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12353 SourceLocation StartLoc, 12354 SourceLocation EndLoc) { 12355 OMPClause *Res = nullptr; 12356 switch (Kind) { 12357 case OMPC_ordered: 12358 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12359 break; 12360 case OMPC_nowait: 12361 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12362 break; 12363 case OMPC_untied: 12364 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12365 break; 12366 case OMPC_mergeable: 12367 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12368 break; 12369 case OMPC_read: 12370 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12371 break; 12372 case OMPC_write: 12373 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12374 break; 12375 case OMPC_update: 12376 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12377 break; 12378 case OMPC_capture: 12379 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12380 break; 12381 case OMPC_seq_cst: 12382 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12383 break; 12384 case OMPC_acq_rel: 12385 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 12386 break; 12387 case OMPC_threads: 12388 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12389 break; 12390 case OMPC_simd: 12391 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12392 break; 12393 case OMPC_nogroup: 12394 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12395 break; 12396 case OMPC_unified_address: 12397 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12398 break; 12399 case OMPC_unified_shared_memory: 12400 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12401 break; 12402 case OMPC_reverse_offload: 12403 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12404 break; 12405 case OMPC_dynamic_allocators: 12406 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12407 break; 12408 case OMPC_if: 12409 case OMPC_final: 12410 case OMPC_num_threads: 12411 case OMPC_safelen: 12412 case OMPC_simdlen: 12413 case OMPC_allocator: 12414 case OMPC_collapse: 12415 case OMPC_schedule: 12416 case OMPC_private: 12417 case OMPC_firstprivate: 12418 case OMPC_lastprivate: 12419 case OMPC_shared: 12420 case OMPC_reduction: 12421 case OMPC_task_reduction: 12422 case OMPC_in_reduction: 12423 case OMPC_linear: 12424 case OMPC_aligned: 12425 case OMPC_copyin: 12426 case OMPC_copyprivate: 12427 case OMPC_default: 12428 case OMPC_proc_bind: 12429 case OMPC_threadprivate: 12430 case OMPC_allocate: 12431 case OMPC_flush: 12432 case OMPC_depend: 12433 case OMPC_device: 12434 case OMPC_map: 12435 case OMPC_num_teams: 12436 case OMPC_thread_limit: 12437 case OMPC_priority: 12438 case OMPC_grainsize: 12439 case OMPC_num_tasks: 12440 case OMPC_hint: 12441 case OMPC_dist_schedule: 12442 case OMPC_defaultmap: 12443 case OMPC_unknown: 12444 case OMPC_uniform: 12445 case OMPC_to: 12446 case OMPC_from: 12447 case OMPC_use_device_ptr: 12448 case OMPC_is_device_ptr: 12449 case OMPC_atomic_default_mem_order: 12450 case OMPC_device_type: 12451 case OMPC_match: 12452 case OMPC_nontemporal: 12453 case OMPC_order: 12454 llvm_unreachable("Clause is not allowed."); 12455 } 12456 return Res; 12457 } 12458 12459 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12460 SourceLocation EndLoc) { 12461 DSAStack->setNowaitRegion(); 12462 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12463 } 12464 12465 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12466 SourceLocation EndLoc) { 12467 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12468 } 12469 12470 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12471 SourceLocation EndLoc) { 12472 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12473 } 12474 12475 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12476 SourceLocation EndLoc) { 12477 return new (Context) OMPReadClause(StartLoc, EndLoc); 12478 } 12479 12480 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12481 SourceLocation EndLoc) { 12482 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12483 } 12484 12485 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12486 SourceLocation EndLoc) { 12487 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 12488 } 12489 12490 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12491 SourceLocation EndLoc) { 12492 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12493 } 12494 12495 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12496 SourceLocation EndLoc) { 12497 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12498 } 12499 12500 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 12501 SourceLocation EndLoc) { 12502 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 12503 } 12504 12505 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 12506 SourceLocation EndLoc) { 12507 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 12508 } 12509 12510 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 12511 SourceLocation EndLoc) { 12512 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 12513 } 12514 12515 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 12516 SourceLocation EndLoc) { 12517 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 12518 } 12519 12520 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 12521 SourceLocation EndLoc) { 12522 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 12523 } 12524 12525 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 12526 SourceLocation EndLoc) { 12527 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12528 } 12529 12530 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 12531 SourceLocation EndLoc) { 12532 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 12533 } 12534 12535 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 12536 SourceLocation EndLoc) { 12537 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 12538 } 12539 12540 OMPClause *Sema::ActOnOpenMPVarListClause( 12541 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12542 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12543 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12544 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 12545 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12546 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 12547 SourceLocation DepLinMapLastLoc) { 12548 SourceLocation StartLoc = Locs.StartLoc; 12549 SourceLocation LParenLoc = Locs.LParenLoc; 12550 SourceLocation EndLoc = Locs.EndLoc; 12551 OMPClause *Res = nullptr; 12552 switch (Kind) { 12553 case OMPC_private: 12554 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12555 break; 12556 case OMPC_firstprivate: 12557 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12558 break; 12559 case OMPC_lastprivate: 12560 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 12561 "Unexpected lastprivate modifier."); 12562 Res = ActOnOpenMPLastprivateClause( 12563 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 12564 DepLinMapLastLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 12565 break; 12566 case OMPC_shared: 12567 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12568 break; 12569 case OMPC_reduction: 12570 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12571 EndLoc, ReductionOrMapperIdScopeSpec, 12572 ReductionOrMapperId); 12573 break; 12574 case OMPC_task_reduction: 12575 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12576 EndLoc, ReductionOrMapperIdScopeSpec, 12577 ReductionOrMapperId); 12578 break; 12579 case OMPC_in_reduction: 12580 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12581 EndLoc, ReductionOrMapperIdScopeSpec, 12582 ReductionOrMapperId); 12583 break; 12584 case OMPC_linear: 12585 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 12586 "Unexpected linear modifier."); 12587 Res = ActOnOpenMPLinearClause( 12588 VarList, TailExpr, StartLoc, LParenLoc, 12589 static_cast<OpenMPLinearClauseKind>(ExtraModifier), DepLinMapLastLoc, 12590 ColonLoc, EndLoc); 12591 break; 12592 case OMPC_aligned: 12593 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12594 ColonLoc, EndLoc); 12595 break; 12596 case OMPC_copyin: 12597 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12598 break; 12599 case OMPC_copyprivate: 12600 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12601 break; 12602 case OMPC_flush: 12603 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12604 break; 12605 case OMPC_depend: 12606 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 12607 "Unexpected depend modifier."); 12608 Res = ActOnOpenMPDependClause( 12609 static_cast<OpenMPDependClauseKind>(ExtraModifier), DepLinMapLastLoc, 12610 ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 12611 break; 12612 case OMPC_map: 12613 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 12614 "Unexpected map modifier."); 12615 Res = ActOnOpenMPMapClause( 12616 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 12617 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 12618 IsMapTypeImplicit, DepLinMapLastLoc, ColonLoc, VarList, Locs); 12619 break; 12620 case OMPC_to: 12621 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12622 ReductionOrMapperId, Locs); 12623 break; 12624 case OMPC_from: 12625 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12626 ReductionOrMapperId, Locs); 12627 break; 12628 case OMPC_use_device_ptr: 12629 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12630 break; 12631 case OMPC_is_device_ptr: 12632 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12633 break; 12634 case OMPC_allocate: 12635 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12636 ColonLoc, EndLoc); 12637 break; 12638 case OMPC_nontemporal: 12639 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 12640 break; 12641 case OMPC_if: 12642 case OMPC_final: 12643 case OMPC_num_threads: 12644 case OMPC_safelen: 12645 case OMPC_simdlen: 12646 case OMPC_allocator: 12647 case OMPC_collapse: 12648 case OMPC_default: 12649 case OMPC_proc_bind: 12650 case OMPC_schedule: 12651 case OMPC_ordered: 12652 case OMPC_nowait: 12653 case OMPC_untied: 12654 case OMPC_mergeable: 12655 case OMPC_threadprivate: 12656 case OMPC_read: 12657 case OMPC_write: 12658 case OMPC_update: 12659 case OMPC_capture: 12660 case OMPC_seq_cst: 12661 case OMPC_acq_rel: 12662 case OMPC_device: 12663 case OMPC_threads: 12664 case OMPC_simd: 12665 case OMPC_num_teams: 12666 case OMPC_thread_limit: 12667 case OMPC_priority: 12668 case OMPC_grainsize: 12669 case OMPC_nogroup: 12670 case OMPC_num_tasks: 12671 case OMPC_hint: 12672 case OMPC_dist_schedule: 12673 case OMPC_defaultmap: 12674 case OMPC_unknown: 12675 case OMPC_uniform: 12676 case OMPC_unified_address: 12677 case OMPC_unified_shared_memory: 12678 case OMPC_reverse_offload: 12679 case OMPC_dynamic_allocators: 12680 case OMPC_atomic_default_mem_order: 12681 case OMPC_device_type: 12682 case OMPC_match: 12683 case OMPC_order: 12684 llvm_unreachable("Clause is not allowed."); 12685 } 12686 return Res; 12687 } 12688 12689 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12690 ExprObjectKind OK, SourceLocation Loc) { 12691 ExprResult Res = BuildDeclRefExpr( 12692 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12693 if (!Res.isUsable()) 12694 return ExprError(); 12695 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12696 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12697 if (!Res.isUsable()) 12698 return ExprError(); 12699 } 12700 if (VK != VK_LValue && Res.get()->isGLValue()) { 12701 Res = DefaultLvalueConversion(Res.get()); 12702 if (!Res.isUsable()) 12703 return ExprError(); 12704 } 12705 return Res; 12706 } 12707 12708 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12709 SourceLocation StartLoc, 12710 SourceLocation LParenLoc, 12711 SourceLocation EndLoc) { 12712 SmallVector<Expr *, 8> Vars; 12713 SmallVector<Expr *, 8> PrivateCopies; 12714 for (Expr *RefExpr : VarList) { 12715 assert(RefExpr && "NULL expr in OpenMP private clause."); 12716 SourceLocation ELoc; 12717 SourceRange ERange; 12718 Expr *SimpleRefExpr = RefExpr; 12719 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12720 if (Res.second) { 12721 // It will be analyzed later. 12722 Vars.push_back(RefExpr); 12723 PrivateCopies.push_back(nullptr); 12724 } 12725 ValueDecl *D = Res.first; 12726 if (!D) 12727 continue; 12728 12729 QualType Type = D->getType(); 12730 auto *VD = dyn_cast<VarDecl>(D); 12731 12732 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12733 // A variable that appears in a private clause must not have an incomplete 12734 // type or a reference type. 12735 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12736 continue; 12737 Type = Type.getNonReferenceType(); 12738 12739 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12740 // A variable that is privatized must not have a const-qualified type 12741 // unless it is of class type with a mutable member. This restriction does 12742 // not apply to the firstprivate clause. 12743 // 12744 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12745 // A variable that appears in a private clause must not have a 12746 // const-qualified type unless it is of class type with a mutable member. 12747 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12748 continue; 12749 12750 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12751 // in a Construct] 12752 // Variables with the predetermined data-sharing attributes may not be 12753 // listed in data-sharing attributes clauses, except for the cases 12754 // listed below. For these exceptions only, listing a predetermined 12755 // variable in a data-sharing attribute clause is allowed and overrides 12756 // the variable's predetermined data-sharing attributes. 12757 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12758 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12759 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12760 << getOpenMPClauseName(OMPC_private); 12761 reportOriginalDsa(*this, DSAStack, D, DVar); 12762 continue; 12763 } 12764 12765 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12766 // Variably modified types are not supported for tasks. 12767 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12768 isOpenMPTaskingDirective(CurrDir)) { 12769 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12770 << getOpenMPClauseName(OMPC_private) << Type 12771 << getOpenMPDirectiveName(CurrDir); 12772 bool IsDecl = 12773 !VD || 12774 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12775 Diag(D->getLocation(), 12776 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12777 << D; 12778 continue; 12779 } 12780 12781 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12782 // A list item cannot appear in both a map clause and a data-sharing 12783 // attribute clause on the same construct 12784 // 12785 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12786 // A list item cannot appear in both a map clause and a data-sharing 12787 // attribute clause on the same construct unless the construct is a 12788 // combined construct. 12789 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12790 CurrDir == OMPD_target) { 12791 OpenMPClauseKind ConflictKind; 12792 if (DSAStack->checkMappableExprComponentListsForDecl( 12793 VD, /*CurrentRegionOnly=*/true, 12794 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12795 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12796 ConflictKind = WhereFoundClauseKind; 12797 return true; 12798 })) { 12799 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12800 << getOpenMPClauseName(OMPC_private) 12801 << getOpenMPClauseName(ConflictKind) 12802 << getOpenMPDirectiveName(CurrDir); 12803 reportOriginalDsa(*this, DSAStack, D, DVar); 12804 continue; 12805 } 12806 } 12807 12808 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12809 // A variable of class type (or array thereof) that appears in a private 12810 // clause requires an accessible, unambiguous default constructor for the 12811 // class type. 12812 // Generate helper private variable and initialize it with the default 12813 // value. The address of the original variable is replaced by the address of 12814 // the new private variable in CodeGen. This new variable is not added to 12815 // IdResolver, so the code in the OpenMP region uses original variable for 12816 // proper diagnostics. 12817 Type = Type.getUnqualifiedType(); 12818 VarDecl *VDPrivate = 12819 buildVarDecl(*this, ELoc, Type, D->getName(), 12820 D->hasAttrs() ? &D->getAttrs() : nullptr, 12821 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12822 ActOnUninitializedDecl(VDPrivate); 12823 if (VDPrivate->isInvalidDecl()) 12824 continue; 12825 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12826 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12827 12828 DeclRefExpr *Ref = nullptr; 12829 if (!VD && !CurContext->isDependentContext()) 12830 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12831 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12832 Vars.push_back((VD || CurContext->isDependentContext()) 12833 ? RefExpr->IgnoreParens() 12834 : Ref); 12835 PrivateCopies.push_back(VDPrivateRefExpr); 12836 } 12837 12838 if (Vars.empty()) 12839 return nullptr; 12840 12841 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12842 PrivateCopies); 12843 } 12844 12845 namespace { 12846 class DiagsUninitializedSeveretyRAII { 12847 private: 12848 DiagnosticsEngine &Diags; 12849 SourceLocation SavedLoc; 12850 bool IsIgnored = false; 12851 12852 public: 12853 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12854 bool IsIgnored) 12855 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12856 if (!IsIgnored) { 12857 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12858 /*Map*/ diag::Severity::Ignored, Loc); 12859 } 12860 } 12861 ~DiagsUninitializedSeveretyRAII() { 12862 if (!IsIgnored) 12863 Diags.popMappings(SavedLoc); 12864 } 12865 }; 12866 } 12867 12868 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12869 SourceLocation StartLoc, 12870 SourceLocation LParenLoc, 12871 SourceLocation EndLoc) { 12872 SmallVector<Expr *, 8> Vars; 12873 SmallVector<Expr *, 8> PrivateCopies; 12874 SmallVector<Expr *, 8> Inits; 12875 SmallVector<Decl *, 4> ExprCaptures; 12876 bool IsImplicitClause = 12877 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12878 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12879 12880 for (Expr *RefExpr : VarList) { 12881 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12882 SourceLocation ELoc; 12883 SourceRange ERange; 12884 Expr *SimpleRefExpr = RefExpr; 12885 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12886 if (Res.second) { 12887 // It will be analyzed later. 12888 Vars.push_back(RefExpr); 12889 PrivateCopies.push_back(nullptr); 12890 Inits.push_back(nullptr); 12891 } 12892 ValueDecl *D = Res.first; 12893 if (!D) 12894 continue; 12895 12896 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12897 QualType Type = D->getType(); 12898 auto *VD = dyn_cast<VarDecl>(D); 12899 12900 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12901 // A variable that appears in a private clause must not have an incomplete 12902 // type or a reference type. 12903 if (RequireCompleteType(ELoc, Type, 12904 diag::err_omp_firstprivate_incomplete_type)) 12905 continue; 12906 Type = Type.getNonReferenceType(); 12907 12908 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12909 // A variable of class type (or array thereof) that appears in a private 12910 // clause requires an accessible, unambiguous copy constructor for the 12911 // class type. 12912 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12913 12914 // If an implicit firstprivate variable found it was checked already. 12915 DSAStackTy::DSAVarData TopDVar; 12916 if (!IsImplicitClause) { 12917 DSAStackTy::DSAVarData DVar = 12918 DSAStack->getTopDSA(D, /*FromParent=*/false); 12919 TopDVar = DVar; 12920 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12921 bool IsConstant = ElemType.isConstant(Context); 12922 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12923 // A list item that specifies a given variable may not appear in more 12924 // than one clause on the same directive, except that a variable may be 12925 // specified in both firstprivate and lastprivate clauses. 12926 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12927 // A list item may appear in a firstprivate or lastprivate clause but not 12928 // both. 12929 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12930 (isOpenMPDistributeDirective(CurrDir) || 12931 DVar.CKind != OMPC_lastprivate) && 12932 DVar.RefExpr) { 12933 Diag(ELoc, diag::err_omp_wrong_dsa) 12934 << getOpenMPClauseName(DVar.CKind) 12935 << getOpenMPClauseName(OMPC_firstprivate); 12936 reportOriginalDsa(*this, DSAStack, D, DVar); 12937 continue; 12938 } 12939 12940 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12941 // in a Construct] 12942 // Variables with the predetermined data-sharing attributes may not be 12943 // listed in data-sharing attributes clauses, except for the cases 12944 // listed below. For these exceptions only, listing a predetermined 12945 // variable in a data-sharing attribute clause is allowed and overrides 12946 // the variable's predetermined data-sharing attributes. 12947 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12948 // in a Construct, C/C++, p.2] 12949 // Variables with const-qualified type having no mutable member may be 12950 // listed in a firstprivate clause, even if they are static data members. 12951 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12952 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12953 Diag(ELoc, diag::err_omp_wrong_dsa) 12954 << getOpenMPClauseName(DVar.CKind) 12955 << getOpenMPClauseName(OMPC_firstprivate); 12956 reportOriginalDsa(*this, DSAStack, D, DVar); 12957 continue; 12958 } 12959 12960 // OpenMP [2.9.3.4, Restrictions, p.2] 12961 // A list item that is private within a parallel region must not appear 12962 // in a firstprivate clause on a worksharing construct if any of the 12963 // worksharing regions arising from the worksharing construct ever bind 12964 // to any of the parallel regions arising from the parallel construct. 12965 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12966 // A list item that is private within a teams region must not appear in a 12967 // firstprivate clause on a distribute construct if any of the distribute 12968 // regions arising from the distribute construct ever bind to any of the 12969 // teams regions arising from the teams construct. 12970 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12971 // A list item that appears in a reduction clause of a teams construct 12972 // must not appear in a firstprivate clause on a distribute construct if 12973 // any of the distribute regions arising from the distribute construct 12974 // ever bind to any of the teams regions arising from the teams construct. 12975 if ((isOpenMPWorksharingDirective(CurrDir) || 12976 isOpenMPDistributeDirective(CurrDir)) && 12977 !isOpenMPParallelDirective(CurrDir) && 12978 !isOpenMPTeamsDirective(CurrDir)) { 12979 DVar = DSAStack->getImplicitDSA(D, true); 12980 if (DVar.CKind != OMPC_shared && 12981 (isOpenMPParallelDirective(DVar.DKind) || 12982 isOpenMPTeamsDirective(DVar.DKind) || 12983 DVar.DKind == OMPD_unknown)) { 12984 Diag(ELoc, diag::err_omp_required_access) 12985 << getOpenMPClauseName(OMPC_firstprivate) 12986 << getOpenMPClauseName(OMPC_shared); 12987 reportOriginalDsa(*this, DSAStack, D, DVar); 12988 continue; 12989 } 12990 } 12991 // OpenMP [2.9.3.4, Restrictions, p.3] 12992 // A list item that appears in a reduction clause of a parallel construct 12993 // must not appear in a firstprivate clause on a worksharing or task 12994 // construct if any of the worksharing or task regions arising from the 12995 // worksharing or task construct ever bind to any of the parallel regions 12996 // arising from the parallel construct. 12997 // OpenMP [2.9.3.4, Restrictions, p.4] 12998 // A list item that appears in a reduction clause in worksharing 12999 // construct must not appear in a firstprivate clause in a task construct 13000 // encountered during execution of any of the worksharing regions arising 13001 // from the worksharing construct. 13002 if (isOpenMPTaskingDirective(CurrDir)) { 13003 DVar = DSAStack->hasInnermostDSA( 13004 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13005 [](OpenMPDirectiveKind K) { 13006 return isOpenMPParallelDirective(K) || 13007 isOpenMPWorksharingDirective(K) || 13008 isOpenMPTeamsDirective(K); 13009 }, 13010 /*FromParent=*/true); 13011 if (DVar.CKind == OMPC_reduction && 13012 (isOpenMPParallelDirective(DVar.DKind) || 13013 isOpenMPWorksharingDirective(DVar.DKind) || 13014 isOpenMPTeamsDirective(DVar.DKind))) { 13015 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13016 << getOpenMPDirectiveName(DVar.DKind); 13017 reportOriginalDsa(*this, DSAStack, D, DVar); 13018 continue; 13019 } 13020 } 13021 13022 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13023 // A list item cannot appear in both a map clause and a data-sharing 13024 // attribute clause on the same construct 13025 // 13026 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13027 // A list item cannot appear in both a map clause and a data-sharing 13028 // attribute clause on the same construct unless the construct is a 13029 // combined construct. 13030 if ((LangOpts.OpenMP <= 45 && 13031 isOpenMPTargetExecutionDirective(CurrDir)) || 13032 CurrDir == OMPD_target) { 13033 OpenMPClauseKind ConflictKind; 13034 if (DSAStack->checkMappableExprComponentListsForDecl( 13035 VD, /*CurrentRegionOnly=*/true, 13036 [&ConflictKind]( 13037 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13038 OpenMPClauseKind WhereFoundClauseKind) { 13039 ConflictKind = WhereFoundClauseKind; 13040 return true; 13041 })) { 13042 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13043 << getOpenMPClauseName(OMPC_firstprivate) 13044 << getOpenMPClauseName(ConflictKind) 13045 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13046 reportOriginalDsa(*this, DSAStack, D, DVar); 13047 continue; 13048 } 13049 } 13050 } 13051 13052 // Variably modified types are not supported for tasks. 13053 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13054 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13055 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13056 << getOpenMPClauseName(OMPC_firstprivate) << Type 13057 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13058 bool IsDecl = 13059 !VD || 13060 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13061 Diag(D->getLocation(), 13062 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13063 << D; 13064 continue; 13065 } 13066 13067 Type = Type.getUnqualifiedType(); 13068 VarDecl *VDPrivate = 13069 buildVarDecl(*this, ELoc, Type, D->getName(), 13070 D->hasAttrs() ? &D->getAttrs() : nullptr, 13071 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13072 // Generate helper private variable and initialize it with the value of the 13073 // original variable. The address of the original variable is replaced by 13074 // the address of the new private variable in the CodeGen. This new variable 13075 // is not added to IdResolver, so the code in the OpenMP region uses 13076 // original variable for proper diagnostics and variable capturing. 13077 Expr *VDInitRefExpr = nullptr; 13078 // For arrays generate initializer for single element and replace it by the 13079 // original array element in CodeGen. 13080 if (Type->isArrayType()) { 13081 VarDecl *VDInit = 13082 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13083 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13084 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13085 ElemType = ElemType.getUnqualifiedType(); 13086 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13087 ".firstprivate.temp"); 13088 InitializedEntity Entity = 13089 InitializedEntity::InitializeVariable(VDInitTemp); 13090 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13091 13092 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13093 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13094 if (Result.isInvalid()) 13095 VDPrivate->setInvalidDecl(); 13096 else 13097 VDPrivate->setInit(Result.getAs<Expr>()); 13098 // Remove temp variable declaration. 13099 Context.Deallocate(VDInitTemp); 13100 } else { 13101 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13102 ".firstprivate.temp"); 13103 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13104 RefExpr->getExprLoc()); 13105 AddInitializerToDecl(VDPrivate, 13106 DefaultLvalueConversion(VDInitRefExpr).get(), 13107 /*DirectInit=*/false); 13108 } 13109 if (VDPrivate->isInvalidDecl()) { 13110 if (IsImplicitClause) { 13111 Diag(RefExpr->getExprLoc(), 13112 diag::note_omp_task_predetermined_firstprivate_here); 13113 } 13114 continue; 13115 } 13116 CurContext->addDecl(VDPrivate); 13117 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13118 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13119 RefExpr->getExprLoc()); 13120 DeclRefExpr *Ref = nullptr; 13121 if (!VD && !CurContext->isDependentContext()) { 13122 if (TopDVar.CKind == OMPC_lastprivate) { 13123 Ref = TopDVar.PrivateCopy; 13124 } else { 13125 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13126 if (!isOpenMPCapturedDecl(D)) 13127 ExprCaptures.push_back(Ref->getDecl()); 13128 } 13129 } 13130 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13131 Vars.push_back((VD || CurContext->isDependentContext()) 13132 ? RefExpr->IgnoreParens() 13133 : Ref); 13134 PrivateCopies.push_back(VDPrivateRefExpr); 13135 Inits.push_back(VDInitRefExpr); 13136 } 13137 13138 if (Vars.empty()) 13139 return nullptr; 13140 13141 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13142 Vars, PrivateCopies, Inits, 13143 buildPreInits(Context, ExprCaptures)); 13144 } 13145 13146 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13147 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13148 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13149 SourceLocation LParenLoc, SourceLocation EndLoc) { 13150 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13151 assert(ColonLoc.isValid() && "Colon location must be valid."); 13152 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13153 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13154 /*Last=*/OMPC_LASTPRIVATE_unknown) 13155 << getOpenMPClauseName(OMPC_lastprivate); 13156 return nullptr; 13157 } 13158 13159 SmallVector<Expr *, 8> Vars; 13160 SmallVector<Expr *, 8> SrcExprs; 13161 SmallVector<Expr *, 8> DstExprs; 13162 SmallVector<Expr *, 8> AssignmentOps; 13163 SmallVector<Decl *, 4> ExprCaptures; 13164 SmallVector<Expr *, 4> ExprPostUpdates; 13165 for (Expr *RefExpr : VarList) { 13166 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13167 SourceLocation ELoc; 13168 SourceRange ERange; 13169 Expr *SimpleRefExpr = RefExpr; 13170 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13171 if (Res.second) { 13172 // It will be analyzed later. 13173 Vars.push_back(RefExpr); 13174 SrcExprs.push_back(nullptr); 13175 DstExprs.push_back(nullptr); 13176 AssignmentOps.push_back(nullptr); 13177 } 13178 ValueDecl *D = Res.first; 13179 if (!D) 13180 continue; 13181 13182 QualType Type = D->getType(); 13183 auto *VD = dyn_cast<VarDecl>(D); 13184 13185 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13186 // A variable that appears in a lastprivate clause must not have an 13187 // incomplete type or a reference type. 13188 if (RequireCompleteType(ELoc, Type, 13189 diag::err_omp_lastprivate_incomplete_type)) 13190 continue; 13191 Type = Type.getNonReferenceType(); 13192 13193 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13194 // A variable that is privatized must not have a const-qualified type 13195 // unless it is of class type with a mutable member. This restriction does 13196 // not apply to the firstprivate clause. 13197 // 13198 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13199 // A variable that appears in a lastprivate clause must not have a 13200 // const-qualified type unless it is of class type with a mutable member. 13201 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13202 continue; 13203 13204 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13205 // A list item that appears in a lastprivate clause with the conditional 13206 // modifier must be a scalar variable. 13207 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13208 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13209 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13210 VarDecl::DeclarationOnly; 13211 Diag(D->getLocation(), 13212 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13213 << D; 13214 continue; 13215 } 13216 13217 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13218 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13219 // in a Construct] 13220 // Variables with the predetermined data-sharing attributes may not be 13221 // listed in data-sharing attributes clauses, except for the cases 13222 // listed below. 13223 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13224 // A list item may appear in a firstprivate or lastprivate clause but not 13225 // both. 13226 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13227 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13228 (isOpenMPDistributeDirective(CurrDir) || 13229 DVar.CKind != OMPC_firstprivate) && 13230 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13231 Diag(ELoc, diag::err_omp_wrong_dsa) 13232 << getOpenMPClauseName(DVar.CKind) 13233 << getOpenMPClauseName(OMPC_lastprivate); 13234 reportOriginalDsa(*this, DSAStack, D, DVar); 13235 continue; 13236 } 13237 13238 // OpenMP [2.14.3.5, Restrictions, p.2] 13239 // A list item that is private within a parallel region, or that appears in 13240 // the reduction clause of a parallel construct, must not appear in a 13241 // lastprivate clause on a worksharing construct if any of the corresponding 13242 // worksharing regions ever binds to any of the corresponding parallel 13243 // regions. 13244 DSAStackTy::DSAVarData TopDVar = DVar; 13245 if (isOpenMPWorksharingDirective(CurrDir) && 13246 !isOpenMPParallelDirective(CurrDir) && 13247 !isOpenMPTeamsDirective(CurrDir)) { 13248 DVar = DSAStack->getImplicitDSA(D, true); 13249 if (DVar.CKind != OMPC_shared) { 13250 Diag(ELoc, diag::err_omp_required_access) 13251 << getOpenMPClauseName(OMPC_lastprivate) 13252 << getOpenMPClauseName(OMPC_shared); 13253 reportOriginalDsa(*this, DSAStack, D, DVar); 13254 continue; 13255 } 13256 } 13257 13258 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13259 // A variable of class type (or array thereof) that appears in a 13260 // lastprivate clause requires an accessible, unambiguous default 13261 // constructor for the class type, unless the list item is also specified 13262 // in a firstprivate clause. 13263 // A variable of class type (or array thereof) that appears in a 13264 // lastprivate clause requires an accessible, unambiguous copy assignment 13265 // operator for the class type. 13266 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13267 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13268 Type.getUnqualifiedType(), ".lastprivate.src", 13269 D->hasAttrs() ? &D->getAttrs() : nullptr); 13270 DeclRefExpr *PseudoSrcExpr = 13271 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13272 VarDecl *DstVD = 13273 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13274 D->hasAttrs() ? &D->getAttrs() : nullptr); 13275 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13276 // For arrays generate assignment operation for single element and replace 13277 // it by the original array element in CodeGen. 13278 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13279 PseudoDstExpr, PseudoSrcExpr); 13280 if (AssignmentOp.isInvalid()) 13281 continue; 13282 AssignmentOp = 13283 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13284 if (AssignmentOp.isInvalid()) 13285 continue; 13286 13287 DeclRefExpr *Ref = nullptr; 13288 if (!VD && !CurContext->isDependentContext()) { 13289 if (TopDVar.CKind == OMPC_firstprivate) { 13290 Ref = TopDVar.PrivateCopy; 13291 } else { 13292 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13293 if (!isOpenMPCapturedDecl(D)) 13294 ExprCaptures.push_back(Ref->getDecl()); 13295 } 13296 if (TopDVar.CKind == OMPC_firstprivate || 13297 (!isOpenMPCapturedDecl(D) && 13298 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13299 ExprResult RefRes = DefaultLvalueConversion(Ref); 13300 if (!RefRes.isUsable()) 13301 continue; 13302 ExprResult PostUpdateRes = 13303 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13304 RefRes.get()); 13305 if (!PostUpdateRes.isUsable()) 13306 continue; 13307 ExprPostUpdates.push_back( 13308 IgnoredValueConversions(PostUpdateRes.get()).get()); 13309 } 13310 } 13311 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13312 Vars.push_back((VD || CurContext->isDependentContext()) 13313 ? RefExpr->IgnoreParens() 13314 : Ref); 13315 SrcExprs.push_back(PseudoSrcExpr); 13316 DstExprs.push_back(PseudoDstExpr); 13317 AssignmentOps.push_back(AssignmentOp.get()); 13318 } 13319 13320 if (Vars.empty()) 13321 return nullptr; 13322 13323 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13324 Vars, SrcExprs, DstExprs, AssignmentOps, 13325 LPKind, LPKindLoc, ColonLoc, 13326 buildPreInits(Context, ExprCaptures), 13327 buildPostUpdate(*this, ExprPostUpdates)); 13328 } 13329 13330 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13331 SourceLocation StartLoc, 13332 SourceLocation LParenLoc, 13333 SourceLocation EndLoc) { 13334 SmallVector<Expr *, 8> Vars; 13335 for (Expr *RefExpr : VarList) { 13336 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13337 SourceLocation ELoc; 13338 SourceRange ERange; 13339 Expr *SimpleRefExpr = RefExpr; 13340 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13341 if (Res.second) { 13342 // It will be analyzed later. 13343 Vars.push_back(RefExpr); 13344 } 13345 ValueDecl *D = Res.first; 13346 if (!D) 13347 continue; 13348 13349 auto *VD = dyn_cast<VarDecl>(D); 13350 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13351 // in a Construct] 13352 // Variables with the predetermined data-sharing attributes may not be 13353 // listed in data-sharing attributes clauses, except for the cases 13354 // listed below. For these exceptions only, listing a predetermined 13355 // variable in a data-sharing attribute clause is allowed and overrides 13356 // the variable's predetermined data-sharing attributes. 13357 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13358 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13359 DVar.RefExpr) { 13360 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13361 << getOpenMPClauseName(OMPC_shared); 13362 reportOriginalDsa(*this, DSAStack, D, DVar); 13363 continue; 13364 } 13365 13366 DeclRefExpr *Ref = nullptr; 13367 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13368 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13369 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13370 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13371 ? RefExpr->IgnoreParens() 13372 : Ref); 13373 } 13374 13375 if (Vars.empty()) 13376 return nullptr; 13377 13378 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13379 } 13380 13381 namespace { 13382 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13383 DSAStackTy *Stack; 13384 13385 public: 13386 bool VisitDeclRefExpr(DeclRefExpr *E) { 13387 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13388 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13389 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13390 return false; 13391 if (DVar.CKind != OMPC_unknown) 13392 return true; 13393 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13394 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13395 /*FromParent=*/true); 13396 return DVarPrivate.CKind != OMPC_unknown; 13397 } 13398 return false; 13399 } 13400 bool VisitStmt(Stmt *S) { 13401 for (Stmt *Child : S->children()) { 13402 if (Child && Visit(Child)) 13403 return true; 13404 } 13405 return false; 13406 } 13407 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13408 }; 13409 } // namespace 13410 13411 namespace { 13412 // Transform MemberExpression for specified FieldDecl of current class to 13413 // DeclRefExpr to specified OMPCapturedExprDecl. 13414 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13415 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13416 ValueDecl *Field = nullptr; 13417 DeclRefExpr *CapturedExpr = nullptr; 13418 13419 public: 13420 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13421 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13422 13423 ExprResult TransformMemberExpr(MemberExpr *E) { 13424 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13425 E->getMemberDecl() == Field) { 13426 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13427 return CapturedExpr; 13428 } 13429 return BaseTransform::TransformMemberExpr(E); 13430 } 13431 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13432 }; 13433 } // namespace 13434 13435 template <typename T, typename U> 13436 static T filterLookupForUDReductionAndMapper( 13437 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13438 for (U &Set : Lookups) { 13439 for (auto *D : Set) { 13440 if (T Res = Gen(cast<ValueDecl>(D))) 13441 return Res; 13442 } 13443 } 13444 return T(); 13445 } 13446 13447 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13448 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13449 13450 for (auto RD : D->redecls()) { 13451 // Don't bother with extra checks if we already know this one isn't visible. 13452 if (RD == D) 13453 continue; 13454 13455 auto ND = cast<NamedDecl>(RD); 13456 if (LookupResult::isVisible(SemaRef, ND)) 13457 return ND; 13458 } 13459 13460 return nullptr; 13461 } 13462 13463 static void 13464 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13465 SourceLocation Loc, QualType Ty, 13466 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13467 // Find all of the associated namespaces and classes based on the 13468 // arguments we have. 13469 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13470 Sema::AssociatedClassSet AssociatedClasses; 13471 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13472 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13473 AssociatedClasses); 13474 13475 // C++ [basic.lookup.argdep]p3: 13476 // Let X be the lookup set produced by unqualified lookup (3.4.1) 13477 // and let Y be the lookup set produced by argument dependent 13478 // lookup (defined as follows). If X contains [...] then Y is 13479 // empty. Otherwise Y is the set of declarations found in the 13480 // namespaces associated with the argument types as described 13481 // below. The set of declarations found by the lookup of the name 13482 // is the union of X and Y. 13483 // 13484 // Here, we compute Y and add its members to the overloaded 13485 // candidate set. 13486 for (auto *NS : AssociatedNamespaces) { 13487 // When considering an associated namespace, the lookup is the 13488 // same as the lookup performed when the associated namespace is 13489 // used as a qualifier (3.4.3.2) except that: 13490 // 13491 // -- Any using-directives in the associated namespace are 13492 // ignored. 13493 // 13494 // -- Any namespace-scope friend functions declared in 13495 // associated classes are visible within their respective 13496 // namespaces even if they are not visible during an ordinary 13497 // lookup (11.4). 13498 DeclContext::lookup_result R = NS->lookup(Id.getName()); 13499 for (auto *D : R) { 13500 auto *Underlying = D; 13501 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13502 Underlying = USD->getTargetDecl(); 13503 13504 if (!isa<OMPDeclareReductionDecl>(Underlying) && 13505 !isa<OMPDeclareMapperDecl>(Underlying)) 13506 continue; 13507 13508 if (!SemaRef.isVisible(D)) { 13509 D = findAcceptableDecl(SemaRef, D); 13510 if (!D) 13511 continue; 13512 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13513 Underlying = USD->getTargetDecl(); 13514 } 13515 Lookups.emplace_back(); 13516 Lookups.back().addDecl(Underlying); 13517 } 13518 } 13519 } 13520 13521 static ExprResult 13522 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 13523 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 13524 const DeclarationNameInfo &ReductionId, QualType Ty, 13525 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 13526 if (ReductionIdScopeSpec.isInvalid()) 13527 return ExprError(); 13528 SmallVector<UnresolvedSet<8>, 4> Lookups; 13529 if (S) { 13530 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13531 Lookup.suppressDiagnostics(); 13532 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 13533 NamedDecl *D = Lookup.getRepresentativeDecl(); 13534 do { 13535 S = S->getParent(); 13536 } while (S && !S->isDeclScope(D)); 13537 if (S) 13538 S = S->getParent(); 13539 Lookups.emplace_back(); 13540 Lookups.back().append(Lookup.begin(), Lookup.end()); 13541 Lookup.clear(); 13542 } 13543 } else if (auto *ULE = 13544 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 13545 Lookups.push_back(UnresolvedSet<8>()); 13546 Decl *PrevD = nullptr; 13547 for (NamedDecl *D : ULE->decls()) { 13548 if (D == PrevD) 13549 Lookups.push_back(UnresolvedSet<8>()); 13550 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 13551 Lookups.back().addDecl(DRD); 13552 PrevD = D; 13553 } 13554 } 13555 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 13556 Ty->isInstantiationDependentType() || 13557 Ty->containsUnexpandedParameterPack() || 13558 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13559 return !D->isInvalidDecl() && 13560 (D->getType()->isDependentType() || 13561 D->getType()->isInstantiationDependentType() || 13562 D->getType()->containsUnexpandedParameterPack()); 13563 })) { 13564 UnresolvedSet<8> ResSet; 13565 for (const UnresolvedSet<8> &Set : Lookups) { 13566 if (Set.empty()) 13567 continue; 13568 ResSet.append(Set.begin(), Set.end()); 13569 // The last item marks the end of all declarations at the specified scope. 13570 ResSet.addDecl(Set[Set.size() - 1]); 13571 } 13572 return UnresolvedLookupExpr::Create( 13573 SemaRef.Context, /*NamingClass=*/nullptr, 13574 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 13575 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 13576 } 13577 // Lookup inside the classes. 13578 // C++ [over.match.oper]p3: 13579 // For a unary operator @ with an operand of a type whose 13580 // cv-unqualified version is T1, and for a binary operator @ with 13581 // a left operand of a type whose cv-unqualified version is T1 and 13582 // a right operand of a type whose cv-unqualified version is T2, 13583 // three sets of candidate functions, designated member 13584 // candidates, non-member candidates and built-in candidates, are 13585 // constructed as follows: 13586 // -- If T1 is a complete class type or a class currently being 13587 // defined, the set of member candidates is the result of the 13588 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13589 // the set of member candidates is empty. 13590 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13591 Lookup.suppressDiagnostics(); 13592 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13593 // Complete the type if it can be completed. 13594 // If the type is neither complete nor being defined, bail out now. 13595 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13596 TyRec->getDecl()->getDefinition()) { 13597 Lookup.clear(); 13598 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13599 if (Lookup.empty()) { 13600 Lookups.emplace_back(); 13601 Lookups.back().append(Lookup.begin(), Lookup.end()); 13602 } 13603 } 13604 } 13605 // Perform ADL. 13606 if (SemaRef.getLangOpts().CPlusPlus) 13607 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13608 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13609 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13610 if (!D->isInvalidDecl() && 13611 SemaRef.Context.hasSameType(D->getType(), Ty)) 13612 return D; 13613 return nullptr; 13614 })) 13615 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13616 VK_LValue, Loc); 13617 if (SemaRef.getLangOpts().CPlusPlus) { 13618 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13619 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13620 if (!D->isInvalidDecl() && 13621 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13622 !Ty.isMoreQualifiedThan(D->getType())) 13623 return D; 13624 return nullptr; 13625 })) { 13626 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13627 /*DetectVirtual=*/false); 13628 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13629 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13630 VD->getType().getUnqualifiedType()))) { 13631 if (SemaRef.CheckBaseClassAccess( 13632 Loc, VD->getType(), Ty, Paths.front(), 13633 /*DiagID=*/0) != Sema::AR_inaccessible) { 13634 SemaRef.BuildBasePathArray(Paths, BasePath); 13635 return SemaRef.BuildDeclRefExpr( 13636 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13637 } 13638 } 13639 } 13640 } 13641 } 13642 if (ReductionIdScopeSpec.isSet()) { 13643 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 13644 << Ty << Range; 13645 return ExprError(); 13646 } 13647 return ExprEmpty(); 13648 } 13649 13650 namespace { 13651 /// Data for the reduction-based clauses. 13652 struct ReductionData { 13653 /// List of original reduction items. 13654 SmallVector<Expr *, 8> Vars; 13655 /// List of private copies of the reduction items. 13656 SmallVector<Expr *, 8> Privates; 13657 /// LHS expressions for the reduction_op expressions. 13658 SmallVector<Expr *, 8> LHSs; 13659 /// RHS expressions for the reduction_op expressions. 13660 SmallVector<Expr *, 8> RHSs; 13661 /// Reduction operation expression. 13662 SmallVector<Expr *, 8> ReductionOps; 13663 /// Taskgroup descriptors for the corresponding reduction items in 13664 /// in_reduction clauses. 13665 SmallVector<Expr *, 8> TaskgroupDescriptors; 13666 /// List of captures for clause. 13667 SmallVector<Decl *, 4> ExprCaptures; 13668 /// List of postupdate expressions. 13669 SmallVector<Expr *, 4> ExprPostUpdates; 13670 ReductionData() = delete; 13671 /// Reserves required memory for the reduction data. 13672 ReductionData(unsigned Size) { 13673 Vars.reserve(Size); 13674 Privates.reserve(Size); 13675 LHSs.reserve(Size); 13676 RHSs.reserve(Size); 13677 ReductionOps.reserve(Size); 13678 TaskgroupDescriptors.reserve(Size); 13679 ExprCaptures.reserve(Size); 13680 ExprPostUpdates.reserve(Size); 13681 } 13682 /// Stores reduction item and reduction operation only (required for dependent 13683 /// reduction item). 13684 void push(Expr *Item, Expr *ReductionOp) { 13685 Vars.emplace_back(Item); 13686 Privates.emplace_back(nullptr); 13687 LHSs.emplace_back(nullptr); 13688 RHSs.emplace_back(nullptr); 13689 ReductionOps.emplace_back(ReductionOp); 13690 TaskgroupDescriptors.emplace_back(nullptr); 13691 } 13692 /// Stores reduction data. 13693 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13694 Expr *TaskgroupDescriptor) { 13695 Vars.emplace_back(Item); 13696 Privates.emplace_back(Private); 13697 LHSs.emplace_back(LHS); 13698 RHSs.emplace_back(RHS); 13699 ReductionOps.emplace_back(ReductionOp); 13700 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13701 } 13702 }; 13703 } // namespace 13704 13705 static bool checkOMPArraySectionConstantForReduction( 13706 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13707 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13708 const Expr *Length = OASE->getLength(); 13709 if (Length == nullptr) { 13710 // For array sections of the form [1:] or [:], we would need to analyze 13711 // the lower bound... 13712 if (OASE->getColonLoc().isValid()) 13713 return false; 13714 13715 // This is an array subscript which has implicit length 1! 13716 SingleElement = true; 13717 ArraySizes.push_back(llvm::APSInt::get(1)); 13718 } else { 13719 Expr::EvalResult Result; 13720 if (!Length->EvaluateAsInt(Result, Context)) 13721 return false; 13722 13723 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13724 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13725 ArraySizes.push_back(ConstantLengthValue); 13726 } 13727 13728 // Get the base of this array section and walk up from there. 13729 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13730 13731 // We require length = 1 for all array sections except the right-most to 13732 // guarantee that the memory region is contiguous and has no holes in it. 13733 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13734 Length = TempOASE->getLength(); 13735 if (Length == nullptr) { 13736 // For array sections of the form [1:] or [:], we would need to analyze 13737 // the lower bound... 13738 if (OASE->getColonLoc().isValid()) 13739 return false; 13740 13741 // This is an array subscript which has implicit length 1! 13742 ArraySizes.push_back(llvm::APSInt::get(1)); 13743 } else { 13744 Expr::EvalResult Result; 13745 if (!Length->EvaluateAsInt(Result, Context)) 13746 return false; 13747 13748 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13749 if (ConstantLengthValue.getSExtValue() != 1) 13750 return false; 13751 13752 ArraySizes.push_back(ConstantLengthValue); 13753 } 13754 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13755 } 13756 13757 // If we have a single element, we don't need to add the implicit lengths. 13758 if (!SingleElement) { 13759 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13760 // Has implicit length 1! 13761 ArraySizes.push_back(llvm::APSInt::get(1)); 13762 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13763 } 13764 } 13765 13766 // This array section can be privatized as a single value or as a constant 13767 // sized array. 13768 return true; 13769 } 13770 13771 static bool actOnOMPReductionKindClause( 13772 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13773 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13774 SourceLocation ColonLoc, SourceLocation EndLoc, 13775 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13776 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13777 DeclarationName DN = ReductionId.getName(); 13778 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13779 BinaryOperatorKind BOK = BO_Comma; 13780 13781 ASTContext &Context = S.Context; 13782 // OpenMP [2.14.3.6, reduction clause] 13783 // C 13784 // reduction-identifier is either an identifier or one of the following 13785 // operators: +, -, *, &, |, ^, && and || 13786 // C++ 13787 // reduction-identifier is either an id-expression or one of the following 13788 // operators: +, -, *, &, |, ^, && and || 13789 switch (OOK) { 13790 case OO_Plus: 13791 case OO_Minus: 13792 BOK = BO_Add; 13793 break; 13794 case OO_Star: 13795 BOK = BO_Mul; 13796 break; 13797 case OO_Amp: 13798 BOK = BO_And; 13799 break; 13800 case OO_Pipe: 13801 BOK = BO_Or; 13802 break; 13803 case OO_Caret: 13804 BOK = BO_Xor; 13805 break; 13806 case OO_AmpAmp: 13807 BOK = BO_LAnd; 13808 break; 13809 case OO_PipePipe: 13810 BOK = BO_LOr; 13811 break; 13812 case OO_New: 13813 case OO_Delete: 13814 case OO_Array_New: 13815 case OO_Array_Delete: 13816 case OO_Slash: 13817 case OO_Percent: 13818 case OO_Tilde: 13819 case OO_Exclaim: 13820 case OO_Equal: 13821 case OO_Less: 13822 case OO_Greater: 13823 case OO_LessEqual: 13824 case OO_GreaterEqual: 13825 case OO_PlusEqual: 13826 case OO_MinusEqual: 13827 case OO_StarEqual: 13828 case OO_SlashEqual: 13829 case OO_PercentEqual: 13830 case OO_CaretEqual: 13831 case OO_AmpEqual: 13832 case OO_PipeEqual: 13833 case OO_LessLess: 13834 case OO_GreaterGreater: 13835 case OO_LessLessEqual: 13836 case OO_GreaterGreaterEqual: 13837 case OO_EqualEqual: 13838 case OO_ExclaimEqual: 13839 case OO_Spaceship: 13840 case OO_PlusPlus: 13841 case OO_MinusMinus: 13842 case OO_Comma: 13843 case OO_ArrowStar: 13844 case OO_Arrow: 13845 case OO_Call: 13846 case OO_Subscript: 13847 case OO_Conditional: 13848 case OO_Coawait: 13849 case NUM_OVERLOADED_OPERATORS: 13850 llvm_unreachable("Unexpected reduction identifier"); 13851 case OO_None: 13852 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13853 if (II->isStr("max")) 13854 BOK = BO_GT; 13855 else if (II->isStr("min")) 13856 BOK = BO_LT; 13857 } 13858 break; 13859 } 13860 SourceRange ReductionIdRange; 13861 if (ReductionIdScopeSpec.isValid()) 13862 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13863 else 13864 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13865 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13866 13867 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13868 bool FirstIter = true; 13869 for (Expr *RefExpr : VarList) { 13870 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13871 // OpenMP [2.1, C/C++] 13872 // A list item is a variable or array section, subject to the restrictions 13873 // specified in Section 2.4 on page 42 and in each of the sections 13874 // describing clauses and directives for which a list appears. 13875 // OpenMP [2.14.3.3, Restrictions, p.1] 13876 // A variable that is part of another variable (as an array or 13877 // structure element) cannot appear in a private clause. 13878 if (!FirstIter && IR != ER) 13879 ++IR; 13880 FirstIter = false; 13881 SourceLocation ELoc; 13882 SourceRange ERange; 13883 Expr *SimpleRefExpr = RefExpr; 13884 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13885 /*AllowArraySection=*/true); 13886 if (Res.second) { 13887 // Try to find 'declare reduction' corresponding construct before using 13888 // builtin/overloaded operators. 13889 QualType Type = Context.DependentTy; 13890 CXXCastPath BasePath; 13891 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13892 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13893 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13894 Expr *ReductionOp = nullptr; 13895 if (S.CurContext->isDependentContext() && 13896 (DeclareReductionRef.isUnset() || 13897 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13898 ReductionOp = DeclareReductionRef.get(); 13899 // It will be analyzed later. 13900 RD.push(RefExpr, ReductionOp); 13901 } 13902 ValueDecl *D = Res.first; 13903 if (!D) 13904 continue; 13905 13906 Expr *TaskgroupDescriptor = nullptr; 13907 QualType Type; 13908 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13909 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13910 if (ASE) { 13911 Type = ASE->getType().getNonReferenceType(); 13912 } else if (OASE) { 13913 QualType BaseType = 13914 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13915 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13916 Type = ATy->getElementType(); 13917 else 13918 Type = BaseType->getPointeeType(); 13919 Type = Type.getNonReferenceType(); 13920 } else { 13921 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13922 } 13923 auto *VD = dyn_cast<VarDecl>(D); 13924 13925 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13926 // A variable that appears in a private clause must not have an incomplete 13927 // type or a reference type. 13928 if (S.RequireCompleteType(ELoc, D->getType(), 13929 diag::err_omp_reduction_incomplete_type)) 13930 continue; 13931 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13932 // A list item that appears in a reduction clause must not be 13933 // const-qualified. 13934 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13935 /*AcceptIfMutable*/ false, ASE || OASE)) 13936 continue; 13937 13938 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13939 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13940 // If a list-item is a reference type then it must bind to the same object 13941 // for all threads of the team. 13942 if (!ASE && !OASE) { 13943 if (VD) { 13944 VarDecl *VDDef = VD->getDefinition(); 13945 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13946 DSARefChecker Check(Stack); 13947 if (Check.Visit(VDDef->getInit())) { 13948 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13949 << getOpenMPClauseName(ClauseKind) << ERange; 13950 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13951 continue; 13952 } 13953 } 13954 } 13955 13956 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13957 // in a Construct] 13958 // Variables with the predetermined data-sharing attributes may not be 13959 // listed in data-sharing attributes clauses, except for the cases 13960 // listed below. For these exceptions only, listing a predetermined 13961 // variable in a data-sharing attribute clause is allowed and overrides 13962 // the variable's predetermined data-sharing attributes. 13963 // OpenMP [2.14.3.6, Restrictions, p.3] 13964 // Any number of reduction clauses can be specified on the directive, 13965 // but a list item can appear only once in the reduction clauses for that 13966 // directive. 13967 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13968 if (DVar.CKind == OMPC_reduction) { 13969 S.Diag(ELoc, diag::err_omp_once_referenced) 13970 << getOpenMPClauseName(ClauseKind); 13971 if (DVar.RefExpr) 13972 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13973 continue; 13974 } 13975 if (DVar.CKind != OMPC_unknown) { 13976 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13977 << getOpenMPClauseName(DVar.CKind) 13978 << getOpenMPClauseName(OMPC_reduction); 13979 reportOriginalDsa(S, Stack, D, DVar); 13980 continue; 13981 } 13982 13983 // OpenMP [2.14.3.6, Restrictions, p.1] 13984 // A list item that appears in a reduction clause of a worksharing 13985 // construct must be shared in the parallel regions to which any of the 13986 // worksharing regions arising from the worksharing construct bind. 13987 if (isOpenMPWorksharingDirective(CurrDir) && 13988 !isOpenMPParallelDirective(CurrDir) && 13989 !isOpenMPTeamsDirective(CurrDir)) { 13990 DVar = Stack->getImplicitDSA(D, true); 13991 if (DVar.CKind != OMPC_shared) { 13992 S.Diag(ELoc, diag::err_omp_required_access) 13993 << getOpenMPClauseName(OMPC_reduction) 13994 << getOpenMPClauseName(OMPC_shared); 13995 reportOriginalDsa(S, Stack, D, DVar); 13996 continue; 13997 } 13998 } 13999 } 14000 14001 // Try to find 'declare reduction' corresponding construct before using 14002 // builtin/overloaded operators. 14003 CXXCastPath BasePath; 14004 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14005 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14006 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14007 if (DeclareReductionRef.isInvalid()) 14008 continue; 14009 if (S.CurContext->isDependentContext() && 14010 (DeclareReductionRef.isUnset() || 14011 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14012 RD.push(RefExpr, DeclareReductionRef.get()); 14013 continue; 14014 } 14015 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14016 // Not allowed reduction identifier is found. 14017 S.Diag(ReductionId.getBeginLoc(), 14018 diag::err_omp_unknown_reduction_identifier) 14019 << Type << ReductionIdRange; 14020 continue; 14021 } 14022 14023 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14024 // The type of a list item that appears in a reduction clause must be valid 14025 // for the reduction-identifier. For a max or min reduction in C, the type 14026 // of the list item must be an allowed arithmetic data type: char, int, 14027 // float, double, or _Bool, possibly modified with long, short, signed, or 14028 // unsigned. For a max or min reduction in C++, the type of the list item 14029 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14030 // double, or bool, possibly modified with long, short, signed, or unsigned. 14031 if (DeclareReductionRef.isUnset()) { 14032 if ((BOK == BO_GT || BOK == BO_LT) && 14033 !(Type->isScalarType() || 14034 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14035 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14036 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14037 if (!ASE && !OASE) { 14038 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14039 VarDecl::DeclarationOnly; 14040 S.Diag(D->getLocation(), 14041 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14042 << D; 14043 } 14044 continue; 14045 } 14046 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14047 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14048 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14049 << getOpenMPClauseName(ClauseKind); 14050 if (!ASE && !OASE) { 14051 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14052 VarDecl::DeclarationOnly; 14053 S.Diag(D->getLocation(), 14054 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14055 << D; 14056 } 14057 continue; 14058 } 14059 } 14060 14061 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14062 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14063 D->hasAttrs() ? &D->getAttrs() : nullptr); 14064 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14065 D->hasAttrs() ? &D->getAttrs() : nullptr); 14066 QualType PrivateTy = Type; 14067 14068 // Try if we can determine constant lengths for all array sections and avoid 14069 // the VLA. 14070 bool ConstantLengthOASE = false; 14071 if (OASE) { 14072 bool SingleElement; 14073 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14074 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14075 Context, OASE, SingleElement, ArraySizes); 14076 14077 // If we don't have a single element, we must emit a constant array type. 14078 if (ConstantLengthOASE && !SingleElement) { 14079 for (llvm::APSInt &Size : ArraySizes) 14080 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14081 ArrayType::Normal, 14082 /*IndexTypeQuals=*/0); 14083 } 14084 } 14085 14086 if ((OASE && !ConstantLengthOASE) || 14087 (!OASE && !ASE && 14088 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14089 if (!Context.getTargetInfo().isVLASupported()) { 14090 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14091 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14092 S.Diag(ELoc, diag::note_vla_unsupported); 14093 } else { 14094 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14095 S.targetDiag(ELoc, diag::note_vla_unsupported); 14096 } 14097 continue; 14098 } 14099 // For arrays/array sections only: 14100 // Create pseudo array type for private copy. The size for this array will 14101 // be generated during codegen. 14102 // For array subscripts or single variables Private Ty is the same as Type 14103 // (type of the variable or single array element). 14104 PrivateTy = Context.getVariableArrayType( 14105 Type, 14106 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14107 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14108 } else if (!ASE && !OASE && 14109 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14110 PrivateTy = D->getType().getNonReferenceType(); 14111 } 14112 // Private copy. 14113 VarDecl *PrivateVD = 14114 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14115 D->hasAttrs() ? &D->getAttrs() : nullptr, 14116 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14117 // Add initializer for private variable. 14118 Expr *Init = nullptr; 14119 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14120 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14121 if (DeclareReductionRef.isUsable()) { 14122 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14123 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14124 if (DRD->getInitializer()) { 14125 Init = DRDRef; 14126 RHSVD->setInit(DRDRef); 14127 RHSVD->setInitStyle(VarDecl::CallInit); 14128 } 14129 } else { 14130 switch (BOK) { 14131 case BO_Add: 14132 case BO_Xor: 14133 case BO_Or: 14134 case BO_LOr: 14135 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14136 if (Type->isScalarType() || Type->isAnyComplexType()) 14137 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14138 break; 14139 case BO_Mul: 14140 case BO_LAnd: 14141 if (Type->isScalarType() || Type->isAnyComplexType()) { 14142 // '*' and '&&' reduction ops - initializer is '1'. 14143 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14144 } 14145 break; 14146 case BO_And: { 14147 // '&' reduction op - initializer is '~0'. 14148 QualType OrigType = Type; 14149 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14150 Type = ComplexTy->getElementType(); 14151 if (Type->isRealFloatingType()) { 14152 llvm::APFloat InitValue = 14153 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14154 /*isIEEE=*/true); 14155 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14156 Type, ELoc); 14157 } else if (Type->isScalarType()) { 14158 uint64_t Size = Context.getTypeSize(Type); 14159 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14160 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14161 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14162 } 14163 if (Init && OrigType->isAnyComplexType()) { 14164 // Init = 0xFFFF + 0xFFFFi; 14165 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14166 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14167 } 14168 Type = OrigType; 14169 break; 14170 } 14171 case BO_LT: 14172 case BO_GT: { 14173 // 'min' reduction op - initializer is 'Largest representable number in 14174 // the reduction list item type'. 14175 // 'max' reduction op - initializer is 'Least representable number in 14176 // the reduction list item type'. 14177 if (Type->isIntegerType() || Type->isPointerType()) { 14178 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14179 uint64_t Size = Context.getTypeSize(Type); 14180 QualType IntTy = 14181 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14182 llvm::APInt InitValue = 14183 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14184 : llvm::APInt::getMinValue(Size) 14185 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14186 : llvm::APInt::getMaxValue(Size); 14187 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14188 if (Type->isPointerType()) { 14189 // Cast to pointer type. 14190 ExprResult CastExpr = S.BuildCStyleCastExpr( 14191 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14192 if (CastExpr.isInvalid()) 14193 continue; 14194 Init = CastExpr.get(); 14195 } 14196 } else if (Type->isRealFloatingType()) { 14197 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14198 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14199 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14200 Type, ELoc); 14201 } 14202 break; 14203 } 14204 case BO_PtrMemD: 14205 case BO_PtrMemI: 14206 case BO_MulAssign: 14207 case BO_Div: 14208 case BO_Rem: 14209 case BO_Sub: 14210 case BO_Shl: 14211 case BO_Shr: 14212 case BO_LE: 14213 case BO_GE: 14214 case BO_EQ: 14215 case BO_NE: 14216 case BO_Cmp: 14217 case BO_AndAssign: 14218 case BO_XorAssign: 14219 case BO_OrAssign: 14220 case BO_Assign: 14221 case BO_AddAssign: 14222 case BO_SubAssign: 14223 case BO_DivAssign: 14224 case BO_RemAssign: 14225 case BO_ShlAssign: 14226 case BO_ShrAssign: 14227 case BO_Comma: 14228 llvm_unreachable("Unexpected reduction operation"); 14229 } 14230 } 14231 if (Init && DeclareReductionRef.isUnset()) 14232 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14233 else if (!Init) 14234 S.ActOnUninitializedDecl(RHSVD); 14235 if (RHSVD->isInvalidDecl()) 14236 continue; 14237 if (!RHSVD->hasInit() && 14238 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14239 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14240 << Type << ReductionIdRange; 14241 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14242 VarDecl::DeclarationOnly; 14243 S.Diag(D->getLocation(), 14244 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14245 << D; 14246 continue; 14247 } 14248 // Store initializer for single element in private copy. Will be used during 14249 // codegen. 14250 PrivateVD->setInit(RHSVD->getInit()); 14251 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14252 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14253 ExprResult ReductionOp; 14254 if (DeclareReductionRef.isUsable()) { 14255 QualType RedTy = DeclareReductionRef.get()->getType(); 14256 QualType PtrRedTy = Context.getPointerType(RedTy); 14257 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14258 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14259 if (!BasePath.empty()) { 14260 LHS = S.DefaultLvalueConversion(LHS.get()); 14261 RHS = S.DefaultLvalueConversion(RHS.get()); 14262 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14263 CK_UncheckedDerivedToBase, LHS.get(), 14264 &BasePath, LHS.get()->getValueKind()); 14265 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14266 CK_UncheckedDerivedToBase, RHS.get(), 14267 &BasePath, RHS.get()->getValueKind()); 14268 } 14269 FunctionProtoType::ExtProtoInfo EPI; 14270 QualType Params[] = {PtrRedTy, PtrRedTy}; 14271 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14272 auto *OVE = new (Context) OpaqueValueExpr( 14273 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14274 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14275 Expr *Args[] = {LHS.get(), RHS.get()}; 14276 ReductionOp = 14277 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14278 } else { 14279 ReductionOp = S.BuildBinOp( 14280 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14281 if (ReductionOp.isUsable()) { 14282 if (BOK != BO_LT && BOK != BO_GT) { 14283 ReductionOp = 14284 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14285 BO_Assign, LHSDRE, ReductionOp.get()); 14286 } else { 14287 auto *ConditionalOp = new (Context) 14288 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14289 Type, VK_LValue, OK_Ordinary); 14290 ReductionOp = 14291 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14292 BO_Assign, LHSDRE, ConditionalOp); 14293 } 14294 if (ReductionOp.isUsable()) 14295 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14296 /*DiscardedValue*/ false); 14297 } 14298 if (!ReductionOp.isUsable()) 14299 continue; 14300 } 14301 14302 // OpenMP [2.15.4.6, Restrictions, p.2] 14303 // A list item that appears in an in_reduction clause of a task construct 14304 // must appear in a task_reduction clause of a construct associated with a 14305 // taskgroup region that includes the participating task in its taskgroup 14306 // set. The construct associated with the innermost region that meets this 14307 // condition must specify the same reduction-identifier as the in_reduction 14308 // clause. 14309 if (ClauseKind == OMPC_in_reduction) { 14310 SourceRange ParentSR; 14311 BinaryOperatorKind ParentBOK; 14312 const Expr *ParentReductionOp; 14313 Expr *ParentBOKTD, *ParentReductionOpTD; 14314 DSAStackTy::DSAVarData ParentBOKDSA = 14315 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14316 ParentBOKTD); 14317 DSAStackTy::DSAVarData ParentReductionOpDSA = 14318 Stack->getTopMostTaskgroupReductionData( 14319 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14320 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14321 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14322 if (!IsParentBOK && !IsParentReductionOp) { 14323 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 14324 continue; 14325 } 14326 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14327 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 14328 IsParentReductionOp) { 14329 bool EmitError = true; 14330 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14331 llvm::FoldingSetNodeID RedId, ParentRedId; 14332 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14333 DeclareReductionRef.get()->Profile(RedId, Context, 14334 /*Canonical=*/true); 14335 EmitError = RedId != ParentRedId; 14336 } 14337 if (EmitError) { 14338 S.Diag(ReductionId.getBeginLoc(), 14339 diag::err_omp_reduction_identifier_mismatch) 14340 << ReductionIdRange << RefExpr->getSourceRange(); 14341 S.Diag(ParentSR.getBegin(), 14342 diag::note_omp_previous_reduction_identifier) 14343 << ParentSR 14344 << (IsParentBOK ? ParentBOKDSA.RefExpr 14345 : ParentReductionOpDSA.RefExpr) 14346 ->getSourceRange(); 14347 continue; 14348 } 14349 } 14350 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14351 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 14352 } 14353 14354 DeclRefExpr *Ref = nullptr; 14355 Expr *VarsExpr = RefExpr->IgnoreParens(); 14356 if (!VD && !S.CurContext->isDependentContext()) { 14357 if (ASE || OASE) { 14358 TransformExprToCaptures RebuildToCapture(S, D); 14359 VarsExpr = 14360 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14361 Ref = RebuildToCapture.getCapturedExpr(); 14362 } else { 14363 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14364 } 14365 if (!S.isOpenMPCapturedDecl(D)) { 14366 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14367 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14368 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14369 if (!RefRes.isUsable()) 14370 continue; 14371 ExprResult PostUpdateRes = 14372 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14373 RefRes.get()); 14374 if (!PostUpdateRes.isUsable()) 14375 continue; 14376 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14377 Stack->getCurrentDirective() == OMPD_taskgroup) { 14378 S.Diag(RefExpr->getExprLoc(), 14379 diag::err_omp_reduction_non_addressable_expression) 14380 << RefExpr->getSourceRange(); 14381 continue; 14382 } 14383 RD.ExprPostUpdates.emplace_back( 14384 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14385 } 14386 } 14387 } 14388 // All reduction items are still marked as reduction (to do not increase 14389 // code base size). 14390 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 14391 if (CurrDir == OMPD_taskgroup) { 14392 if (DeclareReductionRef.isUsable()) 14393 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14394 DeclareReductionRef.get()); 14395 else 14396 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14397 } 14398 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14399 TaskgroupDescriptor); 14400 } 14401 return RD.Vars.empty(); 14402 } 14403 14404 OMPClause *Sema::ActOnOpenMPReductionClause( 14405 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14406 SourceLocation ColonLoc, SourceLocation EndLoc, 14407 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14408 ArrayRef<Expr *> UnresolvedReductions) { 14409 ReductionData RD(VarList.size()); 14410 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14411 StartLoc, LParenLoc, ColonLoc, EndLoc, 14412 ReductionIdScopeSpec, ReductionId, 14413 UnresolvedReductions, RD)) 14414 return nullptr; 14415 14416 return OMPReductionClause::Create( 14417 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14418 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14419 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14420 buildPreInits(Context, RD.ExprCaptures), 14421 buildPostUpdate(*this, RD.ExprPostUpdates)); 14422 } 14423 14424 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14425 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14426 SourceLocation ColonLoc, SourceLocation EndLoc, 14427 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14428 ArrayRef<Expr *> UnresolvedReductions) { 14429 ReductionData RD(VarList.size()); 14430 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14431 StartLoc, LParenLoc, ColonLoc, EndLoc, 14432 ReductionIdScopeSpec, ReductionId, 14433 UnresolvedReductions, RD)) 14434 return nullptr; 14435 14436 return OMPTaskReductionClause::Create( 14437 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14438 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14439 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14440 buildPreInits(Context, RD.ExprCaptures), 14441 buildPostUpdate(*this, RD.ExprPostUpdates)); 14442 } 14443 14444 OMPClause *Sema::ActOnOpenMPInReductionClause( 14445 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14446 SourceLocation ColonLoc, SourceLocation EndLoc, 14447 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14448 ArrayRef<Expr *> UnresolvedReductions) { 14449 ReductionData RD(VarList.size()); 14450 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14451 StartLoc, LParenLoc, ColonLoc, EndLoc, 14452 ReductionIdScopeSpec, ReductionId, 14453 UnresolvedReductions, RD)) 14454 return nullptr; 14455 14456 return OMPInReductionClause::Create( 14457 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14458 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14459 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 14460 buildPreInits(Context, RD.ExprCaptures), 14461 buildPostUpdate(*this, RD.ExprPostUpdates)); 14462 } 14463 14464 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 14465 SourceLocation LinLoc) { 14466 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 14467 LinKind == OMPC_LINEAR_unknown) { 14468 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 14469 return true; 14470 } 14471 return false; 14472 } 14473 14474 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 14475 OpenMPLinearClauseKind LinKind, 14476 QualType Type) { 14477 const auto *VD = dyn_cast_or_null<VarDecl>(D); 14478 // A variable must not have an incomplete type or a reference type. 14479 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 14480 return true; 14481 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 14482 !Type->isReferenceType()) { 14483 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 14484 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 14485 return true; 14486 } 14487 Type = Type.getNonReferenceType(); 14488 14489 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14490 // A variable that is privatized must not have a const-qualified type 14491 // unless it is of class type with a mutable member. This restriction does 14492 // not apply to the firstprivate clause. 14493 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 14494 return true; 14495 14496 // A list item must be of integral or pointer type. 14497 Type = Type.getUnqualifiedType().getCanonicalType(); 14498 const auto *Ty = Type.getTypePtrOrNull(); 14499 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 14500 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 14501 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 14502 if (D) { 14503 bool IsDecl = 14504 !VD || 14505 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14506 Diag(D->getLocation(), 14507 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14508 << D; 14509 } 14510 return true; 14511 } 14512 return false; 14513 } 14514 14515 OMPClause *Sema::ActOnOpenMPLinearClause( 14516 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 14517 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 14518 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14519 SmallVector<Expr *, 8> Vars; 14520 SmallVector<Expr *, 8> Privates; 14521 SmallVector<Expr *, 8> Inits; 14522 SmallVector<Decl *, 4> ExprCaptures; 14523 SmallVector<Expr *, 4> ExprPostUpdates; 14524 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 14525 LinKind = OMPC_LINEAR_val; 14526 for (Expr *RefExpr : VarList) { 14527 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14528 SourceLocation ELoc; 14529 SourceRange ERange; 14530 Expr *SimpleRefExpr = RefExpr; 14531 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14532 if (Res.second) { 14533 // It will be analyzed later. 14534 Vars.push_back(RefExpr); 14535 Privates.push_back(nullptr); 14536 Inits.push_back(nullptr); 14537 } 14538 ValueDecl *D = Res.first; 14539 if (!D) 14540 continue; 14541 14542 QualType Type = D->getType(); 14543 auto *VD = dyn_cast<VarDecl>(D); 14544 14545 // OpenMP [2.14.3.7, linear clause] 14546 // A list-item cannot appear in more than one linear clause. 14547 // A list-item that appears in a linear clause cannot appear in any 14548 // other data-sharing attribute clause. 14549 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14550 if (DVar.RefExpr) { 14551 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14552 << getOpenMPClauseName(OMPC_linear); 14553 reportOriginalDsa(*this, DSAStack, D, DVar); 14554 continue; 14555 } 14556 14557 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 14558 continue; 14559 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14560 14561 // Build private copy of original var. 14562 VarDecl *Private = 14563 buildVarDecl(*this, ELoc, Type, D->getName(), 14564 D->hasAttrs() ? &D->getAttrs() : nullptr, 14565 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14566 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 14567 // Build var to save initial value. 14568 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 14569 Expr *InitExpr; 14570 DeclRefExpr *Ref = nullptr; 14571 if (!VD && !CurContext->isDependentContext()) { 14572 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14573 if (!isOpenMPCapturedDecl(D)) { 14574 ExprCaptures.push_back(Ref->getDecl()); 14575 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14576 ExprResult RefRes = DefaultLvalueConversion(Ref); 14577 if (!RefRes.isUsable()) 14578 continue; 14579 ExprResult PostUpdateRes = 14580 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14581 SimpleRefExpr, RefRes.get()); 14582 if (!PostUpdateRes.isUsable()) 14583 continue; 14584 ExprPostUpdates.push_back( 14585 IgnoredValueConversions(PostUpdateRes.get()).get()); 14586 } 14587 } 14588 } 14589 if (LinKind == OMPC_LINEAR_uval) 14590 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14591 else 14592 InitExpr = VD ? SimpleRefExpr : Ref; 14593 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14594 /*DirectInit=*/false); 14595 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14596 14597 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14598 Vars.push_back((VD || CurContext->isDependentContext()) 14599 ? RefExpr->IgnoreParens() 14600 : Ref); 14601 Privates.push_back(PrivateRef); 14602 Inits.push_back(InitRef); 14603 } 14604 14605 if (Vars.empty()) 14606 return nullptr; 14607 14608 Expr *StepExpr = Step; 14609 Expr *CalcStepExpr = nullptr; 14610 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14611 !Step->isInstantiationDependent() && 14612 !Step->containsUnexpandedParameterPack()) { 14613 SourceLocation StepLoc = Step->getBeginLoc(); 14614 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14615 if (Val.isInvalid()) 14616 return nullptr; 14617 StepExpr = Val.get(); 14618 14619 // Build var to save the step value. 14620 VarDecl *SaveVar = 14621 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14622 ExprResult SaveRef = 14623 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14624 ExprResult CalcStep = 14625 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14626 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14627 14628 // Warn about zero linear step (it would be probably better specified as 14629 // making corresponding variables 'const'). 14630 llvm::APSInt Result; 14631 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14632 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14633 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14634 << (Vars.size() > 1); 14635 if (!IsConstant && CalcStep.isUsable()) { 14636 // Calculate the step beforehand instead of doing this on each iteration. 14637 // (This is not used if the number of iterations may be kfold-ed). 14638 CalcStepExpr = CalcStep.get(); 14639 } 14640 } 14641 14642 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14643 ColonLoc, EndLoc, Vars, Privates, Inits, 14644 StepExpr, CalcStepExpr, 14645 buildPreInits(Context, ExprCaptures), 14646 buildPostUpdate(*this, ExprPostUpdates)); 14647 } 14648 14649 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14650 Expr *NumIterations, Sema &SemaRef, 14651 Scope *S, DSAStackTy *Stack) { 14652 // Walk the vars and build update/final expressions for the CodeGen. 14653 SmallVector<Expr *, 8> Updates; 14654 SmallVector<Expr *, 8> Finals; 14655 SmallVector<Expr *, 8> UsedExprs; 14656 Expr *Step = Clause.getStep(); 14657 Expr *CalcStep = Clause.getCalcStep(); 14658 // OpenMP [2.14.3.7, linear clause] 14659 // If linear-step is not specified it is assumed to be 1. 14660 if (!Step) 14661 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14662 else if (CalcStep) 14663 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14664 bool HasErrors = false; 14665 auto CurInit = Clause.inits().begin(); 14666 auto CurPrivate = Clause.privates().begin(); 14667 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14668 for (Expr *RefExpr : Clause.varlists()) { 14669 SourceLocation ELoc; 14670 SourceRange ERange; 14671 Expr *SimpleRefExpr = RefExpr; 14672 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14673 ValueDecl *D = Res.first; 14674 if (Res.second || !D) { 14675 Updates.push_back(nullptr); 14676 Finals.push_back(nullptr); 14677 HasErrors = true; 14678 continue; 14679 } 14680 auto &&Info = Stack->isLoopControlVariable(D); 14681 // OpenMP [2.15.11, distribute simd Construct] 14682 // A list item may not appear in a linear clause, unless it is the loop 14683 // iteration variable. 14684 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14685 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14686 SemaRef.Diag(ELoc, 14687 diag::err_omp_linear_distribute_var_non_loop_iteration); 14688 Updates.push_back(nullptr); 14689 Finals.push_back(nullptr); 14690 HasErrors = true; 14691 continue; 14692 } 14693 Expr *InitExpr = *CurInit; 14694 14695 // Build privatized reference to the current linear var. 14696 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14697 Expr *CapturedRef; 14698 if (LinKind == OMPC_LINEAR_uval) 14699 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14700 else 14701 CapturedRef = 14702 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14703 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14704 /*RefersToCapture=*/true); 14705 14706 // Build update: Var = InitExpr + IV * Step 14707 ExprResult Update; 14708 if (!Info.first) 14709 Update = buildCounterUpdate( 14710 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14711 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14712 else 14713 Update = *CurPrivate; 14714 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14715 /*DiscardedValue*/ false); 14716 14717 // Build final: Var = InitExpr + NumIterations * Step 14718 ExprResult Final; 14719 if (!Info.first) 14720 Final = 14721 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14722 InitExpr, NumIterations, Step, /*Subtract=*/false, 14723 /*IsNonRectangularLB=*/false); 14724 else 14725 Final = *CurPrivate; 14726 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14727 /*DiscardedValue*/ false); 14728 14729 if (!Update.isUsable() || !Final.isUsable()) { 14730 Updates.push_back(nullptr); 14731 Finals.push_back(nullptr); 14732 UsedExprs.push_back(nullptr); 14733 HasErrors = true; 14734 } else { 14735 Updates.push_back(Update.get()); 14736 Finals.push_back(Final.get()); 14737 if (!Info.first) 14738 UsedExprs.push_back(SimpleRefExpr); 14739 } 14740 ++CurInit; 14741 ++CurPrivate; 14742 } 14743 if (Expr *S = Clause.getStep()) 14744 UsedExprs.push_back(S); 14745 // Fill the remaining part with the nullptr. 14746 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14747 Clause.setUpdates(Updates); 14748 Clause.setFinals(Finals); 14749 Clause.setUsedExprs(UsedExprs); 14750 return HasErrors; 14751 } 14752 14753 OMPClause *Sema::ActOnOpenMPAlignedClause( 14754 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14755 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14756 SmallVector<Expr *, 8> Vars; 14757 for (Expr *RefExpr : VarList) { 14758 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14759 SourceLocation ELoc; 14760 SourceRange ERange; 14761 Expr *SimpleRefExpr = RefExpr; 14762 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14763 if (Res.second) { 14764 // It will be analyzed later. 14765 Vars.push_back(RefExpr); 14766 } 14767 ValueDecl *D = Res.first; 14768 if (!D) 14769 continue; 14770 14771 QualType QType = D->getType(); 14772 auto *VD = dyn_cast<VarDecl>(D); 14773 14774 // OpenMP [2.8.1, simd construct, Restrictions] 14775 // The type of list items appearing in the aligned clause must be 14776 // array, pointer, reference to array, or reference to pointer. 14777 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14778 const Type *Ty = QType.getTypePtrOrNull(); 14779 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14780 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14781 << QType << getLangOpts().CPlusPlus << ERange; 14782 bool IsDecl = 14783 !VD || 14784 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14785 Diag(D->getLocation(), 14786 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14787 << D; 14788 continue; 14789 } 14790 14791 // OpenMP [2.8.1, simd construct, Restrictions] 14792 // A list-item cannot appear in more than one aligned clause. 14793 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14794 Diag(ELoc, diag::err_omp_used_in_clause_twice) 14795 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 14796 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14797 << getOpenMPClauseName(OMPC_aligned); 14798 continue; 14799 } 14800 14801 DeclRefExpr *Ref = nullptr; 14802 if (!VD && isOpenMPCapturedDecl(D)) 14803 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14804 Vars.push_back(DefaultFunctionArrayConversion( 14805 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14806 .get()); 14807 } 14808 14809 // OpenMP [2.8.1, simd construct, Description] 14810 // The parameter of the aligned clause, alignment, must be a constant 14811 // positive integer expression. 14812 // If no optional parameter is specified, implementation-defined default 14813 // alignments for SIMD instructions on the target platforms are assumed. 14814 if (Alignment != nullptr) { 14815 ExprResult AlignResult = 14816 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14817 if (AlignResult.isInvalid()) 14818 return nullptr; 14819 Alignment = AlignResult.get(); 14820 } 14821 if (Vars.empty()) 14822 return nullptr; 14823 14824 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14825 EndLoc, Vars, Alignment); 14826 } 14827 14828 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14829 SourceLocation StartLoc, 14830 SourceLocation LParenLoc, 14831 SourceLocation EndLoc) { 14832 SmallVector<Expr *, 8> Vars; 14833 SmallVector<Expr *, 8> SrcExprs; 14834 SmallVector<Expr *, 8> DstExprs; 14835 SmallVector<Expr *, 8> AssignmentOps; 14836 for (Expr *RefExpr : VarList) { 14837 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14838 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14839 // It will be analyzed later. 14840 Vars.push_back(RefExpr); 14841 SrcExprs.push_back(nullptr); 14842 DstExprs.push_back(nullptr); 14843 AssignmentOps.push_back(nullptr); 14844 continue; 14845 } 14846 14847 SourceLocation ELoc = RefExpr->getExprLoc(); 14848 // OpenMP [2.1, C/C++] 14849 // A list item is a variable name. 14850 // OpenMP [2.14.4.1, Restrictions, p.1] 14851 // A list item that appears in a copyin clause must be threadprivate. 14852 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14853 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14854 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14855 << 0 << RefExpr->getSourceRange(); 14856 continue; 14857 } 14858 14859 Decl *D = DE->getDecl(); 14860 auto *VD = cast<VarDecl>(D); 14861 14862 QualType Type = VD->getType(); 14863 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14864 // It will be analyzed later. 14865 Vars.push_back(DE); 14866 SrcExprs.push_back(nullptr); 14867 DstExprs.push_back(nullptr); 14868 AssignmentOps.push_back(nullptr); 14869 continue; 14870 } 14871 14872 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14873 // A list item that appears in a copyin clause must be threadprivate. 14874 if (!DSAStack->isThreadPrivate(VD)) { 14875 Diag(ELoc, diag::err_omp_required_access) 14876 << getOpenMPClauseName(OMPC_copyin) 14877 << getOpenMPDirectiveName(OMPD_threadprivate); 14878 continue; 14879 } 14880 14881 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14882 // A variable of class type (or array thereof) that appears in a 14883 // copyin clause requires an accessible, unambiguous copy assignment 14884 // operator for the class type. 14885 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14886 VarDecl *SrcVD = 14887 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14888 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14889 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14890 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14891 VarDecl *DstVD = 14892 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14893 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14894 DeclRefExpr *PseudoDstExpr = 14895 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14896 // For arrays generate assignment operation for single element and replace 14897 // it by the original array element in CodeGen. 14898 ExprResult AssignmentOp = 14899 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14900 PseudoSrcExpr); 14901 if (AssignmentOp.isInvalid()) 14902 continue; 14903 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14904 /*DiscardedValue*/ false); 14905 if (AssignmentOp.isInvalid()) 14906 continue; 14907 14908 DSAStack->addDSA(VD, DE, OMPC_copyin); 14909 Vars.push_back(DE); 14910 SrcExprs.push_back(PseudoSrcExpr); 14911 DstExprs.push_back(PseudoDstExpr); 14912 AssignmentOps.push_back(AssignmentOp.get()); 14913 } 14914 14915 if (Vars.empty()) 14916 return nullptr; 14917 14918 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14919 SrcExprs, DstExprs, AssignmentOps); 14920 } 14921 14922 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14923 SourceLocation StartLoc, 14924 SourceLocation LParenLoc, 14925 SourceLocation EndLoc) { 14926 SmallVector<Expr *, 8> Vars; 14927 SmallVector<Expr *, 8> SrcExprs; 14928 SmallVector<Expr *, 8> DstExprs; 14929 SmallVector<Expr *, 8> AssignmentOps; 14930 for (Expr *RefExpr : VarList) { 14931 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14932 SourceLocation ELoc; 14933 SourceRange ERange; 14934 Expr *SimpleRefExpr = RefExpr; 14935 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14936 if (Res.second) { 14937 // It will be analyzed later. 14938 Vars.push_back(RefExpr); 14939 SrcExprs.push_back(nullptr); 14940 DstExprs.push_back(nullptr); 14941 AssignmentOps.push_back(nullptr); 14942 } 14943 ValueDecl *D = Res.first; 14944 if (!D) 14945 continue; 14946 14947 QualType Type = D->getType(); 14948 auto *VD = dyn_cast<VarDecl>(D); 14949 14950 // OpenMP [2.14.4.2, Restrictions, p.2] 14951 // A list item that appears in a copyprivate clause may not appear in a 14952 // private or firstprivate clause on the single construct. 14953 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14954 DSAStackTy::DSAVarData DVar = 14955 DSAStack->getTopDSA(D, /*FromParent=*/false); 14956 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14957 DVar.RefExpr) { 14958 Diag(ELoc, diag::err_omp_wrong_dsa) 14959 << getOpenMPClauseName(DVar.CKind) 14960 << getOpenMPClauseName(OMPC_copyprivate); 14961 reportOriginalDsa(*this, DSAStack, D, DVar); 14962 continue; 14963 } 14964 14965 // OpenMP [2.11.4.2, Restrictions, p.1] 14966 // All list items that appear in a copyprivate clause must be either 14967 // threadprivate or private in the enclosing context. 14968 if (DVar.CKind == OMPC_unknown) { 14969 DVar = DSAStack->getImplicitDSA(D, false); 14970 if (DVar.CKind == OMPC_shared) { 14971 Diag(ELoc, diag::err_omp_required_access) 14972 << getOpenMPClauseName(OMPC_copyprivate) 14973 << "threadprivate or private in the enclosing context"; 14974 reportOriginalDsa(*this, DSAStack, D, DVar); 14975 continue; 14976 } 14977 } 14978 } 14979 14980 // Variably modified types are not supported. 14981 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14982 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14983 << getOpenMPClauseName(OMPC_copyprivate) << Type 14984 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14985 bool IsDecl = 14986 !VD || 14987 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14988 Diag(D->getLocation(), 14989 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14990 << D; 14991 continue; 14992 } 14993 14994 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14995 // A variable of class type (or array thereof) that appears in a 14996 // copyin clause requires an accessible, unambiguous copy assignment 14997 // operator for the class type. 14998 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14999 .getUnqualifiedType(); 15000 VarDecl *SrcVD = 15001 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15002 D->hasAttrs() ? &D->getAttrs() : nullptr); 15003 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15004 VarDecl *DstVD = 15005 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15006 D->hasAttrs() ? &D->getAttrs() : nullptr); 15007 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15008 ExprResult AssignmentOp = BuildBinOp( 15009 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15010 if (AssignmentOp.isInvalid()) 15011 continue; 15012 AssignmentOp = 15013 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15014 if (AssignmentOp.isInvalid()) 15015 continue; 15016 15017 // No need to mark vars as copyprivate, they are already threadprivate or 15018 // implicitly private. 15019 assert(VD || isOpenMPCapturedDecl(D)); 15020 Vars.push_back( 15021 VD ? RefExpr->IgnoreParens() 15022 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15023 SrcExprs.push_back(PseudoSrcExpr); 15024 DstExprs.push_back(PseudoDstExpr); 15025 AssignmentOps.push_back(AssignmentOp.get()); 15026 } 15027 15028 if (Vars.empty()) 15029 return nullptr; 15030 15031 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15032 Vars, SrcExprs, DstExprs, AssignmentOps); 15033 } 15034 15035 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15036 SourceLocation StartLoc, 15037 SourceLocation LParenLoc, 15038 SourceLocation EndLoc) { 15039 if (VarList.empty()) 15040 return nullptr; 15041 15042 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15043 } 15044 15045 OMPClause * 15046 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 15047 SourceLocation DepLoc, SourceLocation ColonLoc, 15048 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15049 SourceLocation LParenLoc, SourceLocation EndLoc) { 15050 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15051 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15052 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15053 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15054 return nullptr; 15055 } 15056 if (DSAStack->getCurrentDirective() != OMPD_ordered && 15057 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15058 DepKind == OMPC_DEPEND_sink)) { 15059 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 15060 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15061 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 15062 /*Last=*/OMPC_DEPEND_unknown, Except) 15063 << getOpenMPClauseName(OMPC_depend); 15064 return nullptr; 15065 } 15066 SmallVector<Expr *, 8> Vars; 15067 DSAStackTy::OperatorOffsetTy OpsOffs; 15068 llvm::APSInt DepCounter(/*BitWidth=*/32); 15069 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15070 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15071 if (const Expr *OrderedCountExpr = 15072 DSAStack->getParentOrderedRegionParam().first) { 15073 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15074 TotalDepCount.setIsUnsigned(/*Val=*/true); 15075 } 15076 } 15077 for (Expr *RefExpr : VarList) { 15078 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15079 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15080 // It will be analyzed later. 15081 Vars.push_back(RefExpr); 15082 continue; 15083 } 15084 15085 SourceLocation ELoc = RefExpr->getExprLoc(); 15086 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15087 if (DepKind == OMPC_DEPEND_sink) { 15088 if (DSAStack->getParentOrderedRegionParam().first && 15089 DepCounter >= TotalDepCount) { 15090 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15091 continue; 15092 } 15093 ++DepCounter; 15094 // OpenMP [2.13.9, Summary] 15095 // depend(dependence-type : vec), where dependence-type is: 15096 // 'sink' and where vec is the iteration vector, which has the form: 15097 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15098 // where n is the value specified by the ordered clause in the loop 15099 // directive, xi denotes the loop iteration variable of the i-th nested 15100 // loop associated with the loop directive, and di is a constant 15101 // non-negative integer. 15102 if (CurContext->isDependentContext()) { 15103 // It will be analyzed later. 15104 Vars.push_back(RefExpr); 15105 continue; 15106 } 15107 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15108 OverloadedOperatorKind OOK = OO_None; 15109 SourceLocation OOLoc; 15110 Expr *LHS = SimpleExpr; 15111 Expr *RHS = nullptr; 15112 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15113 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15114 OOLoc = BO->getOperatorLoc(); 15115 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15116 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15117 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15118 OOK = OCE->getOperator(); 15119 OOLoc = OCE->getOperatorLoc(); 15120 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15121 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15122 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15123 OOK = MCE->getMethodDecl() 15124 ->getNameInfo() 15125 .getName() 15126 .getCXXOverloadedOperator(); 15127 OOLoc = MCE->getCallee()->getExprLoc(); 15128 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15129 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15130 } 15131 SourceLocation ELoc; 15132 SourceRange ERange; 15133 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15134 if (Res.second) { 15135 // It will be analyzed later. 15136 Vars.push_back(RefExpr); 15137 } 15138 ValueDecl *D = Res.first; 15139 if (!D) 15140 continue; 15141 15142 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15143 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15144 continue; 15145 } 15146 if (RHS) { 15147 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15148 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15149 if (RHSRes.isInvalid()) 15150 continue; 15151 } 15152 if (!CurContext->isDependentContext() && 15153 DSAStack->getParentOrderedRegionParam().first && 15154 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15155 const ValueDecl *VD = 15156 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15157 if (VD) 15158 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15159 << 1 << VD; 15160 else 15161 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15162 continue; 15163 } 15164 OpsOffs.emplace_back(RHS, OOK); 15165 } else { 15166 // OpenMP 5.0 [2.17.11, Restrictions] 15167 // List items used in depend clauses cannot be zero-length array sections. 15168 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15169 if (OASE) { 15170 const Expr *Length = OASE->getLength(); 15171 Expr::EvalResult Result; 15172 if (Length && !Length->isValueDependent() && 15173 Length->EvaluateAsInt(Result, Context) && 15174 Result.Val.getInt().isNullValue()) { 15175 Diag(ELoc, 15176 diag::err_omp_depend_zero_length_array_section_not_allowed) 15177 << SimpleExpr->getSourceRange(); 15178 continue; 15179 } 15180 } 15181 15182 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15183 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15184 (ASE && 15185 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 15186 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15187 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15188 << RefExpr->getSourceRange(); 15189 continue; 15190 } 15191 15192 ExprResult Res; 15193 { 15194 Sema::TentativeAnalysisScope Trap(*this); 15195 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15196 RefExpr->IgnoreParenImpCasts()); 15197 } 15198 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 15199 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15200 << RefExpr->getSourceRange(); 15201 continue; 15202 } 15203 } 15204 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15205 } 15206 15207 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15208 TotalDepCount > VarList.size() && 15209 DSAStack->getParentOrderedRegionParam().first && 15210 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15211 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15212 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15213 } 15214 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15215 Vars.empty()) 15216 return nullptr; 15217 15218 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15219 DepKind, DepLoc, ColonLoc, Vars, 15220 TotalDepCount.getZExtValue()); 15221 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15222 DSAStack->isParentOrderedRegion()) 15223 DSAStack->addDoacrossDependClause(C, OpsOffs); 15224 return C; 15225 } 15226 15227 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 15228 SourceLocation LParenLoc, 15229 SourceLocation EndLoc) { 15230 Expr *ValExpr = Device; 15231 Stmt *HelperValStmt = nullptr; 15232 15233 // OpenMP [2.9.1, Restrictions] 15234 // The device expression must evaluate to a non-negative integer value. 15235 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15236 /*StrictlyPositive=*/false)) 15237 return nullptr; 15238 15239 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15240 OpenMPDirectiveKind CaptureRegion = 15241 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15242 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15243 ValExpr = MakeFullExpr(ValExpr).get(); 15244 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15245 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15246 HelperValStmt = buildPreInits(Context, Captures); 15247 } 15248 15249 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 15250 StartLoc, LParenLoc, EndLoc); 15251 } 15252 15253 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15254 DSAStackTy *Stack, QualType QTy, 15255 bool FullCheck = true) { 15256 NamedDecl *ND; 15257 if (QTy->isIncompleteType(&ND)) { 15258 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15259 return false; 15260 } 15261 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15262 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15263 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15264 return true; 15265 } 15266 15267 /// Return true if it can be proven that the provided array expression 15268 /// (array section or array subscript) does NOT specify the whole size of the 15269 /// array whose base type is \a BaseQTy. 15270 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15271 const Expr *E, 15272 QualType BaseQTy) { 15273 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15274 15275 // If this is an array subscript, it refers to the whole size if the size of 15276 // the dimension is constant and equals 1. Also, an array section assumes the 15277 // format of an array subscript if no colon is used. 15278 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15279 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15280 return ATy->getSize().getSExtValue() != 1; 15281 // Size can't be evaluated statically. 15282 return false; 15283 } 15284 15285 assert(OASE && "Expecting array section if not an array subscript."); 15286 const Expr *LowerBound = OASE->getLowerBound(); 15287 const Expr *Length = OASE->getLength(); 15288 15289 // If there is a lower bound that does not evaluates to zero, we are not 15290 // covering the whole dimension. 15291 if (LowerBound) { 15292 Expr::EvalResult Result; 15293 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15294 return false; // Can't get the integer value as a constant. 15295 15296 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15297 if (ConstLowerBound.getSExtValue()) 15298 return true; 15299 } 15300 15301 // If we don't have a length we covering the whole dimension. 15302 if (!Length) 15303 return false; 15304 15305 // If the base is a pointer, we don't have a way to get the size of the 15306 // pointee. 15307 if (BaseQTy->isPointerType()) 15308 return false; 15309 15310 // We can only check if the length is the same as the size of the dimension 15311 // if we have a constant array. 15312 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 15313 if (!CATy) 15314 return false; 15315 15316 Expr::EvalResult Result; 15317 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15318 return false; // Can't get the integer value as a constant. 15319 15320 llvm::APSInt ConstLength = Result.Val.getInt(); 15321 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 15322 } 15323 15324 // Return true if it can be proven that the provided array expression (array 15325 // section or array subscript) does NOT specify a single element of the array 15326 // whose base type is \a BaseQTy. 15327 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 15328 const Expr *E, 15329 QualType BaseQTy) { 15330 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15331 15332 // An array subscript always refer to a single element. Also, an array section 15333 // assumes the format of an array subscript if no colon is used. 15334 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 15335 return false; 15336 15337 assert(OASE && "Expecting array section if not an array subscript."); 15338 const Expr *Length = OASE->getLength(); 15339 15340 // If we don't have a length we have to check if the array has unitary size 15341 // for this dimension. Also, we should always expect a length if the base type 15342 // is pointer. 15343 if (!Length) { 15344 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15345 return ATy->getSize().getSExtValue() != 1; 15346 // We cannot assume anything. 15347 return false; 15348 } 15349 15350 // Check if the length evaluates to 1. 15351 Expr::EvalResult Result; 15352 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15353 return false; // Can't get the integer value as a constant. 15354 15355 llvm::APSInt ConstLength = Result.Val.getInt(); 15356 return ConstLength.getSExtValue() != 1; 15357 } 15358 15359 // Return the expression of the base of the mappable expression or null if it 15360 // cannot be determined and do all the necessary checks to see if the expression 15361 // is valid as a standalone mappable expression. In the process, record all the 15362 // components of the expression. 15363 static const Expr *checkMapClauseExpressionBase( 15364 Sema &SemaRef, Expr *E, 15365 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 15366 OpenMPClauseKind CKind, bool NoDiagnose) { 15367 SourceLocation ELoc = E->getExprLoc(); 15368 SourceRange ERange = E->getSourceRange(); 15369 15370 // The base of elements of list in a map clause have to be either: 15371 // - a reference to variable or field. 15372 // - a member expression. 15373 // - an array expression. 15374 // 15375 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 15376 // reference to 'r'. 15377 // 15378 // If we have: 15379 // 15380 // struct SS { 15381 // Bla S; 15382 // foo() { 15383 // #pragma omp target map (S.Arr[:12]); 15384 // } 15385 // } 15386 // 15387 // We want to retrieve the member expression 'this->S'; 15388 15389 const Expr *RelevantExpr = nullptr; 15390 15391 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 15392 // If a list item is an array section, it must specify contiguous storage. 15393 // 15394 // For this restriction it is sufficient that we make sure only references 15395 // to variables or fields and array expressions, and that no array sections 15396 // exist except in the rightmost expression (unless they cover the whole 15397 // dimension of the array). E.g. these would be invalid: 15398 // 15399 // r.ArrS[3:5].Arr[6:7] 15400 // 15401 // r.ArrS[3:5].x 15402 // 15403 // but these would be valid: 15404 // r.ArrS[3].Arr[6:7] 15405 // 15406 // r.ArrS[3].x 15407 15408 bool AllowUnitySizeArraySection = true; 15409 bool AllowWholeSizeArraySection = true; 15410 15411 while (!RelevantExpr) { 15412 E = E->IgnoreParenImpCasts(); 15413 15414 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 15415 if (!isa<VarDecl>(CurE->getDecl())) 15416 return nullptr; 15417 15418 RelevantExpr = CurE; 15419 15420 // If we got a reference to a declaration, we should not expect any array 15421 // section before that. 15422 AllowUnitySizeArraySection = false; 15423 AllowWholeSizeArraySection = false; 15424 15425 // Record the component. 15426 CurComponents.emplace_back(CurE, CurE->getDecl()); 15427 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 15428 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 15429 15430 if (isa<CXXThisExpr>(BaseE)) 15431 // We found a base expression: this->Val. 15432 RelevantExpr = CurE; 15433 else 15434 E = BaseE; 15435 15436 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 15437 if (!NoDiagnose) { 15438 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 15439 << CurE->getSourceRange(); 15440 return nullptr; 15441 } 15442 if (RelevantExpr) 15443 return nullptr; 15444 continue; 15445 } 15446 15447 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 15448 15449 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 15450 // A bit-field cannot appear in a map clause. 15451 // 15452 if (FD->isBitField()) { 15453 if (!NoDiagnose) { 15454 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 15455 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 15456 return nullptr; 15457 } 15458 if (RelevantExpr) 15459 return nullptr; 15460 continue; 15461 } 15462 15463 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15464 // If the type of a list item is a reference to a type T then the type 15465 // will be considered to be T for all purposes of this clause. 15466 QualType CurType = BaseE->getType().getNonReferenceType(); 15467 15468 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 15469 // A list item cannot be a variable that is a member of a structure with 15470 // a union type. 15471 // 15472 if (CurType->isUnionType()) { 15473 if (!NoDiagnose) { 15474 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 15475 << CurE->getSourceRange(); 15476 return nullptr; 15477 } 15478 continue; 15479 } 15480 15481 // If we got a member expression, we should not expect any array section 15482 // before that: 15483 // 15484 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 15485 // If a list item is an element of a structure, only the rightmost symbol 15486 // of the variable reference can be an array section. 15487 // 15488 AllowUnitySizeArraySection = false; 15489 AllowWholeSizeArraySection = false; 15490 15491 // Record the component. 15492 CurComponents.emplace_back(CurE, FD); 15493 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 15494 E = CurE->getBase()->IgnoreParenImpCasts(); 15495 15496 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 15497 if (!NoDiagnose) { 15498 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15499 << 0 << CurE->getSourceRange(); 15500 return nullptr; 15501 } 15502 continue; 15503 } 15504 15505 // If we got an array subscript that express the whole dimension we 15506 // can have any array expressions before. If it only expressing part of 15507 // the dimension, we can only have unitary-size array expressions. 15508 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 15509 E->getType())) 15510 AllowWholeSizeArraySection = false; 15511 15512 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15513 Expr::EvalResult Result; 15514 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 15515 if (!Result.Val.getInt().isNullValue()) { 15516 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15517 diag::err_omp_invalid_map_this_expr); 15518 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15519 diag::note_omp_invalid_subscript_on_this_ptr_map); 15520 } 15521 } 15522 RelevantExpr = TE; 15523 } 15524 15525 // Record the component - we don't have any declaration associated. 15526 CurComponents.emplace_back(CurE, nullptr); 15527 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 15528 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 15529 E = CurE->getBase()->IgnoreParenImpCasts(); 15530 15531 QualType CurType = 15532 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15533 15534 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15535 // If the type of a list item is a reference to a type T then the type 15536 // will be considered to be T for all purposes of this clause. 15537 if (CurType->isReferenceType()) 15538 CurType = CurType->getPointeeType(); 15539 15540 bool IsPointer = CurType->isAnyPointerType(); 15541 15542 if (!IsPointer && !CurType->isArrayType()) { 15543 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15544 << 0 << CurE->getSourceRange(); 15545 return nullptr; 15546 } 15547 15548 bool NotWhole = 15549 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 15550 bool NotUnity = 15551 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 15552 15553 if (AllowWholeSizeArraySection) { 15554 // Any array section is currently allowed. Allowing a whole size array 15555 // section implies allowing a unity array section as well. 15556 // 15557 // If this array section refers to the whole dimension we can still 15558 // accept other array sections before this one, except if the base is a 15559 // pointer. Otherwise, only unitary sections are accepted. 15560 if (NotWhole || IsPointer) 15561 AllowWholeSizeArraySection = false; 15562 } else if (AllowUnitySizeArraySection && NotUnity) { 15563 // A unity or whole array section is not allowed and that is not 15564 // compatible with the properties of the current array section. 15565 SemaRef.Diag( 15566 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 15567 << CurE->getSourceRange(); 15568 return nullptr; 15569 } 15570 15571 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15572 Expr::EvalResult ResultR; 15573 Expr::EvalResult ResultL; 15574 if (CurE->getLength()->EvaluateAsInt(ResultR, 15575 SemaRef.getASTContext())) { 15576 if (!ResultR.Val.getInt().isOneValue()) { 15577 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15578 diag::err_omp_invalid_map_this_expr); 15579 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15580 diag::note_omp_invalid_length_on_this_ptr_mapping); 15581 } 15582 } 15583 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 15584 ResultL, SemaRef.getASTContext())) { 15585 if (!ResultL.Val.getInt().isNullValue()) { 15586 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15587 diag::err_omp_invalid_map_this_expr); 15588 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15589 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 15590 } 15591 } 15592 RelevantExpr = TE; 15593 } 15594 15595 // Record the component - we don't have any declaration associated. 15596 CurComponents.emplace_back(CurE, nullptr); 15597 } else { 15598 if (!NoDiagnose) { 15599 // If nothing else worked, this is not a valid map clause expression. 15600 SemaRef.Diag( 15601 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 15602 << ERange; 15603 } 15604 return nullptr; 15605 } 15606 } 15607 15608 return RelevantExpr; 15609 } 15610 15611 // Return true if expression E associated with value VD has conflicts with other 15612 // map information. 15613 static bool checkMapConflicts( 15614 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15615 bool CurrentRegionOnly, 15616 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15617 OpenMPClauseKind CKind) { 15618 assert(VD && E); 15619 SourceLocation ELoc = E->getExprLoc(); 15620 SourceRange ERange = E->getSourceRange(); 15621 15622 // In order to easily check the conflicts we need to match each component of 15623 // the expression under test with the components of the expressions that are 15624 // already in the stack. 15625 15626 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15627 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15628 "Map clause expression with unexpected base!"); 15629 15630 // Variables to help detecting enclosing problems in data environment nests. 15631 bool IsEnclosedByDataEnvironmentExpr = false; 15632 const Expr *EnclosingExpr = nullptr; 15633 15634 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15635 VD, CurrentRegionOnly, 15636 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15637 ERange, CKind, &EnclosingExpr, 15638 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15639 StackComponents, 15640 OpenMPClauseKind) { 15641 assert(!StackComponents.empty() && 15642 "Map clause expression with no components!"); 15643 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15644 "Map clause expression with unexpected base!"); 15645 (void)VD; 15646 15647 // The whole expression in the stack. 15648 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15649 15650 // Expressions must start from the same base. Here we detect at which 15651 // point both expressions diverge from each other and see if we can 15652 // detect if the memory referred to both expressions is contiguous and 15653 // do not overlap. 15654 auto CI = CurComponents.rbegin(); 15655 auto CE = CurComponents.rend(); 15656 auto SI = StackComponents.rbegin(); 15657 auto SE = StackComponents.rend(); 15658 for (; CI != CE && SI != SE; ++CI, ++SI) { 15659 15660 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15661 // At most one list item can be an array item derived from a given 15662 // variable in map clauses of the same construct. 15663 if (CurrentRegionOnly && 15664 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15665 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15666 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15667 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15668 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15669 diag::err_omp_multiple_array_items_in_map_clause) 15670 << CI->getAssociatedExpression()->getSourceRange(); 15671 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15672 diag::note_used_here) 15673 << SI->getAssociatedExpression()->getSourceRange(); 15674 return true; 15675 } 15676 15677 // Do both expressions have the same kind? 15678 if (CI->getAssociatedExpression()->getStmtClass() != 15679 SI->getAssociatedExpression()->getStmtClass()) 15680 break; 15681 15682 // Are we dealing with different variables/fields? 15683 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15684 break; 15685 } 15686 // Check if the extra components of the expressions in the enclosing 15687 // data environment are redundant for the current base declaration. 15688 // If they are, the maps completely overlap, which is legal. 15689 for (; SI != SE; ++SI) { 15690 QualType Type; 15691 if (const auto *ASE = 15692 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15693 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15694 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15695 SI->getAssociatedExpression())) { 15696 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15697 Type = 15698 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15699 } 15700 if (Type.isNull() || Type->isAnyPointerType() || 15701 checkArrayExpressionDoesNotReferToWholeSize( 15702 SemaRef, SI->getAssociatedExpression(), Type)) 15703 break; 15704 } 15705 15706 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15707 // List items of map clauses in the same construct must not share 15708 // original storage. 15709 // 15710 // If the expressions are exactly the same or one is a subset of the 15711 // other, it means they are sharing storage. 15712 if (CI == CE && SI == SE) { 15713 if (CurrentRegionOnly) { 15714 if (CKind == OMPC_map) { 15715 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15716 } else { 15717 assert(CKind == OMPC_to || CKind == OMPC_from); 15718 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15719 << ERange; 15720 } 15721 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15722 << RE->getSourceRange(); 15723 return true; 15724 } 15725 // If we find the same expression in the enclosing data environment, 15726 // that is legal. 15727 IsEnclosedByDataEnvironmentExpr = true; 15728 return false; 15729 } 15730 15731 QualType DerivedType = 15732 std::prev(CI)->getAssociatedDeclaration()->getType(); 15733 SourceLocation DerivedLoc = 15734 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15735 15736 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15737 // If the type of a list item is a reference to a type T then the type 15738 // will be considered to be T for all purposes of this clause. 15739 DerivedType = DerivedType.getNonReferenceType(); 15740 15741 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15742 // A variable for which the type is pointer and an array section 15743 // derived from that variable must not appear as list items of map 15744 // clauses of the same construct. 15745 // 15746 // Also, cover one of the cases in: 15747 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15748 // If any part of the original storage of a list item has corresponding 15749 // storage in the device data environment, all of the original storage 15750 // must have corresponding storage in the device data environment. 15751 // 15752 if (DerivedType->isAnyPointerType()) { 15753 if (CI == CE || SI == SE) { 15754 SemaRef.Diag( 15755 DerivedLoc, 15756 diag::err_omp_pointer_mapped_along_with_derived_section) 15757 << DerivedLoc; 15758 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15759 << RE->getSourceRange(); 15760 return true; 15761 } 15762 if (CI->getAssociatedExpression()->getStmtClass() != 15763 SI->getAssociatedExpression()->getStmtClass() || 15764 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15765 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15766 assert(CI != CE && SI != SE); 15767 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15768 << DerivedLoc; 15769 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15770 << RE->getSourceRange(); 15771 return true; 15772 } 15773 } 15774 15775 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15776 // List items of map clauses in the same construct must not share 15777 // original storage. 15778 // 15779 // An expression is a subset of the other. 15780 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15781 if (CKind == OMPC_map) { 15782 if (CI != CE || SI != SE) { 15783 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15784 // a pointer. 15785 auto Begin = 15786 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15787 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15788 auto It = Begin; 15789 while (It != End && !It->getAssociatedDeclaration()) 15790 std::advance(It, 1); 15791 assert(It != End && 15792 "Expected at least one component with the declaration."); 15793 if (It != Begin && It->getAssociatedDeclaration() 15794 ->getType() 15795 .getCanonicalType() 15796 ->isAnyPointerType()) { 15797 IsEnclosedByDataEnvironmentExpr = false; 15798 EnclosingExpr = nullptr; 15799 return false; 15800 } 15801 } 15802 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15803 } else { 15804 assert(CKind == OMPC_to || CKind == OMPC_from); 15805 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15806 << ERange; 15807 } 15808 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15809 << RE->getSourceRange(); 15810 return true; 15811 } 15812 15813 // The current expression uses the same base as other expression in the 15814 // data environment but does not contain it completely. 15815 if (!CurrentRegionOnly && SI != SE) 15816 EnclosingExpr = RE; 15817 15818 // The current expression is a subset of the expression in the data 15819 // environment. 15820 IsEnclosedByDataEnvironmentExpr |= 15821 (!CurrentRegionOnly && CI != CE && SI == SE); 15822 15823 return false; 15824 }); 15825 15826 if (CurrentRegionOnly) 15827 return FoundError; 15828 15829 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15830 // If any part of the original storage of a list item has corresponding 15831 // storage in the device data environment, all of the original storage must 15832 // have corresponding storage in the device data environment. 15833 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15834 // If a list item is an element of a structure, and a different element of 15835 // the structure has a corresponding list item in the device data environment 15836 // prior to a task encountering the construct associated with the map clause, 15837 // then the list item must also have a corresponding list item in the device 15838 // data environment prior to the task encountering the construct. 15839 // 15840 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15841 SemaRef.Diag(ELoc, 15842 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15843 << ERange; 15844 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15845 << EnclosingExpr->getSourceRange(); 15846 return true; 15847 } 15848 15849 return FoundError; 15850 } 15851 15852 // Look up the user-defined mapper given the mapper name and mapped type, and 15853 // build a reference to it. 15854 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15855 CXXScopeSpec &MapperIdScopeSpec, 15856 const DeclarationNameInfo &MapperId, 15857 QualType Type, 15858 Expr *UnresolvedMapper) { 15859 if (MapperIdScopeSpec.isInvalid()) 15860 return ExprError(); 15861 // Get the actual type for the array type. 15862 if (Type->isArrayType()) { 15863 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15864 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15865 } 15866 // Find all user-defined mappers with the given MapperId. 15867 SmallVector<UnresolvedSet<8>, 4> Lookups; 15868 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15869 Lookup.suppressDiagnostics(); 15870 if (S) { 15871 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15872 NamedDecl *D = Lookup.getRepresentativeDecl(); 15873 while (S && !S->isDeclScope(D)) 15874 S = S->getParent(); 15875 if (S) 15876 S = S->getParent(); 15877 Lookups.emplace_back(); 15878 Lookups.back().append(Lookup.begin(), Lookup.end()); 15879 Lookup.clear(); 15880 } 15881 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15882 // Extract the user-defined mappers with the given MapperId. 15883 Lookups.push_back(UnresolvedSet<8>()); 15884 for (NamedDecl *D : ULE->decls()) { 15885 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15886 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15887 Lookups.back().addDecl(DMD); 15888 } 15889 } 15890 // Defer the lookup for dependent types. The results will be passed through 15891 // UnresolvedMapper on instantiation. 15892 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15893 Type->isInstantiationDependentType() || 15894 Type->containsUnexpandedParameterPack() || 15895 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15896 return !D->isInvalidDecl() && 15897 (D->getType()->isDependentType() || 15898 D->getType()->isInstantiationDependentType() || 15899 D->getType()->containsUnexpandedParameterPack()); 15900 })) { 15901 UnresolvedSet<8> URS; 15902 for (const UnresolvedSet<8> &Set : Lookups) { 15903 if (Set.empty()) 15904 continue; 15905 URS.append(Set.begin(), Set.end()); 15906 } 15907 return UnresolvedLookupExpr::Create( 15908 SemaRef.Context, /*NamingClass=*/nullptr, 15909 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15910 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15911 } 15912 SourceLocation Loc = MapperId.getLoc(); 15913 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15914 // The type must be of struct, union or class type in C and C++ 15915 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15916 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15917 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15918 return ExprError(); 15919 } 15920 // Perform argument dependent lookup. 15921 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15922 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15923 // Return the first user-defined mapper with the desired type. 15924 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15925 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15926 if (!D->isInvalidDecl() && 15927 SemaRef.Context.hasSameType(D->getType(), Type)) 15928 return D; 15929 return nullptr; 15930 })) 15931 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15932 // Find the first user-defined mapper with a type derived from the desired 15933 // type. 15934 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15935 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15936 if (!D->isInvalidDecl() && 15937 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15938 !Type.isMoreQualifiedThan(D->getType())) 15939 return D; 15940 return nullptr; 15941 })) { 15942 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15943 /*DetectVirtual=*/false); 15944 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15945 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15946 VD->getType().getUnqualifiedType()))) { 15947 if (SemaRef.CheckBaseClassAccess( 15948 Loc, VD->getType(), Type, Paths.front(), 15949 /*DiagID=*/0) != Sema::AR_inaccessible) { 15950 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15951 } 15952 } 15953 } 15954 } 15955 // Report error if a mapper is specified, but cannot be found. 15956 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15957 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15958 << Type << MapperId.getName(); 15959 return ExprError(); 15960 } 15961 return ExprEmpty(); 15962 } 15963 15964 namespace { 15965 // Utility struct that gathers all the related lists associated with a mappable 15966 // expression. 15967 struct MappableVarListInfo { 15968 // The list of expressions. 15969 ArrayRef<Expr *> VarList; 15970 // The list of processed expressions. 15971 SmallVector<Expr *, 16> ProcessedVarList; 15972 // The mappble components for each expression. 15973 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15974 // The base declaration of the variable. 15975 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15976 // The reference to the user-defined mapper associated with every expression. 15977 SmallVector<Expr *, 16> UDMapperList; 15978 15979 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15980 // We have a list of components and base declarations for each entry in the 15981 // variable list. 15982 VarComponents.reserve(VarList.size()); 15983 VarBaseDeclarations.reserve(VarList.size()); 15984 } 15985 }; 15986 } 15987 15988 // Check the validity of the provided variable list for the provided clause kind 15989 // \a CKind. In the check process the valid expressions, mappable expression 15990 // components, variables, and user-defined mappers are extracted and used to 15991 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15992 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15993 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15994 static void checkMappableExpressionList( 15995 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15996 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15997 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15998 ArrayRef<Expr *> UnresolvedMappers, 15999 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 16000 bool IsMapTypeImplicit = false) { 16001 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 16002 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 16003 "Unexpected clause kind with mappable expressions!"); 16004 16005 // If the identifier of user-defined mapper is not specified, it is "default". 16006 // We do not change the actual name in this clause to distinguish whether a 16007 // mapper is specified explicitly, i.e., it is not explicitly specified when 16008 // MapperId.getName() is empty. 16009 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 16010 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 16011 MapperId.setName(DeclNames.getIdentifier( 16012 &SemaRef.getASTContext().Idents.get("default"))); 16013 } 16014 16015 // Iterators to find the current unresolved mapper expression. 16016 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 16017 bool UpdateUMIt = false; 16018 Expr *UnresolvedMapper = nullptr; 16019 16020 // Keep track of the mappable components and base declarations in this clause. 16021 // Each entry in the list is going to have a list of components associated. We 16022 // record each set of the components so that we can build the clause later on. 16023 // In the end we should have the same amount of declarations and component 16024 // lists. 16025 16026 for (Expr *RE : MVLI.VarList) { 16027 assert(RE && "Null expr in omp to/from/map clause"); 16028 SourceLocation ELoc = RE->getExprLoc(); 16029 16030 // Find the current unresolved mapper expression. 16031 if (UpdateUMIt && UMIt != UMEnd) { 16032 UMIt++; 16033 assert( 16034 UMIt != UMEnd && 16035 "Expect the size of UnresolvedMappers to match with that of VarList"); 16036 } 16037 UpdateUMIt = true; 16038 if (UMIt != UMEnd) 16039 UnresolvedMapper = *UMIt; 16040 16041 const Expr *VE = RE->IgnoreParenLValueCasts(); 16042 16043 if (VE->isValueDependent() || VE->isTypeDependent() || 16044 VE->isInstantiationDependent() || 16045 VE->containsUnexpandedParameterPack()) { 16046 // Try to find the associated user-defined mapper. 16047 ExprResult ER = buildUserDefinedMapperRef( 16048 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16049 VE->getType().getCanonicalType(), UnresolvedMapper); 16050 if (ER.isInvalid()) 16051 continue; 16052 MVLI.UDMapperList.push_back(ER.get()); 16053 // We can only analyze this information once the missing information is 16054 // resolved. 16055 MVLI.ProcessedVarList.push_back(RE); 16056 continue; 16057 } 16058 16059 Expr *SimpleExpr = RE->IgnoreParenCasts(); 16060 16061 if (!RE->IgnoreParenImpCasts()->isLValue()) { 16062 SemaRef.Diag(ELoc, 16063 diag::err_omp_expected_named_var_member_or_array_expression) 16064 << RE->getSourceRange(); 16065 continue; 16066 } 16067 16068 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 16069 ValueDecl *CurDeclaration = nullptr; 16070 16071 // Obtain the array or member expression bases if required. Also, fill the 16072 // components array with all the components identified in the process. 16073 const Expr *BE = checkMapClauseExpressionBase( 16074 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 16075 if (!BE) 16076 continue; 16077 16078 assert(!CurComponents.empty() && 16079 "Invalid mappable expression information."); 16080 16081 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 16082 // Add store "this" pointer to class in DSAStackTy for future checking 16083 DSAS->addMappedClassesQualTypes(TE->getType()); 16084 // Try to find the associated user-defined mapper. 16085 ExprResult ER = buildUserDefinedMapperRef( 16086 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16087 VE->getType().getCanonicalType(), UnresolvedMapper); 16088 if (ER.isInvalid()) 16089 continue; 16090 MVLI.UDMapperList.push_back(ER.get()); 16091 // Skip restriction checking for variable or field declarations 16092 MVLI.ProcessedVarList.push_back(RE); 16093 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16094 MVLI.VarComponents.back().append(CurComponents.begin(), 16095 CurComponents.end()); 16096 MVLI.VarBaseDeclarations.push_back(nullptr); 16097 continue; 16098 } 16099 16100 // For the following checks, we rely on the base declaration which is 16101 // expected to be associated with the last component. The declaration is 16102 // expected to be a variable or a field (if 'this' is being mapped). 16103 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 16104 assert(CurDeclaration && "Null decl on map clause."); 16105 assert( 16106 CurDeclaration->isCanonicalDecl() && 16107 "Expecting components to have associated only canonical declarations."); 16108 16109 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 16110 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 16111 16112 assert((VD || FD) && "Only variables or fields are expected here!"); 16113 (void)FD; 16114 16115 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 16116 // threadprivate variables cannot appear in a map clause. 16117 // OpenMP 4.5 [2.10.5, target update Construct] 16118 // threadprivate variables cannot appear in a from clause. 16119 if (VD && DSAS->isThreadPrivate(VD)) { 16120 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16121 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 16122 << getOpenMPClauseName(CKind); 16123 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 16124 continue; 16125 } 16126 16127 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16128 // A list item cannot appear in both a map clause and a data-sharing 16129 // attribute clause on the same construct. 16130 16131 // Check conflicts with other map clause expressions. We check the conflicts 16132 // with the current construct separately from the enclosing data 16133 // environment, because the restrictions are different. We only have to 16134 // check conflicts across regions for the map clauses. 16135 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16136 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 16137 break; 16138 if (CKind == OMPC_map && 16139 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16140 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 16141 break; 16142 16143 // OpenMP 4.5 [2.10.5, target update Construct] 16144 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16145 // If the type of a list item is a reference to a type T then the type will 16146 // be considered to be T for all purposes of this clause. 16147 auto I = llvm::find_if( 16148 CurComponents, 16149 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16150 return MC.getAssociatedDeclaration(); 16151 }); 16152 assert(I != CurComponents.end() && "Null decl on map clause."); 16153 QualType Type; 16154 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16155 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16156 if (ASE) { 16157 Type = ASE->getType().getNonReferenceType(); 16158 } else if (OASE) { 16159 QualType BaseType = 16160 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16161 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16162 Type = ATy->getElementType(); 16163 else 16164 Type = BaseType->getPointeeType(); 16165 Type = Type.getNonReferenceType(); 16166 } else { 16167 Type = VE->getType(); 16168 } 16169 16170 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 16171 // A list item in a to or from clause must have a mappable type. 16172 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16173 // A list item must have a mappable type. 16174 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 16175 DSAS, Type)) 16176 continue; 16177 16178 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 16179 16180 if (CKind == OMPC_map) { 16181 // target enter data 16182 // OpenMP [2.10.2, Restrictions, p. 99] 16183 // A map-type must be specified in all map clauses and must be either 16184 // to or alloc. 16185 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 16186 if (DKind == OMPD_target_enter_data && 16187 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 16188 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16189 << (IsMapTypeImplicit ? 1 : 0) 16190 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16191 << getOpenMPDirectiveName(DKind); 16192 continue; 16193 } 16194 16195 // target exit_data 16196 // OpenMP [2.10.3, Restrictions, p. 102] 16197 // A map-type must be specified in all map clauses and must be either 16198 // from, release, or delete. 16199 if (DKind == OMPD_target_exit_data && 16200 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 16201 MapType == OMPC_MAP_delete)) { 16202 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16203 << (IsMapTypeImplicit ? 1 : 0) 16204 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16205 << getOpenMPDirectiveName(DKind); 16206 continue; 16207 } 16208 16209 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 16210 // A list item cannot appear in both a map clause and a data-sharing 16211 // attribute clause on the same construct 16212 // 16213 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 16214 // A list item cannot appear in both a map clause and a data-sharing 16215 // attribute clause on the same construct unless the construct is a 16216 // combined construct. 16217 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 16218 isOpenMPTargetExecutionDirective(DKind)) || 16219 DKind == OMPD_target)) { 16220 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16221 if (isOpenMPPrivate(DVar.CKind)) { 16222 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16223 << getOpenMPClauseName(DVar.CKind) 16224 << getOpenMPClauseName(OMPC_map) 16225 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 16226 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 16227 continue; 16228 } 16229 } 16230 } 16231 16232 // Try to find the associated user-defined mapper. 16233 ExprResult ER = buildUserDefinedMapperRef( 16234 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16235 Type.getCanonicalType(), UnresolvedMapper); 16236 if (ER.isInvalid()) 16237 continue; 16238 MVLI.UDMapperList.push_back(ER.get()); 16239 16240 // Save the current expression. 16241 MVLI.ProcessedVarList.push_back(RE); 16242 16243 // Store the components in the stack so that they can be used to check 16244 // against other clauses later on. 16245 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 16246 /*WhereFoundClauseKind=*/OMPC_map); 16247 16248 // Save the components and declaration to create the clause. For purposes of 16249 // the clause creation, any component list that has has base 'this' uses 16250 // null as base declaration. 16251 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16252 MVLI.VarComponents.back().append(CurComponents.begin(), 16253 CurComponents.end()); 16254 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 16255 : CurDeclaration); 16256 } 16257 } 16258 16259 OMPClause *Sema::ActOnOpenMPMapClause( 16260 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 16261 ArrayRef<SourceLocation> MapTypeModifiersLoc, 16262 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 16263 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 16264 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 16265 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 16266 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 16267 OMPC_MAP_MODIFIER_unknown, 16268 OMPC_MAP_MODIFIER_unknown}; 16269 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 16270 16271 // Process map-type-modifiers, flag errors for duplicate modifiers. 16272 unsigned Count = 0; 16273 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 16274 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 16275 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 16276 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 16277 continue; 16278 } 16279 assert(Count < OMPMapClause::NumberOfModifiers && 16280 "Modifiers exceed the allowed number of map type modifiers"); 16281 Modifiers[Count] = MapTypeModifiers[I]; 16282 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 16283 ++Count; 16284 } 16285 16286 MappableVarListInfo MVLI(VarList); 16287 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 16288 MapperIdScopeSpec, MapperId, UnresolvedMappers, 16289 MapType, IsMapTypeImplicit); 16290 16291 // We need to produce a map clause even if we don't have variables so that 16292 // other diagnostics related with non-existing map clauses are accurate. 16293 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 16294 MVLI.VarBaseDeclarations, MVLI.VarComponents, 16295 MVLI.UDMapperList, Modifiers, ModifiersLoc, 16296 MapperIdScopeSpec.getWithLocInContext(Context), 16297 MapperId, MapType, IsMapTypeImplicit, MapLoc); 16298 } 16299 16300 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 16301 TypeResult ParsedType) { 16302 assert(ParsedType.isUsable()); 16303 16304 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 16305 if (ReductionType.isNull()) 16306 return QualType(); 16307 16308 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 16309 // A type name in a declare reduction directive cannot be a function type, an 16310 // array type, a reference type, or a type qualified with const, volatile or 16311 // restrict. 16312 if (ReductionType.hasQualifiers()) { 16313 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 16314 return QualType(); 16315 } 16316 16317 if (ReductionType->isFunctionType()) { 16318 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 16319 return QualType(); 16320 } 16321 if (ReductionType->isReferenceType()) { 16322 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 16323 return QualType(); 16324 } 16325 if (ReductionType->isArrayType()) { 16326 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 16327 return QualType(); 16328 } 16329 return ReductionType; 16330 } 16331 16332 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 16333 Scope *S, DeclContext *DC, DeclarationName Name, 16334 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 16335 AccessSpecifier AS, Decl *PrevDeclInScope) { 16336 SmallVector<Decl *, 8> Decls; 16337 Decls.reserve(ReductionTypes.size()); 16338 16339 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 16340 forRedeclarationInCurContext()); 16341 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 16342 // A reduction-identifier may not be re-declared in the current scope for the 16343 // same type or for a type that is compatible according to the base language 16344 // rules. 16345 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16346 OMPDeclareReductionDecl *PrevDRD = nullptr; 16347 bool InCompoundScope = true; 16348 if (S != nullptr) { 16349 // Find previous declaration with the same name not referenced in other 16350 // declarations. 16351 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16352 InCompoundScope = 16353 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16354 LookupName(Lookup, S); 16355 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16356 /*AllowInlineNamespace=*/false); 16357 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 16358 LookupResult::Filter Filter = Lookup.makeFilter(); 16359 while (Filter.hasNext()) { 16360 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 16361 if (InCompoundScope) { 16362 auto I = UsedAsPrevious.find(PrevDecl); 16363 if (I == UsedAsPrevious.end()) 16364 UsedAsPrevious[PrevDecl] = false; 16365 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 16366 UsedAsPrevious[D] = true; 16367 } 16368 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16369 PrevDecl->getLocation(); 16370 } 16371 Filter.done(); 16372 if (InCompoundScope) { 16373 for (const auto &PrevData : UsedAsPrevious) { 16374 if (!PrevData.second) { 16375 PrevDRD = PrevData.first; 16376 break; 16377 } 16378 } 16379 } 16380 } else if (PrevDeclInScope != nullptr) { 16381 auto *PrevDRDInScope = PrevDRD = 16382 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 16383 do { 16384 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 16385 PrevDRDInScope->getLocation(); 16386 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 16387 } while (PrevDRDInScope != nullptr); 16388 } 16389 for (const auto &TyData : ReductionTypes) { 16390 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 16391 bool Invalid = false; 16392 if (I != PreviousRedeclTypes.end()) { 16393 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 16394 << TyData.first; 16395 Diag(I->second, diag::note_previous_definition); 16396 Invalid = true; 16397 } 16398 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 16399 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 16400 Name, TyData.first, PrevDRD); 16401 DC->addDecl(DRD); 16402 DRD->setAccess(AS); 16403 Decls.push_back(DRD); 16404 if (Invalid) 16405 DRD->setInvalidDecl(); 16406 else 16407 PrevDRD = DRD; 16408 } 16409 16410 return DeclGroupPtrTy::make( 16411 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 16412 } 16413 16414 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 16415 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16416 16417 // Enter new function scope. 16418 PushFunctionScope(); 16419 setFunctionHasBranchProtectedScope(); 16420 getCurFunction()->setHasOMPDeclareReductionCombiner(); 16421 16422 if (S != nullptr) 16423 PushDeclContext(S, DRD); 16424 else 16425 CurContext = DRD; 16426 16427 PushExpressionEvaluationContext( 16428 ExpressionEvaluationContext::PotentiallyEvaluated); 16429 16430 QualType ReductionType = DRD->getType(); 16431 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 16432 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 16433 // uses semantics of argument handles by value, but it should be passed by 16434 // reference. C lang does not support references, so pass all parameters as 16435 // pointers. 16436 // Create 'T omp_in;' variable. 16437 VarDecl *OmpInParm = 16438 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 16439 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 16440 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 16441 // uses semantics of argument handles by value, but it should be passed by 16442 // reference. C lang does not support references, so pass all parameters as 16443 // pointers. 16444 // Create 'T omp_out;' variable. 16445 VarDecl *OmpOutParm = 16446 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 16447 if (S != nullptr) { 16448 PushOnScopeChains(OmpInParm, S); 16449 PushOnScopeChains(OmpOutParm, S); 16450 } else { 16451 DRD->addDecl(OmpInParm); 16452 DRD->addDecl(OmpOutParm); 16453 } 16454 Expr *InE = 16455 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 16456 Expr *OutE = 16457 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 16458 DRD->setCombinerData(InE, OutE); 16459 } 16460 16461 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 16462 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16463 DiscardCleanupsInEvaluationContext(); 16464 PopExpressionEvaluationContext(); 16465 16466 PopDeclContext(); 16467 PopFunctionScopeInfo(); 16468 16469 if (Combiner != nullptr) 16470 DRD->setCombiner(Combiner); 16471 else 16472 DRD->setInvalidDecl(); 16473 } 16474 16475 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 16476 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16477 16478 // Enter new function scope. 16479 PushFunctionScope(); 16480 setFunctionHasBranchProtectedScope(); 16481 16482 if (S != nullptr) 16483 PushDeclContext(S, DRD); 16484 else 16485 CurContext = DRD; 16486 16487 PushExpressionEvaluationContext( 16488 ExpressionEvaluationContext::PotentiallyEvaluated); 16489 16490 QualType ReductionType = DRD->getType(); 16491 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 16492 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 16493 // uses semantics of argument handles by value, but it should be passed by 16494 // reference. C lang does not support references, so pass all parameters as 16495 // pointers. 16496 // Create 'T omp_priv;' variable. 16497 VarDecl *OmpPrivParm = 16498 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 16499 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 16500 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 16501 // uses semantics of argument handles by value, but it should be passed by 16502 // reference. C lang does not support references, so pass all parameters as 16503 // pointers. 16504 // Create 'T omp_orig;' variable. 16505 VarDecl *OmpOrigParm = 16506 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 16507 if (S != nullptr) { 16508 PushOnScopeChains(OmpPrivParm, S); 16509 PushOnScopeChains(OmpOrigParm, S); 16510 } else { 16511 DRD->addDecl(OmpPrivParm); 16512 DRD->addDecl(OmpOrigParm); 16513 } 16514 Expr *OrigE = 16515 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 16516 Expr *PrivE = 16517 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 16518 DRD->setInitializerData(OrigE, PrivE); 16519 return OmpPrivParm; 16520 } 16521 16522 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 16523 VarDecl *OmpPrivParm) { 16524 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16525 DiscardCleanupsInEvaluationContext(); 16526 PopExpressionEvaluationContext(); 16527 16528 PopDeclContext(); 16529 PopFunctionScopeInfo(); 16530 16531 if (Initializer != nullptr) { 16532 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 16533 } else if (OmpPrivParm->hasInit()) { 16534 DRD->setInitializer(OmpPrivParm->getInit(), 16535 OmpPrivParm->isDirectInit() 16536 ? OMPDeclareReductionDecl::DirectInit 16537 : OMPDeclareReductionDecl::CopyInit); 16538 } else { 16539 DRD->setInvalidDecl(); 16540 } 16541 } 16542 16543 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 16544 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 16545 for (Decl *D : DeclReductions.get()) { 16546 if (IsValid) { 16547 if (S) 16548 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 16549 /*AddToContext=*/false); 16550 } else { 16551 D->setInvalidDecl(); 16552 } 16553 } 16554 return DeclReductions; 16555 } 16556 16557 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 16558 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 16559 QualType T = TInfo->getType(); 16560 if (D.isInvalidType()) 16561 return true; 16562 16563 if (getLangOpts().CPlusPlus) { 16564 // Check that there are no default arguments (C++ only). 16565 CheckExtraCXXDefaultArguments(D); 16566 } 16567 16568 return CreateParsedType(T, TInfo); 16569 } 16570 16571 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 16572 TypeResult ParsedType) { 16573 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 16574 16575 QualType MapperType = GetTypeFromParser(ParsedType.get()); 16576 assert(!MapperType.isNull() && "Expect valid mapper type"); 16577 16578 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16579 // The type must be of struct, union or class type in C and C++ 16580 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 16581 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 16582 return QualType(); 16583 } 16584 return MapperType; 16585 } 16586 16587 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 16588 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 16589 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 16590 Decl *PrevDeclInScope) { 16591 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 16592 forRedeclarationInCurContext()); 16593 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16594 // A mapper-identifier may not be redeclared in the current scope for the 16595 // same type or for a type that is compatible according to the base language 16596 // rules. 16597 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16598 OMPDeclareMapperDecl *PrevDMD = nullptr; 16599 bool InCompoundScope = true; 16600 if (S != nullptr) { 16601 // Find previous declaration with the same name not referenced in other 16602 // declarations. 16603 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16604 InCompoundScope = 16605 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16606 LookupName(Lookup, S); 16607 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16608 /*AllowInlineNamespace=*/false); 16609 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 16610 LookupResult::Filter Filter = Lookup.makeFilter(); 16611 while (Filter.hasNext()) { 16612 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 16613 if (InCompoundScope) { 16614 auto I = UsedAsPrevious.find(PrevDecl); 16615 if (I == UsedAsPrevious.end()) 16616 UsedAsPrevious[PrevDecl] = false; 16617 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16618 UsedAsPrevious[D] = true; 16619 } 16620 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16621 PrevDecl->getLocation(); 16622 } 16623 Filter.done(); 16624 if (InCompoundScope) { 16625 for (const auto &PrevData : UsedAsPrevious) { 16626 if (!PrevData.second) { 16627 PrevDMD = PrevData.first; 16628 break; 16629 } 16630 } 16631 } 16632 } else if (PrevDeclInScope) { 16633 auto *PrevDMDInScope = PrevDMD = 16634 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16635 do { 16636 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16637 PrevDMDInScope->getLocation(); 16638 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16639 } while (PrevDMDInScope != nullptr); 16640 } 16641 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16642 bool Invalid = false; 16643 if (I != PreviousRedeclTypes.end()) { 16644 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16645 << MapperType << Name; 16646 Diag(I->second, diag::note_previous_definition); 16647 Invalid = true; 16648 } 16649 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16650 MapperType, VN, PrevDMD); 16651 DC->addDecl(DMD); 16652 DMD->setAccess(AS); 16653 if (Invalid) 16654 DMD->setInvalidDecl(); 16655 16656 // Enter new function scope. 16657 PushFunctionScope(); 16658 setFunctionHasBranchProtectedScope(); 16659 16660 CurContext = DMD; 16661 16662 return DMD; 16663 } 16664 16665 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16666 Scope *S, 16667 QualType MapperType, 16668 SourceLocation StartLoc, 16669 DeclarationName VN) { 16670 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16671 if (S) 16672 PushOnScopeChains(VD, S); 16673 else 16674 DMD->addDecl(VD); 16675 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16676 DMD->setMapperVarRef(MapperVarRefExpr); 16677 } 16678 16679 Sema::DeclGroupPtrTy 16680 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16681 ArrayRef<OMPClause *> ClauseList) { 16682 PopDeclContext(); 16683 PopFunctionScopeInfo(); 16684 16685 if (D) { 16686 if (S) 16687 PushOnScopeChains(D, S, /*AddToContext=*/false); 16688 D->CreateClauses(Context, ClauseList); 16689 } 16690 16691 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16692 } 16693 16694 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16695 SourceLocation StartLoc, 16696 SourceLocation LParenLoc, 16697 SourceLocation EndLoc) { 16698 Expr *ValExpr = NumTeams; 16699 Stmt *HelperValStmt = nullptr; 16700 16701 // OpenMP [teams Constrcut, Restrictions] 16702 // The num_teams expression must evaluate to a positive integer value. 16703 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16704 /*StrictlyPositive=*/true)) 16705 return nullptr; 16706 16707 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16708 OpenMPDirectiveKind CaptureRegion = 16709 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 16710 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16711 ValExpr = MakeFullExpr(ValExpr).get(); 16712 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16713 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16714 HelperValStmt = buildPreInits(Context, Captures); 16715 } 16716 16717 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16718 StartLoc, LParenLoc, EndLoc); 16719 } 16720 16721 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16722 SourceLocation StartLoc, 16723 SourceLocation LParenLoc, 16724 SourceLocation EndLoc) { 16725 Expr *ValExpr = ThreadLimit; 16726 Stmt *HelperValStmt = nullptr; 16727 16728 // OpenMP [teams Constrcut, Restrictions] 16729 // The thread_limit expression must evaluate to a positive integer value. 16730 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16731 /*StrictlyPositive=*/true)) 16732 return nullptr; 16733 16734 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16735 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 16736 DKind, OMPC_thread_limit, LangOpts.OpenMP); 16737 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16738 ValExpr = MakeFullExpr(ValExpr).get(); 16739 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16740 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16741 HelperValStmt = buildPreInits(Context, Captures); 16742 } 16743 16744 return new (Context) OMPThreadLimitClause( 16745 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16746 } 16747 16748 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16749 SourceLocation StartLoc, 16750 SourceLocation LParenLoc, 16751 SourceLocation EndLoc) { 16752 Expr *ValExpr = Priority; 16753 Stmt *HelperValStmt = nullptr; 16754 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16755 16756 // OpenMP [2.9.1, task Constrcut] 16757 // The priority-value is a non-negative numerical scalar expression. 16758 if (!isNonNegativeIntegerValue( 16759 ValExpr, *this, OMPC_priority, 16760 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16761 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16762 return nullptr; 16763 16764 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16765 StartLoc, LParenLoc, EndLoc); 16766 } 16767 16768 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16769 SourceLocation StartLoc, 16770 SourceLocation LParenLoc, 16771 SourceLocation EndLoc) { 16772 Expr *ValExpr = Grainsize; 16773 Stmt *HelperValStmt = nullptr; 16774 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16775 16776 // OpenMP [2.9.2, taskloop Constrcut] 16777 // The parameter of the grainsize clause must be a positive integer 16778 // expression. 16779 if (!isNonNegativeIntegerValue( 16780 ValExpr, *this, OMPC_grainsize, 16781 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16782 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16783 return nullptr; 16784 16785 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16786 StartLoc, LParenLoc, EndLoc); 16787 } 16788 16789 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16790 SourceLocation StartLoc, 16791 SourceLocation LParenLoc, 16792 SourceLocation EndLoc) { 16793 Expr *ValExpr = NumTasks; 16794 Stmt *HelperValStmt = nullptr; 16795 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16796 16797 // OpenMP [2.9.2, taskloop Constrcut] 16798 // The parameter of the num_tasks clause must be a positive integer 16799 // expression. 16800 if (!isNonNegativeIntegerValue( 16801 ValExpr, *this, OMPC_num_tasks, 16802 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16803 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16804 return nullptr; 16805 16806 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16807 StartLoc, LParenLoc, EndLoc); 16808 } 16809 16810 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16811 SourceLocation LParenLoc, 16812 SourceLocation EndLoc) { 16813 // OpenMP [2.13.2, critical construct, Description] 16814 // ... where hint-expression is an integer constant expression that evaluates 16815 // to a valid lock hint. 16816 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16817 if (HintExpr.isInvalid()) 16818 return nullptr; 16819 return new (Context) 16820 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16821 } 16822 16823 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16824 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16825 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16826 SourceLocation EndLoc) { 16827 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16828 std::string Values; 16829 Values += "'"; 16830 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16831 Values += "'"; 16832 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16833 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16834 return nullptr; 16835 } 16836 Expr *ValExpr = ChunkSize; 16837 Stmt *HelperValStmt = nullptr; 16838 if (ChunkSize) { 16839 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16840 !ChunkSize->isInstantiationDependent() && 16841 !ChunkSize->containsUnexpandedParameterPack()) { 16842 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16843 ExprResult Val = 16844 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16845 if (Val.isInvalid()) 16846 return nullptr; 16847 16848 ValExpr = Val.get(); 16849 16850 // OpenMP [2.7.1, Restrictions] 16851 // chunk_size must be a loop invariant integer expression with a positive 16852 // value. 16853 llvm::APSInt Result; 16854 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16855 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16856 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16857 << "dist_schedule" << ChunkSize->getSourceRange(); 16858 return nullptr; 16859 } 16860 } else if (getOpenMPCaptureRegionForClause( 16861 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 16862 LangOpts.OpenMP) != OMPD_unknown && 16863 !CurContext->isDependentContext()) { 16864 ValExpr = MakeFullExpr(ValExpr).get(); 16865 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16866 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16867 HelperValStmt = buildPreInits(Context, Captures); 16868 } 16869 } 16870 } 16871 16872 return new (Context) 16873 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16874 Kind, ValExpr, HelperValStmt); 16875 } 16876 16877 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16878 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16879 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16880 SourceLocation KindLoc, SourceLocation EndLoc) { 16881 if (getLangOpts().OpenMP < 50) { 16882 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 16883 Kind != OMPC_DEFAULTMAP_scalar) { 16884 std::string Value; 16885 SourceLocation Loc; 16886 Value += "'"; 16887 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16888 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16889 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16890 Loc = MLoc; 16891 } else { 16892 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16893 OMPC_DEFAULTMAP_scalar); 16894 Loc = KindLoc; 16895 } 16896 Value += "'"; 16897 Diag(Loc, diag::err_omp_unexpected_clause_value) 16898 << Value << getOpenMPClauseName(OMPC_defaultmap); 16899 return nullptr; 16900 } 16901 } else { 16902 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 16903 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 16904 if (!isDefaultmapKind || !isDefaultmapModifier) { 16905 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 16906 "'firstprivate', 'none', 'default'"; 16907 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 16908 if (!isDefaultmapKind && isDefaultmapModifier) { 16909 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16910 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16911 } else if (isDefaultmapKind && !isDefaultmapModifier) { 16912 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16913 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16914 } else { 16915 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16916 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16917 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16918 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16919 } 16920 return nullptr; 16921 } 16922 16923 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 16924 // At most one defaultmap clause for each category can appear on the 16925 // directive. 16926 if (DSAStack->checkDefaultmapCategory(Kind)) { 16927 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 16928 return nullptr; 16929 } 16930 } 16931 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 16932 16933 return new (Context) 16934 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16935 } 16936 16937 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16938 DeclContext *CurLexicalContext = getCurLexicalContext(); 16939 if (!CurLexicalContext->isFileContext() && 16940 !CurLexicalContext->isExternCContext() && 16941 !CurLexicalContext->isExternCXXContext() && 16942 !isa<CXXRecordDecl>(CurLexicalContext) && 16943 !isa<ClassTemplateDecl>(CurLexicalContext) && 16944 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16945 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16946 Diag(Loc, diag::err_omp_region_not_file_context); 16947 return false; 16948 } 16949 ++DeclareTargetNestingLevel; 16950 return true; 16951 } 16952 16953 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16954 assert(DeclareTargetNestingLevel > 0 && 16955 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16956 --DeclareTargetNestingLevel; 16957 } 16958 16959 NamedDecl * 16960 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16961 const DeclarationNameInfo &Id, 16962 NamedDeclSetType &SameDirectiveDecls) { 16963 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16964 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16965 16966 if (Lookup.isAmbiguous()) 16967 return nullptr; 16968 Lookup.suppressDiagnostics(); 16969 16970 if (!Lookup.isSingleResult()) { 16971 VarOrFuncDeclFilterCCC CCC(*this); 16972 if (TypoCorrection Corrected = 16973 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16974 CTK_ErrorRecovery)) { 16975 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16976 << Id.getName()); 16977 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16978 return nullptr; 16979 } 16980 16981 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16982 return nullptr; 16983 } 16984 16985 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16986 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16987 !isa<FunctionTemplateDecl>(ND)) { 16988 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16989 return nullptr; 16990 } 16991 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16992 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16993 return ND; 16994 } 16995 16996 void Sema::ActOnOpenMPDeclareTargetName( 16997 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16998 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16999 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 17000 isa<FunctionTemplateDecl>(ND)) && 17001 "Expected variable, function or function template."); 17002 17003 // Diagnose marking after use as it may lead to incorrect diagnosis and 17004 // codegen. 17005 if (LangOpts.OpenMP >= 50 && 17006 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 17007 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 17008 17009 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17010 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 17011 if (DevTy.hasValue() && *DevTy != DT) { 17012 Diag(Loc, diag::err_omp_device_type_mismatch) 17013 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 17014 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 17015 return; 17016 } 17017 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17018 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 17019 if (!Res) { 17020 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 17021 SourceRange(Loc, Loc)); 17022 ND->addAttr(A); 17023 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17024 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 17025 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 17026 } else if (*Res != MT) { 17027 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 17028 } 17029 } 17030 17031 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 17032 Sema &SemaRef, Decl *D) { 17033 if (!D || !isa<VarDecl>(D)) 17034 return; 17035 auto *VD = cast<VarDecl>(D); 17036 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17037 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17038 if (SemaRef.LangOpts.OpenMP >= 50 && 17039 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 17040 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 17041 VD->hasGlobalStorage()) { 17042 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17043 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17044 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 17045 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 17046 // If a lambda declaration and definition appears between a 17047 // declare target directive and the matching end declare target 17048 // directive, all variables that are captured by the lambda 17049 // expression must also appear in a to clause. 17050 SemaRef.Diag(VD->getLocation(), 17051 diag::err_omp_lambda_capture_in_declare_target_not_to); 17052 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 17053 << VD << 0 << SR; 17054 return; 17055 } 17056 } 17057 if (MapTy.hasValue()) 17058 return; 17059 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 17060 SemaRef.Diag(SL, diag::note_used_here) << SR; 17061 } 17062 17063 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 17064 Sema &SemaRef, DSAStackTy *Stack, 17065 ValueDecl *VD) { 17066 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 17067 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 17068 /*FullCheck=*/false); 17069 } 17070 17071 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 17072 SourceLocation IdLoc) { 17073 if (!D || D->isInvalidDecl()) 17074 return; 17075 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 17076 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 17077 if (auto *VD = dyn_cast<VarDecl>(D)) { 17078 // Only global variables can be marked as declare target. 17079 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 17080 !VD->isStaticDataMember()) 17081 return; 17082 // 2.10.6: threadprivate variable cannot appear in a declare target 17083 // directive. 17084 if (DSAStack->isThreadPrivate(VD)) { 17085 Diag(SL, diag::err_omp_threadprivate_in_target); 17086 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 17087 return; 17088 } 17089 } 17090 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 17091 D = FTD->getTemplatedDecl(); 17092 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 17093 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17094 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 17095 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 17096 Diag(IdLoc, diag::err_omp_function_in_link_clause); 17097 Diag(FD->getLocation(), diag::note_defined_here) << FD; 17098 return; 17099 } 17100 // Mark the function as must be emitted for the device. 17101 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17102 OMPDeclareTargetDeclAttr::getDeviceType(FD); 17103 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 17104 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 17105 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 17106 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 17107 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 17108 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 17109 } 17110 if (auto *VD = dyn_cast<ValueDecl>(D)) { 17111 // Problem if any with var declared with incomplete type will be reported 17112 // as normal, so no need to check it here. 17113 if ((E || !VD->getType()->isIncompleteType()) && 17114 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 17115 return; 17116 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 17117 // Checking declaration inside declare target region. 17118 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 17119 isa<FunctionTemplateDecl>(D)) { 17120 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 17121 Context, OMPDeclareTargetDeclAttr::MT_To, 17122 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 17123 D->addAttr(A); 17124 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17125 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 17126 } 17127 return; 17128 } 17129 } 17130 if (!E) 17131 return; 17132 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 17133 } 17134 17135 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 17136 CXXScopeSpec &MapperIdScopeSpec, 17137 DeclarationNameInfo &MapperId, 17138 const OMPVarListLocTy &Locs, 17139 ArrayRef<Expr *> UnresolvedMappers) { 17140 MappableVarListInfo MVLI(VarList); 17141 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 17142 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17143 if (MVLI.ProcessedVarList.empty()) 17144 return nullptr; 17145 17146 return OMPToClause::Create( 17147 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17148 MVLI.VarComponents, MVLI.UDMapperList, 17149 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17150 } 17151 17152 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 17153 CXXScopeSpec &MapperIdScopeSpec, 17154 DeclarationNameInfo &MapperId, 17155 const OMPVarListLocTy &Locs, 17156 ArrayRef<Expr *> UnresolvedMappers) { 17157 MappableVarListInfo MVLI(VarList); 17158 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 17159 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17160 if (MVLI.ProcessedVarList.empty()) 17161 return nullptr; 17162 17163 return OMPFromClause::Create( 17164 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17165 MVLI.VarComponents, MVLI.UDMapperList, 17166 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17167 } 17168 17169 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 17170 const OMPVarListLocTy &Locs) { 17171 MappableVarListInfo MVLI(VarList); 17172 SmallVector<Expr *, 8> PrivateCopies; 17173 SmallVector<Expr *, 8> Inits; 17174 17175 for (Expr *RefExpr : VarList) { 17176 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 17177 SourceLocation ELoc; 17178 SourceRange ERange; 17179 Expr *SimpleRefExpr = RefExpr; 17180 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17181 if (Res.second) { 17182 // It will be analyzed later. 17183 MVLI.ProcessedVarList.push_back(RefExpr); 17184 PrivateCopies.push_back(nullptr); 17185 Inits.push_back(nullptr); 17186 } 17187 ValueDecl *D = Res.first; 17188 if (!D) 17189 continue; 17190 17191 QualType Type = D->getType(); 17192 Type = Type.getNonReferenceType().getUnqualifiedType(); 17193 17194 auto *VD = dyn_cast<VarDecl>(D); 17195 17196 // Item should be a pointer or reference to pointer. 17197 if (!Type->isPointerType()) { 17198 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 17199 << 0 << RefExpr->getSourceRange(); 17200 continue; 17201 } 17202 17203 // Build the private variable and the expression that refers to it. 17204 auto VDPrivate = 17205 buildVarDecl(*this, ELoc, Type, D->getName(), 17206 D->hasAttrs() ? &D->getAttrs() : nullptr, 17207 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17208 if (VDPrivate->isInvalidDecl()) 17209 continue; 17210 17211 CurContext->addDecl(VDPrivate); 17212 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17213 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17214 17215 // Add temporary variable to initialize the private copy of the pointer. 17216 VarDecl *VDInit = 17217 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 17218 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 17219 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 17220 AddInitializerToDecl(VDPrivate, 17221 DefaultLvalueConversion(VDInitRefExpr).get(), 17222 /*DirectInit=*/false); 17223 17224 // If required, build a capture to implement the privatization initialized 17225 // with the current list item value. 17226 DeclRefExpr *Ref = nullptr; 17227 if (!VD) 17228 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17229 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 17230 PrivateCopies.push_back(VDPrivateRefExpr); 17231 Inits.push_back(VDInitRefExpr); 17232 17233 // We need to add a data sharing attribute for this variable to make sure it 17234 // is correctly captured. A variable that shows up in a use_device_ptr has 17235 // similar properties of a first private variable. 17236 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17237 17238 // Create a mappable component for the list item. List items in this clause 17239 // only need a component. 17240 MVLI.VarBaseDeclarations.push_back(D); 17241 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17242 MVLI.VarComponents.back().push_back( 17243 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 17244 } 17245 17246 if (MVLI.ProcessedVarList.empty()) 17247 return nullptr; 17248 17249 return OMPUseDevicePtrClause::Create( 17250 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 17251 MVLI.VarBaseDeclarations, MVLI.VarComponents); 17252 } 17253 17254 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 17255 const OMPVarListLocTy &Locs) { 17256 MappableVarListInfo MVLI(VarList); 17257 for (Expr *RefExpr : VarList) { 17258 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 17259 SourceLocation ELoc; 17260 SourceRange ERange; 17261 Expr *SimpleRefExpr = RefExpr; 17262 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17263 if (Res.second) { 17264 // It will be analyzed later. 17265 MVLI.ProcessedVarList.push_back(RefExpr); 17266 } 17267 ValueDecl *D = Res.first; 17268 if (!D) 17269 continue; 17270 17271 QualType Type = D->getType(); 17272 // item should be a pointer or array or reference to pointer or array 17273 if (!Type.getNonReferenceType()->isPointerType() && 17274 !Type.getNonReferenceType()->isArrayType()) { 17275 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 17276 << 0 << RefExpr->getSourceRange(); 17277 continue; 17278 } 17279 17280 // Check if the declaration in the clause does not show up in any data 17281 // sharing attribute. 17282 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17283 if (isOpenMPPrivate(DVar.CKind)) { 17284 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17285 << getOpenMPClauseName(DVar.CKind) 17286 << getOpenMPClauseName(OMPC_is_device_ptr) 17287 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17288 reportOriginalDsa(*this, DSAStack, D, DVar); 17289 continue; 17290 } 17291 17292 const Expr *ConflictExpr; 17293 if (DSAStack->checkMappableExprComponentListsForDecl( 17294 D, /*CurrentRegionOnly=*/true, 17295 [&ConflictExpr]( 17296 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 17297 OpenMPClauseKind) -> bool { 17298 ConflictExpr = R.front().getAssociatedExpression(); 17299 return true; 17300 })) { 17301 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 17302 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 17303 << ConflictExpr->getSourceRange(); 17304 continue; 17305 } 17306 17307 // Store the components in the stack so that they can be used to check 17308 // against other clauses later on. 17309 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 17310 DSAStack->addMappableExpressionComponents( 17311 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 17312 17313 // Record the expression we've just processed. 17314 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 17315 17316 // Create a mappable component for the list item. List items in this clause 17317 // only need a component. We use a null declaration to signal fields in 17318 // 'this'. 17319 assert((isa<DeclRefExpr>(SimpleRefExpr) || 17320 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 17321 "Unexpected device pointer expression!"); 17322 MVLI.VarBaseDeclarations.push_back( 17323 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 17324 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17325 MVLI.VarComponents.back().push_back(MC); 17326 } 17327 17328 if (MVLI.ProcessedVarList.empty()) 17329 return nullptr; 17330 17331 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 17332 MVLI.VarBaseDeclarations, 17333 MVLI.VarComponents); 17334 } 17335 17336 OMPClause *Sema::ActOnOpenMPAllocateClause( 17337 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 17338 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 17339 if (Allocator) { 17340 // OpenMP [2.11.4 allocate Clause, Description] 17341 // allocator is an expression of omp_allocator_handle_t type. 17342 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 17343 return nullptr; 17344 17345 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 17346 if (AllocatorRes.isInvalid()) 17347 return nullptr; 17348 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 17349 DSAStack->getOMPAllocatorHandleT(), 17350 Sema::AA_Initializing, 17351 /*AllowExplicit=*/true); 17352 if (AllocatorRes.isInvalid()) 17353 return nullptr; 17354 Allocator = AllocatorRes.get(); 17355 } else { 17356 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 17357 // allocate clauses that appear on a target construct or on constructs in a 17358 // target region must specify an allocator expression unless a requires 17359 // directive with the dynamic_allocators clause is present in the same 17360 // compilation unit. 17361 if (LangOpts.OpenMPIsDevice && 17362 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 17363 targetDiag(StartLoc, diag::err_expected_allocator_expression); 17364 } 17365 // Analyze and build list of variables. 17366 SmallVector<Expr *, 8> Vars; 17367 for (Expr *RefExpr : VarList) { 17368 assert(RefExpr && "NULL expr in OpenMP private clause."); 17369 SourceLocation ELoc; 17370 SourceRange ERange; 17371 Expr *SimpleRefExpr = RefExpr; 17372 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17373 if (Res.second) { 17374 // It will be analyzed later. 17375 Vars.push_back(RefExpr); 17376 } 17377 ValueDecl *D = Res.first; 17378 if (!D) 17379 continue; 17380 17381 auto *VD = dyn_cast<VarDecl>(D); 17382 DeclRefExpr *Ref = nullptr; 17383 if (!VD && !CurContext->isDependentContext()) 17384 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17385 Vars.push_back((VD || CurContext->isDependentContext()) 17386 ? RefExpr->IgnoreParens() 17387 : Ref); 17388 } 17389 17390 if (Vars.empty()) 17391 return nullptr; 17392 17393 if (Allocator) 17394 DSAStack->addInnerAllocatorExpr(Allocator); 17395 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 17396 ColonLoc, EndLoc, Vars); 17397 } 17398 17399 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 17400 SourceLocation StartLoc, 17401 SourceLocation LParenLoc, 17402 SourceLocation EndLoc) { 17403 SmallVector<Expr *, 8> Vars; 17404 for (Expr *RefExpr : VarList) { 17405 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 17406 SourceLocation ELoc; 17407 SourceRange ERange; 17408 Expr *SimpleRefExpr = RefExpr; 17409 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17410 if (Res.second) 17411 // It will be analyzed later. 17412 Vars.push_back(RefExpr); 17413 ValueDecl *D = Res.first; 17414 if (!D) 17415 continue; 17416 17417 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 17418 // A list-item cannot appear in more than one nontemporal clause. 17419 if (const Expr *PrevRef = 17420 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 17421 Diag(ELoc, diag::err_omp_used_in_clause_twice) 17422 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 17423 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 17424 << getOpenMPClauseName(OMPC_nontemporal); 17425 continue; 17426 } 17427 17428 Vars.push_back(RefExpr); 17429 } 17430 17431 if (Vars.empty()) 17432 return nullptr; 17433 17434 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17435 Vars); 17436 } 17437