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_depend: 4991 case OMPC_threads: 4992 case OMPC_simd: 4993 case OMPC_map: 4994 case OMPC_nogroup: 4995 case OMPC_defaultmap: 4996 case OMPC_to: 4997 case OMPC_from: 4998 case OMPC_use_device_ptr: 4999 case OMPC_is_device_ptr: 5000 case OMPC_nontemporal: 5001 case OMPC_order: 5002 continue; 5003 case OMPC_allocator: 5004 case OMPC_flush: 5005 case OMPC_threadprivate: 5006 case OMPC_uniform: 5007 case OMPC_unknown: 5008 case OMPC_unified_address: 5009 case OMPC_unified_shared_memory: 5010 case OMPC_reverse_offload: 5011 case OMPC_dynamic_allocators: 5012 case OMPC_atomic_default_mem_order: 5013 case OMPC_device_type: 5014 case OMPC_match: 5015 llvm_unreachable("Unexpected clause"); 5016 } 5017 for (Stmt *CC : C->children()) { 5018 if (CC) 5019 DSAChecker.Visit(CC); 5020 } 5021 } 5022 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5023 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5024 } 5025 for (const auto &P : VarsWithInheritedDSA) { 5026 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5027 continue; 5028 ErrorFound = true; 5029 if (DSAStack->getDefaultDSA() == DSA_none) { 5030 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5031 << P.first << P.second->getSourceRange(); 5032 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5033 } else if (getLangOpts().OpenMP >= 50) { 5034 Diag(P.second->getExprLoc(), 5035 diag::err_omp_defaultmap_no_attr_for_variable) 5036 << P.first << P.second->getSourceRange(); 5037 Diag(DSAStack->getDefaultDSALocation(), 5038 diag::note_omp_defaultmap_attr_none); 5039 } 5040 } 5041 5042 if (!AllowedNameModifiers.empty()) 5043 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5044 ErrorFound; 5045 5046 if (ErrorFound) 5047 return StmtError(); 5048 5049 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 5050 Res.getAs<OMPExecutableDirective>() 5051 ->getStructuredBlock() 5052 ->setIsOMPStructuredBlock(true); 5053 } 5054 5055 if (!CurContext->isDependentContext() && 5056 isOpenMPTargetExecutionDirective(Kind) && 5057 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5058 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5059 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5060 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5061 // Register target to DSA Stack. 5062 DSAStack->addTargetDirLocation(StartLoc); 5063 } 5064 5065 return Res; 5066 } 5067 5068 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5069 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5070 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5071 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5072 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5073 assert(Aligneds.size() == Alignments.size()); 5074 assert(Linears.size() == LinModifiers.size()); 5075 assert(Linears.size() == Steps.size()); 5076 if (!DG || DG.get().isNull()) 5077 return DeclGroupPtrTy(); 5078 5079 const int SimdId = 0; 5080 if (!DG.get().isSingleDecl()) { 5081 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5082 << SimdId; 5083 return DG; 5084 } 5085 Decl *ADecl = DG.get().getSingleDecl(); 5086 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5087 ADecl = FTD->getTemplatedDecl(); 5088 5089 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5090 if (!FD) { 5091 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5092 return DeclGroupPtrTy(); 5093 } 5094 5095 // OpenMP [2.8.2, declare simd construct, Description] 5096 // The parameter of the simdlen clause must be a constant positive integer 5097 // expression. 5098 ExprResult SL; 5099 if (Simdlen) 5100 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5101 // OpenMP [2.8.2, declare simd construct, Description] 5102 // The special this pointer can be used as if was one of the arguments to the 5103 // function in any of the linear, aligned, or uniform clauses. 5104 // The uniform clause declares one or more arguments to have an invariant 5105 // value for all concurrent invocations of the function in the execution of a 5106 // single SIMD loop. 5107 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5108 const Expr *UniformedLinearThis = nullptr; 5109 for (const Expr *E : Uniforms) { 5110 E = E->IgnoreParenImpCasts(); 5111 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5112 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5113 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5114 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5115 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5116 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5117 continue; 5118 } 5119 if (isa<CXXThisExpr>(E)) { 5120 UniformedLinearThis = E; 5121 continue; 5122 } 5123 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5124 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5125 } 5126 // OpenMP [2.8.2, declare simd construct, Description] 5127 // The aligned clause declares that the object to which each list item points 5128 // is aligned to the number of bytes expressed in the optional parameter of 5129 // the aligned clause. 5130 // The special this pointer can be used as if was one of the arguments to the 5131 // function in any of the linear, aligned, or uniform clauses. 5132 // The type of list items appearing in the aligned clause must be array, 5133 // pointer, reference to array, or reference to pointer. 5134 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5135 const Expr *AlignedThis = nullptr; 5136 for (const Expr *E : Aligneds) { 5137 E = E->IgnoreParenImpCasts(); 5138 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5139 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5140 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5141 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5142 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5143 ->getCanonicalDecl() == CanonPVD) { 5144 // OpenMP [2.8.1, simd construct, Restrictions] 5145 // A list-item cannot appear in more than one aligned clause. 5146 if (AlignedArgs.count(CanonPVD) > 0) { 5147 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5148 << 1 << getOpenMPClauseName(OMPC_aligned) 5149 << E->getSourceRange(); 5150 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5151 diag::note_omp_explicit_dsa) 5152 << getOpenMPClauseName(OMPC_aligned); 5153 continue; 5154 } 5155 AlignedArgs[CanonPVD] = E; 5156 QualType QTy = PVD->getType() 5157 .getNonReferenceType() 5158 .getUnqualifiedType() 5159 .getCanonicalType(); 5160 const Type *Ty = QTy.getTypePtrOrNull(); 5161 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5162 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5163 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5164 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5165 } 5166 continue; 5167 } 5168 } 5169 if (isa<CXXThisExpr>(E)) { 5170 if (AlignedThis) { 5171 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5172 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5173 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5174 << getOpenMPClauseName(OMPC_aligned); 5175 } 5176 AlignedThis = E; 5177 continue; 5178 } 5179 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5180 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5181 } 5182 // The optional parameter of the aligned clause, alignment, must be a constant 5183 // positive integer expression. If no optional parameter is specified, 5184 // implementation-defined default alignments for SIMD instructions on the 5185 // target platforms are assumed. 5186 SmallVector<const Expr *, 4> NewAligns; 5187 for (Expr *E : Alignments) { 5188 ExprResult Align; 5189 if (E) 5190 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5191 NewAligns.push_back(Align.get()); 5192 } 5193 // OpenMP [2.8.2, declare simd construct, Description] 5194 // The linear clause declares one or more list items to be private to a SIMD 5195 // lane and to have a linear relationship with respect to the iteration space 5196 // of a loop. 5197 // The special this pointer can be used as if was one of the arguments to the 5198 // function in any of the linear, aligned, or uniform clauses. 5199 // When a linear-step expression is specified in a linear clause it must be 5200 // either a constant integer expression or an integer-typed parameter that is 5201 // specified in a uniform clause on the directive. 5202 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5203 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5204 auto MI = LinModifiers.begin(); 5205 for (const Expr *E : Linears) { 5206 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5207 ++MI; 5208 E = E->IgnoreParenImpCasts(); 5209 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5210 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5211 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5212 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5213 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5214 ->getCanonicalDecl() == CanonPVD) { 5215 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5216 // A list-item cannot appear in more than one linear clause. 5217 if (LinearArgs.count(CanonPVD) > 0) { 5218 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5219 << getOpenMPClauseName(OMPC_linear) 5220 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5221 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5222 diag::note_omp_explicit_dsa) 5223 << getOpenMPClauseName(OMPC_linear); 5224 continue; 5225 } 5226 // Each argument can appear in at most one uniform or linear clause. 5227 if (UniformedArgs.count(CanonPVD) > 0) { 5228 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5229 << getOpenMPClauseName(OMPC_linear) 5230 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5231 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5232 diag::note_omp_explicit_dsa) 5233 << getOpenMPClauseName(OMPC_uniform); 5234 continue; 5235 } 5236 LinearArgs[CanonPVD] = E; 5237 if (E->isValueDependent() || E->isTypeDependent() || 5238 E->isInstantiationDependent() || 5239 E->containsUnexpandedParameterPack()) 5240 continue; 5241 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5242 PVD->getOriginalType()); 5243 continue; 5244 } 5245 } 5246 if (isa<CXXThisExpr>(E)) { 5247 if (UniformedLinearThis) { 5248 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5249 << getOpenMPClauseName(OMPC_linear) 5250 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5251 << E->getSourceRange(); 5252 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5253 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5254 : OMPC_linear); 5255 continue; 5256 } 5257 UniformedLinearThis = E; 5258 if (E->isValueDependent() || E->isTypeDependent() || 5259 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5260 continue; 5261 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5262 E->getType()); 5263 continue; 5264 } 5265 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5266 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5267 } 5268 Expr *Step = nullptr; 5269 Expr *NewStep = nullptr; 5270 SmallVector<Expr *, 4> NewSteps; 5271 for (Expr *E : Steps) { 5272 // Skip the same step expression, it was checked already. 5273 if (Step == E || !E) { 5274 NewSteps.push_back(E ? NewStep : nullptr); 5275 continue; 5276 } 5277 Step = E; 5278 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5279 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5280 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5281 if (UniformedArgs.count(CanonPVD) == 0) { 5282 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5283 << Step->getSourceRange(); 5284 } else if (E->isValueDependent() || E->isTypeDependent() || 5285 E->isInstantiationDependent() || 5286 E->containsUnexpandedParameterPack() || 5287 CanonPVD->getType()->hasIntegerRepresentation()) { 5288 NewSteps.push_back(Step); 5289 } else { 5290 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5291 << Step->getSourceRange(); 5292 } 5293 continue; 5294 } 5295 NewStep = Step; 5296 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5297 !Step->isInstantiationDependent() && 5298 !Step->containsUnexpandedParameterPack()) { 5299 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5300 .get(); 5301 if (NewStep) 5302 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5303 } 5304 NewSteps.push_back(NewStep); 5305 } 5306 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5307 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5308 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5309 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5310 const_cast<Expr **>(Linears.data()), Linears.size(), 5311 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5312 NewSteps.data(), NewSteps.size(), SR); 5313 ADecl->addAttr(NewAttr); 5314 return DG; 5315 } 5316 5317 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5318 QualType NewType) { 5319 assert(NewType->isFunctionProtoType() && 5320 "Expected function type with prototype."); 5321 assert(FD->getType()->isFunctionNoProtoType() && 5322 "Expected function with type with no prototype."); 5323 assert(FDWithProto->getType()->isFunctionProtoType() && 5324 "Expected function with prototype."); 5325 // Synthesize parameters with the same types. 5326 FD->setType(NewType); 5327 SmallVector<ParmVarDecl *, 16> Params; 5328 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5329 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5330 SourceLocation(), nullptr, P->getType(), 5331 /*TInfo=*/nullptr, SC_None, nullptr); 5332 Param->setScopeInfo(0, Params.size()); 5333 Param->setImplicit(); 5334 Params.push_back(Param); 5335 } 5336 5337 FD->setParams(Params); 5338 } 5339 5340 Optional<std::pair<FunctionDecl *, Expr *>> 5341 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5342 Expr *VariantRef, SourceRange SR) { 5343 if (!DG || DG.get().isNull()) 5344 return None; 5345 5346 const int VariantId = 1; 5347 // Must be applied only to single decl. 5348 if (!DG.get().isSingleDecl()) { 5349 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5350 << VariantId << SR; 5351 return None; 5352 } 5353 Decl *ADecl = DG.get().getSingleDecl(); 5354 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5355 ADecl = FTD->getTemplatedDecl(); 5356 5357 // Decl must be a function. 5358 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5359 if (!FD) { 5360 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5361 << VariantId << SR; 5362 return None; 5363 } 5364 5365 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5366 return FD->hasAttrs() && 5367 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5368 FD->hasAttr<TargetAttr>()); 5369 }; 5370 // OpenMP is not compatible with CPU-specific attributes. 5371 if (HasMultiVersionAttributes(FD)) { 5372 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5373 << SR; 5374 return None; 5375 } 5376 5377 // Allow #pragma omp declare variant only if the function is not used. 5378 if (FD->isUsed(false)) 5379 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5380 << FD->getLocation(); 5381 5382 // Check if the function was emitted already. 5383 const FunctionDecl *Definition; 5384 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5385 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5386 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5387 << FD->getLocation(); 5388 5389 // The VariantRef must point to function. 5390 if (!VariantRef) { 5391 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5392 return None; 5393 } 5394 5395 // Do not check templates, wait until instantiation. 5396 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5397 VariantRef->containsUnexpandedParameterPack() || 5398 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5399 return std::make_pair(FD, VariantRef); 5400 5401 // Convert VariantRef expression to the type of the original function to 5402 // resolve possible conflicts. 5403 ExprResult VariantRefCast; 5404 if (LangOpts.CPlusPlus) { 5405 QualType FnPtrType; 5406 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5407 if (Method && !Method->isStatic()) { 5408 const Type *ClassType = 5409 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5410 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5411 ExprResult ER; 5412 { 5413 // Build adrr_of unary op to correctly handle type checks for member 5414 // functions. 5415 Sema::TentativeAnalysisScope Trap(*this); 5416 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5417 VariantRef); 5418 } 5419 if (!ER.isUsable()) { 5420 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5421 << VariantId << VariantRef->getSourceRange(); 5422 return None; 5423 } 5424 VariantRef = ER.get(); 5425 } else { 5426 FnPtrType = Context.getPointerType(FD->getType()); 5427 } 5428 ImplicitConversionSequence ICS = 5429 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5430 /*SuppressUserConversions=*/false, 5431 AllowedExplicit::None, 5432 /*InOverloadResolution=*/false, 5433 /*CStyle=*/false, 5434 /*AllowObjCWritebackConversion=*/false); 5435 if (ICS.isFailure()) { 5436 Diag(VariantRef->getExprLoc(), 5437 diag::err_omp_declare_variant_incompat_types) 5438 << VariantRef->getType() 5439 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5440 << VariantRef->getSourceRange(); 5441 return None; 5442 } 5443 VariantRefCast = PerformImplicitConversion( 5444 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5445 if (!VariantRefCast.isUsable()) 5446 return None; 5447 // Drop previously built artificial addr_of unary op for member functions. 5448 if (Method && !Method->isStatic()) { 5449 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5450 if (auto *UO = dyn_cast<UnaryOperator>( 5451 PossibleAddrOfVariantRef->IgnoreImplicit())) 5452 VariantRefCast = UO->getSubExpr(); 5453 } 5454 } else { 5455 VariantRefCast = VariantRef; 5456 } 5457 5458 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5459 if (!ER.isUsable() || 5460 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5461 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5462 << VariantId << VariantRef->getSourceRange(); 5463 return None; 5464 } 5465 5466 // The VariantRef must point to function. 5467 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5468 if (!DRE) { 5469 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5470 << VariantId << VariantRef->getSourceRange(); 5471 return None; 5472 } 5473 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5474 if (!NewFD) { 5475 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5476 << VariantId << VariantRef->getSourceRange(); 5477 return None; 5478 } 5479 5480 // Check if function types are compatible in C. 5481 if (!LangOpts.CPlusPlus) { 5482 QualType NewType = 5483 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5484 if (NewType.isNull()) { 5485 Diag(VariantRef->getExprLoc(), 5486 diag::err_omp_declare_variant_incompat_types) 5487 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5488 return None; 5489 } 5490 if (NewType->isFunctionProtoType()) { 5491 if (FD->getType()->isFunctionNoProtoType()) 5492 setPrototype(*this, FD, NewFD, NewType); 5493 else if (NewFD->getType()->isFunctionNoProtoType()) 5494 setPrototype(*this, NewFD, FD, NewType); 5495 } 5496 } 5497 5498 // Check if variant function is not marked with declare variant directive. 5499 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5500 Diag(VariantRef->getExprLoc(), 5501 diag::warn_omp_declare_variant_marked_as_declare_variant) 5502 << VariantRef->getSourceRange(); 5503 SourceRange SR = 5504 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5505 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5506 return None; 5507 } 5508 5509 enum DoesntSupport { 5510 VirtFuncs = 1, 5511 Constructors = 3, 5512 Destructors = 4, 5513 DeletedFuncs = 5, 5514 DefaultedFuncs = 6, 5515 ConstexprFuncs = 7, 5516 ConstevalFuncs = 8, 5517 }; 5518 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5519 if (CXXFD->isVirtual()) { 5520 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5521 << VirtFuncs; 5522 return None; 5523 } 5524 5525 if (isa<CXXConstructorDecl>(FD)) { 5526 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5527 << Constructors; 5528 return None; 5529 } 5530 5531 if (isa<CXXDestructorDecl>(FD)) { 5532 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5533 << Destructors; 5534 return None; 5535 } 5536 } 5537 5538 if (FD->isDeleted()) { 5539 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5540 << DeletedFuncs; 5541 return None; 5542 } 5543 5544 if (FD->isDefaulted()) { 5545 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5546 << DefaultedFuncs; 5547 return None; 5548 } 5549 5550 if (FD->isConstexpr()) { 5551 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5552 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5553 return None; 5554 } 5555 5556 // Check general compatibility. 5557 if (areMultiversionVariantFunctionsCompatible( 5558 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5559 PartialDiagnosticAt(SourceLocation(), 5560 PartialDiagnostic::NullDiagnostic()), 5561 PartialDiagnosticAt( 5562 VariantRef->getExprLoc(), 5563 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5564 PartialDiagnosticAt(VariantRef->getExprLoc(), 5565 PDiag(diag::err_omp_declare_variant_diff) 5566 << FD->getLocation()), 5567 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5568 /*CLinkageMayDiffer=*/true)) 5569 return None; 5570 return std::make_pair(FD, cast<Expr>(DRE)); 5571 } 5572 5573 void Sema::ActOnOpenMPDeclareVariantDirective( 5574 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5575 ArrayRef<OMPCtxSelectorData> Data) { 5576 if (Data.empty()) 5577 return; 5578 SmallVector<Expr *, 4> CtxScores; 5579 SmallVector<unsigned, 4> CtxSets; 5580 SmallVector<unsigned, 4> Ctxs; 5581 SmallVector<StringRef, 4> ImplVendors, DeviceKinds; 5582 bool IsError = false; 5583 for (const OMPCtxSelectorData &D : Data) { 5584 OpenMPContextSelectorSetKind CtxSet = D.CtxSet; 5585 OpenMPContextSelectorKind Ctx = D.Ctx; 5586 if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown) 5587 return; 5588 Expr *Score = nullptr; 5589 if (D.Score.isUsable()) { 5590 Score = D.Score.get(); 5591 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5592 !Score->isInstantiationDependent() && 5593 !Score->containsUnexpandedParameterPack()) { 5594 Score = 5595 PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score) 5596 .get(); 5597 if (Score) 5598 Score = VerifyIntegerConstantExpression(Score).get(); 5599 } 5600 } else { 5601 // OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors. 5602 // The kind, arch, and isa selectors are given the values 2^l, 2^(l+1) and 5603 // 2^(l+2), respectively, where l is the number of traits in the construct 5604 // set. 5605 // TODO: implement correct logic for isa and arch traits. 5606 // TODO: take the construct context set into account when it is 5607 // implemented. 5608 int L = 0; // Currently set the number of traits in construct set to 0, 5609 // since the construct trait set in not supported yet. 5610 if (CtxSet == OMP_CTX_SET_device && Ctx == OMP_CTX_kind) 5611 Score = ActOnIntegerConstant(SourceLocation(), std::pow(2, L)).get(); 5612 else 5613 Score = ActOnIntegerConstant(SourceLocation(), 0).get(); 5614 } 5615 switch (Ctx) { 5616 case OMP_CTX_vendor: 5617 assert(CtxSet == OMP_CTX_SET_implementation && 5618 "Expected implementation context selector set."); 5619 ImplVendors.append(D.Names.begin(), D.Names.end()); 5620 break; 5621 case OMP_CTX_kind: 5622 assert(CtxSet == OMP_CTX_SET_device && 5623 "Expected device context selector set."); 5624 DeviceKinds.append(D.Names.begin(), D.Names.end()); 5625 break; 5626 case OMP_CTX_unknown: 5627 llvm_unreachable("Unknown context selector kind."); 5628 } 5629 IsError = IsError || !Score; 5630 CtxSets.push_back(CtxSet); 5631 Ctxs.push_back(Ctx); 5632 CtxScores.push_back(Score); 5633 } 5634 if (!IsError) { 5635 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5636 Context, VariantRef, CtxScores.begin(), CtxScores.size(), 5637 CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(), 5638 ImplVendors.begin(), ImplVendors.size(), DeviceKinds.begin(), 5639 DeviceKinds.size(), SR); 5640 FD->addAttr(NewAttr); 5641 } 5642 } 5643 5644 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5645 FunctionDecl *Func, 5646 bool MightBeOdrUse) { 5647 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5648 5649 if (!Func->isDependentContext() && Func->hasAttrs()) { 5650 for (OMPDeclareVariantAttr *A : 5651 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5652 // TODO: add checks for active OpenMP context where possible. 5653 Expr *VariantRef = A->getVariantFuncRef(); 5654 auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5655 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5656 if (!F->isDefined() && F->isTemplateInstantiation()) 5657 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5658 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5659 } 5660 } 5661 } 5662 5663 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5664 Stmt *AStmt, 5665 SourceLocation StartLoc, 5666 SourceLocation EndLoc) { 5667 if (!AStmt) 5668 return StmtError(); 5669 5670 auto *CS = cast<CapturedStmt>(AStmt); 5671 // 1.2.2 OpenMP Language Terminology 5672 // Structured block - An executable statement with a single entry at the 5673 // top and a single exit at the bottom. 5674 // The point of exit cannot be a branch out of the structured block. 5675 // longjmp() and throw() must not violate the entry/exit criteria. 5676 CS->getCapturedDecl()->setNothrow(); 5677 5678 setFunctionHasBranchProtectedScope(); 5679 5680 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5681 DSAStack->isCancelRegion()); 5682 } 5683 5684 namespace { 5685 /// Iteration space of a single for loop. 5686 struct LoopIterationSpace final { 5687 /// True if the condition operator is the strict compare operator (<, > or 5688 /// !=). 5689 bool IsStrictCompare = false; 5690 /// Condition of the loop. 5691 Expr *PreCond = nullptr; 5692 /// This expression calculates the number of iterations in the loop. 5693 /// It is always possible to calculate it before starting the loop. 5694 Expr *NumIterations = nullptr; 5695 /// The loop counter variable. 5696 Expr *CounterVar = nullptr; 5697 /// Private loop counter variable. 5698 Expr *PrivateCounterVar = nullptr; 5699 /// This is initializer for the initial value of #CounterVar. 5700 Expr *CounterInit = nullptr; 5701 /// This is step for the #CounterVar used to generate its update: 5702 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5703 Expr *CounterStep = nullptr; 5704 /// Should step be subtracted? 5705 bool Subtract = false; 5706 /// Source range of the loop init. 5707 SourceRange InitSrcRange; 5708 /// Source range of the loop condition. 5709 SourceRange CondSrcRange; 5710 /// Source range of the loop increment. 5711 SourceRange IncSrcRange; 5712 /// Minimum value that can have the loop control variable. Used to support 5713 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5714 /// since only such variables can be used in non-loop invariant expressions. 5715 Expr *MinValue = nullptr; 5716 /// Maximum value that can have the loop control variable. Used to support 5717 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5718 /// since only such variables can be used in non-loop invariant expressions. 5719 Expr *MaxValue = nullptr; 5720 /// true, if the lower bound depends on the outer loop control var. 5721 bool IsNonRectangularLB = false; 5722 /// true, if the upper bound depends on the outer loop control var. 5723 bool IsNonRectangularUB = false; 5724 /// Index of the loop this loop depends on and forms non-rectangular loop 5725 /// nest. 5726 unsigned LoopDependentIdx = 0; 5727 /// Final condition for the non-rectangular loop nest support. It is used to 5728 /// check that the number of iterations for this particular counter must be 5729 /// finished. 5730 Expr *FinalCondition = nullptr; 5731 }; 5732 5733 /// Helper class for checking canonical form of the OpenMP loops and 5734 /// extracting iteration space of each loop in the loop nest, that will be used 5735 /// for IR generation. 5736 class OpenMPIterationSpaceChecker { 5737 /// Reference to Sema. 5738 Sema &SemaRef; 5739 /// Data-sharing stack. 5740 DSAStackTy &Stack; 5741 /// A location for diagnostics (when there is no some better location). 5742 SourceLocation DefaultLoc; 5743 /// A location for diagnostics (when increment is not compatible). 5744 SourceLocation ConditionLoc; 5745 /// A source location for referring to loop init later. 5746 SourceRange InitSrcRange; 5747 /// A source location for referring to condition later. 5748 SourceRange ConditionSrcRange; 5749 /// A source location for referring to increment later. 5750 SourceRange IncrementSrcRange; 5751 /// Loop variable. 5752 ValueDecl *LCDecl = nullptr; 5753 /// Reference to loop variable. 5754 Expr *LCRef = nullptr; 5755 /// Lower bound (initializer for the var). 5756 Expr *LB = nullptr; 5757 /// Upper bound. 5758 Expr *UB = nullptr; 5759 /// Loop step (increment). 5760 Expr *Step = nullptr; 5761 /// This flag is true when condition is one of: 5762 /// Var < UB 5763 /// Var <= UB 5764 /// UB > Var 5765 /// UB >= Var 5766 /// This will have no value when the condition is != 5767 llvm::Optional<bool> TestIsLessOp; 5768 /// This flag is true when condition is strict ( < or > ). 5769 bool TestIsStrictOp = false; 5770 /// This flag is true when step is subtracted on each iteration. 5771 bool SubtractStep = false; 5772 /// The outer loop counter this loop depends on (if any). 5773 const ValueDecl *DepDecl = nullptr; 5774 /// Contains number of loop (starts from 1) on which loop counter init 5775 /// expression of this loop depends on. 5776 Optional<unsigned> InitDependOnLC; 5777 /// Contains number of loop (starts from 1) on which loop counter condition 5778 /// expression of this loop depends on. 5779 Optional<unsigned> CondDependOnLC; 5780 /// Checks if the provide statement depends on the loop counter. 5781 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5782 /// Original condition required for checking of the exit condition for 5783 /// non-rectangular loop. 5784 Expr *Condition = nullptr; 5785 5786 public: 5787 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5788 SourceLocation DefaultLoc) 5789 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5790 ConditionLoc(DefaultLoc) {} 5791 /// Check init-expr for canonical loop form and save loop counter 5792 /// variable - #Var and its initialization value - #LB. 5793 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5794 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5795 /// for less/greater and for strict/non-strict comparison. 5796 bool checkAndSetCond(Expr *S); 5797 /// Check incr-expr for canonical loop form and return true if it 5798 /// does not conform, otherwise save loop step (#Step). 5799 bool checkAndSetInc(Expr *S); 5800 /// Return the loop counter variable. 5801 ValueDecl *getLoopDecl() const { return LCDecl; } 5802 /// Return the reference expression to loop counter variable. 5803 Expr *getLoopDeclRefExpr() const { return LCRef; } 5804 /// Source range of the loop init. 5805 SourceRange getInitSrcRange() const { return InitSrcRange; } 5806 /// Source range of the loop condition. 5807 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5808 /// Source range of the loop increment. 5809 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5810 /// True if the step should be subtracted. 5811 bool shouldSubtractStep() const { return SubtractStep; } 5812 /// True, if the compare operator is strict (<, > or !=). 5813 bool isStrictTestOp() const { return TestIsStrictOp; } 5814 /// Build the expression to calculate the number of iterations. 5815 Expr *buildNumIterations( 5816 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5817 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5818 /// Build the precondition expression for the loops. 5819 Expr * 5820 buildPreCond(Scope *S, Expr *Cond, 5821 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5822 /// Build reference expression to the counter be used for codegen. 5823 DeclRefExpr * 5824 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5825 DSAStackTy &DSA) const; 5826 /// Build reference expression to the private counter be used for 5827 /// codegen. 5828 Expr *buildPrivateCounterVar() const; 5829 /// Build initialization of the counter be used for codegen. 5830 Expr *buildCounterInit() const; 5831 /// Build step of the counter be used for codegen. 5832 Expr *buildCounterStep() const; 5833 /// Build loop data with counter value for depend clauses in ordered 5834 /// directives. 5835 Expr * 5836 buildOrderedLoopData(Scope *S, Expr *Counter, 5837 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5838 SourceLocation Loc, Expr *Inc = nullptr, 5839 OverloadedOperatorKind OOK = OO_Amp); 5840 /// Builds the minimum value for the loop counter. 5841 std::pair<Expr *, Expr *> buildMinMaxValues( 5842 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5843 /// Builds final condition for the non-rectangular loops. 5844 Expr *buildFinalCondition(Scope *S) const; 5845 /// Return true if any expression is dependent. 5846 bool dependent() const; 5847 /// Returns true if the initializer forms non-rectangular loop. 5848 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5849 /// Returns true if the condition forms non-rectangular loop. 5850 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5851 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5852 unsigned getLoopDependentIdx() const { 5853 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5854 } 5855 5856 private: 5857 /// Check the right-hand side of an assignment in the increment 5858 /// expression. 5859 bool checkAndSetIncRHS(Expr *RHS); 5860 /// Helper to set loop counter variable and its initializer. 5861 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5862 bool EmitDiags); 5863 /// Helper to set upper bound. 5864 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5865 SourceRange SR, SourceLocation SL); 5866 /// Helper to set loop increment. 5867 bool setStep(Expr *NewStep, bool Subtract); 5868 }; 5869 5870 bool OpenMPIterationSpaceChecker::dependent() const { 5871 if (!LCDecl) { 5872 assert(!LB && !UB && !Step); 5873 return false; 5874 } 5875 return LCDecl->getType()->isDependentType() || 5876 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5877 (Step && Step->isValueDependent()); 5878 } 5879 5880 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5881 Expr *NewLCRefExpr, 5882 Expr *NewLB, bool EmitDiags) { 5883 // State consistency checking to ensure correct usage. 5884 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5885 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5886 if (!NewLCDecl || !NewLB) 5887 return true; 5888 LCDecl = getCanonicalDecl(NewLCDecl); 5889 LCRef = NewLCRefExpr; 5890 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5891 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5892 if ((Ctor->isCopyOrMoveConstructor() || 5893 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5894 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5895 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5896 LB = NewLB; 5897 if (EmitDiags) 5898 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5899 return false; 5900 } 5901 5902 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5903 llvm::Optional<bool> LessOp, 5904 bool StrictOp, SourceRange SR, 5905 SourceLocation SL) { 5906 // State consistency checking to ensure correct usage. 5907 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5908 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5909 if (!NewUB) 5910 return true; 5911 UB = NewUB; 5912 if (LessOp) 5913 TestIsLessOp = LessOp; 5914 TestIsStrictOp = StrictOp; 5915 ConditionSrcRange = SR; 5916 ConditionLoc = SL; 5917 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5918 return false; 5919 } 5920 5921 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5922 // State consistency checking to ensure correct usage. 5923 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5924 if (!NewStep) 5925 return true; 5926 if (!NewStep->isValueDependent()) { 5927 // Check that the step is integer expression. 5928 SourceLocation StepLoc = NewStep->getBeginLoc(); 5929 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5930 StepLoc, getExprAsWritten(NewStep)); 5931 if (Val.isInvalid()) 5932 return true; 5933 NewStep = Val.get(); 5934 5935 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5936 // If test-expr is of form var relational-op b and relational-op is < or 5937 // <= then incr-expr must cause var to increase on each iteration of the 5938 // loop. If test-expr is of form var relational-op b and relational-op is 5939 // > or >= then incr-expr must cause var to decrease on each iteration of 5940 // the loop. 5941 // If test-expr is of form b relational-op var and relational-op is < or 5942 // <= then incr-expr must cause var to decrease on each iteration of the 5943 // loop. If test-expr is of form b relational-op var and relational-op is 5944 // > or >= then incr-expr must cause var to increase on each iteration of 5945 // the loop. 5946 llvm::APSInt Result; 5947 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5948 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5949 bool IsConstNeg = 5950 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5951 bool IsConstPos = 5952 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5953 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5954 5955 // != with increment is treated as <; != with decrement is treated as > 5956 if (!TestIsLessOp.hasValue()) 5957 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5958 if (UB && (IsConstZero || 5959 (TestIsLessOp.getValue() ? 5960 (IsConstNeg || (IsUnsigned && Subtract)) : 5961 (IsConstPos || (IsUnsigned && !Subtract))))) { 5962 SemaRef.Diag(NewStep->getExprLoc(), 5963 diag::err_omp_loop_incr_not_compatible) 5964 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5965 SemaRef.Diag(ConditionLoc, 5966 diag::note_omp_loop_cond_requres_compatible_incr) 5967 << TestIsLessOp.getValue() << ConditionSrcRange; 5968 return true; 5969 } 5970 if (TestIsLessOp.getValue() == Subtract) { 5971 NewStep = 5972 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5973 .get(); 5974 Subtract = !Subtract; 5975 } 5976 } 5977 5978 Step = NewStep; 5979 SubtractStep = Subtract; 5980 return false; 5981 } 5982 5983 namespace { 5984 /// Checker for the non-rectangular loops. Checks if the initializer or 5985 /// condition expression references loop counter variable. 5986 class LoopCounterRefChecker final 5987 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5988 Sema &SemaRef; 5989 DSAStackTy &Stack; 5990 const ValueDecl *CurLCDecl = nullptr; 5991 const ValueDecl *DepDecl = nullptr; 5992 const ValueDecl *PrevDepDecl = nullptr; 5993 bool IsInitializer = true; 5994 unsigned BaseLoopId = 0; 5995 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5996 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5997 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5998 << (IsInitializer ? 0 : 1); 5999 return false; 6000 } 6001 const auto &&Data = Stack.isLoopControlVariable(VD); 6002 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6003 // The type of the loop iterator on which we depend may not have a random 6004 // access iterator type. 6005 if (Data.first && VD->getType()->isRecordType()) { 6006 SmallString<128> Name; 6007 llvm::raw_svector_ostream OS(Name); 6008 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6009 /*Qualified=*/true); 6010 SemaRef.Diag(E->getExprLoc(), 6011 diag::err_omp_wrong_dependency_iterator_type) 6012 << OS.str(); 6013 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6014 return false; 6015 } 6016 if (Data.first && 6017 (DepDecl || (PrevDepDecl && 6018 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6019 if (!DepDecl && PrevDepDecl) 6020 DepDecl = PrevDepDecl; 6021 SmallString<128> Name; 6022 llvm::raw_svector_ostream OS(Name); 6023 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6024 /*Qualified=*/true); 6025 SemaRef.Diag(E->getExprLoc(), 6026 diag::err_omp_invariant_or_linear_dependency) 6027 << OS.str(); 6028 return false; 6029 } 6030 if (Data.first) { 6031 DepDecl = VD; 6032 BaseLoopId = Data.first; 6033 } 6034 return Data.first; 6035 } 6036 6037 public: 6038 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6039 const ValueDecl *VD = E->getDecl(); 6040 if (isa<VarDecl>(VD)) 6041 return checkDecl(E, VD); 6042 return false; 6043 } 6044 bool VisitMemberExpr(const MemberExpr *E) { 6045 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6046 const ValueDecl *VD = E->getMemberDecl(); 6047 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6048 return checkDecl(E, VD); 6049 } 6050 return false; 6051 } 6052 bool VisitStmt(const Stmt *S) { 6053 bool Res = false; 6054 for (const Stmt *Child : S->children()) 6055 Res = (Child && Visit(Child)) || Res; 6056 return Res; 6057 } 6058 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6059 const ValueDecl *CurLCDecl, bool IsInitializer, 6060 const ValueDecl *PrevDepDecl = nullptr) 6061 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6062 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6063 unsigned getBaseLoopId() const { 6064 assert(CurLCDecl && "Expected loop dependency."); 6065 return BaseLoopId; 6066 } 6067 const ValueDecl *getDepDecl() const { 6068 assert(CurLCDecl && "Expected loop dependency."); 6069 return DepDecl; 6070 } 6071 }; 6072 } // namespace 6073 6074 Optional<unsigned> 6075 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6076 bool IsInitializer) { 6077 // Check for the non-rectangular loops. 6078 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6079 DepDecl); 6080 if (LoopStmtChecker.Visit(S)) { 6081 DepDecl = LoopStmtChecker.getDepDecl(); 6082 return LoopStmtChecker.getBaseLoopId(); 6083 } 6084 return llvm::None; 6085 } 6086 6087 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6088 // Check init-expr for canonical loop form and save loop counter 6089 // variable - #Var and its initialization value - #LB. 6090 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6091 // var = lb 6092 // integer-type var = lb 6093 // random-access-iterator-type var = lb 6094 // pointer-type var = lb 6095 // 6096 if (!S) { 6097 if (EmitDiags) { 6098 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6099 } 6100 return true; 6101 } 6102 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6103 if (!ExprTemp->cleanupsHaveSideEffects()) 6104 S = ExprTemp->getSubExpr(); 6105 6106 InitSrcRange = S->getSourceRange(); 6107 if (Expr *E = dyn_cast<Expr>(S)) 6108 S = E->IgnoreParens(); 6109 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6110 if (BO->getOpcode() == BO_Assign) { 6111 Expr *LHS = BO->getLHS()->IgnoreParens(); 6112 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6113 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6114 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6115 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6116 EmitDiags); 6117 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6118 } 6119 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6120 if (ME->isArrow() && 6121 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6122 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6123 EmitDiags); 6124 } 6125 } 6126 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6127 if (DS->isSingleDecl()) { 6128 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6129 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6130 // Accept non-canonical init form here but emit ext. warning. 6131 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6132 SemaRef.Diag(S->getBeginLoc(), 6133 diag::ext_omp_loop_not_canonical_init) 6134 << S->getSourceRange(); 6135 return setLCDeclAndLB( 6136 Var, 6137 buildDeclRefExpr(SemaRef, Var, 6138 Var->getType().getNonReferenceType(), 6139 DS->getBeginLoc()), 6140 Var->getInit(), EmitDiags); 6141 } 6142 } 6143 } 6144 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6145 if (CE->getOperator() == OO_Equal) { 6146 Expr *LHS = CE->getArg(0); 6147 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6148 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6149 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6150 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6151 EmitDiags); 6152 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6153 } 6154 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6155 if (ME->isArrow() && 6156 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6157 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6158 EmitDiags); 6159 } 6160 } 6161 } 6162 6163 if (dependent() || SemaRef.CurContext->isDependentContext()) 6164 return false; 6165 if (EmitDiags) { 6166 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6167 << S->getSourceRange(); 6168 } 6169 return true; 6170 } 6171 6172 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6173 /// variable (which may be the loop variable) if possible. 6174 static const ValueDecl *getInitLCDecl(const Expr *E) { 6175 if (!E) 6176 return nullptr; 6177 E = getExprAsWritten(E); 6178 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6179 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6180 if ((Ctor->isCopyOrMoveConstructor() || 6181 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6182 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6183 E = CE->getArg(0)->IgnoreParenImpCasts(); 6184 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6185 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6186 return getCanonicalDecl(VD); 6187 } 6188 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6189 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6190 return getCanonicalDecl(ME->getMemberDecl()); 6191 return nullptr; 6192 } 6193 6194 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6195 // Check test-expr for canonical form, save upper-bound UB, flags for 6196 // less/greater and for strict/non-strict comparison. 6197 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6198 // var relational-op b 6199 // b relational-op var 6200 // 6201 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6202 if (!S) { 6203 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6204 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6205 return true; 6206 } 6207 Condition = S; 6208 S = getExprAsWritten(S); 6209 SourceLocation CondLoc = S->getBeginLoc(); 6210 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6211 if (BO->isRelationalOp()) { 6212 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6213 return setUB(BO->getRHS(), 6214 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6215 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6216 BO->getSourceRange(), BO->getOperatorLoc()); 6217 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6218 return setUB(BO->getLHS(), 6219 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6220 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6221 BO->getSourceRange(), BO->getOperatorLoc()); 6222 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6223 return setUB( 6224 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6225 /*LessOp=*/llvm::None, 6226 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6227 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6228 if (CE->getNumArgs() == 2) { 6229 auto Op = CE->getOperator(); 6230 switch (Op) { 6231 case OO_Greater: 6232 case OO_GreaterEqual: 6233 case OO_Less: 6234 case OO_LessEqual: 6235 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6236 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6237 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6238 CE->getOperatorLoc()); 6239 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6240 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6241 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6242 CE->getOperatorLoc()); 6243 break; 6244 case OO_ExclaimEqual: 6245 if (IneqCondIsCanonical) 6246 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6247 : CE->getArg(0), 6248 /*LessOp=*/llvm::None, 6249 /*StrictOp=*/true, CE->getSourceRange(), 6250 CE->getOperatorLoc()); 6251 break; 6252 default: 6253 break; 6254 } 6255 } 6256 } 6257 if (dependent() || SemaRef.CurContext->isDependentContext()) 6258 return false; 6259 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6260 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6261 return true; 6262 } 6263 6264 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6265 // RHS of canonical loop form increment can be: 6266 // var + incr 6267 // incr + var 6268 // var - incr 6269 // 6270 RHS = RHS->IgnoreParenImpCasts(); 6271 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6272 if (BO->isAdditiveOp()) { 6273 bool IsAdd = BO->getOpcode() == BO_Add; 6274 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6275 return setStep(BO->getRHS(), !IsAdd); 6276 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6277 return setStep(BO->getLHS(), /*Subtract=*/false); 6278 } 6279 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6280 bool IsAdd = CE->getOperator() == OO_Plus; 6281 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6282 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6283 return setStep(CE->getArg(1), !IsAdd); 6284 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6285 return setStep(CE->getArg(0), /*Subtract=*/false); 6286 } 6287 } 6288 if (dependent() || SemaRef.CurContext->isDependentContext()) 6289 return false; 6290 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6291 << RHS->getSourceRange() << LCDecl; 6292 return true; 6293 } 6294 6295 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6296 // Check incr-expr for canonical loop form and return true if it 6297 // does not conform. 6298 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6299 // ++var 6300 // var++ 6301 // --var 6302 // var-- 6303 // var += incr 6304 // var -= incr 6305 // var = var + incr 6306 // var = incr + var 6307 // var = var - incr 6308 // 6309 if (!S) { 6310 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6311 return true; 6312 } 6313 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6314 if (!ExprTemp->cleanupsHaveSideEffects()) 6315 S = ExprTemp->getSubExpr(); 6316 6317 IncrementSrcRange = S->getSourceRange(); 6318 S = S->IgnoreParens(); 6319 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6320 if (UO->isIncrementDecrementOp() && 6321 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6322 return setStep(SemaRef 6323 .ActOnIntegerConstant(UO->getBeginLoc(), 6324 (UO->isDecrementOp() ? -1 : 1)) 6325 .get(), 6326 /*Subtract=*/false); 6327 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6328 switch (BO->getOpcode()) { 6329 case BO_AddAssign: 6330 case BO_SubAssign: 6331 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6332 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6333 break; 6334 case BO_Assign: 6335 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6336 return checkAndSetIncRHS(BO->getRHS()); 6337 break; 6338 default: 6339 break; 6340 } 6341 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6342 switch (CE->getOperator()) { 6343 case OO_PlusPlus: 6344 case OO_MinusMinus: 6345 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6346 return setStep(SemaRef 6347 .ActOnIntegerConstant( 6348 CE->getBeginLoc(), 6349 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6350 .get(), 6351 /*Subtract=*/false); 6352 break; 6353 case OO_PlusEqual: 6354 case OO_MinusEqual: 6355 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6356 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6357 break; 6358 case OO_Equal: 6359 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6360 return checkAndSetIncRHS(CE->getArg(1)); 6361 break; 6362 default: 6363 break; 6364 } 6365 } 6366 if (dependent() || SemaRef.CurContext->isDependentContext()) 6367 return false; 6368 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6369 << S->getSourceRange() << LCDecl; 6370 return true; 6371 } 6372 6373 static ExprResult 6374 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6375 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6376 if (SemaRef.CurContext->isDependentContext()) 6377 return ExprResult(Capture); 6378 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6379 return SemaRef.PerformImplicitConversion( 6380 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6381 /*AllowExplicit=*/true); 6382 auto I = Captures.find(Capture); 6383 if (I != Captures.end()) 6384 return buildCapture(SemaRef, Capture, I->second); 6385 DeclRefExpr *Ref = nullptr; 6386 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6387 Captures[Capture] = Ref; 6388 return Res; 6389 } 6390 6391 /// Build the expression to calculate the number of iterations. 6392 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6393 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6394 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6395 ExprResult Diff; 6396 QualType VarType = LCDecl->getType().getNonReferenceType(); 6397 if (VarType->isIntegerType() || VarType->isPointerType() || 6398 SemaRef.getLangOpts().CPlusPlus) { 6399 Expr *LBVal = LB; 6400 Expr *UBVal = UB; 6401 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6402 // max(LB(MinVal), LB(MaxVal)) 6403 if (InitDependOnLC) { 6404 const LoopIterationSpace &IS = 6405 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6406 InitDependOnLC.getValueOr( 6407 CondDependOnLC.getValueOr(0))]; 6408 if (!IS.MinValue || !IS.MaxValue) 6409 return nullptr; 6410 // OuterVar = Min 6411 ExprResult MinValue = 6412 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6413 if (!MinValue.isUsable()) 6414 return nullptr; 6415 6416 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6417 IS.CounterVar, MinValue.get()); 6418 if (!LBMinVal.isUsable()) 6419 return nullptr; 6420 // OuterVar = Min, LBVal 6421 LBMinVal = 6422 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6423 if (!LBMinVal.isUsable()) 6424 return nullptr; 6425 // (OuterVar = Min, LBVal) 6426 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6427 if (!LBMinVal.isUsable()) 6428 return nullptr; 6429 6430 // OuterVar = Max 6431 ExprResult MaxValue = 6432 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6433 if (!MaxValue.isUsable()) 6434 return nullptr; 6435 6436 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6437 IS.CounterVar, MaxValue.get()); 6438 if (!LBMaxVal.isUsable()) 6439 return nullptr; 6440 // OuterVar = Max, LBVal 6441 LBMaxVal = 6442 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6443 if (!LBMaxVal.isUsable()) 6444 return nullptr; 6445 // (OuterVar = Max, LBVal) 6446 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6447 if (!LBMaxVal.isUsable()) 6448 return nullptr; 6449 6450 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6451 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6452 if (!LBMin || !LBMax) 6453 return nullptr; 6454 // LB(MinVal) < LB(MaxVal) 6455 ExprResult MinLessMaxRes = 6456 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6457 if (!MinLessMaxRes.isUsable()) 6458 return nullptr; 6459 Expr *MinLessMax = 6460 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6461 if (!MinLessMax) 6462 return nullptr; 6463 if (TestIsLessOp.getValue()) { 6464 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6465 // LB(MaxVal)) 6466 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6467 MinLessMax, LBMin, LBMax); 6468 if (!MinLB.isUsable()) 6469 return nullptr; 6470 LBVal = MinLB.get(); 6471 } else { 6472 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6473 // LB(MaxVal)) 6474 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6475 MinLessMax, LBMax, LBMin); 6476 if (!MaxLB.isUsable()) 6477 return nullptr; 6478 LBVal = MaxLB.get(); 6479 } 6480 } 6481 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6482 // min(UB(MinVal), UB(MaxVal)) 6483 if (CondDependOnLC) { 6484 const LoopIterationSpace &IS = 6485 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6486 InitDependOnLC.getValueOr( 6487 CondDependOnLC.getValueOr(0))]; 6488 if (!IS.MinValue || !IS.MaxValue) 6489 return nullptr; 6490 // OuterVar = Min 6491 ExprResult MinValue = 6492 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6493 if (!MinValue.isUsable()) 6494 return nullptr; 6495 6496 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6497 IS.CounterVar, MinValue.get()); 6498 if (!UBMinVal.isUsable()) 6499 return nullptr; 6500 // OuterVar = Min, UBVal 6501 UBMinVal = 6502 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6503 if (!UBMinVal.isUsable()) 6504 return nullptr; 6505 // (OuterVar = Min, UBVal) 6506 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6507 if (!UBMinVal.isUsable()) 6508 return nullptr; 6509 6510 // OuterVar = Max 6511 ExprResult MaxValue = 6512 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6513 if (!MaxValue.isUsable()) 6514 return nullptr; 6515 6516 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6517 IS.CounterVar, MaxValue.get()); 6518 if (!UBMaxVal.isUsable()) 6519 return nullptr; 6520 // OuterVar = Max, UBVal 6521 UBMaxVal = 6522 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6523 if (!UBMaxVal.isUsable()) 6524 return nullptr; 6525 // (OuterVar = Max, UBVal) 6526 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6527 if (!UBMaxVal.isUsable()) 6528 return nullptr; 6529 6530 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6531 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6532 if (!UBMin || !UBMax) 6533 return nullptr; 6534 // UB(MinVal) > UB(MaxVal) 6535 ExprResult MinGreaterMaxRes = 6536 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6537 if (!MinGreaterMaxRes.isUsable()) 6538 return nullptr; 6539 Expr *MinGreaterMax = 6540 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6541 if (!MinGreaterMax) 6542 return nullptr; 6543 if (TestIsLessOp.getValue()) { 6544 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6545 // UB(MaxVal)) 6546 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6547 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6548 if (!MaxUB.isUsable()) 6549 return nullptr; 6550 UBVal = MaxUB.get(); 6551 } else { 6552 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6553 // UB(MaxVal)) 6554 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6555 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6556 if (!MinUB.isUsable()) 6557 return nullptr; 6558 UBVal = MinUB.get(); 6559 } 6560 } 6561 // Upper - Lower 6562 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6563 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6564 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6565 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6566 if (!Upper || !Lower) 6567 return nullptr; 6568 6569 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6570 6571 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6572 // BuildBinOp already emitted error, this one is to point user to upper 6573 // and lower bound, and to tell what is passed to 'operator-'. 6574 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6575 << Upper->getSourceRange() << Lower->getSourceRange(); 6576 return nullptr; 6577 } 6578 } 6579 6580 if (!Diff.isUsable()) 6581 return nullptr; 6582 6583 // Upper - Lower [- 1] 6584 if (TestIsStrictOp) 6585 Diff = SemaRef.BuildBinOp( 6586 S, DefaultLoc, BO_Sub, Diff.get(), 6587 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6588 if (!Diff.isUsable()) 6589 return nullptr; 6590 6591 // Upper - Lower [- 1] + Step 6592 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6593 if (!NewStep.isUsable()) 6594 return nullptr; 6595 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6596 if (!Diff.isUsable()) 6597 return nullptr; 6598 6599 // Parentheses (for dumping/debugging purposes only). 6600 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6601 if (!Diff.isUsable()) 6602 return nullptr; 6603 6604 // (Upper - Lower [- 1] + Step) / Step 6605 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6606 if (!Diff.isUsable()) 6607 return nullptr; 6608 6609 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6610 QualType Type = Diff.get()->getType(); 6611 ASTContext &C = SemaRef.Context; 6612 bool UseVarType = VarType->hasIntegerRepresentation() && 6613 C.getTypeSize(Type) > C.getTypeSize(VarType); 6614 if (!Type->isIntegerType() || UseVarType) { 6615 unsigned NewSize = 6616 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6617 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6618 : Type->hasSignedIntegerRepresentation(); 6619 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6620 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6621 Diff = SemaRef.PerformImplicitConversion( 6622 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6623 if (!Diff.isUsable()) 6624 return nullptr; 6625 } 6626 } 6627 if (LimitedType) { 6628 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6629 if (NewSize != C.getTypeSize(Type)) { 6630 if (NewSize < C.getTypeSize(Type)) { 6631 assert(NewSize == 64 && "incorrect loop var size"); 6632 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6633 << InitSrcRange << ConditionSrcRange; 6634 } 6635 QualType NewType = C.getIntTypeForBitwidth( 6636 NewSize, Type->hasSignedIntegerRepresentation() || 6637 C.getTypeSize(Type) < NewSize); 6638 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6639 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6640 Sema::AA_Converting, true); 6641 if (!Diff.isUsable()) 6642 return nullptr; 6643 } 6644 } 6645 } 6646 6647 return Diff.get(); 6648 } 6649 6650 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6651 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6652 // Do not build for iterators, they cannot be used in non-rectangular loop 6653 // nests. 6654 if (LCDecl->getType()->isRecordType()) 6655 return std::make_pair(nullptr, nullptr); 6656 // If we subtract, the min is in the condition, otherwise the min is in the 6657 // init value. 6658 Expr *MinExpr = nullptr; 6659 Expr *MaxExpr = nullptr; 6660 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6661 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6662 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6663 : CondDependOnLC.hasValue(); 6664 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6665 : InitDependOnLC.hasValue(); 6666 Expr *Lower = 6667 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6668 Expr *Upper = 6669 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6670 if (!Upper || !Lower) 6671 return std::make_pair(nullptr, nullptr); 6672 6673 if (TestIsLessOp.getValue()) 6674 MinExpr = Lower; 6675 else 6676 MaxExpr = Upper; 6677 6678 // Build minimum/maximum value based on number of iterations. 6679 ExprResult Diff; 6680 QualType VarType = LCDecl->getType().getNonReferenceType(); 6681 6682 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6683 if (!Diff.isUsable()) 6684 return std::make_pair(nullptr, nullptr); 6685 6686 // Upper - Lower [- 1] 6687 if (TestIsStrictOp) 6688 Diff = SemaRef.BuildBinOp( 6689 S, DefaultLoc, BO_Sub, Diff.get(), 6690 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6691 if (!Diff.isUsable()) 6692 return std::make_pair(nullptr, nullptr); 6693 6694 // Upper - Lower [- 1] + Step 6695 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6696 if (!NewStep.isUsable()) 6697 return std::make_pair(nullptr, nullptr); 6698 6699 // Parentheses (for dumping/debugging purposes only). 6700 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6701 if (!Diff.isUsable()) 6702 return std::make_pair(nullptr, nullptr); 6703 6704 // (Upper - Lower [- 1]) / Step 6705 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6706 if (!Diff.isUsable()) 6707 return std::make_pair(nullptr, nullptr); 6708 6709 // ((Upper - Lower [- 1]) / Step) * Step 6710 // Parentheses (for dumping/debugging purposes only). 6711 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6712 if (!Diff.isUsable()) 6713 return std::make_pair(nullptr, nullptr); 6714 6715 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6716 if (!Diff.isUsable()) 6717 return std::make_pair(nullptr, nullptr); 6718 6719 // Convert to the original type or ptrdiff_t, if original type is pointer. 6720 if (!VarType->isAnyPointerType() && 6721 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6722 Diff = SemaRef.PerformImplicitConversion( 6723 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6724 } else if (VarType->isAnyPointerType() && 6725 !SemaRef.Context.hasSameType( 6726 Diff.get()->getType(), 6727 SemaRef.Context.getUnsignedPointerDiffType())) { 6728 Diff = SemaRef.PerformImplicitConversion( 6729 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6730 Sema::AA_Converting, /*AllowExplicit=*/true); 6731 } 6732 if (!Diff.isUsable()) 6733 return std::make_pair(nullptr, nullptr); 6734 6735 // Parentheses (for dumping/debugging purposes only). 6736 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6737 if (!Diff.isUsable()) 6738 return std::make_pair(nullptr, nullptr); 6739 6740 if (TestIsLessOp.getValue()) { 6741 // MinExpr = Lower; 6742 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6743 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6744 if (!Diff.isUsable()) 6745 return std::make_pair(nullptr, nullptr); 6746 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6747 if (!Diff.isUsable()) 6748 return std::make_pair(nullptr, nullptr); 6749 MaxExpr = Diff.get(); 6750 } else { 6751 // MaxExpr = Upper; 6752 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6753 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6754 if (!Diff.isUsable()) 6755 return std::make_pair(nullptr, nullptr); 6756 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6757 if (!Diff.isUsable()) 6758 return std::make_pair(nullptr, nullptr); 6759 MinExpr = Diff.get(); 6760 } 6761 6762 return std::make_pair(MinExpr, MaxExpr); 6763 } 6764 6765 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6766 if (InitDependOnLC || CondDependOnLC) 6767 return Condition; 6768 return nullptr; 6769 } 6770 6771 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6772 Scope *S, Expr *Cond, 6773 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6774 // Do not build a precondition when the condition/initialization is dependent 6775 // to prevent pessimistic early loop exit. 6776 // TODO: this can be improved by calculating min/max values but not sure that 6777 // it will be very effective. 6778 if (CondDependOnLC || InitDependOnLC) 6779 return SemaRef.PerformImplicitConversion( 6780 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6781 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6782 /*AllowExplicit=*/true).get(); 6783 6784 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6785 Sema::TentativeAnalysisScope Trap(SemaRef); 6786 6787 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6788 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6789 if (!NewLB.isUsable() || !NewUB.isUsable()) 6790 return nullptr; 6791 6792 ExprResult CondExpr = 6793 SemaRef.BuildBinOp(S, DefaultLoc, 6794 TestIsLessOp.getValue() ? 6795 (TestIsStrictOp ? BO_LT : BO_LE) : 6796 (TestIsStrictOp ? BO_GT : BO_GE), 6797 NewLB.get(), NewUB.get()); 6798 if (CondExpr.isUsable()) { 6799 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6800 SemaRef.Context.BoolTy)) 6801 CondExpr = SemaRef.PerformImplicitConversion( 6802 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6803 /*AllowExplicit=*/true); 6804 } 6805 6806 // Otherwise use original loop condition and evaluate it in runtime. 6807 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6808 } 6809 6810 /// Build reference expression to the counter be used for codegen. 6811 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6812 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6813 DSAStackTy &DSA) const { 6814 auto *VD = dyn_cast<VarDecl>(LCDecl); 6815 if (!VD) { 6816 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6817 DeclRefExpr *Ref = buildDeclRefExpr( 6818 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6819 const DSAStackTy::DSAVarData Data = 6820 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6821 // If the loop control decl is explicitly marked as private, do not mark it 6822 // as captured again. 6823 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6824 Captures.insert(std::make_pair(LCRef, Ref)); 6825 return Ref; 6826 } 6827 return cast<DeclRefExpr>(LCRef); 6828 } 6829 6830 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6831 if (LCDecl && !LCDecl->isInvalidDecl()) { 6832 QualType Type = LCDecl->getType().getNonReferenceType(); 6833 VarDecl *PrivateVar = buildVarDecl( 6834 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6835 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6836 isa<VarDecl>(LCDecl) 6837 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6838 : nullptr); 6839 if (PrivateVar->isInvalidDecl()) 6840 return nullptr; 6841 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6842 } 6843 return nullptr; 6844 } 6845 6846 /// Build initialization of the counter to be used for codegen. 6847 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6848 6849 /// Build step of the counter be used for codegen. 6850 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6851 6852 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6853 Scope *S, Expr *Counter, 6854 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6855 Expr *Inc, OverloadedOperatorKind OOK) { 6856 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6857 if (!Cnt) 6858 return nullptr; 6859 if (Inc) { 6860 assert((OOK == OO_Plus || OOK == OO_Minus) && 6861 "Expected only + or - operations for depend clauses."); 6862 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6863 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6864 if (!Cnt) 6865 return nullptr; 6866 } 6867 ExprResult Diff; 6868 QualType VarType = LCDecl->getType().getNonReferenceType(); 6869 if (VarType->isIntegerType() || VarType->isPointerType() || 6870 SemaRef.getLangOpts().CPlusPlus) { 6871 // Upper - Lower 6872 Expr *Upper = TestIsLessOp.getValue() 6873 ? Cnt 6874 : tryBuildCapture(SemaRef, UB, Captures).get(); 6875 Expr *Lower = TestIsLessOp.getValue() 6876 ? tryBuildCapture(SemaRef, LB, Captures).get() 6877 : Cnt; 6878 if (!Upper || !Lower) 6879 return nullptr; 6880 6881 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6882 6883 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6884 // BuildBinOp already emitted error, this one is to point user to upper 6885 // and lower bound, and to tell what is passed to 'operator-'. 6886 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6887 << Upper->getSourceRange() << Lower->getSourceRange(); 6888 return nullptr; 6889 } 6890 } 6891 6892 if (!Diff.isUsable()) 6893 return nullptr; 6894 6895 // Parentheses (for dumping/debugging purposes only). 6896 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6897 if (!Diff.isUsable()) 6898 return nullptr; 6899 6900 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6901 if (!NewStep.isUsable()) 6902 return nullptr; 6903 // (Upper - Lower) / Step 6904 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6905 if (!Diff.isUsable()) 6906 return nullptr; 6907 6908 return Diff.get(); 6909 } 6910 } // namespace 6911 6912 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6913 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6914 assert(Init && "Expected loop in canonical form."); 6915 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6916 if (AssociatedLoops > 0 && 6917 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6918 DSAStack->loopStart(); 6919 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6920 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6921 if (ValueDecl *D = ISC.getLoopDecl()) { 6922 auto *VD = dyn_cast<VarDecl>(D); 6923 DeclRefExpr *PrivateRef = nullptr; 6924 if (!VD) { 6925 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6926 VD = Private; 6927 } else { 6928 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6929 /*WithInit=*/false); 6930 VD = cast<VarDecl>(PrivateRef->getDecl()); 6931 } 6932 } 6933 DSAStack->addLoopControlVariable(D, VD); 6934 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6935 if (LD != D->getCanonicalDecl()) { 6936 DSAStack->resetPossibleLoopCounter(); 6937 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6938 MarkDeclarationsReferencedInExpr( 6939 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6940 Var->getType().getNonLValueExprType(Context), 6941 ForLoc, /*RefersToCapture=*/true)); 6942 } 6943 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6944 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6945 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6946 // associated for-loop of a simd construct with just one associated 6947 // for-loop may be listed in a linear clause with a constant-linear-step 6948 // that is the increment of the associated for-loop. The loop iteration 6949 // variable(s) in the associated for-loop(s) of a for or parallel for 6950 // construct may be listed in a private or lastprivate clause. 6951 DSAStackTy::DSAVarData DVar = 6952 DSAStack->getTopDSA(D, /*FromParent=*/false); 6953 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6954 // is declared in the loop and it is predetermined as a private. 6955 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6956 OpenMPClauseKind PredeterminedCKind = 6957 isOpenMPSimdDirective(DKind) 6958 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6959 : OMPC_private; 6960 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6961 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6962 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6963 DVar.CKind != OMPC_private))) || 6964 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6965 DKind == OMPD_master_taskloop || 6966 DKind == OMPD_parallel_master_taskloop || 6967 isOpenMPDistributeDirective(DKind)) && 6968 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6969 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6970 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6971 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6972 << getOpenMPClauseName(DVar.CKind) 6973 << getOpenMPDirectiveName(DKind) 6974 << getOpenMPClauseName(PredeterminedCKind); 6975 if (DVar.RefExpr == nullptr) 6976 DVar.CKind = PredeterminedCKind; 6977 reportOriginalDsa(*this, DSAStack, D, DVar, 6978 /*IsLoopIterVar=*/true); 6979 } else if (LoopDeclRefExpr) { 6980 // Make the loop iteration variable private (for worksharing 6981 // constructs), linear (for simd directives with the only one 6982 // associated loop) or lastprivate (for simd directives with several 6983 // collapsed or ordered loops). 6984 if (DVar.CKind == OMPC_unknown) 6985 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6986 PrivateRef); 6987 } 6988 } 6989 } 6990 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6991 } 6992 } 6993 6994 /// Called on a for stmt to check and extract its iteration space 6995 /// for further processing (such as collapsing). 6996 static bool checkOpenMPIterationSpace( 6997 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6998 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6999 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7000 Expr *OrderedLoopCountExpr, 7001 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7002 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7003 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7004 // OpenMP [2.9.1, Canonical Loop Form] 7005 // for (init-expr; test-expr; incr-expr) structured-block 7006 // for (range-decl: range-expr) structured-block 7007 auto *For = dyn_cast_or_null<ForStmt>(S); 7008 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7009 // Ranged for is supported only in OpenMP 5.0. 7010 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7011 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7012 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7013 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7014 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7015 if (TotalNestedLoopCount > 1) { 7016 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7017 SemaRef.Diag(DSA.getConstructLoc(), 7018 diag::note_omp_collapse_ordered_expr) 7019 << 2 << CollapseLoopCountExpr->getSourceRange() 7020 << OrderedLoopCountExpr->getSourceRange(); 7021 else if (CollapseLoopCountExpr) 7022 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7023 diag::note_omp_collapse_ordered_expr) 7024 << 0 << CollapseLoopCountExpr->getSourceRange(); 7025 else 7026 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7027 diag::note_omp_collapse_ordered_expr) 7028 << 1 << OrderedLoopCountExpr->getSourceRange(); 7029 } 7030 return true; 7031 } 7032 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7033 "No loop body."); 7034 7035 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7036 For ? For->getForLoc() : CXXFor->getForLoc()); 7037 7038 // Check init. 7039 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7040 if (ISC.checkAndSetInit(Init)) 7041 return true; 7042 7043 bool HasErrors = false; 7044 7045 // Check loop variable's type. 7046 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7047 // OpenMP [2.6, Canonical Loop Form] 7048 // Var is one of the following: 7049 // A variable of signed or unsigned integer type. 7050 // For C++, a variable of a random access iterator type. 7051 // For C, a variable of a pointer type. 7052 QualType VarType = LCDecl->getType().getNonReferenceType(); 7053 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7054 !VarType->isPointerType() && 7055 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7056 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7057 << SemaRef.getLangOpts().CPlusPlus; 7058 HasErrors = true; 7059 } 7060 7061 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7062 // a Construct 7063 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7064 // parallel for construct is (are) private. 7065 // The loop iteration variable in the associated for-loop of a simd 7066 // construct with just one associated for-loop is linear with a 7067 // constant-linear-step that is the increment of the associated for-loop. 7068 // Exclude loop var from the list of variables with implicitly defined data 7069 // sharing attributes. 7070 VarsWithImplicitDSA.erase(LCDecl); 7071 7072 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7073 7074 // Check test-expr. 7075 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7076 7077 // Check incr-expr. 7078 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7079 } 7080 7081 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7082 return HasErrors; 7083 7084 // Build the loop's iteration space representation. 7085 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7086 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7087 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7088 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7089 (isOpenMPWorksharingDirective(DKind) || 7090 isOpenMPTaskLoopDirective(DKind) || 7091 isOpenMPDistributeDirective(DKind)), 7092 Captures); 7093 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7094 ISC.buildCounterVar(Captures, DSA); 7095 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7096 ISC.buildPrivateCounterVar(); 7097 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7098 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7099 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7100 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7101 ISC.getConditionSrcRange(); 7102 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7103 ISC.getIncrementSrcRange(); 7104 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7105 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7106 ISC.isStrictTestOp(); 7107 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7108 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7109 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7110 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7111 ISC.buildFinalCondition(DSA.getCurScope()); 7112 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7113 ISC.doesInitDependOnLC(); 7114 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7115 ISC.doesCondDependOnLC(); 7116 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7117 ISC.getLoopDependentIdx(); 7118 7119 HasErrors |= 7120 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7121 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7122 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7123 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7124 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7125 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7126 if (!HasErrors && DSA.isOrderedRegion()) { 7127 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7128 if (CurrentNestedLoopCount < 7129 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7130 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7131 CurrentNestedLoopCount, 7132 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7133 DSA.getOrderedRegionParam().second->setLoopCounter( 7134 CurrentNestedLoopCount, 7135 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7136 } 7137 } 7138 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7139 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7140 // Erroneous case - clause has some problems. 7141 continue; 7142 } 7143 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7144 Pair.second.size() <= CurrentNestedLoopCount) { 7145 // Erroneous case - clause has some problems. 7146 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7147 continue; 7148 } 7149 Expr *CntValue; 7150 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7151 CntValue = ISC.buildOrderedLoopData( 7152 DSA.getCurScope(), 7153 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7154 Pair.first->getDependencyLoc()); 7155 else 7156 CntValue = ISC.buildOrderedLoopData( 7157 DSA.getCurScope(), 7158 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7159 Pair.first->getDependencyLoc(), 7160 Pair.second[CurrentNestedLoopCount].first, 7161 Pair.second[CurrentNestedLoopCount].second); 7162 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7163 } 7164 } 7165 7166 return HasErrors; 7167 } 7168 7169 /// Build 'VarRef = Start. 7170 static ExprResult 7171 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7172 ExprResult Start, bool IsNonRectangularLB, 7173 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7174 // Build 'VarRef = Start. 7175 ExprResult NewStart = IsNonRectangularLB 7176 ? Start.get() 7177 : tryBuildCapture(SemaRef, Start.get(), Captures); 7178 if (!NewStart.isUsable()) 7179 return ExprError(); 7180 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7181 VarRef.get()->getType())) { 7182 NewStart = SemaRef.PerformImplicitConversion( 7183 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7184 /*AllowExplicit=*/true); 7185 if (!NewStart.isUsable()) 7186 return ExprError(); 7187 } 7188 7189 ExprResult Init = 7190 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7191 return Init; 7192 } 7193 7194 /// Build 'VarRef = Start + Iter * Step'. 7195 static ExprResult buildCounterUpdate( 7196 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7197 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7198 bool IsNonRectangularLB, 7199 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7200 // Add parentheses (for debugging purposes only). 7201 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7202 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7203 !Step.isUsable()) 7204 return ExprError(); 7205 7206 ExprResult NewStep = Step; 7207 if (Captures) 7208 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7209 if (NewStep.isInvalid()) 7210 return ExprError(); 7211 ExprResult Update = 7212 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7213 if (!Update.isUsable()) 7214 return ExprError(); 7215 7216 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7217 // 'VarRef = Start (+|-) Iter * Step'. 7218 if (!Start.isUsable()) 7219 return ExprError(); 7220 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7221 if (!NewStart.isUsable()) 7222 return ExprError(); 7223 if (Captures && !IsNonRectangularLB) 7224 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7225 if (NewStart.isInvalid()) 7226 return ExprError(); 7227 7228 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7229 ExprResult SavedUpdate = Update; 7230 ExprResult UpdateVal; 7231 if (VarRef.get()->getType()->isOverloadableType() || 7232 NewStart.get()->getType()->isOverloadableType() || 7233 Update.get()->getType()->isOverloadableType()) { 7234 Sema::TentativeAnalysisScope Trap(SemaRef); 7235 7236 Update = 7237 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7238 if (Update.isUsable()) { 7239 UpdateVal = 7240 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7241 VarRef.get(), SavedUpdate.get()); 7242 if (UpdateVal.isUsable()) { 7243 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7244 UpdateVal.get()); 7245 } 7246 } 7247 } 7248 7249 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7250 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7251 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7252 NewStart.get(), SavedUpdate.get()); 7253 if (!Update.isUsable()) 7254 return ExprError(); 7255 7256 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7257 VarRef.get()->getType())) { 7258 Update = SemaRef.PerformImplicitConversion( 7259 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7260 if (!Update.isUsable()) 7261 return ExprError(); 7262 } 7263 7264 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7265 } 7266 return Update; 7267 } 7268 7269 /// Convert integer expression \a E to make it have at least \a Bits 7270 /// bits. 7271 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7272 if (E == nullptr) 7273 return ExprError(); 7274 ASTContext &C = SemaRef.Context; 7275 QualType OldType = E->getType(); 7276 unsigned HasBits = C.getTypeSize(OldType); 7277 if (HasBits >= Bits) 7278 return ExprResult(E); 7279 // OK to convert to signed, because new type has more bits than old. 7280 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7281 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7282 true); 7283 } 7284 7285 /// Check if the given expression \a E is a constant integer that fits 7286 /// into \a Bits bits. 7287 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7288 if (E == nullptr) 7289 return false; 7290 llvm::APSInt Result; 7291 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7292 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7293 return false; 7294 } 7295 7296 /// Build preinits statement for the given declarations. 7297 static Stmt *buildPreInits(ASTContext &Context, 7298 MutableArrayRef<Decl *> PreInits) { 7299 if (!PreInits.empty()) { 7300 return new (Context) DeclStmt( 7301 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7302 SourceLocation(), SourceLocation()); 7303 } 7304 return nullptr; 7305 } 7306 7307 /// Build preinits statement for the given declarations. 7308 static Stmt * 7309 buildPreInits(ASTContext &Context, 7310 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7311 if (!Captures.empty()) { 7312 SmallVector<Decl *, 16> PreInits; 7313 for (const auto &Pair : Captures) 7314 PreInits.push_back(Pair.second->getDecl()); 7315 return buildPreInits(Context, PreInits); 7316 } 7317 return nullptr; 7318 } 7319 7320 /// Build postupdate expression for the given list of postupdates expressions. 7321 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7322 Expr *PostUpdate = nullptr; 7323 if (!PostUpdates.empty()) { 7324 for (Expr *E : PostUpdates) { 7325 Expr *ConvE = S.BuildCStyleCastExpr( 7326 E->getExprLoc(), 7327 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7328 E->getExprLoc(), E) 7329 .get(); 7330 PostUpdate = PostUpdate 7331 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7332 PostUpdate, ConvE) 7333 .get() 7334 : ConvE; 7335 } 7336 } 7337 return PostUpdate; 7338 } 7339 7340 /// Called on a for stmt to check itself and nested loops (if any). 7341 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7342 /// number of collapsed loops otherwise. 7343 static unsigned 7344 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7345 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7346 DSAStackTy &DSA, 7347 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7348 OMPLoopDirective::HelperExprs &Built) { 7349 unsigned NestedLoopCount = 1; 7350 if (CollapseLoopCountExpr) { 7351 // Found 'collapse' clause - calculate collapse number. 7352 Expr::EvalResult Result; 7353 if (!CollapseLoopCountExpr->isValueDependent() && 7354 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7355 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7356 } else { 7357 Built.clear(/*Size=*/1); 7358 return 1; 7359 } 7360 } 7361 unsigned OrderedLoopCount = 1; 7362 if (OrderedLoopCountExpr) { 7363 // Found 'ordered' clause - calculate collapse number. 7364 Expr::EvalResult EVResult; 7365 if (!OrderedLoopCountExpr->isValueDependent() && 7366 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7367 SemaRef.getASTContext())) { 7368 llvm::APSInt Result = EVResult.Val.getInt(); 7369 if (Result.getLimitedValue() < NestedLoopCount) { 7370 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7371 diag::err_omp_wrong_ordered_loop_count) 7372 << OrderedLoopCountExpr->getSourceRange(); 7373 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7374 diag::note_collapse_loop_count) 7375 << CollapseLoopCountExpr->getSourceRange(); 7376 } 7377 OrderedLoopCount = Result.getLimitedValue(); 7378 } else { 7379 Built.clear(/*Size=*/1); 7380 return 1; 7381 } 7382 } 7383 // This is helper routine for loop directives (e.g., 'for', 'simd', 7384 // 'for simd', etc.). 7385 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7386 SmallVector<LoopIterationSpace, 4> IterSpaces( 7387 std::max(OrderedLoopCount, NestedLoopCount)); 7388 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7389 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7390 if (checkOpenMPIterationSpace( 7391 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7392 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7393 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7394 return 0; 7395 // Move on to the next nested for loop, or to the loop body. 7396 // OpenMP [2.8.1, simd construct, Restrictions] 7397 // All loops associated with the construct must be perfectly nested; that 7398 // is, there must be no intervening code nor any OpenMP directive between 7399 // any two loops. 7400 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7401 CurStmt = For->getBody(); 7402 } else { 7403 assert(isa<CXXForRangeStmt>(CurStmt) && 7404 "Expected canonical for or range-based for loops."); 7405 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7406 } 7407 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7408 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7409 } 7410 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7411 if (checkOpenMPIterationSpace( 7412 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7413 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7414 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7415 return 0; 7416 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7417 // Handle initialization of captured loop iterator variables. 7418 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7419 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7420 Captures[DRE] = DRE; 7421 } 7422 } 7423 // Move on to the next nested for loop, or to the loop body. 7424 // OpenMP [2.8.1, simd construct, Restrictions] 7425 // All loops associated with the construct must be perfectly nested; that 7426 // is, there must be no intervening code nor any OpenMP directive between 7427 // any two loops. 7428 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7429 CurStmt = For->getBody(); 7430 } else { 7431 assert(isa<CXXForRangeStmt>(CurStmt) && 7432 "Expected canonical for or range-based for loops."); 7433 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7434 } 7435 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7436 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7437 } 7438 7439 Built.clear(/* size */ NestedLoopCount); 7440 7441 if (SemaRef.CurContext->isDependentContext()) 7442 return NestedLoopCount; 7443 7444 // An example of what is generated for the following code: 7445 // 7446 // #pragma omp simd collapse(2) ordered(2) 7447 // for (i = 0; i < NI; ++i) 7448 // for (k = 0; k < NK; ++k) 7449 // for (j = J0; j < NJ; j+=2) { 7450 // <loop body> 7451 // } 7452 // 7453 // We generate the code below. 7454 // Note: the loop body may be outlined in CodeGen. 7455 // Note: some counters may be C++ classes, operator- is used to find number of 7456 // iterations and operator+= to calculate counter value. 7457 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7458 // or i64 is currently supported). 7459 // 7460 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7461 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7462 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7463 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7464 // // similar updates for vars in clauses (e.g. 'linear') 7465 // <loop body (using local i and j)> 7466 // } 7467 // i = NI; // assign final values of counters 7468 // j = NJ; 7469 // 7470 7471 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7472 // the iteration counts of the collapsed for loops. 7473 // Precondition tests if there is at least one iteration (all conditions are 7474 // true). 7475 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7476 Expr *N0 = IterSpaces[0].NumIterations; 7477 ExprResult LastIteration32 = 7478 widenIterationCount(/*Bits=*/32, 7479 SemaRef 7480 .PerformImplicitConversion( 7481 N0->IgnoreImpCasts(), N0->getType(), 7482 Sema::AA_Converting, /*AllowExplicit=*/true) 7483 .get(), 7484 SemaRef); 7485 ExprResult LastIteration64 = widenIterationCount( 7486 /*Bits=*/64, 7487 SemaRef 7488 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7489 Sema::AA_Converting, 7490 /*AllowExplicit=*/true) 7491 .get(), 7492 SemaRef); 7493 7494 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7495 return NestedLoopCount; 7496 7497 ASTContext &C = SemaRef.Context; 7498 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7499 7500 Scope *CurScope = DSA.getCurScope(); 7501 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7502 if (PreCond.isUsable()) { 7503 PreCond = 7504 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7505 PreCond.get(), IterSpaces[Cnt].PreCond); 7506 } 7507 Expr *N = IterSpaces[Cnt].NumIterations; 7508 SourceLocation Loc = N->getExprLoc(); 7509 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7510 if (LastIteration32.isUsable()) 7511 LastIteration32 = SemaRef.BuildBinOp( 7512 CurScope, Loc, BO_Mul, LastIteration32.get(), 7513 SemaRef 7514 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7515 Sema::AA_Converting, 7516 /*AllowExplicit=*/true) 7517 .get()); 7518 if (LastIteration64.isUsable()) 7519 LastIteration64 = SemaRef.BuildBinOp( 7520 CurScope, Loc, BO_Mul, LastIteration64.get(), 7521 SemaRef 7522 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7523 Sema::AA_Converting, 7524 /*AllowExplicit=*/true) 7525 .get()); 7526 } 7527 7528 // Choose either the 32-bit or 64-bit version. 7529 ExprResult LastIteration = LastIteration64; 7530 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7531 (LastIteration32.isUsable() && 7532 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7533 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7534 fitsInto( 7535 /*Bits=*/32, 7536 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7537 LastIteration64.get(), SemaRef)))) 7538 LastIteration = LastIteration32; 7539 QualType VType = LastIteration.get()->getType(); 7540 QualType RealVType = VType; 7541 QualType StrideVType = VType; 7542 if (isOpenMPTaskLoopDirective(DKind)) { 7543 VType = 7544 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7545 StrideVType = 7546 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7547 } 7548 7549 if (!LastIteration.isUsable()) 7550 return 0; 7551 7552 // Save the number of iterations. 7553 ExprResult NumIterations = LastIteration; 7554 { 7555 LastIteration = SemaRef.BuildBinOp( 7556 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7557 LastIteration.get(), 7558 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7559 if (!LastIteration.isUsable()) 7560 return 0; 7561 } 7562 7563 // Calculate the last iteration number beforehand instead of doing this on 7564 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7565 llvm::APSInt Result; 7566 bool IsConstant = 7567 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7568 ExprResult CalcLastIteration; 7569 if (!IsConstant) { 7570 ExprResult SaveRef = 7571 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7572 LastIteration = SaveRef; 7573 7574 // Prepare SaveRef + 1. 7575 NumIterations = SemaRef.BuildBinOp( 7576 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7577 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7578 if (!NumIterations.isUsable()) 7579 return 0; 7580 } 7581 7582 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7583 7584 // Build variables passed into runtime, necessary for worksharing directives. 7585 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7586 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7587 isOpenMPDistributeDirective(DKind)) { 7588 // Lower bound variable, initialized with zero. 7589 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7590 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7591 SemaRef.AddInitializerToDecl(LBDecl, 7592 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7593 /*DirectInit*/ false); 7594 7595 // Upper bound variable, initialized with last iteration number. 7596 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7597 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7598 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7599 /*DirectInit*/ false); 7600 7601 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7602 // This will be used to implement clause 'lastprivate'. 7603 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7604 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7605 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7606 SemaRef.AddInitializerToDecl(ILDecl, 7607 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7608 /*DirectInit*/ false); 7609 7610 // Stride variable returned by runtime (we initialize it to 1 by default). 7611 VarDecl *STDecl = 7612 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7613 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7614 SemaRef.AddInitializerToDecl(STDecl, 7615 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7616 /*DirectInit*/ false); 7617 7618 // Build expression: UB = min(UB, LastIteration) 7619 // It is necessary for CodeGen of directives with static scheduling. 7620 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7621 UB.get(), LastIteration.get()); 7622 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7623 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7624 LastIteration.get(), UB.get()); 7625 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7626 CondOp.get()); 7627 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7628 7629 // If we have a combined directive that combines 'distribute', 'for' or 7630 // 'simd' we need to be able to access the bounds of the schedule of the 7631 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7632 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7633 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7634 // Lower bound variable, initialized with zero. 7635 VarDecl *CombLBDecl = 7636 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7637 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7638 SemaRef.AddInitializerToDecl( 7639 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7640 /*DirectInit*/ false); 7641 7642 // Upper bound variable, initialized with last iteration number. 7643 VarDecl *CombUBDecl = 7644 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7645 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7646 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7647 /*DirectInit*/ false); 7648 7649 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7650 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7651 ExprResult CombCondOp = 7652 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7653 LastIteration.get(), CombUB.get()); 7654 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7655 CombCondOp.get()); 7656 CombEUB = 7657 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7658 7659 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7660 // We expect to have at least 2 more parameters than the 'parallel' 7661 // directive does - the lower and upper bounds of the previous schedule. 7662 assert(CD->getNumParams() >= 4 && 7663 "Unexpected number of parameters in loop combined directive"); 7664 7665 // Set the proper type for the bounds given what we learned from the 7666 // enclosed loops. 7667 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7668 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7669 7670 // Previous lower and upper bounds are obtained from the region 7671 // parameters. 7672 PrevLB = 7673 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7674 PrevUB = 7675 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7676 } 7677 } 7678 7679 // Build the iteration variable and its initialization before loop. 7680 ExprResult IV; 7681 ExprResult Init, CombInit; 7682 { 7683 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7684 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7685 Expr *RHS = 7686 (isOpenMPWorksharingDirective(DKind) || 7687 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7688 ? LB.get() 7689 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7690 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7691 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7692 7693 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7694 Expr *CombRHS = 7695 (isOpenMPWorksharingDirective(DKind) || 7696 isOpenMPTaskLoopDirective(DKind) || 7697 isOpenMPDistributeDirective(DKind)) 7698 ? CombLB.get() 7699 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7700 CombInit = 7701 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7702 CombInit = 7703 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7704 } 7705 } 7706 7707 bool UseStrictCompare = 7708 RealVType->hasUnsignedIntegerRepresentation() && 7709 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7710 return LIS.IsStrictCompare; 7711 }); 7712 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7713 // unsigned IV)) for worksharing loops. 7714 SourceLocation CondLoc = AStmt->getBeginLoc(); 7715 Expr *BoundUB = UB.get(); 7716 if (UseStrictCompare) { 7717 BoundUB = 7718 SemaRef 7719 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7720 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7721 .get(); 7722 BoundUB = 7723 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7724 } 7725 ExprResult Cond = 7726 (isOpenMPWorksharingDirective(DKind) || 7727 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7728 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7729 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7730 BoundUB) 7731 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7732 NumIterations.get()); 7733 ExprResult CombDistCond; 7734 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7735 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7736 NumIterations.get()); 7737 } 7738 7739 ExprResult CombCond; 7740 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7741 Expr *BoundCombUB = CombUB.get(); 7742 if (UseStrictCompare) { 7743 BoundCombUB = 7744 SemaRef 7745 .BuildBinOp( 7746 CurScope, CondLoc, BO_Add, BoundCombUB, 7747 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7748 .get(); 7749 BoundCombUB = 7750 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7751 .get(); 7752 } 7753 CombCond = 7754 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7755 IV.get(), BoundCombUB); 7756 } 7757 // Loop increment (IV = IV + 1) 7758 SourceLocation IncLoc = AStmt->getBeginLoc(); 7759 ExprResult Inc = 7760 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7761 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7762 if (!Inc.isUsable()) 7763 return 0; 7764 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7765 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7766 if (!Inc.isUsable()) 7767 return 0; 7768 7769 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7770 // Used for directives with static scheduling. 7771 // In combined construct, add combined version that use CombLB and CombUB 7772 // base variables for the update 7773 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7774 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7775 isOpenMPDistributeDirective(DKind)) { 7776 // LB + ST 7777 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7778 if (!NextLB.isUsable()) 7779 return 0; 7780 // LB = LB + ST 7781 NextLB = 7782 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7783 NextLB = 7784 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7785 if (!NextLB.isUsable()) 7786 return 0; 7787 // UB + ST 7788 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7789 if (!NextUB.isUsable()) 7790 return 0; 7791 // UB = UB + ST 7792 NextUB = 7793 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7794 NextUB = 7795 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7796 if (!NextUB.isUsable()) 7797 return 0; 7798 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7799 CombNextLB = 7800 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7801 if (!NextLB.isUsable()) 7802 return 0; 7803 // LB = LB + ST 7804 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7805 CombNextLB.get()); 7806 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7807 /*DiscardedValue*/ false); 7808 if (!CombNextLB.isUsable()) 7809 return 0; 7810 // UB + ST 7811 CombNextUB = 7812 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7813 if (!CombNextUB.isUsable()) 7814 return 0; 7815 // UB = UB + ST 7816 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7817 CombNextUB.get()); 7818 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7819 /*DiscardedValue*/ false); 7820 if (!CombNextUB.isUsable()) 7821 return 0; 7822 } 7823 } 7824 7825 // Create increment expression for distribute loop when combined in a same 7826 // directive with for as IV = IV + ST; ensure upper bound expression based 7827 // on PrevUB instead of NumIterations - used to implement 'for' when found 7828 // in combination with 'distribute', like in 'distribute parallel for' 7829 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7830 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7831 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7832 DistCond = SemaRef.BuildBinOp( 7833 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7834 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7835 7836 DistInc = 7837 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7838 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7839 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7840 DistInc.get()); 7841 DistInc = 7842 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7843 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7844 7845 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7846 // construct 7847 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7848 ExprResult IsUBGreater = 7849 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7850 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7851 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7852 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7853 CondOp.get()); 7854 PrevEUB = 7855 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7856 7857 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7858 // parallel for is in combination with a distribute directive with 7859 // schedule(static, 1) 7860 Expr *BoundPrevUB = PrevUB.get(); 7861 if (UseStrictCompare) { 7862 BoundPrevUB = 7863 SemaRef 7864 .BuildBinOp( 7865 CurScope, CondLoc, BO_Add, BoundPrevUB, 7866 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7867 .get(); 7868 BoundPrevUB = 7869 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7870 .get(); 7871 } 7872 ParForInDistCond = 7873 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7874 IV.get(), BoundPrevUB); 7875 } 7876 7877 // Build updates and final values of the loop counters. 7878 bool HasErrors = false; 7879 Built.Counters.resize(NestedLoopCount); 7880 Built.Inits.resize(NestedLoopCount); 7881 Built.Updates.resize(NestedLoopCount); 7882 Built.Finals.resize(NestedLoopCount); 7883 Built.DependentCounters.resize(NestedLoopCount); 7884 Built.DependentInits.resize(NestedLoopCount); 7885 Built.FinalsConditions.resize(NestedLoopCount); 7886 { 7887 // We implement the following algorithm for obtaining the 7888 // original loop iteration variable values based on the 7889 // value of the collapsed loop iteration variable IV. 7890 // 7891 // Let n+1 be the number of collapsed loops in the nest. 7892 // Iteration variables (I0, I1, .... In) 7893 // Iteration counts (N0, N1, ... Nn) 7894 // 7895 // Acc = IV; 7896 // 7897 // To compute Ik for loop k, 0 <= k <= n, generate: 7898 // Prod = N(k+1) * N(k+2) * ... * Nn; 7899 // Ik = Acc / Prod; 7900 // Acc -= Ik * Prod; 7901 // 7902 ExprResult Acc = IV; 7903 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7904 LoopIterationSpace &IS = IterSpaces[Cnt]; 7905 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7906 ExprResult Iter; 7907 7908 // Compute prod 7909 ExprResult Prod = 7910 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7911 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7912 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7913 IterSpaces[K].NumIterations); 7914 7915 // Iter = Acc / Prod 7916 // If there is at least one more inner loop to avoid 7917 // multiplication by 1. 7918 if (Cnt + 1 < NestedLoopCount) 7919 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7920 Acc.get(), Prod.get()); 7921 else 7922 Iter = Acc; 7923 if (!Iter.isUsable()) { 7924 HasErrors = true; 7925 break; 7926 } 7927 7928 // Update Acc: 7929 // Acc -= Iter * Prod 7930 // Check if there is at least one more inner loop to avoid 7931 // multiplication by 1. 7932 if (Cnt + 1 < NestedLoopCount) 7933 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7934 Iter.get(), Prod.get()); 7935 else 7936 Prod = Iter; 7937 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7938 Acc.get(), Prod.get()); 7939 7940 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7941 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7942 DeclRefExpr *CounterVar = buildDeclRefExpr( 7943 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7944 /*RefersToCapture=*/true); 7945 ExprResult Init = 7946 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7947 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7948 if (!Init.isUsable()) { 7949 HasErrors = true; 7950 break; 7951 } 7952 ExprResult Update = buildCounterUpdate( 7953 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7954 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7955 if (!Update.isUsable()) { 7956 HasErrors = true; 7957 break; 7958 } 7959 7960 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7961 ExprResult Final = 7962 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7963 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7964 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7965 if (!Final.isUsable()) { 7966 HasErrors = true; 7967 break; 7968 } 7969 7970 if (!Update.isUsable() || !Final.isUsable()) { 7971 HasErrors = true; 7972 break; 7973 } 7974 // Save results 7975 Built.Counters[Cnt] = IS.CounterVar; 7976 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7977 Built.Inits[Cnt] = Init.get(); 7978 Built.Updates[Cnt] = Update.get(); 7979 Built.Finals[Cnt] = Final.get(); 7980 Built.DependentCounters[Cnt] = nullptr; 7981 Built.DependentInits[Cnt] = nullptr; 7982 Built.FinalsConditions[Cnt] = nullptr; 7983 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7984 Built.DependentCounters[Cnt] = 7985 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7986 Built.DependentInits[Cnt] = 7987 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7988 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7989 } 7990 } 7991 } 7992 7993 if (HasErrors) 7994 return 0; 7995 7996 // Save results 7997 Built.IterationVarRef = IV.get(); 7998 Built.LastIteration = LastIteration.get(); 7999 Built.NumIterations = NumIterations.get(); 8000 Built.CalcLastIteration = SemaRef 8001 .ActOnFinishFullExpr(CalcLastIteration.get(), 8002 /*DiscardedValue=*/false) 8003 .get(); 8004 Built.PreCond = PreCond.get(); 8005 Built.PreInits = buildPreInits(C, Captures); 8006 Built.Cond = Cond.get(); 8007 Built.Init = Init.get(); 8008 Built.Inc = Inc.get(); 8009 Built.LB = LB.get(); 8010 Built.UB = UB.get(); 8011 Built.IL = IL.get(); 8012 Built.ST = ST.get(); 8013 Built.EUB = EUB.get(); 8014 Built.NLB = NextLB.get(); 8015 Built.NUB = NextUB.get(); 8016 Built.PrevLB = PrevLB.get(); 8017 Built.PrevUB = PrevUB.get(); 8018 Built.DistInc = DistInc.get(); 8019 Built.PrevEUB = PrevEUB.get(); 8020 Built.DistCombinedFields.LB = CombLB.get(); 8021 Built.DistCombinedFields.UB = CombUB.get(); 8022 Built.DistCombinedFields.EUB = CombEUB.get(); 8023 Built.DistCombinedFields.Init = CombInit.get(); 8024 Built.DistCombinedFields.Cond = CombCond.get(); 8025 Built.DistCombinedFields.NLB = CombNextLB.get(); 8026 Built.DistCombinedFields.NUB = CombNextUB.get(); 8027 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8028 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8029 8030 return NestedLoopCount; 8031 } 8032 8033 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8034 auto CollapseClauses = 8035 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8036 if (CollapseClauses.begin() != CollapseClauses.end()) 8037 return (*CollapseClauses.begin())->getNumForLoops(); 8038 return nullptr; 8039 } 8040 8041 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8042 auto OrderedClauses = 8043 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8044 if (OrderedClauses.begin() != OrderedClauses.end()) 8045 return (*OrderedClauses.begin())->getNumForLoops(); 8046 return nullptr; 8047 } 8048 8049 static bool checkSimdlenSafelenSpecified(Sema &S, 8050 const ArrayRef<OMPClause *> Clauses) { 8051 const OMPSafelenClause *Safelen = nullptr; 8052 const OMPSimdlenClause *Simdlen = nullptr; 8053 8054 for (const OMPClause *Clause : Clauses) { 8055 if (Clause->getClauseKind() == OMPC_safelen) 8056 Safelen = cast<OMPSafelenClause>(Clause); 8057 else if (Clause->getClauseKind() == OMPC_simdlen) 8058 Simdlen = cast<OMPSimdlenClause>(Clause); 8059 if (Safelen && Simdlen) 8060 break; 8061 } 8062 8063 if (Simdlen && Safelen) { 8064 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8065 const Expr *SafelenLength = Safelen->getSafelen(); 8066 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8067 SimdlenLength->isInstantiationDependent() || 8068 SimdlenLength->containsUnexpandedParameterPack()) 8069 return false; 8070 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8071 SafelenLength->isInstantiationDependent() || 8072 SafelenLength->containsUnexpandedParameterPack()) 8073 return false; 8074 Expr::EvalResult SimdlenResult, SafelenResult; 8075 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8076 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8077 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8078 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8079 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8080 // If both simdlen and safelen clauses are specified, the value of the 8081 // simdlen parameter must be less than or equal to the value of the safelen 8082 // parameter. 8083 if (SimdlenRes > SafelenRes) { 8084 S.Diag(SimdlenLength->getExprLoc(), 8085 diag::err_omp_wrong_simdlen_safelen_values) 8086 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8087 return true; 8088 } 8089 } 8090 return false; 8091 } 8092 8093 StmtResult 8094 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8095 SourceLocation StartLoc, SourceLocation EndLoc, 8096 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8097 if (!AStmt) 8098 return StmtError(); 8099 8100 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8101 OMPLoopDirective::HelperExprs B; 8102 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8103 // define the nested loops number. 8104 unsigned NestedLoopCount = checkOpenMPLoop( 8105 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8106 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8107 if (NestedLoopCount == 0) 8108 return StmtError(); 8109 8110 assert((CurContext->isDependentContext() || B.builtAll()) && 8111 "omp simd loop exprs were not built"); 8112 8113 if (!CurContext->isDependentContext()) { 8114 // Finalize the clauses that need pre-built expressions for CodeGen. 8115 for (OMPClause *C : Clauses) { 8116 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8117 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8118 B.NumIterations, *this, CurScope, 8119 DSAStack)) 8120 return StmtError(); 8121 } 8122 } 8123 8124 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8125 return StmtError(); 8126 8127 setFunctionHasBranchProtectedScope(); 8128 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8129 Clauses, AStmt, B); 8130 } 8131 8132 StmtResult 8133 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8134 SourceLocation StartLoc, SourceLocation EndLoc, 8135 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8136 if (!AStmt) 8137 return StmtError(); 8138 8139 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8140 OMPLoopDirective::HelperExprs B; 8141 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8142 // define the nested loops number. 8143 unsigned NestedLoopCount = checkOpenMPLoop( 8144 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8145 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8146 if (NestedLoopCount == 0) 8147 return StmtError(); 8148 8149 assert((CurContext->isDependentContext() || B.builtAll()) && 8150 "omp for loop exprs were not built"); 8151 8152 if (!CurContext->isDependentContext()) { 8153 // Finalize the clauses that need pre-built expressions for CodeGen. 8154 for (OMPClause *C : Clauses) { 8155 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8156 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8157 B.NumIterations, *this, CurScope, 8158 DSAStack)) 8159 return StmtError(); 8160 } 8161 } 8162 8163 setFunctionHasBranchProtectedScope(); 8164 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8165 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8166 } 8167 8168 StmtResult Sema::ActOnOpenMPForSimdDirective( 8169 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8170 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8171 if (!AStmt) 8172 return StmtError(); 8173 8174 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8175 OMPLoopDirective::HelperExprs B; 8176 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8177 // define the nested loops number. 8178 unsigned NestedLoopCount = 8179 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8180 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8181 VarsWithImplicitDSA, B); 8182 if (NestedLoopCount == 0) 8183 return StmtError(); 8184 8185 assert((CurContext->isDependentContext() || B.builtAll()) && 8186 "omp for simd loop exprs were not built"); 8187 8188 if (!CurContext->isDependentContext()) { 8189 // Finalize the clauses that need pre-built expressions for CodeGen. 8190 for (OMPClause *C : Clauses) { 8191 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8192 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8193 B.NumIterations, *this, CurScope, 8194 DSAStack)) 8195 return StmtError(); 8196 } 8197 } 8198 8199 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8200 return StmtError(); 8201 8202 setFunctionHasBranchProtectedScope(); 8203 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8204 Clauses, AStmt, B); 8205 } 8206 8207 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8208 Stmt *AStmt, 8209 SourceLocation StartLoc, 8210 SourceLocation EndLoc) { 8211 if (!AStmt) 8212 return StmtError(); 8213 8214 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8215 auto BaseStmt = AStmt; 8216 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8217 BaseStmt = CS->getCapturedStmt(); 8218 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8219 auto S = C->children(); 8220 if (S.begin() == S.end()) 8221 return StmtError(); 8222 // All associated statements must be '#pragma omp section' except for 8223 // the first one. 8224 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8225 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8226 if (SectionStmt) 8227 Diag(SectionStmt->getBeginLoc(), 8228 diag::err_omp_sections_substmt_not_section); 8229 return StmtError(); 8230 } 8231 cast<OMPSectionDirective>(SectionStmt) 8232 ->setHasCancel(DSAStack->isCancelRegion()); 8233 } 8234 } else { 8235 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8236 return StmtError(); 8237 } 8238 8239 setFunctionHasBranchProtectedScope(); 8240 8241 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8242 DSAStack->isCancelRegion()); 8243 } 8244 8245 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8246 SourceLocation StartLoc, 8247 SourceLocation EndLoc) { 8248 if (!AStmt) 8249 return StmtError(); 8250 8251 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8252 8253 setFunctionHasBranchProtectedScope(); 8254 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8255 8256 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8257 DSAStack->isCancelRegion()); 8258 } 8259 8260 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8261 Stmt *AStmt, 8262 SourceLocation StartLoc, 8263 SourceLocation EndLoc) { 8264 if (!AStmt) 8265 return StmtError(); 8266 8267 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8268 8269 setFunctionHasBranchProtectedScope(); 8270 8271 // OpenMP [2.7.3, single Construct, Restrictions] 8272 // The copyprivate clause must not be used with the nowait clause. 8273 const OMPClause *Nowait = nullptr; 8274 const OMPClause *Copyprivate = nullptr; 8275 for (const OMPClause *Clause : Clauses) { 8276 if (Clause->getClauseKind() == OMPC_nowait) 8277 Nowait = Clause; 8278 else if (Clause->getClauseKind() == OMPC_copyprivate) 8279 Copyprivate = Clause; 8280 if (Copyprivate && Nowait) { 8281 Diag(Copyprivate->getBeginLoc(), 8282 diag::err_omp_single_copyprivate_with_nowait); 8283 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8284 return StmtError(); 8285 } 8286 } 8287 8288 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8289 } 8290 8291 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8292 SourceLocation StartLoc, 8293 SourceLocation EndLoc) { 8294 if (!AStmt) 8295 return StmtError(); 8296 8297 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8298 8299 setFunctionHasBranchProtectedScope(); 8300 8301 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8302 } 8303 8304 StmtResult Sema::ActOnOpenMPCriticalDirective( 8305 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8306 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8307 if (!AStmt) 8308 return StmtError(); 8309 8310 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8311 8312 bool ErrorFound = false; 8313 llvm::APSInt Hint; 8314 SourceLocation HintLoc; 8315 bool DependentHint = false; 8316 for (const OMPClause *C : Clauses) { 8317 if (C->getClauseKind() == OMPC_hint) { 8318 if (!DirName.getName()) { 8319 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8320 ErrorFound = true; 8321 } 8322 Expr *E = cast<OMPHintClause>(C)->getHint(); 8323 if (E->isTypeDependent() || E->isValueDependent() || 8324 E->isInstantiationDependent()) { 8325 DependentHint = true; 8326 } else { 8327 Hint = E->EvaluateKnownConstInt(Context); 8328 HintLoc = C->getBeginLoc(); 8329 } 8330 } 8331 } 8332 if (ErrorFound) 8333 return StmtError(); 8334 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8335 if (Pair.first && DirName.getName() && !DependentHint) { 8336 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8337 Diag(StartLoc, diag::err_omp_critical_with_hint); 8338 if (HintLoc.isValid()) 8339 Diag(HintLoc, diag::note_omp_critical_hint_here) 8340 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8341 else 8342 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8343 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8344 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8345 << 1 8346 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8347 /*Radix=*/10, /*Signed=*/false); 8348 } else { 8349 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8350 } 8351 } 8352 } 8353 8354 setFunctionHasBranchProtectedScope(); 8355 8356 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8357 Clauses, AStmt); 8358 if (!Pair.first && DirName.getName() && !DependentHint) 8359 DSAStack->addCriticalWithHint(Dir, Hint); 8360 return Dir; 8361 } 8362 8363 StmtResult Sema::ActOnOpenMPParallelForDirective( 8364 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8365 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8366 if (!AStmt) 8367 return StmtError(); 8368 8369 auto *CS = cast<CapturedStmt>(AStmt); 8370 // 1.2.2 OpenMP Language Terminology 8371 // Structured block - An executable statement with a single entry at the 8372 // top and a single exit at the bottom. 8373 // The point of exit cannot be a branch out of the structured block. 8374 // longjmp() and throw() must not violate the entry/exit criteria. 8375 CS->getCapturedDecl()->setNothrow(); 8376 8377 OMPLoopDirective::HelperExprs B; 8378 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8379 // define the nested loops number. 8380 unsigned NestedLoopCount = 8381 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8382 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8383 VarsWithImplicitDSA, B); 8384 if (NestedLoopCount == 0) 8385 return StmtError(); 8386 8387 assert((CurContext->isDependentContext() || B.builtAll()) && 8388 "omp parallel for loop exprs were not built"); 8389 8390 if (!CurContext->isDependentContext()) { 8391 // Finalize the clauses that need pre-built expressions for CodeGen. 8392 for (OMPClause *C : Clauses) { 8393 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8394 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8395 B.NumIterations, *this, CurScope, 8396 DSAStack)) 8397 return StmtError(); 8398 } 8399 } 8400 8401 setFunctionHasBranchProtectedScope(); 8402 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8403 NestedLoopCount, Clauses, AStmt, B, 8404 DSAStack->isCancelRegion()); 8405 } 8406 8407 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8408 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8409 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8410 if (!AStmt) 8411 return StmtError(); 8412 8413 auto *CS = cast<CapturedStmt>(AStmt); 8414 // 1.2.2 OpenMP Language Terminology 8415 // Structured block - An executable statement with a single entry at the 8416 // top and a single exit at the bottom. 8417 // The point of exit cannot be a branch out of the structured block. 8418 // longjmp() and throw() must not violate the entry/exit criteria. 8419 CS->getCapturedDecl()->setNothrow(); 8420 8421 OMPLoopDirective::HelperExprs B; 8422 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8423 // define the nested loops number. 8424 unsigned NestedLoopCount = 8425 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8426 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8427 VarsWithImplicitDSA, B); 8428 if (NestedLoopCount == 0) 8429 return StmtError(); 8430 8431 if (!CurContext->isDependentContext()) { 8432 // Finalize the clauses that need pre-built expressions for CodeGen. 8433 for (OMPClause *C : Clauses) { 8434 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8435 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8436 B.NumIterations, *this, CurScope, 8437 DSAStack)) 8438 return StmtError(); 8439 } 8440 } 8441 8442 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8443 return StmtError(); 8444 8445 setFunctionHasBranchProtectedScope(); 8446 return OMPParallelForSimdDirective::Create( 8447 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8448 } 8449 8450 StmtResult 8451 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8452 Stmt *AStmt, SourceLocation StartLoc, 8453 SourceLocation EndLoc) { 8454 if (!AStmt) 8455 return StmtError(); 8456 8457 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8458 auto *CS = cast<CapturedStmt>(AStmt); 8459 // 1.2.2 OpenMP Language Terminology 8460 // Structured block - An executable statement with a single entry at the 8461 // top and a single exit at the bottom. 8462 // The point of exit cannot be a branch out of the structured block. 8463 // longjmp() and throw() must not violate the entry/exit criteria. 8464 CS->getCapturedDecl()->setNothrow(); 8465 8466 setFunctionHasBranchProtectedScope(); 8467 8468 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8469 AStmt); 8470 } 8471 8472 StmtResult 8473 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8474 Stmt *AStmt, SourceLocation StartLoc, 8475 SourceLocation EndLoc) { 8476 if (!AStmt) 8477 return StmtError(); 8478 8479 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8480 auto BaseStmt = AStmt; 8481 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8482 BaseStmt = CS->getCapturedStmt(); 8483 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8484 auto S = C->children(); 8485 if (S.begin() == S.end()) 8486 return StmtError(); 8487 // All associated statements must be '#pragma omp section' except for 8488 // the first one. 8489 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8490 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8491 if (SectionStmt) 8492 Diag(SectionStmt->getBeginLoc(), 8493 diag::err_omp_parallel_sections_substmt_not_section); 8494 return StmtError(); 8495 } 8496 cast<OMPSectionDirective>(SectionStmt) 8497 ->setHasCancel(DSAStack->isCancelRegion()); 8498 } 8499 } else { 8500 Diag(AStmt->getBeginLoc(), 8501 diag::err_omp_parallel_sections_not_compound_stmt); 8502 return StmtError(); 8503 } 8504 8505 setFunctionHasBranchProtectedScope(); 8506 8507 return OMPParallelSectionsDirective::Create( 8508 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8509 } 8510 8511 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8512 Stmt *AStmt, SourceLocation StartLoc, 8513 SourceLocation EndLoc) { 8514 if (!AStmt) 8515 return StmtError(); 8516 8517 auto *CS = cast<CapturedStmt>(AStmt); 8518 // 1.2.2 OpenMP Language Terminology 8519 // Structured block - An executable statement with a single entry at the 8520 // top and a single exit at the bottom. 8521 // The point of exit cannot be a branch out of the structured block. 8522 // longjmp() and throw() must not violate the entry/exit criteria. 8523 CS->getCapturedDecl()->setNothrow(); 8524 8525 setFunctionHasBranchProtectedScope(); 8526 8527 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8528 DSAStack->isCancelRegion()); 8529 } 8530 8531 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8532 SourceLocation EndLoc) { 8533 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8534 } 8535 8536 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8537 SourceLocation EndLoc) { 8538 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8539 } 8540 8541 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8542 SourceLocation EndLoc) { 8543 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8544 } 8545 8546 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8547 Stmt *AStmt, 8548 SourceLocation StartLoc, 8549 SourceLocation EndLoc) { 8550 if (!AStmt) 8551 return StmtError(); 8552 8553 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8554 8555 setFunctionHasBranchProtectedScope(); 8556 8557 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8558 AStmt, 8559 DSAStack->getTaskgroupReductionRef()); 8560 } 8561 8562 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8563 SourceLocation StartLoc, 8564 SourceLocation EndLoc) { 8565 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8566 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8567 } 8568 8569 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8570 Stmt *AStmt, 8571 SourceLocation StartLoc, 8572 SourceLocation EndLoc) { 8573 const OMPClause *DependFound = nullptr; 8574 const OMPClause *DependSourceClause = nullptr; 8575 const OMPClause *DependSinkClause = nullptr; 8576 bool ErrorFound = false; 8577 const OMPThreadsClause *TC = nullptr; 8578 const OMPSIMDClause *SC = nullptr; 8579 for (const OMPClause *C : Clauses) { 8580 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8581 DependFound = C; 8582 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8583 if (DependSourceClause) { 8584 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8585 << getOpenMPDirectiveName(OMPD_ordered) 8586 << getOpenMPClauseName(OMPC_depend) << 2; 8587 ErrorFound = true; 8588 } else { 8589 DependSourceClause = C; 8590 } 8591 if (DependSinkClause) { 8592 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8593 << 0; 8594 ErrorFound = true; 8595 } 8596 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8597 if (DependSourceClause) { 8598 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8599 << 1; 8600 ErrorFound = true; 8601 } 8602 DependSinkClause = C; 8603 } 8604 } else if (C->getClauseKind() == OMPC_threads) { 8605 TC = cast<OMPThreadsClause>(C); 8606 } else if (C->getClauseKind() == OMPC_simd) { 8607 SC = cast<OMPSIMDClause>(C); 8608 } 8609 } 8610 if (!ErrorFound && !SC && 8611 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8612 // OpenMP [2.8.1,simd Construct, Restrictions] 8613 // An ordered construct with the simd clause is the only OpenMP construct 8614 // that can appear in the simd region. 8615 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8616 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8617 ErrorFound = true; 8618 } else if (DependFound && (TC || SC)) { 8619 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8620 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8621 ErrorFound = true; 8622 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8623 Diag(DependFound->getBeginLoc(), 8624 diag::err_omp_ordered_directive_without_param); 8625 ErrorFound = true; 8626 } else if (TC || Clauses.empty()) { 8627 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8628 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8629 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8630 << (TC != nullptr); 8631 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 8632 ErrorFound = true; 8633 } 8634 } 8635 if ((!AStmt && !DependFound) || ErrorFound) 8636 return StmtError(); 8637 8638 if (AStmt) { 8639 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8640 8641 setFunctionHasBranchProtectedScope(); 8642 } 8643 8644 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8645 } 8646 8647 namespace { 8648 /// Helper class for checking expression in 'omp atomic [update]' 8649 /// construct. 8650 class OpenMPAtomicUpdateChecker { 8651 /// Error results for atomic update expressions. 8652 enum ExprAnalysisErrorCode { 8653 /// A statement is not an expression statement. 8654 NotAnExpression, 8655 /// Expression is not builtin binary or unary operation. 8656 NotABinaryOrUnaryExpression, 8657 /// Unary operation is not post-/pre- increment/decrement operation. 8658 NotAnUnaryIncDecExpression, 8659 /// An expression is not of scalar type. 8660 NotAScalarType, 8661 /// A binary operation is not an assignment operation. 8662 NotAnAssignmentOp, 8663 /// RHS part of the binary operation is not a binary expression. 8664 NotABinaryExpression, 8665 /// RHS part is not additive/multiplicative/shift/biwise binary 8666 /// expression. 8667 NotABinaryOperator, 8668 /// RHS binary operation does not have reference to the updated LHS 8669 /// part. 8670 NotAnUpdateExpression, 8671 /// No errors is found. 8672 NoError 8673 }; 8674 /// Reference to Sema. 8675 Sema &SemaRef; 8676 /// A location for note diagnostics (when error is found). 8677 SourceLocation NoteLoc; 8678 /// 'x' lvalue part of the source atomic expression. 8679 Expr *X; 8680 /// 'expr' rvalue part of the source atomic expression. 8681 Expr *E; 8682 /// Helper expression of the form 8683 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8684 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8685 Expr *UpdateExpr; 8686 /// Is 'x' a LHS in a RHS part of full update expression. It is 8687 /// important for non-associative operations. 8688 bool IsXLHSInRHSPart; 8689 BinaryOperatorKind Op; 8690 SourceLocation OpLoc; 8691 /// true if the source expression is a postfix unary operation, false 8692 /// if it is a prefix unary operation. 8693 bool IsPostfixUpdate; 8694 8695 public: 8696 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8697 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8698 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8699 /// Check specified statement that it is suitable for 'atomic update' 8700 /// constructs and extract 'x', 'expr' and Operation from the original 8701 /// expression. If DiagId and NoteId == 0, then only check is performed 8702 /// without error notification. 8703 /// \param DiagId Diagnostic which should be emitted if error is found. 8704 /// \param NoteId Diagnostic note for the main error message. 8705 /// \return true if statement is not an update expression, false otherwise. 8706 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8707 /// Return the 'x' lvalue part of the source atomic expression. 8708 Expr *getX() const { return X; } 8709 /// Return the 'expr' rvalue part of the source atomic expression. 8710 Expr *getExpr() const { return E; } 8711 /// Return the update expression used in calculation of the updated 8712 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8713 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8714 Expr *getUpdateExpr() const { return UpdateExpr; } 8715 /// Return true if 'x' is LHS in RHS part of full update expression, 8716 /// false otherwise. 8717 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8718 8719 /// true if the source expression is a postfix unary operation, false 8720 /// if it is a prefix unary operation. 8721 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8722 8723 private: 8724 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8725 unsigned NoteId = 0); 8726 }; 8727 } // namespace 8728 8729 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8730 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8731 ExprAnalysisErrorCode ErrorFound = NoError; 8732 SourceLocation ErrorLoc, NoteLoc; 8733 SourceRange ErrorRange, NoteRange; 8734 // Allowed constructs are: 8735 // x = x binop expr; 8736 // x = expr binop x; 8737 if (AtomicBinOp->getOpcode() == BO_Assign) { 8738 X = AtomicBinOp->getLHS(); 8739 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8740 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8741 if (AtomicInnerBinOp->isMultiplicativeOp() || 8742 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8743 AtomicInnerBinOp->isBitwiseOp()) { 8744 Op = AtomicInnerBinOp->getOpcode(); 8745 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8746 Expr *LHS = AtomicInnerBinOp->getLHS(); 8747 Expr *RHS = AtomicInnerBinOp->getRHS(); 8748 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8749 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8750 /*Canonical=*/true); 8751 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8752 /*Canonical=*/true); 8753 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8754 /*Canonical=*/true); 8755 if (XId == LHSId) { 8756 E = RHS; 8757 IsXLHSInRHSPart = true; 8758 } else if (XId == RHSId) { 8759 E = LHS; 8760 IsXLHSInRHSPart = false; 8761 } else { 8762 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8763 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8764 NoteLoc = X->getExprLoc(); 8765 NoteRange = X->getSourceRange(); 8766 ErrorFound = NotAnUpdateExpression; 8767 } 8768 } else { 8769 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8770 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8771 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8772 NoteRange = SourceRange(NoteLoc, NoteLoc); 8773 ErrorFound = NotABinaryOperator; 8774 } 8775 } else { 8776 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8777 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8778 ErrorFound = NotABinaryExpression; 8779 } 8780 } else { 8781 ErrorLoc = AtomicBinOp->getExprLoc(); 8782 ErrorRange = AtomicBinOp->getSourceRange(); 8783 NoteLoc = AtomicBinOp->getOperatorLoc(); 8784 NoteRange = SourceRange(NoteLoc, NoteLoc); 8785 ErrorFound = NotAnAssignmentOp; 8786 } 8787 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8788 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8789 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8790 return true; 8791 } 8792 if (SemaRef.CurContext->isDependentContext()) 8793 E = X = UpdateExpr = nullptr; 8794 return ErrorFound != NoError; 8795 } 8796 8797 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8798 unsigned NoteId) { 8799 ExprAnalysisErrorCode ErrorFound = NoError; 8800 SourceLocation ErrorLoc, NoteLoc; 8801 SourceRange ErrorRange, NoteRange; 8802 // Allowed constructs are: 8803 // x++; 8804 // x--; 8805 // ++x; 8806 // --x; 8807 // x binop= expr; 8808 // x = x binop expr; 8809 // x = expr binop x; 8810 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8811 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8812 if (AtomicBody->getType()->isScalarType() || 8813 AtomicBody->isInstantiationDependent()) { 8814 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8815 AtomicBody->IgnoreParenImpCasts())) { 8816 // Check for Compound Assignment Operation 8817 Op = BinaryOperator::getOpForCompoundAssignment( 8818 AtomicCompAssignOp->getOpcode()); 8819 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8820 E = AtomicCompAssignOp->getRHS(); 8821 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8822 IsXLHSInRHSPart = true; 8823 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8824 AtomicBody->IgnoreParenImpCasts())) { 8825 // Check for Binary Operation 8826 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8827 return true; 8828 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8829 AtomicBody->IgnoreParenImpCasts())) { 8830 // Check for Unary Operation 8831 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8832 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8833 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8834 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8835 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8836 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8837 IsXLHSInRHSPart = true; 8838 } else { 8839 ErrorFound = NotAnUnaryIncDecExpression; 8840 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8841 ErrorRange = AtomicUnaryOp->getSourceRange(); 8842 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8843 NoteRange = SourceRange(NoteLoc, NoteLoc); 8844 } 8845 } else if (!AtomicBody->isInstantiationDependent()) { 8846 ErrorFound = NotABinaryOrUnaryExpression; 8847 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8848 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8849 } 8850 } else { 8851 ErrorFound = NotAScalarType; 8852 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8853 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8854 } 8855 } else { 8856 ErrorFound = NotAnExpression; 8857 NoteLoc = ErrorLoc = S->getBeginLoc(); 8858 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8859 } 8860 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8861 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8862 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8863 return true; 8864 } 8865 if (SemaRef.CurContext->isDependentContext()) 8866 E = X = UpdateExpr = nullptr; 8867 if (ErrorFound == NoError && E && X) { 8868 // Build an update expression of form 'OpaqueValueExpr(x) binop 8869 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8870 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8871 auto *OVEX = new (SemaRef.getASTContext()) 8872 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8873 auto *OVEExpr = new (SemaRef.getASTContext()) 8874 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8875 ExprResult Update = 8876 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8877 IsXLHSInRHSPart ? OVEExpr : OVEX); 8878 if (Update.isInvalid()) 8879 return true; 8880 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8881 Sema::AA_Casting); 8882 if (Update.isInvalid()) 8883 return true; 8884 UpdateExpr = Update.get(); 8885 } 8886 return ErrorFound != NoError; 8887 } 8888 8889 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8890 Stmt *AStmt, 8891 SourceLocation StartLoc, 8892 SourceLocation EndLoc) { 8893 if (!AStmt) 8894 return StmtError(); 8895 8896 auto *CS = cast<CapturedStmt>(AStmt); 8897 // 1.2.2 OpenMP Language Terminology 8898 // Structured block - An executable statement with a single entry at the 8899 // top and a single exit at the bottom. 8900 // The point of exit cannot be a branch out of the structured block. 8901 // longjmp() and throw() must not violate the entry/exit criteria. 8902 OpenMPClauseKind AtomicKind = OMPC_unknown; 8903 SourceLocation AtomicKindLoc; 8904 for (const OMPClause *C : Clauses) { 8905 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8906 C->getClauseKind() == OMPC_update || 8907 C->getClauseKind() == OMPC_capture) { 8908 if (AtomicKind != OMPC_unknown) { 8909 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8910 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8911 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8912 << getOpenMPClauseName(AtomicKind); 8913 } else { 8914 AtomicKind = C->getClauseKind(); 8915 AtomicKindLoc = C->getBeginLoc(); 8916 } 8917 } 8918 } 8919 8920 Stmt *Body = CS->getCapturedStmt(); 8921 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8922 Body = EWC->getSubExpr(); 8923 8924 Expr *X = nullptr; 8925 Expr *V = nullptr; 8926 Expr *E = nullptr; 8927 Expr *UE = nullptr; 8928 bool IsXLHSInRHSPart = false; 8929 bool IsPostfixUpdate = false; 8930 // OpenMP [2.12.6, atomic Construct] 8931 // In the next expressions: 8932 // * x and v (as applicable) are both l-value expressions with scalar type. 8933 // * During the execution of an atomic region, multiple syntactic 8934 // occurrences of x must designate the same storage location. 8935 // * Neither of v and expr (as applicable) may access the storage location 8936 // designated by x. 8937 // * Neither of x and expr (as applicable) may access the storage location 8938 // designated by v. 8939 // * expr is an expression with scalar type. 8940 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8941 // * binop, binop=, ++, and -- are not overloaded operators. 8942 // * The expression x binop expr must be numerically equivalent to x binop 8943 // (expr). This requirement is satisfied if the operators in expr have 8944 // precedence greater than binop, or by using parentheses around expr or 8945 // subexpressions of expr. 8946 // * The expression expr binop x must be numerically equivalent to (expr) 8947 // binop x. This requirement is satisfied if the operators in expr have 8948 // precedence equal to or greater than binop, or by using parentheses around 8949 // expr or subexpressions of expr. 8950 // * For forms that allow multiple occurrences of x, the number of times 8951 // that x is evaluated is unspecified. 8952 if (AtomicKind == OMPC_read) { 8953 enum { 8954 NotAnExpression, 8955 NotAnAssignmentOp, 8956 NotAScalarType, 8957 NotAnLValue, 8958 NoError 8959 } ErrorFound = NoError; 8960 SourceLocation ErrorLoc, NoteLoc; 8961 SourceRange ErrorRange, NoteRange; 8962 // If clause is read: 8963 // v = x; 8964 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8965 const auto *AtomicBinOp = 8966 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8967 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8968 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8969 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8970 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8971 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8972 if (!X->isLValue() || !V->isLValue()) { 8973 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8974 ErrorFound = NotAnLValue; 8975 ErrorLoc = AtomicBinOp->getExprLoc(); 8976 ErrorRange = AtomicBinOp->getSourceRange(); 8977 NoteLoc = NotLValueExpr->getExprLoc(); 8978 NoteRange = NotLValueExpr->getSourceRange(); 8979 } 8980 } else if (!X->isInstantiationDependent() || 8981 !V->isInstantiationDependent()) { 8982 const Expr *NotScalarExpr = 8983 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8984 ? V 8985 : X; 8986 ErrorFound = NotAScalarType; 8987 ErrorLoc = AtomicBinOp->getExprLoc(); 8988 ErrorRange = AtomicBinOp->getSourceRange(); 8989 NoteLoc = NotScalarExpr->getExprLoc(); 8990 NoteRange = NotScalarExpr->getSourceRange(); 8991 } 8992 } else if (!AtomicBody->isInstantiationDependent()) { 8993 ErrorFound = NotAnAssignmentOp; 8994 ErrorLoc = AtomicBody->getExprLoc(); 8995 ErrorRange = AtomicBody->getSourceRange(); 8996 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8997 : AtomicBody->getExprLoc(); 8998 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8999 : AtomicBody->getSourceRange(); 9000 } 9001 } else { 9002 ErrorFound = NotAnExpression; 9003 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9004 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9005 } 9006 if (ErrorFound != NoError) { 9007 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9008 << ErrorRange; 9009 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9010 << NoteRange; 9011 return StmtError(); 9012 } 9013 if (CurContext->isDependentContext()) 9014 V = X = nullptr; 9015 } else if (AtomicKind == OMPC_write) { 9016 enum { 9017 NotAnExpression, 9018 NotAnAssignmentOp, 9019 NotAScalarType, 9020 NotAnLValue, 9021 NoError 9022 } ErrorFound = NoError; 9023 SourceLocation ErrorLoc, NoteLoc; 9024 SourceRange ErrorRange, NoteRange; 9025 // If clause is write: 9026 // x = expr; 9027 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9028 const auto *AtomicBinOp = 9029 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9030 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9031 X = AtomicBinOp->getLHS(); 9032 E = AtomicBinOp->getRHS(); 9033 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9034 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9035 if (!X->isLValue()) { 9036 ErrorFound = NotAnLValue; 9037 ErrorLoc = AtomicBinOp->getExprLoc(); 9038 ErrorRange = AtomicBinOp->getSourceRange(); 9039 NoteLoc = X->getExprLoc(); 9040 NoteRange = X->getSourceRange(); 9041 } 9042 } else if (!X->isInstantiationDependent() || 9043 !E->isInstantiationDependent()) { 9044 const Expr *NotScalarExpr = 9045 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9046 ? E 9047 : X; 9048 ErrorFound = NotAScalarType; 9049 ErrorLoc = AtomicBinOp->getExprLoc(); 9050 ErrorRange = AtomicBinOp->getSourceRange(); 9051 NoteLoc = NotScalarExpr->getExprLoc(); 9052 NoteRange = NotScalarExpr->getSourceRange(); 9053 } 9054 } else if (!AtomicBody->isInstantiationDependent()) { 9055 ErrorFound = NotAnAssignmentOp; 9056 ErrorLoc = AtomicBody->getExprLoc(); 9057 ErrorRange = AtomicBody->getSourceRange(); 9058 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9059 : AtomicBody->getExprLoc(); 9060 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9061 : AtomicBody->getSourceRange(); 9062 } 9063 } else { 9064 ErrorFound = NotAnExpression; 9065 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9066 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9067 } 9068 if (ErrorFound != NoError) { 9069 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9070 << ErrorRange; 9071 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9072 << NoteRange; 9073 return StmtError(); 9074 } 9075 if (CurContext->isDependentContext()) 9076 E = X = nullptr; 9077 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9078 // If clause is update: 9079 // x++; 9080 // x--; 9081 // ++x; 9082 // --x; 9083 // x binop= expr; 9084 // x = x binop expr; 9085 // x = expr binop x; 9086 OpenMPAtomicUpdateChecker Checker(*this); 9087 if (Checker.checkStatement( 9088 Body, (AtomicKind == OMPC_update) 9089 ? diag::err_omp_atomic_update_not_expression_statement 9090 : diag::err_omp_atomic_not_expression_statement, 9091 diag::note_omp_atomic_update)) 9092 return StmtError(); 9093 if (!CurContext->isDependentContext()) { 9094 E = Checker.getExpr(); 9095 X = Checker.getX(); 9096 UE = Checker.getUpdateExpr(); 9097 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9098 } 9099 } else if (AtomicKind == OMPC_capture) { 9100 enum { 9101 NotAnAssignmentOp, 9102 NotACompoundStatement, 9103 NotTwoSubstatements, 9104 NotASpecificExpression, 9105 NoError 9106 } ErrorFound = NoError; 9107 SourceLocation ErrorLoc, NoteLoc; 9108 SourceRange ErrorRange, NoteRange; 9109 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9110 // If clause is a capture: 9111 // v = x++; 9112 // v = x--; 9113 // v = ++x; 9114 // v = --x; 9115 // v = x binop= expr; 9116 // v = x = x binop expr; 9117 // v = x = expr binop x; 9118 const auto *AtomicBinOp = 9119 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9120 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9121 V = AtomicBinOp->getLHS(); 9122 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9123 OpenMPAtomicUpdateChecker Checker(*this); 9124 if (Checker.checkStatement( 9125 Body, diag::err_omp_atomic_capture_not_expression_statement, 9126 diag::note_omp_atomic_update)) 9127 return StmtError(); 9128 E = Checker.getExpr(); 9129 X = Checker.getX(); 9130 UE = Checker.getUpdateExpr(); 9131 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9132 IsPostfixUpdate = Checker.isPostfixUpdate(); 9133 } else if (!AtomicBody->isInstantiationDependent()) { 9134 ErrorLoc = AtomicBody->getExprLoc(); 9135 ErrorRange = AtomicBody->getSourceRange(); 9136 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9137 : AtomicBody->getExprLoc(); 9138 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9139 : AtomicBody->getSourceRange(); 9140 ErrorFound = NotAnAssignmentOp; 9141 } 9142 if (ErrorFound != NoError) { 9143 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9144 << ErrorRange; 9145 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9146 return StmtError(); 9147 } 9148 if (CurContext->isDependentContext()) 9149 UE = V = E = X = nullptr; 9150 } else { 9151 // If clause is a capture: 9152 // { v = x; x = expr; } 9153 // { v = x; x++; } 9154 // { v = x; x--; } 9155 // { v = x; ++x; } 9156 // { v = x; --x; } 9157 // { v = x; x binop= expr; } 9158 // { v = x; x = x binop expr; } 9159 // { v = x; x = expr binop x; } 9160 // { x++; v = x; } 9161 // { x--; v = x; } 9162 // { ++x; v = x; } 9163 // { --x; v = x; } 9164 // { x binop= expr; v = x; } 9165 // { x = x binop expr; v = x; } 9166 // { x = expr binop x; v = x; } 9167 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9168 // Check that this is { expr1; expr2; } 9169 if (CS->size() == 2) { 9170 Stmt *First = CS->body_front(); 9171 Stmt *Second = CS->body_back(); 9172 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9173 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9174 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9175 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9176 // Need to find what subexpression is 'v' and what is 'x'. 9177 OpenMPAtomicUpdateChecker Checker(*this); 9178 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9179 BinaryOperator *BinOp = nullptr; 9180 if (IsUpdateExprFound) { 9181 BinOp = dyn_cast<BinaryOperator>(First); 9182 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9183 } 9184 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9185 // { v = x; x++; } 9186 // { v = x; x--; } 9187 // { v = x; ++x; } 9188 // { v = x; --x; } 9189 // { v = x; x binop= expr; } 9190 // { v = x; x = x binop expr; } 9191 // { v = x; x = expr binop x; } 9192 // Check that the first expression has form v = x. 9193 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9194 llvm::FoldingSetNodeID XId, PossibleXId; 9195 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9196 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9197 IsUpdateExprFound = XId == PossibleXId; 9198 if (IsUpdateExprFound) { 9199 V = BinOp->getLHS(); 9200 X = Checker.getX(); 9201 E = Checker.getExpr(); 9202 UE = Checker.getUpdateExpr(); 9203 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9204 IsPostfixUpdate = true; 9205 } 9206 } 9207 if (!IsUpdateExprFound) { 9208 IsUpdateExprFound = !Checker.checkStatement(First); 9209 BinOp = nullptr; 9210 if (IsUpdateExprFound) { 9211 BinOp = dyn_cast<BinaryOperator>(Second); 9212 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9213 } 9214 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9215 // { x++; v = x; } 9216 // { x--; v = x; } 9217 // { ++x; v = x; } 9218 // { --x; v = x; } 9219 // { x binop= expr; v = x; } 9220 // { x = x binop expr; v = x; } 9221 // { x = expr binop x; v = x; } 9222 // Check that the second expression has form v = x. 9223 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9224 llvm::FoldingSetNodeID XId, PossibleXId; 9225 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9226 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9227 IsUpdateExprFound = XId == PossibleXId; 9228 if (IsUpdateExprFound) { 9229 V = BinOp->getLHS(); 9230 X = Checker.getX(); 9231 E = Checker.getExpr(); 9232 UE = Checker.getUpdateExpr(); 9233 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9234 IsPostfixUpdate = false; 9235 } 9236 } 9237 } 9238 if (!IsUpdateExprFound) { 9239 // { v = x; x = expr; } 9240 auto *FirstExpr = dyn_cast<Expr>(First); 9241 auto *SecondExpr = dyn_cast<Expr>(Second); 9242 if (!FirstExpr || !SecondExpr || 9243 !(FirstExpr->isInstantiationDependent() || 9244 SecondExpr->isInstantiationDependent())) { 9245 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9246 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9247 ErrorFound = NotAnAssignmentOp; 9248 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9249 : First->getBeginLoc(); 9250 NoteRange = ErrorRange = FirstBinOp 9251 ? FirstBinOp->getSourceRange() 9252 : SourceRange(ErrorLoc, ErrorLoc); 9253 } else { 9254 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9255 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9256 ErrorFound = NotAnAssignmentOp; 9257 NoteLoc = ErrorLoc = SecondBinOp 9258 ? SecondBinOp->getOperatorLoc() 9259 : Second->getBeginLoc(); 9260 NoteRange = ErrorRange = 9261 SecondBinOp ? SecondBinOp->getSourceRange() 9262 : SourceRange(ErrorLoc, ErrorLoc); 9263 } else { 9264 Expr *PossibleXRHSInFirst = 9265 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9266 Expr *PossibleXLHSInSecond = 9267 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9268 llvm::FoldingSetNodeID X1Id, X2Id; 9269 PossibleXRHSInFirst->Profile(X1Id, Context, 9270 /*Canonical=*/true); 9271 PossibleXLHSInSecond->Profile(X2Id, Context, 9272 /*Canonical=*/true); 9273 IsUpdateExprFound = X1Id == X2Id; 9274 if (IsUpdateExprFound) { 9275 V = FirstBinOp->getLHS(); 9276 X = SecondBinOp->getLHS(); 9277 E = SecondBinOp->getRHS(); 9278 UE = nullptr; 9279 IsXLHSInRHSPart = false; 9280 IsPostfixUpdate = true; 9281 } else { 9282 ErrorFound = NotASpecificExpression; 9283 ErrorLoc = FirstBinOp->getExprLoc(); 9284 ErrorRange = FirstBinOp->getSourceRange(); 9285 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9286 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9287 } 9288 } 9289 } 9290 } 9291 } 9292 } else { 9293 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9294 NoteRange = ErrorRange = 9295 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9296 ErrorFound = NotTwoSubstatements; 9297 } 9298 } else { 9299 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9300 NoteRange = ErrorRange = 9301 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9302 ErrorFound = NotACompoundStatement; 9303 } 9304 if (ErrorFound != NoError) { 9305 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9306 << ErrorRange; 9307 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9308 return StmtError(); 9309 } 9310 if (CurContext->isDependentContext()) 9311 UE = V = E = X = nullptr; 9312 } 9313 } 9314 9315 setFunctionHasBranchProtectedScope(); 9316 9317 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9318 X, V, E, UE, IsXLHSInRHSPart, 9319 IsPostfixUpdate); 9320 } 9321 9322 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9323 Stmt *AStmt, 9324 SourceLocation StartLoc, 9325 SourceLocation EndLoc) { 9326 if (!AStmt) 9327 return StmtError(); 9328 9329 auto *CS = cast<CapturedStmt>(AStmt); 9330 // 1.2.2 OpenMP Language Terminology 9331 // Structured block - An executable statement with a single entry at the 9332 // top and a single exit at the bottom. 9333 // The point of exit cannot be a branch out of the structured block. 9334 // longjmp() and throw() must not violate the entry/exit criteria. 9335 CS->getCapturedDecl()->setNothrow(); 9336 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9337 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9338 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9339 // 1.2.2 OpenMP Language Terminology 9340 // Structured block - An executable statement with a single entry at the 9341 // top and a single exit at the bottom. 9342 // The point of exit cannot be a branch out of the structured block. 9343 // longjmp() and throw() must not violate the entry/exit criteria. 9344 CS->getCapturedDecl()->setNothrow(); 9345 } 9346 9347 // OpenMP [2.16, Nesting of Regions] 9348 // If specified, a teams construct must be contained within a target 9349 // construct. That target construct must contain no statements or directives 9350 // outside of the teams construct. 9351 if (DSAStack->hasInnerTeamsRegion()) { 9352 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9353 bool OMPTeamsFound = true; 9354 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9355 auto I = CS->body_begin(); 9356 while (I != CS->body_end()) { 9357 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9358 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9359 OMPTeamsFound) { 9360 9361 OMPTeamsFound = false; 9362 break; 9363 } 9364 ++I; 9365 } 9366 assert(I != CS->body_end() && "Not found statement"); 9367 S = *I; 9368 } else { 9369 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9370 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9371 } 9372 if (!OMPTeamsFound) { 9373 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9374 Diag(DSAStack->getInnerTeamsRegionLoc(), 9375 diag::note_omp_nested_teams_construct_here); 9376 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9377 << isa<OMPExecutableDirective>(S); 9378 return StmtError(); 9379 } 9380 } 9381 9382 setFunctionHasBranchProtectedScope(); 9383 9384 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9385 } 9386 9387 StmtResult 9388 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9389 Stmt *AStmt, SourceLocation StartLoc, 9390 SourceLocation EndLoc) { 9391 if (!AStmt) 9392 return StmtError(); 9393 9394 auto *CS = cast<CapturedStmt>(AStmt); 9395 // 1.2.2 OpenMP Language Terminology 9396 // Structured block - An executable statement with a single entry at the 9397 // top and a single exit at the bottom. 9398 // The point of exit cannot be a branch out of the structured block. 9399 // longjmp() and throw() must not violate the entry/exit criteria. 9400 CS->getCapturedDecl()->setNothrow(); 9401 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9402 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9403 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9404 // 1.2.2 OpenMP Language Terminology 9405 // Structured block - An executable statement with a single entry at the 9406 // top and a single exit at the bottom. 9407 // The point of exit cannot be a branch out of the structured block. 9408 // longjmp() and throw() must not violate the entry/exit criteria. 9409 CS->getCapturedDecl()->setNothrow(); 9410 } 9411 9412 setFunctionHasBranchProtectedScope(); 9413 9414 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9415 AStmt); 9416 } 9417 9418 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9419 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9420 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9421 if (!AStmt) 9422 return StmtError(); 9423 9424 auto *CS = cast<CapturedStmt>(AStmt); 9425 // 1.2.2 OpenMP Language Terminology 9426 // Structured block - An executable statement with a single entry at the 9427 // top and a single exit at the bottom. 9428 // The point of exit cannot be a branch out of the structured block. 9429 // longjmp() and throw() must not violate the entry/exit criteria. 9430 CS->getCapturedDecl()->setNothrow(); 9431 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9432 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9433 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9434 // 1.2.2 OpenMP Language Terminology 9435 // Structured block - An executable statement with a single entry at the 9436 // top and a single exit at the bottom. 9437 // The point of exit cannot be a branch out of the structured block. 9438 // longjmp() and throw() must not violate the entry/exit criteria. 9439 CS->getCapturedDecl()->setNothrow(); 9440 } 9441 9442 OMPLoopDirective::HelperExprs B; 9443 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9444 // define the nested loops number. 9445 unsigned NestedLoopCount = 9446 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9447 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9448 VarsWithImplicitDSA, B); 9449 if (NestedLoopCount == 0) 9450 return StmtError(); 9451 9452 assert((CurContext->isDependentContext() || B.builtAll()) && 9453 "omp target parallel for loop exprs were not built"); 9454 9455 if (!CurContext->isDependentContext()) { 9456 // Finalize the clauses that need pre-built expressions for CodeGen. 9457 for (OMPClause *C : Clauses) { 9458 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9459 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9460 B.NumIterations, *this, CurScope, 9461 DSAStack)) 9462 return StmtError(); 9463 } 9464 } 9465 9466 setFunctionHasBranchProtectedScope(); 9467 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9468 NestedLoopCount, Clauses, AStmt, 9469 B, DSAStack->isCancelRegion()); 9470 } 9471 9472 /// Check for existence of a map clause in the list of clauses. 9473 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9474 const OpenMPClauseKind K) { 9475 return llvm::any_of( 9476 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9477 } 9478 9479 template <typename... Params> 9480 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9481 const Params... ClauseTypes) { 9482 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9483 } 9484 9485 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9486 Stmt *AStmt, 9487 SourceLocation StartLoc, 9488 SourceLocation EndLoc) { 9489 if (!AStmt) 9490 return StmtError(); 9491 9492 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9493 9494 // OpenMP [2.10.1, Restrictions, p. 97] 9495 // At least one map clause must appear on the directive. 9496 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9497 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9498 << "'map' or 'use_device_ptr'" 9499 << getOpenMPDirectiveName(OMPD_target_data); 9500 return StmtError(); 9501 } 9502 9503 setFunctionHasBranchProtectedScope(); 9504 9505 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9506 AStmt); 9507 } 9508 9509 StmtResult 9510 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9511 SourceLocation StartLoc, 9512 SourceLocation EndLoc, Stmt *AStmt) { 9513 if (!AStmt) 9514 return StmtError(); 9515 9516 auto *CS = cast<CapturedStmt>(AStmt); 9517 // 1.2.2 OpenMP Language Terminology 9518 // Structured block - An executable statement with a single entry at the 9519 // top and a single exit at the bottom. 9520 // The point of exit cannot be a branch out of the structured block. 9521 // longjmp() and throw() must not violate the entry/exit criteria. 9522 CS->getCapturedDecl()->setNothrow(); 9523 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9524 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9525 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9526 // 1.2.2 OpenMP Language Terminology 9527 // Structured block - An executable statement with a single entry at the 9528 // top and a single exit at the bottom. 9529 // The point of exit cannot be a branch out of the structured block. 9530 // longjmp() and throw() must not violate the entry/exit criteria. 9531 CS->getCapturedDecl()->setNothrow(); 9532 } 9533 9534 // OpenMP [2.10.2, Restrictions, p. 99] 9535 // At least one map clause must appear on the directive. 9536 if (!hasClauses(Clauses, OMPC_map)) { 9537 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9538 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9539 return StmtError(); 9540 } 9541 9542 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9543 AStmt); 9544 } 9545 9546 StmtResult 9547 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9548 SourceLocation StartLoc, 9549 SourceLocation EndLoc, Stmt *AStmt) { 9550 if (!AStmt) 9551 return StmtError(); 9552 9553 auto *CS = cast<CapturedStmt>(AStmt); 9554 // 1.2.2 OpenMP Language Terminology 9555 // Structured block - An executable statement with a single entry at the 9556 // top and a single exit at the bottom. 9557 // The point of exit cannot be a branch out of the structured block. 9558 // longjmp() and throw() must not violate the entry/exit criteria. 9559 CS->getCapturedDecl()->setNothrow(); 9560 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9561 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9562 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9563 // 1.2.2 OpenMP Language Terminology 9564 // Structured block - An executable statement with a single entry at the 9565 // top and a single exit at the bottom. 9566 // The point of exit cannot be a branch out of the structured block. 9567 // longjmp() and throw() must not violate the entry/exit criteria. 9568 CS->getCapturedDecl()->setNothrow(); 9569 } 9570 9571 // OpenMP [2.10.3, Restrictions, p. 102] 9572 // At least one map clause must appear on the directive. 9573 if (!hasClauses(Clauses, OMPC_map)) { 9574 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9575 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9576 return StmtError(); 9577 } 9578 9579 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9580 AStmt); 9581 } 9582 9583 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9584 SourceLocation StartLoc, 9585 SourceLocation EndLoc, 9586 Stmt *AStmt) { 9587 if (!AStmt) 9588 return StmtError(); 9589 9590 auto *CS = cast<CapturedStmt>(AStmt); 9591 // 1.2.2 OpenMP Language Terminology 9592 // Structured block - An executable statement with a single entry at the 9593 // top and a single exit at the bottom. 9594 // The point of exit cannot be a branch out of the structured block. 9595 // longjmp() and throw() must not violate the entry/exit criteria. 9596 CS->getCapturedDecl()->setNothrow(); 9597 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9598 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9599 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9600 // 1.2.2 OpenMP Language Terminology 9601 // Structured block - An executable statement with a single entry at the 9602 // top and a single exit at the bottom. 9603 // The point of exit cannot be a branch out of the structured block. 9604 // longjmp() and throw() must not violate the entry/exit criteria. 9605 CS->getCapturedDecl()->setNothrow(); 9606 } 9607 9608 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9609 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9610 return StmtError(); 9611 } 9612 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9613 AStmt); 9614 } 9615 9616 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9617 Stmt *AStmt, SourceLocation StartLoc, 9618 SourceLocation EndLoc) { 9619 if (!AStmt) 9620 return StmtError(); 9621 9622 auto *CS = cast<CapturedStmt>(AStmt); 9623 // 1.2.2 OpenMP Language Terminology 9624 // Structured block - An executable statement with a single entry at the 9625 // top and a single exit at the bottom. 9626 // The point of exit cannot be a branch out of the structured block. 9627 // longjmp() and throw() must not violate the entry/exit criteria. 9628 CS->getCapturedDecl()->setNothrow(); 9629 9630 setFunctionHasBranchProtectedScope(); 9631 9632 DSAStack->setParentTeamsRegionLoc(StartLoc); 9633 9634 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9635 } 9636 9637 StmtResult 9638 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9639 SourceLocation EndLoc, 9640 OpenMPDirectiveKind CancelRegion) { 9641 if (DSAStack->isParentNowaitRegion()) { 9642 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9643 return StmtError(); 9644 } 9645 if (DSAStack->isParentOrderedRegion()) { 9646 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9647 return StmtError(); 9648 } 9649 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9650 CancelRegion); 9651 } 9652 9653 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9654 SourceLocation StartLoc, 9655 SourceLocation EndLoc, 9656 OpenMPDirectiveKind CancelRegion) { 9657 if (DSAStack->isParentNowaitRegion()) { 9658 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9659 return StmtError(); 9660 } 9661 if (DSAStack->isParentOrderedRegion()) { 9662 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9663 return StmtError(); 9664 } 9665 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9666 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9667 CancelRegion); 9668 } 9669 9670 static bool checkGrainsizeNumTasksClauses(Sema &S, 9671 ArrayRef<OMPClause *> Clauses) { 9672 const OMPClause *PrevClause = nullptr; 9673 bool ErrorFound = false; 9674 for (const OMPClause *C : Clauses) { 9675 if (C->getClauseKind() == OMPC_grainsize || 9676 C->getClauseKind() == OMPC_num_tasks) { 9677 if (!PrevClause) 9678 PrevClause = C; 9679 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9680 S.Diag(C->getBeginLoc(), 9681 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9682 << getOpenMPClauseName(C->getClauseKind()) 9683 << getOpenMPClauseName(PrevClause->getClauseKind()); 9684 S.Diag(PrevClause->getBeginLoc(), 9685 diag::note_omp_previous_grainsize_num_tasks) 9686 << getOpenMPClauseName(PrevClause->getClauseKind()); 9687 ErrorFound = true; 9688 } 9689 } 9690 } 9691 return ErrorFound; 9692 } 9693 9694 static bool checkReductionClauseWithNogroup(Sema &S, 9695 ArrayRef<OMPClause *> Clauses) { 9696 const OMPClause *ReductionClause = nullptr; 9697 const OMPClause *NogroupClause = nullptr; 9698 for (const OMPClause *C : Clauses) { 9699 if (C->getClauseKind() == OMPC_reduction) { 9700 ReductionClause = C; 9701 if (NogroupClause) 9702 break; 9703 continue; 9704 } 9705 if (C->getClauseKind() == OMPC_nogroup) { 9706 NogroupClause = C; 9707 if (ReductionClause) 9708 break; 9709 continue; 9710 } 9711 } 9712 if (ReductionClause && NogroupClause) { 9713 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9714 << SourceRange(NogroupClause->getBeginLoc(), 9715 NogroupClause->getEndLoc()); 9716 return true; 9717 } 9718 return false; 9719 } 9720 9721 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9722 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9723 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9724 if (!AStmt) 9725 return StmtError(); 9726 9727 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9728 OMPLoopDirective::HelperExprs B; 9729 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9730 // define the nested loops number. 9731 unsigned NestedLoopCount = 9732 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9733 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9734 VarsWithImplicitDSA, B); 9735 if (NestedLoopCount == 0) 9736 return StmtError(); 9737 9738 assert((CurContext->isDependentContext() || B.builtAll()) && 9739 "omp for loop exprs were not built"); 9740 9741 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9742 // The grainsize clause and num_tasks clause are mutually exclusive and may 9743 // not appear on the same taskloop directive. 9744 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9745 return StmtError(); 9746 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9747 // If a reduction clause is present on the taskloop directive, the nogroup 9748 // clause must not be specified. 9749 if (checkReductionClauseWithNogroup(*this, Clauses)) 9750 return StmtError(); 9751 9752 setFunctionHasBranchProtectedScope(); 9753 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9754 NestedLoopCount, Clauses, AStmt, B); 9755 } 9756 9757 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9758 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9759 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9760 if (!AStmt) 9761 return StmtError(); 9762 9763 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9764 OMPLoopDirective::HelperExprs B; 9765 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9766 // define the nested loops number. 9767 unsigned NestedLoopCount = 9768 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9769 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9770 VarsWithImplicitDSA, B); 9771 if (NestedLoopCount == 0) 9772 return StmtError(); 9773 9774 assert((CurContext->isDependentContext() || B.builtAll()) && 9775 "omp for loop exprs were not built"); 9776 9777 if (!CurContext->isDependentContext()) { 9778 // Finalize the clauses that need pre-built expressions for CodeGen. 9779 for (OMPClause *C : Clauses) { 9780 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9781 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9782 B.NumIterations, *this, CurScope, 9783 DSAStack)) 9784 return StmtError(); 9785 } 9786 } 9787 9788 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9789 // The grainsize clause and num_tasks clause are mutually exclusive and may 9790 // not appear on the same taskloop directive. 9791 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9792 return StmtError(); 9793 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9794 // If a reduction clause is present on the taskloop directive, the nogroup 9795 // clause must not be specified. 9796 if (checkReductionClauseWithNogroup(*this, Clauses)) 9797 return StmtError(); 9798 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9799 return StmtError(); 9800 9801 setFunctionHasBranchProtectedScope(); 9802 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9803 NestedLoopCount, Clauses, AStmt, B); 9804 } 9805 9806 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9807 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9808 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9809 if (!AStmt) 9810 return StmtError(); 9811 9812 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9813 OMPLoopDirective::HelperExprs B; 9814 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9815 // define the nested loops number. 9816 unsigned NestedLoopCount = 9817 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9818 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9819 VarsWithImplicitDSA, B); 9820 if (NestedLoopCount == 0) 9821 return StmtError(); 9822 9823 assert((CurContext->isDependentContext() || B.builtAll()) && 9824 "omp for loop exprs were not built"); 9825 9826 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9827 // The grainsize clause and num_tasks clause are mutually exclusive and may 9828 // not appear on the same taskloop directive. 9829 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9830 return StmtError(); 9831 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9832 // If a reduction clause is present on the taskloop directive, the nogroup 9833 // clause must not be specified. 9834 if (checkReductionClauseWithNogroup(*this, Clauses)) 9835 return StmtError(); 9836 9837 setFunctionHasBranchProtectedScope(); 9838 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9839 NestedLoopCount, Clauses, AStmt, B); 9840 } 9841 9842 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9843 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9844 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9845 if (!AStmt) 9846 return StmtError(); 9847 9848 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9849 OMPLoopDirective::HelperExprs B; 9850 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9851 // define the nested loops number. 9852 unsigned NestedLoopCount = 9853 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9854 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9855 VarsWithImplicitDSA, B); 9856 if (NestedLoopCount == 0) 9857 return StmtError(); 9858 9859 assert((CurContext->isDependentContext() || B.builtAll()) && 9860 "omp for loop exprs were not built"); 9861 9862 if (!CurContext->isDependentContext()) { 9863 // Finalize the clauses that need pre-built expressions for CodeGen. 9864 for (OMPClause *C : Clauses) { 9865 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9866 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9867 B.NumIterations, *this, CurScope, 9868 DSAStack)) 9869 return StmtError(); 9870 } 9871 } 9872 9873 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9874 // The grainsize clause and num_tasks clause are mutually exclusive and may 9875 // not appear on the same taskloop directive. 9876 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9877 return StmtError(); 9878 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9879 // If a reduction clause is present on the taskloop directive, the nogroup 9880 // clause must not be specified. 9881 if (checkReductionClauseWithNogroup(*this, Clauses)) 9882 return StmtError(); 9883 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9884 return StmtError(); 9885 9886 setFunctionHasBranchProtectedScope(); 9887 return OMPMasterTaskLoopSimdDirective::Create( 9888 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9889 } 9890 9891 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9892 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9893 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9894 if (!AStmt) 9895 return StmtError(); 9896 9897 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9898 auto *CS = cast<CapturedStmt>(AStmt); 9899 // 1.2.2 OpenMP Language Terminology 9900 // Structured block - An executable statement with a single entry at the 9901 // top and a single exit at the bottom. 9902 // The point of exit cannot be a branch out of the structured block. 9903 // longjmp() and throw() must not violate the entry/exit criteria. 9904 CS->getCapturedDecl()->setNothrow(); 9905 for (int ThisCaptureLevel = 9906 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9907 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9908 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9909 // 1.2.2 OpenMP Language Terminology 9910 // Structured block - An executable statement with a single entry at the 9911 // top and a single exit at the bottom. 9912 // The point of exit cannot be a branch out of the structured block. 9913 // longjmp() and throw() must not violate the entry/exit criteria. 9914 CS->getCapturedDecl()->setNothrow(); 9915 } 9916 9917 OMPLoopDirective::HelperExprs B; 9918 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9919 // define the nested loops number. 9920 unsigned NestedLoopCount = checkOpenMPLoop( 9921 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9922 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9923 VarsWithImplicitDSA, B); 9924 if (NestedLoopCount == 0) 9925 return StmtError(); 9926 9927 assert((CurContext->isDependentContext() || B.builtAll()) && 9928 "omp for loop exprs were not built"); 9929 9930 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9931 // The grainsize clause and num_tasks clause are mutually exclusive and may 9932 // not appear on the same taskloop directive. 9933 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9934 return StmtError(); 9935 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9936 // If a reduction clause is present on the taskloop directive, the nogroup 9937 // clause must not be specified. 9938 if (checkReductionClauseWithNogroup(*this, Clauses)) 9939 return StmtError(); 9940 9941 setFunctionHasBranchProtectedScope(); 9942 return OMPParallelMasterTaskLoopDirective::Create( 9943 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9944 } 9945 9946 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 9947 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9948 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9949 if (!AStmt) 9950 return StmtError(); 9951 9952 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9953 auto *CS = cast<CapturedStmt>(AStmt); 9954 // 1.2.2 OpenMP Language Terminology 9955 // Structured block - An executable statement with a single entry at the 9956 // top and a single exit at the bottom. 9957 // The point of exit cannot be a branch out of the structured block. 9958 // longjmp() and throw() must not violate the entry/exit criteria. 9959 CS->getCapturedDecl()->setNothrow(); 9960 for (int ThisCaptureLevel = 9961 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 9962 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9963 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9964 // 1.2.2 OpenMP Language Terminology 9965 // Structured block - An executable statement with a single entry at the 9966 // top and a single exit at the bottom. 9967 // The point of exit cannot be a branch out of the structured block. 9968 // longjmp() and throw() must not violate the entry/exit criteria. 9969 CS->getCapturedDecl()->setNothrow(); 9970 } 9971 9972 OMPLoopDirective::HelperExprs B; 9973 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9974 // define the nested loops number. 9975 unsigned NestedLoopCount = checkOpenMPLoop( 9976 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9977 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9978 VarsWithImplicitDSA, B); 9979 if (NestedLoopCount == 0) 9980 return StmtError(); 9981 9982 assert((CurContext->isDependentContext() || B.builtAll()) && 9983 "omp for loop exprs were not built"); 9984 9985 if (!CurContext->isDependentContext()) { 9986 // Finalize the clauses that need pre-built expressions for CodeGen. 9987 for (OMPClause *C : Clauses) { 9988 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9989 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9990 B.NumIterations, *this, CurScope, 9991 DSAStack)) 9992 return StmtError(); 9993 } 9994 } 9995 9996 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9997 // The grainsize clause and num_tasks clause are mutually exclusive and may 9998 // not appear on the same taskloop directive. 9999 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10000 return StmtError(); 10001 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10002 // If a reduction clause is present on the taskloop directive, the nogroup 10003 // clause must not be specified. 10004 if (checkReductionClauseWithNogroup(*this, Clauses)) 10005 return StmtError(); 10006 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10007 return StmtError(); 10008 10009 setFunctionHasBranchProtectedScope(); 10010 return OMPParallelMasterTaskLoopSimdDirective::Create( 10011 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10012 } 10013 10014 StmtResult Sema::ActOnOpenMPDistributeDirective( 10015 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10016 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10017 if (!AStmt) 10018 return StmtError(); 10019 10020 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10021 OMPLoopDirective::HelperExprs B; 10022 // In presence of clause 'collapse' with number of loops, it will 10023 // define the nested loops number. 10024 unsigned NestedLoopCount = 10025 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10026 nullptr /*ordered not a clause on distribute*/, AStmt, 10027 *this, *DSAStack, VarsWithImplicitDSA, B); 10028 if (NestedLoopCount == 0) 10029 return StmtError(); 10030 10031 assert((CurContext->isDependentContext() || B.builtAll()) && 10032 "omp for loop exprs were not built"); 10033 10034 setFunctionHasBranchProtectedScope(); 10035 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10036 NestedLoopCount, Clauses, AStmt, B); 10037 } 10038 10039 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10040 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10041 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10042 if (!AStmt) 10043 return StmtError(); 10044 10045 auto *CS = cast<CapturedStmt>(AStmt); 10046 // 1.2.2 OpenMP Language Terminology 10047 // Structured block - An executable statement with a single entry at the 10048 // top and a single exit at the bottom. 10049 // The point of exit cannot be a branch out of the structured block. 10050 // longjmp() and throw() must not violate the entry/exit criteria. 10051 CS->getCapturedDecl()->setNothrow(); 10052 for (int ThisCaptureLevel = 10053 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10054 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10055 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10056 // 1.2.2 OpenMP Language Terminology 10057 // Structured block - An executable statement with a single entry at the 10058 // top and a single exit at the bottom. 10059 // The point of exit cannot be a branch out of the structured block. 10060 // longjmp() and throw() must not violate the entry/exit criteria. 10061 CS->getCapturedDecl()->setNothrow(); 10062 } 10063 10064 OMPLoopDirective::HelperExprs B; 10065 // In presence of clause 'collapse' with number of loops, it will 10066 // define the nested loops number. 10067 unsigned NestedLoopCount = checkOpenMPLoop( 10068 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10069 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10070 VarsWithImplicitDSA, B); 10071 if (NestedLoopCount == 0) 10072 return StmtError(); 10073 10074 assert((CurContext->isDependentContext() || B.builtAll()) && 10075 "omp for loop exprs were not built"); 10076 10077 setFunctionHasBranchProtectedScope(); 10078 return OMPDistributeParallelForDirective::Create( 10079 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10080 DSAStack->isCancelRegion()); 10081 } 10082 10083 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10084 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10085 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10086 if (!AStmt) 10087 return StmtError(); 10088 10089 auto *CS = cast<CapturedStmt>(AStmt); 10090 // 1.2.2 OpenMP Language Terminology 10091 // Structured block - An executable statement with a single entry at the 10092 // top and a single exit at the bottom. 10093 // The point of exit cannot be a branch out of the structured block. 10094 // longjmp() and throw() must not violate the entry/exit criteria. 10095 CS->getCapturedDecl()->setNothrow(); 10096 for (int ThisCaptureLevel = 10097 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10098 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10099 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10100 // 1.2.2 OpenMP Language Terminology 10101 // Structured block - An executable statement with a single entry at the 10102 // top and a single exit at the bottom. 10103 // The point of exit cannot be a branch out of the structured block. 10104 // longjmp() and throw() must not violate the entry/exit criteria. 10105 CS->getCapturedDecl()->setNothrow(); 10106 } 10107 10108 OMPLoopDirective::HelperExprs B; 10109 // In presence of clause 'collapse' with number of loops, it will 10110 // define the nested loops number. 10111 unsigned NestedLoopCount = checkOpenMPLoop( 10112 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10113 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10114 VarsWithImplicitDSA, B); 10115 if (NestedLoopCount == 0) 10116 return StmtError(); 10117 10118 assert((CurContext->isDependentContext() || B.builtAll()) && 10119 "omp for loop exprs were not built"); 10120 10121 if (!CurContext->isDependentContext()) { 10122 // Finalize the clauses that need pre-built expressions for CodeGen. 10123 for (OMPClause *C : Clauses) { 10124 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10125 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10126 B.NumIterations, *this, CurScope, 10127 DSAStack)) 10128 return StmtError(); 10129 } 10130 } 10131 10132 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10133 return StmtError(); 10134 10135 setFunctionHasBranchProtectedScope(); 10136 return OMPDistributeParallelForSimdDirective::Create( 10137 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10138 } 10139 10140 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10141 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10142 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10143 if (!AStmt) 10144 return StmtError(); 10145 10146 auto *CS = cast<CapturedStmt>(AStmt); 10147 // 1.2.2 OpenMP Language Terminology 10148 // Structured block - An executable statement with a single entry at the 10149 // top and a single exit at the bottom. 10150 // The point of exit cannot be a branch out of the structured block. 10151 // longjmp() and throw() must not violate the entry/exit criteria. 10152 CS->getCapturedDecl()->setNothrow(); 10153 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10154 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10155 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10156 // 1.2.2 OpenMP Language Terminology 10157 // Structured block - An executable statement with a single entry at the 10158 // top and a single exit at the bottom. 10159 // The point of exit cannot be a branch out of the structured block. 10160 // longjmp() and throw() must not violate the entry/exit criteria. 10161 CS->getCapturedDecl()->setNothrow(); 10162 } 10163 10164 OMPLoopDirective::HelperExprs B; 10165 // In presence of clause 'collapse' with number of loops, it will 10166 // define the nested loops number. 10167 unsigned NestedLoopCount = 10168 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10169 nullptr /*ordered not a clause on distribute*/, CS, *this, 10170 *DSAStack, VarsWithImplicitDSA, B); 10171 if (NestedLoopCount == 0) 10172 return StmtError(); 10173 10174 assert((CurContext->isDependentContext() || B.builtAll()) && 10175 "omp for loop exprs were not built"); 10176 10177 if (!CurContext->isDependentContext()) { 10178 // Finalize the clauses that need pre-built expressions for CodeGen. 10179 for (OMPClause *C : Clauses) { 10180 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10181 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10182 B.NumIterations, *this, CurScope, 10183 DSAStack)) 10184 return StmtError(); 10185 } 10186 } 10187 10188 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10189 return StmtError(); 10190 10191 setFunctionHasBranchProtectedScope(); 10192 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10193 NestedLoopCount, Clauses, AStmt, B); 10194 } 10195 10196 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10197 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10198 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10199 if (!AStmt) 10200 return StmtError(); 10201 10202 auto *CS = cast<CapturedStmt>(AStmt); 10203 // 1.2.2 OpenMP Language Terminology 10204 // Structured block - An executable statement with a single entry at the 10205 // top and a single exit at the bottom. 10206 // The point of exit cannot be a branch out of the structured block. 10207 // longjmp() and throw() must not violate the entry/exit criteria. 10208 CS->getCapturedDecl()->setNothrow(); 10209 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10210 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10211 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10212 // 1.2.2 OpenMP Language Terminology 10213 // Structured block - An executable statement with a single entry at the 10214 // top and a single exit at the bottom. 10215 // The point of exit cannot be a branch out of the structured block. 10216 // longjmp() and throw() must not violate the entry/exit criteria. 10217 CS->getCapturedDecl()->setNothrow(); 10218 } 10219 10220 OMPLoopDirective::HelperExprs B; 10221 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10222 // define the nested loops number. 10223 unsigned NestedLoopCount = checkOpenMPLoop( 10224 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10225 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10226 VarsWithImplicitDSA, B); 10227 if (NestedLoopCount == 0) 10228 return StmtError(); 10229 10230 assert((CurContext->isDependentContext() || B.builtAll()) && 10231 "omp target parallel for simd loop exprs were not built"); 10232 10233 if (!CurContext->isDependentContext()) { 10234 // Finalize the clauses that need pre-built expressions for CodeGen. 10235 for (OMPClause *C : Clauses) { 10236 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10237 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10238 B.NumIterations, *this, CurScope, 10239 DSAStack)) 10240 return StmtError(); 10241 } 10242 } 10243 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10244 return StmtError(); 10245 10246 setFunctionHasBranchProtectedScope(); 10247 return OMPTargetParallelForSimdDirective::Create( 10248 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10249 } 10250 10251 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10252 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10253 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10254 if (!AStmt) 10255 return StmtError(); 10256 10257 auto *CS = cast<CapturedStmt>(AStmt); 10258 // 1.2.2 OpenMP Language Terminology 10259 // Structured block - An executable statement with a single entry at the 10260 // top and a single exit at the bottom. 10261 // The point of exit cannot be a branch out of the structured block. 10262 // longjmp() and throw() must not violate the entry/exit criteria. 10263 CS->getCapturedDecl()->setNothrow(); 10264 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10265 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10266 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10267 // 1.2.2 OpenMP Language Terminology 10268 // Structured block - An executable statement with a single entry at the 10269 // top and a single exit at the bottom. 10270 // The point of exit cannot be a branch out of the structured block. 10271 // longjmp() and throw() must not violate the entry/exit criteria. 10272 CS->getCapturedDecl()->setNothrow(); 10273 } 10274 10275 OMPLoopDirective::HelperExprs B; 10276 // In presence of clause 'collapse' with number of loops, it will define the 10277 // nested loops number. 10278 unsigned NestedLoopCount = 10279 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10280 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10281 VarsWithImplicitDSA, B); 10282 if (NestedLoopCount == 0) 10283 return StmtError(); 10284 10285 assert((CurContext->isDependentContext() || B.builtAll()) && 10286 "omp target simd loop exprs were not built"); 10287 10288 if (!CurContext->isDependentContext()) { 10289 // Finalize the clauses that need pre-built expressions for CodeGen. 10290 for (OMPClause *C : Clauses) { 10291 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10292 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10293 B.NumIterations, *this, CurScope, 10294 DSAStack)) 10295 return StmtError(); 10296 } 10297 } 10298 10299 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10300 return StmtError(); 10301 10302 setFunctionHasBranchProtectedScope(); 10303 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10304 NestedLoopCount, Clauses, AStmt, B); 10305 } 10306 10307 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10308 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10309 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10310 if (!AStmt) 10311 return StmtError(); 10312 10313 auto *CS = cast<CapturedStmt>(AStmt); 10314 // 1.2.2 OpenMP Language Terminology 10315 // Structured block - An executable statement with a single entry at the 10316 // top and a single exit at the bottom. 10317 // The point of exit cannot be a branch out of the structured block. 10318 // longjmp() and throw() must not violate the entry/exit criteria. 10319 CS->getCapturedDecl()->setNothrow(); 10320 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10321 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10322 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10323 // 1.2.2 OpenMP Language Terminology 10324 // Structured block - An executable statement with a single entry at the 10325 // top and a single exit at the bottom. 10326 // The point of exit cannot be a branch out of the structured block. 10327 // longjmp() and throw() must not violate the entry/exit criteria. 10328 CS->getCapturedDecl()->setNothrow(); 10329 } 10330 10331 OMPLoopDirective::HelperExprs B; 10332 // In presence of clause 'collapse' with number of loops, it will 10333 // define the nested loops number. 10334 unsigned NestedLoopCount = 10335 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10336 nullptr /*ordered not a clause on distribute*/, CS, *this, 10337 *DSAStack, VarsWithImplicitDSA, B); 10338 if (NestedLoopCount == 0) 10339 return StmtError(); 10340 10341 assert((CurContext->isDependentContext() || B.builtAll()) && 10342 "omp teams distribute loop exprs were not built"); 10343 10344 setFunctionHasBranchProtectedScope(); 10345 10346 DSAStack->setParentTeamsRegionLoc(StartLoc); 10347 10348 return OMPTeamsDistributeDirective::Create( 10349 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10350 } 10351 10352 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10353 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10354 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10355 if (!AStmt) 10356 return StmtError(); 10357 10358 auto *CS = cast<CapturedStmt>(AStmt); 10359 // 1.2.2 OpenMP Language Terminology 10360 // Structured block - An executable statement with a single entry at the 10361 // top and a single exit at the bottom. 10362 // The point of exit cannot be a branch out of the structured block. 10363 // longjmp() and throw() must not violate the entry/exit criteria. 10364 CS->getCapturedDecl()->setNothrow(); 10365 for (int ThisCaptureLevel = 10366 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10367 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10368 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10369 // 1.2.2 OpenMP Language Terminology 10370 // Structured block - An executable statement with a single entry at the 10371 // top and a single exit at the bottom. 10372 // The point of exit cannot be a branch out of the structured block. 10373 // longjmp() and throw() must not violate the entry/exit criteria. 10374 CS->getCapturedDecl()->setNothrow(); 10375 } 10376 10377 10378 OMPLoopDirective::HelperExprs B; 10379 // In presence of clause 'collapse' with number of loops, it will 10380 // define the nested loops number. 10381 unsigned NestedLoopCount = checkOpenMPLoop( 10382 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10383 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10384 VarsWithImplicitDSA, B); 10385 10386 if (NestedLoopCount == 0) 10387 return StmtError(); 10388 10389 assert((CurContext->isDependentContext() || B.builtAll()) && 10390 "omp teams distribute simd loop exprs were not built"); 10391 10392 if (!CurContext->isDependentContext()) { 10393 // Finalize the clauses that need pre-built expressions for CodeGen. 10394 for (OMPClause *C : Clauses) { 10395 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10396 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10397 B.NumIterations, *this, CurScope, 10398 DSAStack)) 10399 return StmtError(); 10400 } 10401 } 10402 10403 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10404 return StmtError(); 10405 10406 setFunctionHasBranchProtectedScope(); 10407 10408 DSAStack->setParentTeamsRegionLoc(StartLoc); 10409 10410 return OMPTeamsDistributeSimdDirective::Create( 10411 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10412 } 10413 10414 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10415 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10416 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10417 if (!AStmt) 10418 return StmtError(); 10419 10420 auto *CS = cast<CapturedStmt>(AStmt); 10421 // 1.2.2 OpenMP Language Terminology 10422 // Structured block - An executable statement with a single entry at the 10423 // top and a single exit at the bottom. 10424 // The point of exit cannot be a branch out of the structured block. 10425 // longjmp() and throw() must not violate the entry/exit criteria. 10426 CS->getCapturedDecl()->setNothrow(); 10427 10428 for (int ThisCaptureLevel = 10429 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10430 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10431 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10432 // 1.2.2 OpenMP Language Terminology 10433 // Structured block - An executable statement with a single entry at the 10434 // top and a single exit at the bottom. 10435 // The point of exit cannot be a branch out of the structured block. 10436 // longjmp() and throw() must not violate the entry/exit criteria. 10437 CS->getCapturedDecl()->setNothrow(); 10438 } 10439 10440 OMPLoopDirective::HelperExprs B; 10441 // In presence of clause 'collapse' with number of loops, it will 10442 // define the nested loops number. 10443 unsigned NestedLoopCount = checkOpenMPLoop( 10444 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10445 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10446 VarsWithImplicitDSA, B); 10447 10448 if (NestedLoopCount == 0) 10449 return StmtError(); 10450 10451 assert((CurContext->isDependentContext() || B.builtAll()) && 10452 "omp for loop exprs were not built"); 10453 10454 if (!CurContext->isDependentContext()) { 10455 // Finalize the clauses that need pre-built expressions for CodeGen. 10456 for (OMPClause *C : Clauses) { 10457 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10458 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10459 B.NumIterations, *this, CurScope, 10460 DSAStack)) 10461 return StmtError(); 10462 } 10463 } 10464 10465 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10466 return StmtError(); 10467 10468 setFunctionHasBranchProtectedScope(); 10469 10470 DSAStack->setParentTeamsRegionLoc(StartLoc); 10471 10472 return OMPTeamsDistributeParallelForSimdDirective::Create( 10473 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10474 } 10475 10476 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10477 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10478 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10479 if (!AStmt) 10480 return StmtError(); 10481 10482 auto *CS = cast<CapturedStmt>(AStmt); 10483 // 1.2.2 OpenMP Language Terminology 10484 // Structured block - An executable statement with a single entry at the 10485 // top and a single exit at the bottom. 10486 // The point of exit cannot be a branch out of the structured block. 10487 // longjmp() and throw() must not violate the entry/exit criteria. 10488 CS->getCapturedDecl()->setNothrow(); 10489 10490 for (int ThisCaptureLevel = 10491 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10492 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10493 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10494 // 1.2.2 OpenMP Language Terminology 10495 // Structured block - An executable statement with a single entry at the 10496 // top and a single exit at the bottom. 10497 // The point of exit cannot be a branch out of the structured block. 10498 // longjmp() and throw() must not violate the entry/exit criteria. 10499 CS->getCapturedDecl()->setNothrow(); 10500 } 10501 10502 OMPLoopDirective::HelperExprs B; 10503 // In presence of clause 'collapse' with number of loops, it will 10504 // define the nested loops number. 10505 unsigned NestedLoopCount = checkOpenMPLoop( 10506 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10507 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10508 VarsWithImplicitDSA, B); 10509 10510 if (NestedLoopCount == 0) 10511 return StmtError(); 10512 10513 assert((CurContext->isDependentContext() || B.builtAll()) && 10514 "omp for loop exprs were not built"); 10515 10516 setFunctionHasBranchProtectedScope(); 10517 10518 DSAStack->setParentTeamsRegionLoc(StartLoc); 10519 10520 return OMPTeamsDistributeParallelForDirective::Create( 10521 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10522 DSAStack->isCancelRegion()); 10523 } 10524 10525 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10526 Stmt *AStmt, 10527 SourceLocation StartLoc, 10528 SourceLocation EndLoc) { 10529 if (!AStmt) 10530 return StmtError(); 10531 10532 auto *CS = cast<CapturedStmt>(AStmt); 10533 // 1.2.2 OpenMP Language Terminology 10534 // Structured block - An executable statement with a single entry at the 10535 // top and a single exit at the bottom. 10536 // The point of exit cannot be a branch out of the structured block. 10537 // longjmp() and throw() must not violate the entry/exit criteria. 10538 CS->getCapturedDecl()->setNothrow(); 10539 10540 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10541 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10542 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10543 // 1.2.2 OpenMP Language Terminology 10544 // Structured block - An executable statement with a single entry at the 10545 // top and a single exit at the bottom. 10546 // The point of exit cannot be a branch out of the structured block. 10547 // longjmp() and throw() must not violate the entry/exit criteria. 10548 CS->getCapturedDecl()->setNothrow(); 10549 } 10550 setFunctionHasBranchProtectedScope(); 10551 10552 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10553 AStmt); 10554 } 10555 10556 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10557 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10558 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10559 if (!AStmt) 10560 return StmtError(); 10561 10562 auto *CS = cast<CapturedStmt>(AStmt); 10563 // 1.2.2 OpenMP Language Terminology 10564 // Structured block - An executable statement with a single entry at the 10565 // top and a single exit at the bottom. 10566 // The point of exit cannot be a branch out of the structured block. 10567 // longjmp() and throw() must not violate the entry/exit criteria. 10568 CS->getCapturedDecl()->setNothrow(); 10569 for (int ThisCaptureLevel = 10570 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10571 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10572 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10573 // 1.2.2 OpenMP Language Terminology 10574 // Structured block - An executable statement with a single entry at the 10575 // top and a single exit at the bottom. 10576 // The point of exit cannot be a branch out of the structured block. 10577 // longjmp() and throw() must not violate the entry/exit criteria. 10578 CS->getCapturedDecl()->setNothrow(); 10579 } 10580 10581 OMPLoopDirective::HelperExprs B; 10582 // In presence of clause 'collapse' with number of loops, it will 10583 // define the nested loops number. 10584 unsigned NestedLoopCount = checkOpenMPLoop( 10585 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10586 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10587 VarsWithImplicitDSA, B); 10588 if (NestedLoopCount == 0) 10589 return StmtError(); 10590 10591 assert((CurContext->isDependentContext() || B.builtAll()) && 10592 "omp target teams distribute loop exprs were not built"); 10593 10594 setFunctionHasBranchProtectedScope(); 10595 return OMPTargetTeamsDistributeDirective::Create( 10596 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10597 } 10598 10599 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10600 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10601 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10602 if (!AStmt) 10603 return StmtError(); 10604 10605 auto *CS = cast<CapturedStmt>(AStmt); 10606 // 1.2.2 OpenMP Language Terminology 10607 // Structured block - An executable statement with a single entry at the 10608 // top and a single exit at the bottom. 10609 // The point of exit cannot be a branch out of the structured block. 10610 // longjmp() and throw() must not violate the entry/exit criteria. 10611 CS->getCapturedDecl()->setNothrow(); 10612 for (int ThisCaptureLevel = 10613 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10614 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10615 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10616 // 1.2.2 OpenMP Language Terminology 10617 // Structured block - An executable statement with a single entry at the 10618 // top and a single exit at the bottom. 10619 // The point of exit cannot be a branch out of the structured block. 10620 // longjmp() and throw() must not violate the entry/exit criteria. 10621 CS->getCapturedDecl()->setNothrow(); 10622 } 10623 10624 OMPLoopDirective::HelperExprs B; 10625 // In presence of clause 'collapse' with number of loops, it will 10626 // define the nested loops number. 10627 unsigned NestedLoopCount = checkOpenMPLoop( 10628 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10629 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10630 VarsWithImplicitDSA, B); 10631 if (NestedLoopCount == 0) 10632 return StmtError(); 10633 10634 assert((CurContext->isDependentContext() || B.builtAll()) && 10635 "omp target teams distribute parallel for loop exprs were not built"); 10636 10637 if (!CurContext->isDependentContext()) { 10638 // Finalize the clauses that need pre-built expressions for CodeGen. 10639 for (OMPClause *C : Clauses) { 10640 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10641 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10642 B.NumIterations, *this, CurScope, 10643 DSAStack)) 10644 return StmtError(); 10645 } 10646 } 10647 10648 setFunctionHasBranchProtectedScope(); 10649 return OMPTargetTeamsDistributeParallelForDirective::Create( 10650 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10651 DSAStack->isCancelRegion()); 10652 } 10653 10654 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10655 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10656 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10657 if (!AStmt) 10658 return StmtError(); 10659 10660 auto *CS = cast<CapturedStmt>(AStmt); 10661 // 1.2.2 OpenMP Language Terminology 10662 // Structured block - An executable statement with a single entry at the 10663 // top and a single exit at the bottom. 10664 // The point of exit cannot be a branch out of the structured block. 10665 // longjmp() and throw() must not violate the entry/exit criteria. 10666 CS->getCapturedDecl()->setNothrow(); 10667 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10668 OMPD_target_teams_distribute_parallel_for_simd); 10669 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10670 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10671 // 1.2.2 OpenMP Language Terminology 10672 // Structured block - An executable statement with a single entry at the 10673 // top and a single exit at the bottom. 10674 // The point of exit cannot be a branch out of the structured block. 10675 // longjmp() and throw() must not violate the entry/exit criteria. 10676 CS->getCapturedDecl()->setNothrow(); 10677 } 10678 10679 OMPLoopDirective::HelperExprs B; 10680 // In presence of clause 'collapse' with number of loops, it will 10681 // define the nested loops number. 10682 unsigned NestedLoopCount = 10683 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10684 getCollapseNumberExpr(Clauses), 10685 nullptr /*ordered not a clause on distribute*/, CS, *this, 10686 *DSAStack, VarsWithImplicitDSA, B); 10687 if (NestedLoopCount == 0) 10688 return StmtError(); 10689 10690 assert((CurContext->isDependentContext() || B.builtAll()) && 10691 "omp target teams distribute parallel for simd loop exprs were not " 10692 "built"); 10693 10694 if (!CurContext->isDependentContext()) { 10695 // Finalize the clauses that need pre-built expressions for CodeGen. 10696 for (OMPClause *C : Clauses) { 10697 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10698 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10699 B.NumIterations, *this, CurScope, 10700 DSAStack)) 10701 return StmtError(); 10702 } 10703 } 10704 10705 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10706 return StmtError(); 10707 10708 setFunctionHasBranchProtectedScope(); 10709 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10710 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10711 } 10712 10713 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10714 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10715 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10716 if (!AStmt) 10717 return StmtError(); 10718 10719 auto *CS = cast<CapturedStmt>(AStmt); 10720 // 1.2.2 OpenMP Language Terminology 10721 // Structured block - An executable statement with a single entry at the 10722 // top and a single exit at the bottom. 10723 // The point of exit cannot be a branch out of the structured block. 10724 // longjmp() and throw() must not violate the entry/exit criteria. 10725 CS->getCapturedDecl()->setNothrow(); 10726 for (int ThisCaptureLevel = 10727 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10728 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10729 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10730 // 1.2.2 OpenMP Language Terminology 10731 // Structured block - An executable statement with a single entry at the 10732 // top and a single exit at the bottom. 10733 // The point of exit cannot be a branch out of the structured block. 10734 // longjmp() and throw() must not violate the entry/exit criteria. 10735 CS->getCapturedDecl()->setNothrow(); 10736 } 10737 10738 OMPLoopDirective::HelperExprs B; 10739 // In presence of clause 'collapse' with number of loops, it will 10740 // define the nested loops number. 10741 unsigned NestedLoopCount = checkOpenMPLoop( 10742 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10743 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10744 VarsWithImplicitDSA, B); 10745 if (NestedLoopCount == 0) 10746 return StmtError(); 10747 10748 assert((CurContext->isDependentContext() || B.builtAll()) && 10749 "omp target teams distribute simd loop exprs were not built"); 10750 10751 if (!CurContext->isDependentContext()) { 10752 // Finalize the clauses that need pre-built expressions for CodeGen. 10753 for (OMPClause *C : Clauses) { 10754 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10755 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10756 B.NumIterations, *this, CurScope, 10757 DSAStack)) 10758 return StmtError(); 10759 } 10760 } 10761 10762 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10763 return StmtError(); 10764 10765 setFunctionHasBranchProtectedScope(); 10766 return OMPTargetTeamsDistributeSimdDirective::Create( 10767 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10768 } 10769 10770 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10771 SourceLocation StartLoc, 10772 SourceLocation LParenLoc, 10773 SourceLocation EndLoc) { 10774 OMPClause *Res = nullptr; 10775 switch (Kind) { 10776 case OMPC_final: 10777 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10778 break; 10779 case OMPC_num_threads: 10780 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10781 break; 10782 case OMPC_safelen: 10783 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10784 break; 10785 case OMPC_simdlen: 10786 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10787 break; 10788 case OMPC_allocator: 10789 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10790 break; 10791 case OMPC_collapse: 10792 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10793 break; 10794 case OMPC_ordered: 10795 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10796 break; 10797 case OMPC_device: 10798 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10799 break; 10800 case OMPC_num_teams: 10801 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10802 break; 10803 case OMPC_thread_limit: 10804 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10805 break; 10806 case OMPC_priority: 10807 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10808 break; 10809 case OMPC_grainsize: 10810 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10811 break; 10812 case OMPC_num_tasks: 10813 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10814 break; 10815 case OMPC_hint: 10816 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10817 break; 10818 case OMPC_if: 10819 case OMPC_default: 10820 case OMPC_proc_bind: 10821 case OMPC_schedule: 10822 case OMPC_private: 10823 case OMPC_firstprivate: 10824 case OMPC_lastprivate: 10825 case OMPC_shared: 10826 case OMPC_reduction: 10827 case OMPC_task_reduction: 10828 case OMPC_in_reduction: 10829 case OMPC_linear: 10830 case OMPC_aligned: 10831 case OMPC_copyin: 10832 case OMPC_copyprivate: 10833 case OMPC_nowait: 10834 case OMPC_untied: 10835 case OMPC_mergeable: 10836 case OMPC_threadprivate: 10837 case OMPC_allocate: 10838 case OMPC_flush: 10839 case OMPC_read: 10840 case OMPC_write: 10841 case OMPC_update: 10842 case OMPC_capture: 10843 case OMPC_seq_cst: 10844 case OMPC_depend: 10845 case OMPC_threads: 10846 case OMPC_simd: 10847 case OMPC_map: 10848 case OMPC_nogroup: 10849 case OMPC_dist_schedule: 10850 case OMPC_defaultmap: 10851 case OMPC_unknown: 10852 case OMPC_uniform: 10853 case OMPC_to: 10854 case OMPC_from: 10855 case OMPC_use_device_ptr: 10856 case OMPC_is_device_ptr: 10857 case OMPC_unified_address: 10858 case OMPC_unified_shared_memory: 10859 case OMPC_reverse_offload: 10860 case OMPC_dynamic_allocators: 10861 case OMPC_atomic_default_mem_order: 10862 case OMPC_device_type: 10863 case OMPC_match: 10864 case OMPC_nontemporal: 10865 case OMPC_order: 10866 llvm_unreachable("Clause is not allowed."); 10867 } 10868 return Res; 10869 } 10870 10871 // An OpenMP directive such as 'target parallel' has two captured regions: 10872 // for the 'target' and 'parallel' respectively. This function returns 10873 // the region in which to capture expressions associated with a clause. 10874 // A return value of OMPD_unknown signifies that the expression should not 10875 // be captured. 10876 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10877 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 10878 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10879 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10880 switch (CKind) { 10881 case OMPC_if: 10882 switch (DKind) { 10883 case OMPD_target_parallel_for_simd: 10884 if (OpenMPVersion >= 50 && 10885 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10886 CaptureRegion = OMPD_parallel; 10887 break; 10888 } 10889 LLVM_FALLTHROUGH; 10890 case OMPD_target_parallel: 10891 case OMPD_target_parallel_for: 10892 // If this clause applies to the nested 'parallel' region, capture within 10893 // the 'target' region, otherwise do not capture. 10894 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10895 CaptureRegion = OMPD_target; 10896 break; 10897 case OMPD_target_teams_distribute_parallel_for_simd: 10898 if (OpenMPVersion >= 50 && 10899 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10900 CaptureRegion = OMPD_parallel; 10901 break; 10902 } 10903 LLVM_FALLTHROUGH; 10904 case OMPD_target_teams_distribute_parallel_for: 10905 // If this clause applies to the nested 'parallel' region, capture within 10906 // the 'teams' region, otherwise do not capture. 10907 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10908 CaptureRegion = OMPD_teams; 10909 break; 10910 case OMPD_teams_distribute_parallel_for_simd: 10911 if (OpenMPVersion >= 50 && 10912 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10913 CaptureRegion = OMPD_parallel; 10914 break; 10915 } 10916 LLVM_FALLTHROUGH; 10917 case OMPD_teams_distribute_parallel_for: 10918 CaptureRegion = OMPD_teams; 10919 break; 10920 case OMPD_target_update: 10921 case OMPD_target_enter_data: 10922 case OMPD_target_exit_data: 10923 CaptureRegion = OMPD_task; 10924 break; 10925 case OMPD_parallel_master_taskloop: 10926 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10927 CaptureRegion = OMPD_parallel; 10928 break; 10929 case OMPD_parallel_master_taskloop_simd: 10930 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 10931 NameModifier == OMPD_taskloop) { 10932 CaptureRegion = OMPD_parallel; 10933 break; 10934 } 10935 if (OpenMPVersion <= 45) 10936 break; 10937 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10938 CaptureRegion = OMPD_taskloop; 10939 break; 10940 case OMPD_parallel_for_simd: 10941 if (OpenMPVersion <= 45) 10942 break; 10943 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10944 CaptureRegion = OMPD_parallel; 10945 break; 10946 case OMPD_taskloop_simd: 10947 case OMPD_master_taskloop_simd: 10948 if (OpenMPVersion <= 45) 10949 break; 10950 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10951 CaptureRegion = OMPD_taskloop; 10952 break; 10953 case OMPD_distribute_parallel_for_simd: 10954 if (OpenMPVersion <= 45) 10955 break; 10956 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10957 CaptureRegion = OMPD_parallel; 10958 break; 10959 case OMPD_target_simd: 10960 if (OpenMPVersion >= 50 && 10961 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10962 CaptureRegion = OMPD_target; 10963 break; 10964 case OMPD_teams_distribute_simd: 10965 case OMPD_target_teams_distribute_simd: 10966 if (OpenMPVersion >= 50 && 10967 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10968 CaptureRegion = OMPD_teams; 10969 break; 10970 case OMPD_cancel: 10971 case OMPD_parallel: 10972 case OMPD_parallel_master: 10973 case OMPD_parallel_sections: 10974 case OMPD_parallel_for: 10975 case OMPD_target: 10976 case OMPD_target_teams: 10977 case OMPD_target_teams_distribute: 10978 case OMPD_distribute_parallel_for: 10979 case OMPD_task: 10980 case OMPD_taskloop: 10981 case OMPD_master_taskloop: 10982 case OMPD_target_data: 10983 case OMPD_simd: 10984 case OMPD_for_simd: 10985 case OMPD_distribute_simd: 10986 // Do not capture if-clause expressions. 10987 break; 10988 case OMPD_threadprivate: 10989 case OMPD_allocate: 10990 case OMPD_taskyield: 10991 case OMPD_barrier: 10992 case OMPD_taskwait: 10993 case OMPD_cancellation_point: 10994 case OMPD_flush: 10995 case OMPD_declare_reduction: 10996 case OMPD_declare_mapper: 10997 case OMPD_declare_simd: 10998 case OMPD_declare_variant: 10999 case OMPD_declare_target: 11000 case OMPD_end_declare_target: 11001 case OMPD_teams: 11002 case OMPD_for: 11003 case OMPD_sections: 11004 case OMPD_section: 11005 case OMPD_single: 11006 case OMPD_master: 11007 case OMPD_critical: 11008 case OMPD_taskgroup: 11009 case OMPD_distribute: 11010 case OMPD_ordered: 11011 case OMPD_atomic: 11012 case OMPD_teams_distribute: 11013 case OMPD_requires: 11014 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11015 case OMPD_unknown: 11016 llvm_unreachable("Unknown OpenMP directive"); 11017 } 11018 break; 11019 case OMPC_num_threads: 11020 switch (DKind) { 11021 case OMPD_target_parallel: 11022 case OMPD_target_parallel_for: 11023 case OMPD_target_parallel_for_simd: 11024 CaptureRegion = OMPD_target; 11025 break; 11026 case OMPD_teams_distribute_parallel_for: 11027 case OMPD_teams_distribute_parallel_for_simd: 11028 case OMPD_target_teams_distribute_parallel_for: 11029 case OMPD_target_teams_distribute_parallel_for_simd: 11030 CaptureRegion = OMPD_teams; 11031 break; 11032 case OMPD_parallel: 11033 case OMPD_parallel_master: 11034 case OMPD_parallel_sections: 11035 case OMPD_parallel_for: 11036 case OMPD_parallel_for_simd: 11037 case OMPD_distribute_parallel_for: 11038 case OMPD_distribute_parallel_for_simd: 11039 case OMPD_parallel_master_taskloop: 11040 case OMPD_parallel_master_taskloop_simd: 11041 // Do not capture num_threads-clause expressions. 11042 break; 11043 case OMPD_target_data: 11044 case OMPD_target_enter_data: 11045 case OMPD_target_exit_data: 11046 case OMPD_target_update: 11047 case OMPD_target: 11048 case OMPD_target_simd: 11049 case OMPD_target_teams: 11050 case OMPD_target_teams_distribute: 11051 case OMPD_target_teams_distribute_simd: 11052 case OMPD_cancel: 11053 case OMPD_task: 11054 case OMPD_taskloop: 11055 case OMPD_taskloop_simd: 11056 case OMPD_master_taskloop: 11057 case OMPD_master_taskloop_simd: 11058 case OMPD_threadprivate: 11059 case OMPD_allocate: 11060 case OMPD_taskyield: 11061 case OMPD_barrier: 11062 case OMPD_taskwait: 11063 case OMPD_cancellation_point: 11064 case OMPD_flush: 11065 case OMPD_declare_reduction: 11066 case OMPD_declare_mapper: 11067 case OMPD_declare_simd: 11068 case OMPD_declare_variant: 11069 case OMPD_declare_target: 11070 case OMPD_end_declare_target: 11071 case OMPD_teams: 11072 case OMPD_simd: 11073 case OMPD_for: 11074 case OMPD_for_simd: 11075 case OMPD_sections: 11076 case OMPD_section: 11077 case OMPD_single: 11078 case OMPD_master: 11079 case OMPD_critical: 11080 case OMPD_taskgroup: 11081 case OMPD_distribute: 11082 case OMPD_ordered: 11083 case OMPD_atomic: 11084 case OMPD_distribute_simd: 11085 case OMPD_teams_distribute: 11086 case OMPD_teams_distribute_simd: 11087 case OMPD_requires: 11088 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11089 case OMPD_unknown: 11090 llvm_unreachable("Unknown OpenMP directive"); 11091 } 11092 break; 11093 case OMPC_num_teams: 11094 switch (DKind) { 11095 case OMPD_target_teams: 11096 case OMPD_target_teams_distribute: 11097 case OMPD_target_teams_distribute_simd: 11098 case OMPD_target_teams_distribute_parallel_for: 11099 case OMPD_target_teams_distribute_parallel_for_simd: 11100 CaptureRegion = OMPD_target; 11101 break; 11102 case OMPD_teams_distribute_parallel_for: 11103 case OMPD_teams_distribute_parallel_for_simd: 11104 case OMPD_teams: 11105 case OMPD_teams_distribute: 11106 case OMPD_teams_distribute_simd: 11107 // Do not capture num_teams-clause expressions. 11108 break; 11109 case OMPD_distribute_parallel_for: 11110 case OMPD_distribute_parallel_for_simd: 11111 case OMPD_task: 11112 case OMPD_taskloop: 11113 case OMPD_taskloop_simd: 11114 case OMPD_master_taskloop: 11115 case OMPD_master_taskloop_simd: 11116 case OMPD_parallel_master_taskloop: 11117 case OMPD_parallel_master_taskloop_simd: 11118 case OMPD_target_data: 11119 case OMPD_target_enter_data: 11120 case OMPD_target_exit_data: 11121 case OMPD_target_update: 11122 case OMPD_cancel: 11123 case OMPD_parallel: 11124 case OMPD_parallel_master: 11125 case OMPD_parallel_sections: 11126 case OMPD_parallel_for: 11127 case OMPD_parallel_for_simd: 11128 case OMPD_target: 11129 case OMPD_target_simd: 11130 case OMPD_target_parallel: 11131 case OMPD_target_parallel_for: 11132 case OMPD_target_parallel_for_simd: 11133 case OMPD_threadprivate: 11134 case OMPD_allocate: 11135 case OMPD_taskyield: 11136 case OMPD_barrier: 11137 case OMPD_taskwait: 11138 case OMPD_cancellation_point: 11139 case OMPD_flush: 11140 case OMPD_declare_reduction: 11141 case OMPD_declare_mapper: 11142 case OMPD_declare_simd: 11143 case OMPD_declare_variant: 11144 case OMPD_declare_target: 11145 case OMPD_end_declare_target: 11146 case OMPD_simd: 11147 case OMPD_for: 11148 case OMPD_for_simd: 11149 case OMPD_sections: 11150 case OMPD_section: 11151 case OMPD_single: 11152 case OMPD_master: 11153 case OMPD_critical: 11154 case OMPD_taskgroup: 11155 case OMPD_distribute: 11156 case OMPD_ordered: 11157 case OMPD_atomic: 11158 case OMPD_distribute_simd: 11159 case OMPD_requires: 11160 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11161 case OMPD_unknown: 11162 llvm_unreachable("Unknown OpenMP directive"); 11163 } 11164 break; 11165 case OMPC_thread_limit: 11166 switch (DKind) { 11167 case OMPD_target_teams: 11168 case OMPD_target_teams_distribute: 11169 case OMPD_target_teams_distribute_simd: 11170 case OMPD_target_teams_distribute_parallel_for: 11171 case OMPD_target_teams_distribute_parallel_for_simd: 11172 CaptureRegion = OMPD_target; 11173 break; 11174 case OMPD_teams_distribute_parallel_for: 11175 case OMPD_teams_distribute_parallel_for_simd: 11176 case OMPD_teams: 11177 case OMPD_teams_distribute: 11178 case OMPD_teams_distribute_simd: 11179 // Do not capture thread_limit-clause expressions. 11180 break; 11181 case OMPD_distribute_parallel_for: 11182 case OMPD_distribute_parallel_for_simd: 11183 case OMPD_task: 11184 case OMPD_taskloop: 11185 case OMPD_taskloop_simd: 11186 case OMPD_master_taskloop: 11187 case OMPD_master_taskloop_simd: 11188 case OMPD_parallel_master_taskloop: 11189 case OMPD_parallel_master_taskloop_simd: 11190 case OMPD_target_data: 11191 case OMPD_target_enter_data: 11192 case OMPD_target_exit_data: 11193 case OMPD_target_update: 11194 case OMPD_cancel: 11195 case OMPD_parallel: 11196 case OMPD_parallel_master: 11197 case OMPD_parallel_sections: 11198 case OMPD_parallel_for: 11199 case OMPD_parallel_for_simd: 11200 case OMPD_target: 11201 case OMPD_target_simd: 11202 case OMPD_target_parallel: 11203 case OMPD_target_parallel_for: 11204 case OMPD_target_parallel_for_simd: 11205 case OMPD_threadprivate: 11206 case OMPD_allocate: 11207 case OMPD_taskyield: 11208 case OMPD_barrier: 11209 case OMPD_taskwait: 11210 case OMPD_cancellation_point: 11211 case OMPD_flush: 11212 case OMPD_declare_reduction: 11213 case OMPD_declare_mapper: 11214 case OMPD_declare_simd: 11215 case OMPD_declare_variant: 11216 case OMPD_declare_target: 11217 case OMPD_end_declare_target: 11218 case OMPD_simd: 11219 case OMPD_for: 11220 case OMPD_for_simd: 11221 case OMPD_sections: 11222 case OMPD_section: 11223 case OMPD_single: 11224 case OMPD_master: 11225 case OMPD_critical: 11226 case OMPD_taskgroup: 11227 case OMPD_distribute: 11228 case OMPD_ordered: 11229 case OMPD_atomic: 11230 case OMPD_distribute_simd: 11231 case OMPD_requires: 11232 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11233 case OMPD_unknown: 11234 llvm_unreachable("Unknown OpenMP directive"); 11235 } 11236 break; 11237 case OMPC_schedule: 11238 switch (DKind) { 11239 case OMPD_parallel_for: 11240 case OMPD_parallel_for_simd: 11241 case OMPD_distribute_parallel_for: 11242 case OMPD_distribute_parallel_for_simd: 11243 case OMPD_teams_distribute_parallel_for: 11244 case OMPD_teams_distribute_parallel_for_simd: 11245 case OMPD_target_parallel_for: 11246 case OMPD_target_parallel_for_simd: 11247 case OMPD_target_teams_distribute_parallel_for: 11248 case OMPD_target_teams_distribute_parallel_for_simd: 11249 CaptureRegion = OMPD_parallel; 11250 break; 11251 case OMPD_for: 11252 case OMPD_for_simd: 11253 // Do not capture schedule-clause expressions. 11254 break; 11255 case OMPD_task: 11256 case OMPD_taskloop: 11257 case OMPD_taskloop_simd: 11258 case OMPD_master_taskloop: 11259 case OMPD_master_taskloop_simd: 11260 case OMPD_parallel_master_taskloop: 11261 case OMPD_parallel_master_taskloop_simd: 11262 case OMPD_target_data: 11263 case OMPD_target_enter_data: 11264 case OMPD_target_exit_data: 11265 case OMPD_target_update: 11266 case OMPD_teams: 11267 case OMPD_teams_distribute: 11268 case OMPD_teams_distribute_simd: 11269 case OMPD_target_teams_distribute: 11270 case OMPD_target_teams_distribute_simd: 11271 case OMPD_target: 11272 case OMPD_target_simd: 11273 case OMPD_target_parallel: 11274 case OMPD_cancel: 11275 case OMPD_parallel: 11276 case OMPD_parallel_master: 11277 case OMPD_parallel_sections: 11278 case OMPD_threadprivate: 11279 case OMPD_allocate: 11280 case OMPD_taskyield: 11281 case OMPD_barrier: 11282 case OMPD_taskwait: 11283 case OMPD_cancellation_point: 11284 case OMPD_flush: 11285 case OMPD_declare_reduction: 11286 case OMPD_declare_mapper: 11287 case OMPD_declare_simd: 11288 case OMPD_declare_variant: 11289 case OMPD_declare_target: 11290 case OMPD_end_declare_target: 11291 case OMPD_simd: 11292 case OMPD_sections: 11293 case OMPD_section: 11294 case OMPD_single: 11295 case OMPD_master: 11296 case OMPD_critical: 11297 case OMPD_taskgroup: 11298 case OMPD_distribute: 11299 case OMPD_ordered: 11300 case OMPD_atomic: 11301 case OMPD_distribute_simd: 11302 case OMPD_target_teams: 11303 case OMPD_requires: 11304 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11305 case OMPD_unknown: 11306 llvm_unreachable("Unknown OpenMP directive"); 11307 } 11308 break; 11309 case OMPC_dist_schedule: 11310 switch (DKind) { 11311 case OMPD_teams_distribute_parallel_for: 11312 case OMPD_teams_distribute_parallel_for_simd: 11313 case OMPD_teams_distribute: 11314 case OMPD_teams_distribute_simd: 11315 case OMPD_target_teams_distribute_parallel_for: 11316 case OMPD_target_teams_distribute_parallel_for_simd: 11317 case OMPD_target_teams_distribute: 11318 case OMPD_target_teams_distribute_simd: 11319 CaptureRegion = OMPD_teams; 11320 break; 11321 case OMPD_distribute_parallel_for: 11322 case OMPD_distribute_parallel_for_simd: 11323 case OMPD_distribute: 11324 case OMPD_distribute_simd: 11325 // Do not capture thread_limit-clause expressions. 11326 break; 11327 case OMPD_parallel_for: 11328 case OMPD_parallel_for_simd: 11329 case OMPD_target_parallel_for_simd: 11330 case OMPD_target_parallel_for: 11331 case OMPD_task: 11332 case OMPD_taskloop: 11333 case OMPD_taskloop_simd: 11334 case OMPD_master_taskloop: 11335 case OMPD_master_taskloop_simd: 11336 case OMPD_parallel_master_taskloop: 11337 case OMPD_parallel_master_taskloop_simd: 11338 case OMPD_target_data: 11339 case OMPD_target_enter_data: 11340 case OMPD_target_exit_data: 11341 case OMPD_target_update: 11342 case OMPD_teams: 11343 case OMPD_target: 11344 case OMPD_target_simd: 11345 case OMPD_target_parallel: 11346 case OMPD_cancel: 11347 case OMPD_parallel: 11348 case OMPD_parallel_master: 11349 case OMPD_parallel_sections: 11350 case OMPD_threadprivate: 11351 case OMPD_allocate: 11352 case OMPD_taskyield: 11353 case OMPD_barrier: 11354 case OMPD_taskwait: 11355 case OMPD_cancellation_point: 11356 case OMPD_flush: 11357 case OMPD_declare_reduction: 11358 case OMPD_declare_mapper: 11359 case OMPD_declare_simd: 11360 case OMPD_declare_variant: 11361 case OMPD_declare_target: 11362 case OMPD_end_declare_target: 11363 case OMPD_simd: 11364 case OMPD_for: 11365 case OMPD_for_simd: 11366 case OMPD_sections: 11367 case OMPD_section: 11368 case OMPD_single: 11369 case OMPD_master: 11370 case OMPD_critical: 11371 case OMPD_taskgroup: 11372 case OMPD_ordered: 11373 case OMPD_atomic: 11374 case OMPD_target_teams: 11375 case OMPD_requires: 11376 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11377 case OMPD_unknown: 11378 llvm_unreachable("Unknown OpenMP directive"); 11379 } 11380 break; 11381 case OMPC_device: 11382 switch (DKind) { 11383 case OMPD_target_update: 11384 case OMPD_target_enter_data: 11385 case OMPD_target_exit_data: 11386 case OMPD_target: 11387 case OMPD_target_simd: 11388 case OMPD_target_teams: 11389 case OMPD_target_parallel: 11390 case OMPD_target_teams_distribute: 11391 case OMPD_target_teams_distribute_simd: 11392 case OMPD_target_parallel_for: 11393 case OMPD_target_parallel_for_simd: 11394 case OMPD_target_teams_distribute_parallel_for: 11395 case OMPD_target_teams_distribute_parallel_for_simd: 11396 CaptureRegion = OMPD_task; 11397 break; 11398 case OMPD_target_data: 11399 // Do not capture device-clause expressions. 11400 break; 11401 case OMPD_teams_distribute_parallel_for: 11402 case OMPD_teams_distribute_parallel_for_simd: 11403 case OMPD_teams: 11404 case OMPD_teams_distribute: 11405 case OMPD_teams_distribute_simd: 11406 case OMPD_distribute_parallel_for: 11407 case OMPD_distribute_parallel_for_simd: 11408 case OMPD_task: 11409 case OMPD_taskloop: 11410 case OMPD_taskloop_simd: 11411 case OMPD_master_taskloop: 11412 case OMPD_master_taskloop_simd: 11413 case OMPD_parallel_master_taskloop: 11414 case OMPD_parallel_master_taskloop_simd: 11415 case OMPD_cancel: 11416 case OMPD_parallel: 11417 case OMPD_parallel_master: 11418 case OMPD_parallel_sections: 11419 case OMPD_parallel_for: 11420 case OMPD_parallel_for_simd: 11421 case OMPD_threadprivate: 11422 case OMPD_allocate: 11423 case OMPD_taskyield: 11424 case OMPD_barrier: 11425 case OMPD_taskwait: 11426 case OMPD_cancellation_point: 11427 case OMPD_flush: 11428 case OMPD_declare_reduction: 11429 case OMPD_declare_mapper: 11430 case OMPD_declare_simd: 11431 case OMPD_declare_variant: 11432 case OMPD_declare_target: 11433 case OMPD_end_declare_target: 11434 case OMPD_simd: 11435 case OMPD_for: 11436 case OMPD_for_simd: 11437 case OMPD_sections: 11438 case OMPD_section: 11439 case OMPD_single: 11440 case OMPD_master: 11441 case OMPD_critical: 11442 case OMPD_taskgroup: 11443 case OMPD_distribute: 11444 case OMPD_ordered: 11445 case OMPD_atomic: 11446 case OMPD_distribute_simd: 11447 case OMPD_requires: 11448 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11449 case OMPD_unknown: 11450 llvm_unreachable("Unknown OpenMP directive"); 11451 } 11452 break; 11453 case OMPC_grainsize: 11454 case OMPC_num_tasks: 11455 case OMPC_final: 11456 case OMPC_priority: 11457 switch (DKind) { 11458 case OMPD_task: 11459 case OMPD_taskloop: 11460 case OMPD_taskloop_simd: 11461 case OMPD_master_taskloop: 11462 case OMPD_master_taskloop_simd: 11463 break; 11464 case OMPD_parallel_master_taskloop: 11465 case OMPD_parallel_master_taskloop_simd: 11466 CaptureRegion = OMPD_parallel; 11467 break; 11468 case OMPD_target_update: 11469 case OMPD_target_enter_data: 11470 case OMPD_target_exit_data: 11471 case OMPD_target: 11472 case OMPD_target_simd: 11473 case OMPD_target_teams: 11474 case OMPD_target_parallel: 11475 case OMPD_target_teams_distribute: 11476 case OMPD_target_teams_distribute_simd: 11477 case OMPD_target_parallel_for: 11478 case OMPD_target_parallel_for_simd: 11479 case OMPD_target_teams_distribute_parallel_for: 11480 case OMPD_target_teams_distribute_parallel_for_simd: 11481 case OMPD_target_data: 11482 case OMPD_teams_distribute_parallel_for: 11483 case OMPD_teams_distribute_parallel_for_simd: 11484 case OMPD_teams: 11485 case OMPD_teams_distribute: 11486 case OMPD_teams_distribute_simd: 11487 case OMPD_distribute_parallel_for: 11488 case OMPD_distribute_parallel_for_simd: 11489 case OMPD_cancel: 11490 case OMPD_parallel: 11491 case OMPD_parallel_master: 11492 case OMPD_parallel_sections: 11493 case OMPD_parallel_for: 11494 case OMPD_parallel_for_simd: 11495 case OMPD_threadprivate: 11496 case OMPD_allocate: 11497 case OMPD_taskyield: 11498 case OMPD_barrier: 11499 case OMPD_taskwait: 11500 case OMPD_cancellation_point: 11501 case OMPD_flush: 11502 case OMPD_declare_reduction: 11503 case OMPD_declare_mapper: 11504 case OMPD_declare_simd: 11505 case OMPD_declare_variant: 11506 case OMPD_declare_target: 11507 case OMPD_end_declare_target: 11508 case OMPD_simd: 11509 case OMPD_for: 11510 case OMPD_for_simd: 11511 case OMPD_sections: 11512 case OMPD_section: 11513 case OMPD_single: 11514 case OMPD_master: 11515 case OMPD_critical: 11516 case OMPD_taskgroup: 11517 case OMPD_distribute: 11518 case OMPD_ordered: 11519 case OMPD_atomic: 11520 case OMPD_distribute_simd: 11521 case OMPD_requires: 11522 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11523 case OMPD_unknown: 11524 llvm_unreachable("Unknown OpenMP directive"); 11525 } 11526 break; 11527 case OMPC_firstprivate: 11528 case OMPC_lastprivate: 11529 case OMPC_reduction: 11530 case OMPC_task_reduction: 11531 case OMPC_in_reduction: 11532 case OMPC_linear: 11533 case OMPC_default: 11534 case OMPC_proc_bind: 11535 case OMPC_safelen: 11536 case OMPC_simdlen: 11537 case OMPC_allocator: 11538 case OMPC_collapse: 11539 case OMPC_private: 11540 case OMPC_shared: 11541 case OMPC_aligned: 11542 case OMPC_copyin: 11543 case OMPC_copyprivate: 11544 case OMPC_ordered: 11545 case OMPC_nowait: 11546 case OMPC_untied: 11547 case OMPC_mergeable: 11548 case OMPC_threadprivate: 11549 case OMPC_allocate: 11550 case OMPC_flush: 11551 case OMPC_read: 11552 case OMPC_write: 11553 case OMPC_update: 11554 case OMPC_capture: 11555 case OMPC_seq_cst: 11556 case OMPC_depend: 11557 case OMPC_threads: 11558 case OMPC_simd: 11559 case OMPC_map: 11560 case OMPC_nogroup: 11561 case OMPC_hint: 11562 case OMPC_defaultmap: 11563 case OMPC_unknown: 11564 case OMPC_uniform: 11565 case OMPC_to: 11566 case OMPC_from: 11567 case OMPC_use_device_ptr: 11568 case OMPC_is_device_ptr: 11569 case OMPC_unified_address: 11570 case OMPC_unified_shared_memory: 11571 case OMPC_reverse_offload: 11572 case OMPC_dynamic_allocators: 11573 case OMPC_atomic_default_mem_order: 11574 case OMPC_device_type: 11575 case OMPC_match: 11576 case OMPC_nontemporal: 11577 case OMPC_order: 11578 llvm_unreachable("Unexpected OpenMP clause."); 11579 } 11580 return CaptureRegion; 11581 } 11582 11583 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11584 Expr *Condition, SourceLocation StartLoc, 11585 SourceLocation LParenLoc, 11586 SourceLocation NameModifierLoc, 11587 SourceLocation ColonLoc, 11588 SourceLocation EndLoc) { 11589 Expr *ValExpr = Condition; 11590 Stmt *HelperValStmt = nullptr; 11591 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11592 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11593 !Condition->isInstantiationDependent() && 11594 !Condition->containsUnexpandedParameterPack()) { 11595 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11596 if (Val.isInvalid()) 11597 return nullptr; 11598 11599 ValExpr = Val.get(); 11600 11601 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11602 CaptureRegion = getOpenMPCaptureRegionForClause( 11603 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 11604 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11605 ValExpr = MakeFullExpr(ValExpr).get(); 11606 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11607 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11608 HelperValStmt = buildPreInits(Context, Captures); 11609 } 11610 } 11611 11612 return new (Context) 11613 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11614 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11615 } 11616 11617 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11618 SourceLocation StartLoc, 11619 SourceLocation LParenLoc, 11620 SourceLocation EndLoc) { 11621 Expr *ValExpr = Condition; 11622 Stmt *HelperValStmt = nullptr; 11623 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11624 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11625 !Condition->isInstantiationDependent() && 11626 !Condition->containsUnexpandedParameterPack()) { 11627 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11628 if (Val.isInvalid()) 11629 return nullptr; 11630 11631 ValExpr = MakeFullExpr(Val.get()).get(); 11632 11633 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11634 CaptureRegion = 11635 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 11636 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11637 ValExpr = MakeFullExpr(ValExpr).get(); 11638 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11639 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11640 HelperValStmt = buildPreInits(Context, Captures); 11641 } 11642 } 11643 11644 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11645 StartLoc, LParenLoc, EndLoc); 11646 } 11647 11648 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11649 Expr *Op) { 11650 if (!Op) 11651 return ExprError(); 11652 11653 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11654 public: 11655 IntConvertDiagnoser() 11656 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11657 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11658 QualType T) override { 11659 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11660 } 11661 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11662 QualType T) override { 11663 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11664 } 11665 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11666 QualType T, 11667 QualType ConvTy) override { 11668 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11669 } 11670 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11671 QualType ConvTy) override { 11672 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11673 << ConvTy->isEnumeralType() << ConvTy; 11674 } 11675 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11676 QualType T) override { 11677 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11678 } 11679 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11680 QualType ConvTy) override { 11681 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11682 << ConvTy->isEnumeralType() << ConvTy; 11683 } 11684 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11685 QualType) override { 11686 llvm_unreachable("conversion functions are permitted"); 11687 } 11688 } ConvertDiagnoser; 11689 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11690 } 11691 11692 static bool 11693 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11694 bool StrictlyPositive, bool BuildCapture = false, 11695 OpenMPDirectiveKind DKind = OMPD_unknown, 11696 OpenMPDirectiveKind *CaptureRegion = nullptr, 11697 Stmt **HelperValStmt = nullptr) { 11698 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11699 !ValExpr->isInstantiationDependent()) { 11700 SourceLocation Loc = ValExpr->getExprLoc(); 11701 ExprResult Value = 11702 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11703 if (Value.isInvalid()) 11704 return false; 11705 11706 ValExpr = Value.get(); 11707 // The expression must evaluate to a non-negative integer value. 11708 llvm::APSInt Result; 11709 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11710 Result.isSigned() && 11711 !((!StrictlyPositive && Result.isNonNegative()) || 11712 (StrictlyPositive && Result.isStrictlyPositive()))) { 11713 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11714 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11715 << ValExpr->getSourceRange(); 11716 return false; 11717 } 11718 if (!BuildCapture) 11719 return true; 11720 *CaptureRegion = 11721 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 11722 if (*CaptureRegion != OMPD_unknown && 11723 !SemaRef.CurContext->isDependentContext()) { 11724 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11725 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11726 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11727 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11728 } 11729 } 11730 return true; 11731 } 11732 11733 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11734 SourceLocation StartLoc, 11735 SourceLocation LParenLoc, 11736 SourceLocation EndLoc) { 11737 Expr *ValExpr = NumThreads; 11738 Stmt *HelperValStmt = nullptr; 11739 11740 // OpenMP [2.5, Restrictions] 11741 // The num_threads expression must evaluate to a positive integer value. 11742 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11743 /*StrictlyPositive=*/true)) 11744 return nullptr; 11745 11746 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11747 OpenMPDirectiveKind CaptureRegion = 11748 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 11749 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11750 ValExpr = MakeFullExpr(ValExpr).get(); 11751 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11752 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11753 HelperValStmt = buildPreInits(Context, Captures); 11754 } 11755 11756 return new (Context) OMPNumThreadsClause( 11757 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11758 } 11759 11760 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11761 OpenMPClauseKind CKind, 11762 bool StrictlyPositive) { 11763 if (!E) 11764 return ExprError(); 11765 if (E->isValueDependent() || E->isTypeDependent() || 11766 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11767 return E; 11768 llvm::APSInt Result; 11769 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11770 if (ICE.isInvalid()) 11771 return ExprError(); 11772 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11773 (!StrictlyPositive && !Result.isNonNegative())) { 11774 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11775 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11776 << E->getSourceRange(); 11777 return ExprError(); 11778 } 11779 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11780 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11781 << E->getSourceRange(); 11782 return ExprError(); 11783 } 11784 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11785 DSAStack->setAssociatedLoops(Result.getExtValue()); 11786 else if (CKind == OMPC_ordered) 11787 DSAStack->setAssociatedLoops(Result.getExtValue()); 11788 return ICE; 11789 } 11790 11791 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11792 SourceLocation LParenLoc, 11793 SourceLocation EndLoc) { 11794 // OpenMP [2.8.1, simd construct, Description] 11795 // The parameter of the safelen clause must be a constant 11796 // positive integer expression. 11797 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11798 if (Safelen.isInvalid()) 11799 return nullptr; 11800 return new (Context) 11801 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11802 } 11803 11804 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11805 SourceLocation LParenLoc, 11806 SourceLocation EndLoc) { 11807 // OpenMP [2.8.1, simd construct, Description] 11808 // The parameter of the simdlen clause must be a constant 11809 // positive integer expression. 11810 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11811 if (Simdlen.isInvalid()) 11812 return nullptr; 11813 return new (Context) 11814 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11815 } 11816 11817 /// Tries to find omp_allocator_handle_t type. 11818 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11819 DSAStackTy *Stack) { 11820 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11821 if (!OMPAllocatorHandleT.isNull()) 11822 return true; 11823 // Build the predefined allocator expressions. 11824 bool ErrorFound = false; 11825 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11826 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11827 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11828 StringRef Allocator = 11829 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11830 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11831 auto *VD = dyn_cast_or_null<ValueDecl>( 11832 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11833 if (!VD) { 11834 ErrorFound = true; 11835 break; 11836 } 11837 QualType AllocatorType = 11838 VD->getType().getNonLValueExprType(S.getASTContext()); 11839 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11840 if (!Res.isUsable()) { 11841 ErrorFound = true; 11842 break; 11843 } 11844 if (OMPAllocatorHandleT.isNull()) 11845 OMPAllocatorHandleT = AllocatorType; 11846 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11847 ErrorFound = true; 11848 break; 11849 } 11850 Stack->setAllocator(AllocatorKind, Res.get()); 11851 } 11852 if (ErrorFound) { 11853 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11854 return false; 11855 } 11856 OMPAllocatorHandleT.addConst(); 11857 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11858 return true; 11859 } 11860 11861 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11862 SourceLocation LParenLoc, 11863 SourceLocation EndLoc) { 11864 // OpenMP [2.11.3, allocate Directive, Description] 11865 // allocator is an expression of omp_allocator_handle_t type. 11866 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11867 return nullptr; 11868 11869 ExprResult Allocator = DefaultLvalueConversion(A); 11870 if (Allocator.isInvalid()) 11871 return nullptr; 11872 Allocator = PerformImplicitConversion(Allocator.get(), 11873 DSAStack->getOMPAllocatorHandleT(), 11874 Sema::AA_Initializing, 11875 /*AllowExplicit=*/true); 11876 if (Allocator.isInvalid()) 11877 return nullptr; 11878 return new (Context) 11879 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11880 } 11881 11882 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11883 SourceLocation StartLoc, 11884 SourceLocation LParenLoc, 11885 SourceLocation EndLoc) { 11886 // OpenMP [2.7.1, loop construct, Description] 11887 // OpenMP [2.8.1, simd construct, Description] 11888 // OpenMP [2.9.6, distribute construct, Description] 11889 // The parameter of the collapse clause must be a constant 11890 // positive integer expression. 11891 ExprResult NumForLoopsResult = 11892 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11893 if (NumForLoopsResult.isInvalid()) 11894 return nullptr; 11895 return new (Context) 11896 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11897 } 11898 11899 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11900 SourceLocation EndLoc, 11901 SourceLocation LParenLoc, 11902 Expr *NumForLoops) { 11903 // OpenMP [2.7.1, loop construct, Description] 11904 // OpenMP [2.8.1, simd construct, Description] 11905 // OpenMP [2.9.6, distribute construct, Description] 11906 // The parameter of the ordered clause must be a constant 11907 // positive integer expression if any. 11908 if (NumForLoops && LParenLoc.isValid()) { 11909 ExprResult NumForLoopsResult = 11910 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11911 if (NumForLoopsResult.isInvalid()) 11912 return nullptr; 11913 NumForLoops = NumForLoopsResult.get(); 11914 } else { 11915 NumForLoops = nullptr; 11916 } 11917 auto *Clause = OMPOrderedClause::Create( 11918 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11919 StartLoc, LParenLoc, EndLoc); 11920 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11921 return Clause; 11922 } 11923 11924 OMPClause *Sema::ActOnOpenMPSimpleClause( 11925 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11926 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11927 OMPClause *Res = nullptr; 11928 switch (Kind) { 11929 case OMPC_default: 11930 Res = 11931 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11932 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11933 break; 11934 case OMPC_proc_bind: 11935 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 11936 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11937 break; 11938 case OMPC_atomic_default_mem_order: 11939 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11940 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11941 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11942 break; 11943 case OMPC_order: 11944 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 11945 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11946 break; 11947 case OMPC_if: 11948 case OMPC_final: 11949 case OMPC_num_threads: 11950 case OMPC_safelen: 11951 case OMPC_simdlen: 11952 case OMPC_allocator: 11953 case OMPC_collapse: 11954 case OMPC_schedule: 11955 case OMPC_private: 11956 case OMPC_firstprivate: 11957 case OMPC_lastprivate: 11958 case OMPC_shared: 11959 case OMPC_reduction: 11960 case OMPC_task_reduction: 11961 case OMPC_in_reduction: 11962 case OMPC_linear: 11963 case OMPC_aligned: 11964 case OMPC_copyin: 11965 case OMPC_copyprivate: 11966 case OMPC_ordered: 11967 case OMPC_nowait: 11968 case OMPC_untied: 11969 case OMPC_mergeable: 11970 case OMPC_threadprivate: 11971 case OMPC_allocate: 11972 case OMPC_flush: 11973 case OMPC_read: 11974 case OMPC_write: 11975 case OMPC_update: 11976 case OMPC_capture: 11977 case OMPC_seq_cst: 11978 case OMPC_depend: 11979 case OMPC_device: 11980 case OMPC_threads: 11981 case OMPC_simd: 11982 case OMPC_map: 11983 case OMPC_num_teams: 11984 case OMPC_thread_limit: 11985 case OMPC_priority: 11986 case OMPC_grainsize: 11987 case OMPC_nogroup: 11988 case OMPC_num_tasks: 11989 case OMPC_hint: 11990 case OMPC_dist_schedule: 11991 case OMPC_defaultmap: 11992 case OMPC_unknown: 11993 case OMPC_uniform: 11994 case OMPC_to: 11995 case OMPC_from: 11996 case OMPC_use_device_ptr: 11997 case OMPC_is_device_ptr: 11998 case OMPC_unified_address: 11999 case OMPC_unified_shared_memory: 12000 case OMPC_reverse_offload: 12001 case OMPC_dynamic_allocators: 12002 case OMPC_device_type: 12003 case OMPC_match: 12004 case OMPC_nontemporal: 12005 llvm_unreachable("Clause is not allowed."); 12006 } 12007 return Res; 12008 } 12009 12010 static std::string 12011 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12012 ArrayRef<unsigned> Exclude = llvm::None) { 12013 SmallString<256> Buffer; 12014 llvm::raw_svector_ostream Out(Buffer); 12015 unsigned Skipped = Exclude.size(); 12016 auto S = Exclude.begin(), E = Exclude.end(); 12017 for (unsigned I = First; I < Last; ++I) { 12018 if (std::find(S, E, I) != E) { 12019 --Skipped; 12020 continue; 12021 } 12022 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12023 if (I + Skipped + 2 == Last) 12024 Out << " or "; 12025 else if (I + Skipped + 1 != Last) 12026 Out << ", "; 12027 } 12028 return std::string(Out.str()); 12029 } 12030 12031 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 12032 SourceLocation KindKwLoc, 12033 SourceLocation StartLoc, 12034 SourceLocation LParenLoc, 12035 SourceLocation EndLoc) { 12036 if (Kind == OMPC_DEFAULT_unknown) { 12037 static_assert(OMPC_DEFAULT_unknown > 0, 12038 "OMPC_DEFAULT_unknown not greater than 0"); 12039 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12040 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12041 /*Last=*/OMPC_DEFAULT_unknown) 12042 << getOpenMPClauseName(OMPC_default); 12043 return nullptr; 12044 } 12045 switch (Kind) { 12046 case OMPC_DEFAULT_none: 12047 DSAStack->setDefaultDSANone(KindKwLoc); 12048 break; 12049 case OMPC_DEFAULT_shared: 12050 DSAStack->setDefaultDSAShared(KindKwLoc); 12051 break; 12052 case OMPC_DEFAULT_unknown: 12053 llvm_unreachable("Clause kind is not allowed."); 12054 break; 12055 } 12056 return new (Context) 12057 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12058 } 12059 12060 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12061 SourceLocation KindKwLoc, 12062 SourceLocation StartLoc, 12063 SourceLocation LParenLoc, 12064 SourceLocation EndLoc) { 12065 if (Kind == OMP_PROC_BIND_unknown) { 12066 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12067 << getListOfPossibleValues(OMPC_proc_bind, 12068 /*First=*/unsigned(OMP_PROC_BIND_master), 12069 /*Last=*/5) 12070 << getOpenMPClauseName(OMPC_proc_bind); 12071 return nullptr; 12072 } 12073 return new (Context) 12074 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12075 } 12076 12077 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12078 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12079 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12080 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12081 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12082 << getListOfPossibleValues( 12083 OMPC_atomic_default_mem_order, /*First=*/0, 12084 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12085 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12086 return nullptr; 12087 } 12088 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12089 LParenLoc, EndLoc); 12090 } 12091 12092 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12093 SourceLocation KindKwLoc, 12094 SourceLocation StartLoc, 12095 SourceLocation LParenLoc, 12096 SourceLocation EndLoc) { 12097 if (Kind == OMPC_ORDER_unknown) { 12098 static_assert(OMPC_ORDER_unknown > 0, 12099 "OMPC_ORDER_unknown not greater than 0"); 12100 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12101 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12102 /*Last=*/OMPC_ORDER_unknown) 12103 << getOpenMPClauseName(OMPC_order); 12104 return nullptr; 12105 } 12106 return new (Context) 12107 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12108 } 12109 12110 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12111 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12112 SourceLocation StartLoc, SourceLocation LParenLoc, 12113 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12114 SourceLocation EndLoc) { 12115 OMPClause *Res = nullptr; 12116 switch (Kind) { 12117 case OMPC_schedule: 12118 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12119 assert(Argument.size() == NumberOfElements && 12120 ArgumentLoc.size() == NumberOfElements); 12121 Res = ActOnOpenMPScheduleClause( 12122 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12123 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12124 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12125 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12126 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12127 break; 12128 case OMPC_if: 12129 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12130 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12131 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12132 DelimLoc, EndLoc); 12133 break; 12134 case OMPC_dist_schedule: 12135 Res = ActOnOpenMPDistScheduleClause( 12136 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12137 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12138 break; 12139 case OMPC_defaultmap: 12140 enum { Modifier, DefaultmapKind }; 12141 Res = ActOnOpenMPDefaultmapClause( 12142 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12143 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12144 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12145 EndLoc); 12146 break; 12147 case OMPC_final: 12148 case OMPC_num_threads: 12149 case OMPC_safelen: 12150 case OMPC_simdlen: 12151 case OMPC_allocator: 12152 case OMPC_collapse: 12153 case OMPC_default: 12154 case OMPC_proc_bind: 12155 case OMPC_private: 12156 case OMPC_firstprivate: 12157 case OMPC_lastprivate: 12158 case OMPC_shared: 12159 case OMPC_reduction: 12160 case OMPC_task_reduction: 12161 case OMPC_in_reduction: 12162 case OMPC_linear: 12163 case OMPC_aligned: 12164 case OMPC_copyin: 12165 case OMPC_copyprivate: 12166 case OMPC_ordered: 12167 case OMPC_nowait: 12168 case OMPC_untied: 12169 case OMPC_mergeable: 12170 case OMPC_threadprivate: 12171 case OMPC_allocate: 12172 case OMPC_flush: 12173 case OMPC_read: 12174 case OMPC_write: 12175 case OMPC_update: 12176 case OMPC_capture: 12177 case OMPC_seq_cst: 12178 case OMPC_depend: 12179 case OMPC_device: 12180 case OMPC_threads: 12181 case OMPC_simd: 12182 case OMPC_map: 12183 case OMPC_num_teams: 12184 case OMPC_thread_limit: 12185 case OMPC_priority: 12186 case OMPC_grainsize: 12187 case OMPC_nogroup: 12188 case OMPC_num_tasks: 12189 case OMPC_hint: 12190 case OMPC_unknown: 12191 case OMPC_uniform: 12192 case OMPC_to: 12193 case OMPC_from: 12194 case OMPC_use_device_ptr: 12195 case OMPC_is_device_ptr: 12196 case OMPC_unified_address: 12197 case OMPC_unified_shared_memory: 12198 case OMPC_reverse_offload: 12199 case OMPC_dynamic_allocators: 12200 case OMPC_atomic_default_mem_order: 12201 case OMPC_device_type: 12202 case OMPC_match: 12203 case OMPC_nontemporal: 12204 case OMPC_order: 12205 llvm_unreachable("Clause is not allowed."); 12206 } 12207 return Res; 12208 } 12209 12210 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12211 OpenMPScheduleClauseModifier M2, 12212 SourceLocation M1Loc, SourceLocation M2Loc) { 12213 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12214 SmallVector<unsigned, 2> Excluded; 12215 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12216 Excluded.push_back(M2); 12217 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12218 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12219 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12220 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12221 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12222 << getListOfPossibleValues(OMPC_schedule, 12223 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12224 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12225 Excluded) 12226 << getOpenMPClauseName(OMPC_schedule); 12227 return true; 12228 } 12229 return false; 12230 } 12231 12232 OMPClause *Sema::ActOnOpenMPScheduleClause( 12233 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12234 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12235 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12236 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12237 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12238 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12239 return nullptr; 12240 // OpenMP, 2.7.1, Loop Construct, Restrictions 12241 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12242 // but not both. 12243 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12244 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12245 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12246 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12247 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12248 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12249 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12250 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12251 return nullptr; 12252 } 12253 if (Kind == OMPC_SCHEDULE_unknown) { 12254 std::string Values; 12255 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12256 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12257 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12258 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12259 Exclude); 12260 } else { 12261 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12262 /*Last=*/OMPC_SCHEDULE_unknown); 12263 } 12264 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12265 << Values << getOpenMPClauseName(OMPC_schedule); 12266 return nullptr; 12267 } 12268 // OpenMP, 2.7.1, Loop Construct, Restrictions 12269 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12270 // schedule(guided). 12271 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12272 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12273 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12274 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12275 diag::err_omp_schedule_nonmonotonic_static); 12276 return nullptr; 12277 } 12278 Expr *ValExpr = ChunkSize; 12279 Stmt *HelperValStmt = nullptr; 12280 if (ChunkSize) { 12281 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12282 !ChunkSize->isInstantiationDependent() && 12283 !ChunkSize->containsUnexpandedParameterPack()) { 12284 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12285 ExprResult Val = 12286 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12287 if (Val.isInvalid()) 12288 return nullptr; 12289 12290 ValExpr = Val.get(); 12291 12292 // OpenMP [2.7.1, Restrictions] 12293 // chunk_size must be a loop invariant integer expression with a positive 12294 // value. 12295 llvm::APSInt Result; 12296 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12297 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12298 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12299 << "schedule" << 1 << ChunkSize->getSourceRange(); 12300 return nullptr; 12301 } 12302 } else if (getOpenMPCaptureRegionForClause( 12303 DSAStack->getCurrentDirective(), OMPC_schedule, 12304 LangOpts.OpenMP) != OMPD_unknown && 12305 !CurContext->isDependentContext()) { 12306 ValExpr = MakeFullExpr(ValExpr).get(); 12307 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12308 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12309 HelperValStmt = buildPreInits(Context, Captures); 12310 } 12311 } 12312 } 12313 12314 return new (Context) 12315 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12316 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12317 } 12318 12319 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12320 SourceLocation StartLoc, 12321 SourceLocation EndLoc) { 12322 OMPClause *Res = nullptr; 12323 switch (Kind) { 12324 case OMPC_ordered: 12325 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12326 break; 12327 case OMPC_nowait: 12328 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12329 break; 12330 case OMPC_untied: 12331 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12332 break; 12333 case OMPC_mergeable: 12334 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12335 break; 12336 case OMPC_read: 12337 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12338 break; 12339 case OMPC_write: 12340 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12341 break; 12342 case OMPC_update: 12343 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12344 break; 12345 case OMPC_capture: 12346 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12347 break; 12348 case OMPC_seq_cst: 12349 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12350 break; 12351 case OMPC_threads: 12352 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12353 break; 12354 case OMPC_simd: 12355 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12356 break; 12357 case OMPC_nogroup: 12358 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12359 break; 12360 case OMPC_unified_address: 12361 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12362 break; 12363 case OMPC_unified_shared_memory: 12364 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12365 break; 12366 case OMPC_reverse_offload: 12367 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12368 break; 12369 case OMPC_dynamic_allocators: 12370 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12371 break; 12372 case OMPC_if: 12373 case OMPC_final: 12374 case OMPC_num_threads: 12375 case OMPC_safelen: 12376 case OMPC_simdlen: 12377 case OMPC_allocator: 12378 case OMPC_collapse: 12379 case OMPC_schedule: 12380 case OMPC_private: 12381 case OMPC_firstprivate: 12382 case OMPC_lastprivate: 12383 case OMPC_shared: 12384 case OMPC_reduction: 12385 case OMPC_task_reduction: 12386 case OMPC_in_reduction: 12387 case OMPC_linear: 12388 case OMPC_aligned: 12389 case OMPC_copyin: 12390 case OMPC_copyprivate: 12391 case OMPC_default: 12392 case OMPC_proc_bind: 12393 case OMPC_threadprivate: 12394 case OMPC_allocate: 12395 case OMPC_flush: 12396 case OMPC_depend: 12397 case OMPC_device: 12398 case OMPC_map: 12399 case OMPC_num_teams: 12400 case OMPC_thread_limit: 12401 case OMPC_priority: 12402 case OMPC_grainsize: 12403 case OMPC_num_tasks: 12404 case OMPC_hint: 12405 case OMPC_dist_schedule: 12406 case OMPC_defaultmap: 12407 case OMPC_unknown: 12408 case OMPC_uniform: 12409 case OMPC_to: 12410 case OMPC_from: 12411 case OMPC_use_device_ptr: 12412 case OMPC_is_device_ptr: 12413 case OMPC_atomic_default_mem_order: 12414 case OMPC_device_type: 12415 case OMPC_match: 12416 case OMPC_nontemporal: 12417 case OMPC_order: 12418 llvm_unreachable("Clause is not allowed."); 12419 } 12420 return Res; 12421 } 12422 12423 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12424 SourceLocation EndLoc) { 12425 DSAStack->setNowaitRegion(); 12426 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12427 } 12428 12429 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12430 SourceLocation EndLoc) { 12431 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12432 } 12433 12434 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12435 SourceLocation EndLoc) { 12436 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12437 } 12438 12439 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12440 SourceLocation EndLoc) { 12441 return new (Context) OMPReadClause(StartLoc, EndLoc); 12442 } 12443 12444 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12445 SourceLocation EndLoc) { 12446 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12447 } 12448 12449 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12450 SourceLocation EndLoc) { 12451 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 12452 } 12453 12454 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12455 SourceLocation EndLoc) { 12456 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12457 } 12458 12459 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12460 SourceLocation EndLoc) { 12461 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12462 } 12463 12464 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 12465 SourceLocation EndLoc) { 12466 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 12467 } 12468 12469 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 12470 SourceLocation EndLoc) { 12471 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 12472 } 12473 12474 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 12475 SourceLocation EndLoc) { 12476 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 12477 } 12478 12479 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 12480 SourceLocation EndLoc) { 12481 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 12482 } 12483 12484 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 12485 SourceLocation EndLoc) { 12486 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12487 } 12488 12489 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 12490 SourceLocation EndLoc) { 12491 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 12492 } 12493 12494 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 12495 SourceLocation EndLoc) { 12496 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 12497 } 12498 12499 OMPClause *Sema::ActOnOpenMPVarListClause( 12500 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12501 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12502 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12503 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 12504 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12505 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 12506 SourceLocation DepLinMapLastLoc) { 12507 SourceLocation StartLoc = Locs.StartLoc; 12508 SourceLocation LParenLoc = Locs.LParenLoc; 12509 SourceLocation EndLoc = Locs.EndLoc; 12510 OMPClause *Res = nullptr; 12511 switch (Kind) { 12512 case OMPC_private: 12513 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12514 break; 12515 case OMPC_firstprivate: 12516 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12517 break; 12518 case OMPC_lastprivate: 12519 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 12520 "Unexpected lastprivate modifier."); 12521 Res = ActOnOpenMPLastprivateClause( 12522 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 12523 DepLinMapLastLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 12524 break; 12525 case OMPC_shared: 12526 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12527 break; 12528 case OMPC_reduction: 12529 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12530 EndLoc, ReductionOrMapperIdScopeSpec, 12531 ReductionOrMapperId); 12532 break; 12533 case OMPC_task_reduction: 12534 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12535 EndLoc, ReductionOrMapperIdScopeSpec, 12536 ReductionOrMapperId); 12537 break; 12538 case OMPC_in_reduction: 12539 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12540 EndLoc, ReductionOrMapperIdScopeSpec, 12541 ReductionOrMapperId); 12542 break; 12543 case OMPC_linear: 12544 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 12545 "Unexpected linear modifier."); 12546 Res = ActOnOpenMPLinearClause( 12547 VarList, TailExpr, StartLoc, LParenLoc, 12548 static_cast<OpenMPLinearClauseKind>(ExtraModifier), DepLinMapLastLoc, 12549 ColonLoc, EndLoc); 12550 break; 12551 case OMPC_aligned: 12552 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12553 ColonLoc, EndLoc); 12554 break; 12555 case OMPC_copyin: 12556 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12557 break; 12558 case OMPC_copyprivate: 12559 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12560 break; 12561 case OMPC_flush: 12562 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12563 break; 12564 case OMPC_depend: 12565 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 12566 "Unexpected depend modifier."); 12567 Res = ActOnOpenMPDependClause( 12568 static_cast<OpenMPDependClauseKind>(ExtraModifier), DepLinMapLastLoc, 12569 ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 12570 break; 12571 case OMPC_map: 12572 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 12573 "Unexpected map modifier."); 12574 Res = ActOnOpenMPMapClause( 12575 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 12576 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 12577 IsMapTypeImplicit, DepLinMapLastLoc, ColonLoc, VarList, Locs); 12578 break; 12579 case OMPC_to: 12580 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12581 ReductionOrMapperId, Locs); 12582 break; 12583 case OMPC_from: 12584 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12585 ReductionOrMapperId, Locs); 12586 break; 12587 case OMPC_use_device_ptr: 12588 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12589 break; 12590 case OMPC_is_device_ptr: 12591 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12592 break; 12593 case OMPC_allocate: 12594 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12595 ColonLoc, EndLoc); 12596 break; 12597 case OMPC_nontemporal: 12598 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 12599 break; 12600 case OMPC_if: 12601 case OMPC_final: 12602 case OMPC_num_threads: 12603 case OMPC_safelen: 12604 case OMPC_simdlen: 12605 case OMPC_allocator: 12606 case OMPC_collapse: 12607 case OMPC_default: 12608 case OMPC_proc_bind: 12609 case OMPC_schedule: 12610 case OMPC_ordered: 12611 case OMPC_nowait: 12612 case OMPC_untied: 12613 case OMPC_mergeable: 12614 case OMPC_threadprivate: 12615 case OMPC_read: 12616 case OMPC_write: 12617 case OMPC_update: 12618 case OMPC_capture: 12619 case OMPC_seq_cst: 12620 case OMPC_device: 12621 case OMPC_threads: 12622 case OMPC_simd: 12623 case OMPC_num_teams: 12624 case OMPC_thread_limit: 12625 case OMPC_priority: 12626 case OMPC_grainsize: 12627 case OMPC_nogroup: 12628 case OMPC_num_tasks: 12629 case OMPC_hint: 12630 case OMPC_dist_schedule: 12631 case OMPC_defaultmap: 12632 case OMPC_unknown: 12633 case OMPC_uniform: 12634 case OMPC_unified_address: 12635 case OMPC_unified_shared_memory: 12636 case OMPC_reverse_offload: 12637 case OMPC_dynamic_allocators: 12638 case OMPC_atomic_default_mem_order: 12639 case OMPC_device_type: 12640 case OMPC_match: 12641 case OMPC_order: 12642 llvm_unreachable("Clause is not allowed."); 12643 } 12644 return Res; 12645 } 12646 12647 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12648 ExprObjectKind OK, SourceLocation Loc) { 12649 ExprResult Res = BuildDeclRefExpr( 12650 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12651 if (!Res.isUsable()) 12652 return ExprError(); 12653 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12654 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12655 if (!Res.isUsable()) 12656 return ExprError(); 12657 } 12658 if (VK != VK_LValue && Res.get()->isGLValue()) { 12659 Res = DefaultLvalueConversion(Res.get()); 12660 if (!Res.isUsable()) 12661 return ExprError(); 12662 } 12663 return Res; 12664 } 12665 12666 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12667 SourceLocation StartLoc, 12668 SourceLocation LParenLoc, 12669 SourceLocation EndLoc) { 12670 SmallVector<Expr *, 8> Vars; 12671 SmallVector<Expr *, 8> PrivateCopies; 12672 for (Expr *RefExpr : VarList) { 12673 assert(RefExpr && "NULL expr in OpenMP private clause."); 12674 SourceLocation ELoc; 12675 SourceRange ERange; 12676 Expr *SimpleRefExpr = RefExpr; 12677 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12678 if (Res.second) { 12679 // It will be analyzed later. 12680 Vars.push_back(RefExpr); 12681 PrivateCopies.push_back(nullptr); 12682 } 12683 ValueDecl *D = Res.first; 12684 if (!D) 12685 continue; 12686 12687 QualType Type = D->getType(); 12688 auto *VD = dyn_cast<VarDecl>(D); 12689 12690 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12691 // A variable that appears in a private clause must not have an incomplete 12692 // type or a reference type. 12693 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12694 continue; 12695 Type = Type.getNonReferenceType(); 12696 12697 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12698 // A variable that is privatized must not have a const-qualified type 12699 // unless it is of class type with a mutable member. This restriction does 12700 // not apply to the firstprivate clause. 12701 // 12702 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12703 // A variable that appears in a private clause must not have a 12704 // const-qualified type unless it is of class type with a mutable member. 12705 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12706 continue; 12707 12708 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12709 // in a Construct] 12710 // Variables with the predetermined data-sharing attributes may not be 12711 // listed in data-sharing attributes clauses, except for the cases 12712 // listed below. For these exceptions only, listing a predetermined 12713 // variable in a data-sharing attribute clause is allowed and overrides 12714 // the variable's predetermined data-sharing attributes. 12715 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12716 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12717 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12718 << getOpenMPClauseName(OMPC_private); 12719 reportOriginalDsa(*this, DSAStack, D, DVar); 12720 continue; 12721 } 12722 12723 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12724 // Variably modified types are not supported for tasks. 12725 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12726 isOpenMPTaskingDirective(CurrDir)) { 12727 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12728 << getOpenMPClauseName(OMPC_private) << Type 12729 << getOpenMPDirectiveName(CurrDir); 12730 bool IsDecl = 12731 !VD || 12732 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12733 Diag(D->getLocation(), 12734 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12735 << D; 12736 continue; 12737 } 12738 12739 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12740 // A list item cannot appear in both a map clause and a data-sharing 12741 // attribute clause on the same construct 12742 // 12743 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12744 // A list item cannot appear in both a map clause and a data-sharing 12745 // attribute clause on the same construct unless the construct is a 12746 // combined construct. 12747 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12748 CurrDir == OMPD_target) { 12749 OpenMPClauseKind ConflictKind; 12750 if (DSAStack->checkMappableExprComponentListsForDecl( 12751 VD, /*CurrentRegionOnly=*/true, 12752 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12753 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12754 ConflictKind = WhereFoundClauseKind; 12755 return true; 12756 })) { 12757 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12758 << getOpenMPClauseName(OMPC_private) 12759 << getOpenMPClauseName(ConflictKind) 12760 << getOpenMPDirectiveName(CurrDir); 12761 reportOriginalDsa(*this, DSAStack, D, DVar); 12762 continue; 12763 } 12764 } 12765 12766 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12767 // A variable of class type (or array thereof) that appears in a private 12768 // clause requires an accessible, unambiguous default constructor for the 12769 // class type. 12770 // Generate helper private variable and initialize it with the default 12771 // value. The address of the original variable is replaced by the address of 12772 // the new private variable in CodeGen. This new variable is not added to 12773 // IdResolver, so the code in the OpenMP region uses original variable for 12774 // proper diagnostics. 12775 Type = Type.getUnqualifiedType(); 12776 VarDecl *VDPrivate = 12777 buildVarDecl(*this, ELoc, Type, D->getName(), 12778 D->hasAttrs() ? &D->getAttrs() : nullptr, 12779 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12780 ActOnUninitializedDecl(VDPrivate); 12781 if (VDPrivate->isInvalidDecl()) 12782 continue; 12783 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12784 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12785 12786 DeclRefExpr *Ref = nullptr; 12787 if (!VD && !CurContext->isDependentContext()) 12788 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12789 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12790 Vars.push_back((VD || CurContext->isDependentContext()) 12791 ? RefExpr->IgnoreParens() 12792 : Ref); 12793 PrivateCopies.push_back(VDPrivateRefExpr); 12794 } 12795 12796 if (Vars.empty()) 12797 return nullptr; 12798 12799 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12800 PrivateCopies); 12801 } 12802 12803 namespace { 12804 class DiagsUninitializedSeveretyRAII { 12805 private: 12806 DiagnosticsEngine &Diags; 12807 SourceLocation SavedLoc; 12808 bool IsIgnored = false; 12809 12810 public: 12811 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12812 bool IsIgnored) 12813 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12814 if (!IsIgnored) { 12815 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12816 /*Map*/ diag::Severity::Ignored, Loc); 12817 } 12818 } 12819 ~DiagsUninitializedSeveretyRAII() { 12820 if (!IsIgnored) 12821 Diags.popMappings(SavedLoc); 12822 } 12823 }; 12824 } 12825 12826 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12827 SourceLocation StartLoc, 12828 SourceLocation LParenLoc, 12829 SourceLocation EndLoc) { 12830 SmallVector<Expr *, 8> Vars; 12831 SmallVector<Expr *, 8> PrivateCopies; 12832 SmallVector<Expr *, 8> Inits; 12833 SmallVector<Decl *, 4> ExprCaptures; 12834 bool IsImplicitClause = 12835 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12836 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12837 12838 for (Expr *RefExpr : VarList) { 12839 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12840 SourceLocation ELoc; 12841 SourceRange ERange; 12842 Expr *SimpleRefExpr = RefExpr; 12843 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12844 if (Res.second) { 12845 // It will be analyzed later. 12846 Vars.push_back(RefExpr); 12847 PrivateCopies.push_back(nullptr); 12848 Inits.push_back(nullptr); 12849 } 12850 ValueDecl *D = Res.first; 12851 if (!D) 12852 continue; 12853 12854 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12855 QualType Type = D->getType(); 12856 auto *VD = dyn_cast<VarDecl>(D); 12857 12858 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12859 // A variable that appears in a private clause must not have an incomplete 12860 // type or a reference type. 12861 if (RequireCompleteType(ELoc, Type, 12862 diag::err_omp_firstprivate_incomplete_type)) 12863 continue; 12864 Type = Type.getNonReferenceType(); 12865 12866 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12867 // A variable of class type (or array thereof) that appears in a private 12868 // clause requires an accessible, unambiguous copy constructor for the 12869 // class type. 12870 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12871 12872 // If an implicit firstprivate variable found it was checked already. 12873 DSAStackTy::DSAVarData TopDVar; 12874 if (!IsImplicitClause) { 12875 DSAStackTy::DSAVarData DVar = 12876 DSAStack->getTopDSA(D, /*FromParent=*/false); 12877 TopDVar = DVar; 12878 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12879 bool IsConstant = ElemType.isConstant(Context); 12880 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12881 // A list item that specifies a given variable may not appear in more 12882 // than one clause on the same directive, except that a variable may be 12883 // specified in both firstprivate and lastprivate clauses. 12884 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12885 // A list item may appear in a firstprivate or lastprivate clause but not 12886 // both. 12887 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12888 (isOpenMPDistributeDirective(CurrDir) || 12889 DVar.CKind != OMPC_lastprivate) && 12890 DVar.RefExpr) { 12891 Diag(ELoc, diag::err_omp_wrong_dsa) 12892 << getOpenMPClauseName(DVar.CKind) 12893 << getOpenMPClauseName(OMPC_firstprivate); 12894 reportOriginalDsa(*this, DSAStack, D, DVar); 12895 continue; 12896 } 12897 12898 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12899 // in a Construct] 12900 // Variables with the predetermined data-sharing attributes may not be 12901 // listed in data-sharing attributes clauses, except for the cases 12902 // listed below. For these exceptions only, listing a predetermined 12903 // variable in a data-sharing attribute clause is allowed and overrides 12904 // the variable's predetermined data-sharing attributes. 12905 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12906 // in a Construct, C/C++, p.2] 12907 // Variables with const-qualified type having no mutable member may be 12908 // listed in a firstprivate clause, even if they are static data members. 12909 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12910 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12911 Diag(ELoc, diag::err_omp_wrong_dsa) 12912 << getOpenMPClauseName(DVar.CKind) 12913 << getOpenMPClauseName(OMPC_firstprivate); 12914 reportOriginalDsa(*this, DSAStack, D, DVar); 12915 continue; 12916 } 12917 12918 // OpenMP [2.9.3.4, Restrictions, p.2] 12919 // A list item that is private within a parallel region must not appear 12920 // in a firstprivate clause on a worksharing construct if any of the 12921 // worksharing regions arising from the worksharing construct ever bind 12922 // to any of the parallel regions arising from the parallel construct. 12923 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12924 // A list item that is private within a teams region must not appear in a 12925 // firstprivate clause on a distribute construct if any of the distribute 12926 // regions arising from the distribute construct ever bind to any of the 12927 // teams regions arising from the teams construct. 12928 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12929 // A list item that appears in a reduction clause of a teams construct 12930 // must not appear in a firstprivate clause on a distribute construct if 12931 // any of the distribute regions arising from the distribute construct 12932 // ever bind to any of the teams regions arising from the teams construct. 12933 if ((isOpenMPWorksharingDirective(CurrDir) || 12934 isOpenMPDistributeDirective(CurrDir)) && 12935 !isOpenMPParallelDirective(CurrDir) && 12936 !isOpenMPTeamsDirective(CurrDir)) { 12937 DVar = DSAStack->getImplicitDSA(D, true); 12938 if (DVar.CKind != OMPC_shared && 12939 (isOpenMPParallelDirective(DVar.DKind) || 12940 isOpenMPTeamsDirective(DVar.DKind) || 12941 DVar.DKind == OMPD_unknown)) { 12942 Diag(ELoc, diag::err_omp_required_access) 12943 << getOpenMPClauseName(OMPC_firstprivate) 12944 << getOpenMPClauseName(OMPC_shared); 12945 reportOriginalDsa(*this, DSAStack, D, DVar); 12946 continue; 12947 } 12948 } 12949 // OpenMP [2.9.3.4, Restrictions, p.3] 12950 // A list item that appears in a reduction clause of a parallel construct 12951 // must not appear in a firstprivate clause on a worksharing or task 12952 // construct if any of the worksharing or task regions arising from the 12953 // worksharing or task construct ever bind to any of the parallel regions 12954 // arising from the parallel construct. 12955 // OpenMP [2.9.3.4, Restrictions, p.4] 12956 // A list item that appears in a reduction clause in worksharing 12957 // construct must not appear in a firstprivate clause in a task construct 12958 // encountered during execution of any of the worksharing regions arising 12959 // from the worksharing construct. 12960 if (isOpenMPTaskingDirective(CurrDir)) { 12961 DVar = DSAStack->hasInnermostDSA( 12962 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12963 [](OpenMPDirectiveKind K) { 12964 return isOpenMPParallelDirective(K) || 12965 isOpenMPWorksharingDirective(K) || 12966 isOpenMPTeamsDirective(K); 12967 }, 12968 /*FromParent=*/true); 12969 if (DVar.CKind == OMPC_reduction && 12970 (isOpenMPParallelDirective(DVar.DKind) || 12971 isOpenMPWorksharingDirective(DVar.DKind) || 12972 isOpenMPTeamsDirective(DVar.DKind))) { 12973 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12974 << getOpenMPDirectiveName(DVar.DKind); 12975 reportOriginalDsa(*this, DSAStack, D, DVar); 12976 continue; 12977 } 12978 } 12979 12980 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12981 // A list item cannot appear in both a map clause and a data-sharing 12982 // attribute clause on the same construct 12983 // 12984 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12985 // A list item cannot appear in both a map clause and a data-sharing 12986 // attribute clause on the same construct unless the construct is a 12987 // combined construct. 12988 if ((LangOpts.OpenMP <= 45 && 12989 isOpenMPTargetExecutionDirective(CurrDir)) || 12990 CurrDir == OMPD_target) { 12991 OpenMPClauseKind ConflictKind; 12992 if (DSAStack->checkMappableExprComponentListsForDecl( 12993 VD, /*CurrentRegionOnly=*/true, 12994 [&ConflictKind]( 12995 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12996 OpenMPClauseKind WhereFoundClauseKind) { 12997 ConflictKind = WhereFoundClauseKind; 12998 return true; 12999 })) { 13000 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13001 << getOpenMPClauseName(OMPC_firstprivate) 13002 << getOpenMPClauseName(ConflictKind) 13003 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13004 reportOriginalDsa(*this, DSAStack, D, DVar); 13005 continue; 13006 } 13007 } 13008 } 13009 13010 // Variably modified types are not supported for tasks. 13011 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13012 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13013 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13014 << getOpenMPClauseName(OMPC_firstprivate) << Type 13015 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13016 bool IsDecl = 13017 !VD || 13018 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13019 Diag(D->getLocation(), 13020 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13021 << D; 13022 continue; 13023 } 13024 13025 Type = Type.getUnqualifiedType(); 13026 VarDecl *VDPrivate = 13027 buildVarDecl(*this, ELoc, Type, D->getName(), 13028 D->hasAttrs() ? &D->getAttrs() : nullptr, 13029 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13030 // Generate helper private variable and initialize it with the value of the 13031 // original variable. The address of the original variable is replaced by 13032 // the address of the new private variable in the CodeGen. This new variable 13033 // is not added to IdResolver, so the code in the OpenMP region uses 13034 // original variable for proper diagnostics and variable capturing. 13035 Expr *VDInitRefExpr = nullptr; 13036 // For arrays generate initializer for single element and replace it by the 13037 // original array element in CodeGen. 13038 if (Type->isArrayType()) { 13039 VarDecl *VDInit = 13040 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13041 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13042 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13043 ElemType = ElemType.getUnqualifiedType(); 13044 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13045 ".firstprivate.temp"); 13046 InitializedEntity Entity = 13047 InitializedEntity::InitializeVariable(VDInitTemp); 13048 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13049 13050 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13051 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13052 if (Result.isInvalid()) 13053 VDPrivate->setInvalidDecl(); 13054 else 13055 VDPrivate->setInit(Result.getAs<Expr>()); 13056 // Remove temp variable declaration. 13057 Context.Deallocate(VDInitTemp); 13058 } else { 13059 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13060 ".firstprivate.temp"); 13061 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13062 RefExpr->getExprLoc()); 13063 AddInitializerToDecl(VDPrivate, 13064 DefaultLvalueConversion(VDInitRefExpr).get(), 13065 /*DirectInit=*/false); 13066 } 13067 if (VDPrivate->isInvalidDecl()) { 13068 if (IsImplicitClause) { 13069 Diag(RefExpr->getExprLoc(), 13070 diag::note_omp_task_predetermined_firstprivate_here); 13071 } 13072 continue; 13073 } 13074 CurContext->addDecl(VDPrivate); 13075 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13076 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13077 RefExpr->getExprLoc()); 13078 DeclRefExpr *Ref = nullptr; 13079 if (!VD && !CurContext->isDependentContext()) { 13080 if (TopDVar.CKind == OMPC_lastprivate) { 13081 Ref = TopDVar.PrivateCopy; 13082 } else { 13083 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13084 if (!isOpenMPCapturedDecl(D)) 13085 ExprCaptures.push_back(Ref->getDecl()); 13086 } 13087 } 13088 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13089 Vars.push_back((VD || CurContext->isDependentContext()) 13090 ? RefExpr->IgnoreParens() 13091 : Ref); 13092 PrivateCopies.push_back(VDPrivateRefExpr); 13093 Inits.push_back(VDInitRefExpr); 13094 } 13095 13096 if (Vars.empty()) 13097 return nullptr; 13098 13099 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13100 Vars, PrivateCopies, Inits, 13101 buildPreInits(Context, ExprCaptures)); 13102 } 13103 13104 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13105 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13106 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13107 SourceLocation LParenLoc, SourceLocation EndLoc) { 13108 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13109 assert(ColonLoc.isValid() && "Colon location must be valid."); 13110 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13111 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13112 /*Last=*/OMPC_LASTPRIVATE_unknown) 13113 << getOpenMPClauseName(OMPC_lastprivate); 13114 return nullptr; 13115 } 13116 13117 SmallVector<Expr *, 8> Vars; 13118 SmallVector<Expr *, 8> SrcExprs; 13119 SmallVector<Expr *, 8> DstExprs; 13120 SmallVector<Expr *, 8> AssignmentOps; 13121 SmallVector<Decl *, 4> ExprCaptures; 13122 SmallVector<Expr *, 4> ExprPostUpdates; 13123 for (Expr *RefExpr : VarList) { 13124 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13125 SourceLocation ELoc; 13126 SourceRange ERange; 13127 Expr *SimpleRefExpr = RefExpr; 13128 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13129 if (Res.second) { 13130 // It will be analyzed later. 13131 Vars.push_back(RefExpr); 13132 SrcExprs.push_back(nullptr); 13133 DstExprs.push_back(nullptr); 13134 AssignmentOps.push_back(nullptr); 13135 } 13136 ValueDecl *D = Res.first; 13137 if (!D) 13138 continue; 13139 13140 QualType Type = D->getType(); 13141 auto *VD = dyn_cast<VarDecl>(D); 13142 13143 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13144 // A variable that appears in a lastprivate clause must not have an 13145 // incomplete type or a reference type. 13146 if (RequireCompleteType(ELoc, Type, 13147 diag::err_omp_lastprivate_incomplete_type)) 13148 continue; 13149 Type = Type.getNonReferenceType(); 13150 13151 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13152 // A variable that is privatized must not have a const-qualified type 13153 // unless it is of class type with a mutable member. This restriction does 13154 // not apply to the firstprivate clause. 13155 // 13156 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13157 // A variable that appears in a lastprivate clause must not have a 13158 // const-qualified type unless it is of class type with a mutable member. 13159 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13160 continue; 13161 13162 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13163 // A list item that appears in a lastprivate clause with the conditional 13164 // modifier must be a scalar variable. 13165 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13166 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13167 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13168 VarDecl::DeclarationOnly; 13169 Diag(D->getLocation(), 13170 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13171 << D; 13172 continue; 13173 } 13174 13175 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13176 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13177 // in a Construct] 13178 // Variables with the predetermined data-sharing attributes may not be 13179 // listed in data-sharing attributes clauses, except for the cases 13180 // listed below. 13181 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13182 // A list item may appear in a firstprivate or lastprivate clause but not 13183 // both. 13184 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13185 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13186 (isOpenMPDistributeDirective(CurrDir) || 13187 DVar.CKind != OMPC_firstprivate) && 13188 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13189 Diag(ELoc, diag::err_omp_wrong_dsa) 13190 << getOpenMPClauseName(DVar.CKind) 13191 << getOpenMPClauseName(OMPC_lastprivate); 13192 reportOriginalDsa(*this, DSAStack, D, DVar); 13193 continue; 13194 } 13195 13196 // OpenMP [2.14.3.5, Restrictions, p.2] 13197 // A list item that is private within a parallel region, or that appears in 13198 // the reduction clause of a parallel construct, must not appear in a 13199 // lastprivate clause on a worksharing construct if any of the corresponding 13200 // worksharing regions ever binds to any of the corresponding parallel 13201 // regions. 13202 DSAStackTy::DSAVarData TopDVar = DVar; 13203 if (isOpenMPWorksharingDirective(CurrDir) && 13204 !isOpenMPParallelDirective(CurrDir) && 13205 !isOpenMPTeamsDirective(CurrDir)) { 13206 DVar = DSAStack->getImplicitDSA(D, true); 13207 if (DVar.CKind != OMPC_shared) { 13208 Diag(ELoc, diag::err_omp_required_access) 13209 << getOpenMPClauseName(OMPC_lastprivate) 13210 << getOpenMPClauseName(OMPC_shared); 13211 reportOriginalDsa(*this, DSAStack, D, DVar); 13212 continue; 13213 } 13214 } 13215 13216 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13217 // A variable of class type (or array thereof) that appears in a 13218 // lastprivate clause requires an accessible, unambiguous default 13219 // constructor for the class type, unless the list item is also specified 13220 // in a firstprivate clause. 13221 // A variable of class type (or array thereof) that appears in a 13222 // lastprivate clause requires an accessible, unambiguous copy assignment 13223 // operator for the class type. 13224 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13225 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13226 Type.getUnqualifiedType(), ".lastprivate.src", 13227 D->hasAttrs() ? &D->getAttrs() : nullptr); 13228 DeclRefExpr *PseudoSrcExpr = 13229 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13230 VarDecl *DstVD = 13231 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13232 D->hasAttrs() ? &D->getAttrs() : nullptr); 13233 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13234 // For arrays generate assignment operation for single element and replace 13235 // it by the original array element in CodeGen. 13236 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13237 PseudoDstExpr, PseudoSrcExpr); 13238 if (AssignmentOp.isInvalid()) 13239 continue; 13240 AssignmentOp = 13241 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13242 if (AssignmentOp.isInvalid()) 13243 continue; 13244 13245 DeclRefExpr *Ref = nullptr; 13246 if (!VD && !CurContext->isDependentContext()) { 13247 if (TopDVar.CKind == OMPC_firstprivate) { 13248 Ref = TopDVar.PrivateCopy; 13249 } else { 13250 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13251 if (!isOpenMPCapturedDecl(D)) 13252 ExprCaptures.push_back(Ref->getDecl()); 13253 } 13254 if (TopDVar.CKind == OMPC_firstprivate || 13255 (!isOpenMPCapturedDecl(D) && 13256 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13257 ExprResult RefRes = DefaultLvalueConversion(Ref); 13258 if (!RefRes.isUsable()) 13259 continue; 13260 ExprResult PostUpdateRes = 13261 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13262 RefRes.get()); 13263 if (!PostUpdateRes.isUsable()) 13264 continue; 13265 ExprPostUpdates.push_back( 13266 IgnoredValueConversions(PostUpdateRes.get()).get()); 13267 } 13268 } 13269 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13270 Vars.push_back((VD || CurContext->isDependentContext()) 13271 ? RefExpr->IgnoreParens() 13272 : Ref); 13273 SrcExprs.push_back(PseudoSrcExpr); 13274 DstExprs.push_back(PseudoDstExpr); 13275 AssignmentOps.push_back(AssignmentOp.get()); 13276 } 13277 13278 if (Vars.empty()) 13279 return nullptr; 13280 13281 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13282 Vars, SrcExprs, DstExprs, AssignmentOps, 13283 LPKind, LPKindLoc, ColonLoc, 13284 buildPreInits(Context, ExprCaptures), 13285 buildPostUpdate(*this, ExprPostUpdates)); 13286 } 13287 13288 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13289 SourceLocation StartLoc, 13290 SourceLocation LParenLoc, 13291 SourceLocation EndLoc) { 13292 SmallVector<Expr *, 8> Vars; 13293 for (Expr *RefExpr : VarList) { 13294 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13295 SourceLocation ELoc; 13296 SourceRange ERange; 13297 Expr *SimpleRefExpr = RefExpr; 13298 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13299 if (Res.second) { 13300 // It will be analyzed later. 13301 Vars.push_back(RefExpr); 13302 } 13303 ValueDecl *D = Res.first; 13304 if (!D) 13305 continue; 13306 13307 auto *VD = dyn_cast<VarDecl>(D); 13308 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13309 // in a Construct] 13310 // Variables with the predetermined data-sharing attributes may not be 13311 // listed in data-sharing attributes clauses, except for the cases 13312 // listed below. For these exceptions only, listing a predetermined 13313 // variable in a data-sharing attribute clause is allowed and overrides 13314 // the variable's predetermined data-sharing attributes. 13315 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13316 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13317 DVar.RefExpr) { 13318 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13319 << getOpenMPClauseName(OMPC_shared); 13320 reportOriginalDsa(*this, DSAStack, D, DVar); 13321 continue; 13322 } 13323 13324 DeclRefExpr *Ref = nullptr; 13325 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13326 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13327 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13328 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13329 ? RefExpr->IgnoreParens() 13330 : Ref); 13331 } 13332 13333 if (Vars.empty()) 13334 return nullptr; 13335 13336 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13337 } 13338 13339 namespace { 13340 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13341 DSAStackTy *Stack; 13342 13343 public: 13344 bool VisitDeclRefExpr(DeclRefExpr *E) { 13345 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13346 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13347 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13348 return false; 13349 if (DVar.CKind != OMPC_unknown) 13350 return true; 13351 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13352 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13353 /*FromParent=*/true); 13354 return DVarPrivate.CKind != OMPC_unknown; 13355 } 13356 return false; 13357 } 13358 bool VisitStmt(Stmt *S) { 13359 for (Stmt *Child : S->children()) { 13360 if (Child && Visit(Child)) 13361 return true; 13362 } 13363 return false; 13364 } 13365 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13366 }; 13367 } // namespace 13368 13369 namespace { 13370 // Transform MemberExpression for specified FieldDecl of current class to 13371 // DeclRefExpr to specified OMPCapturedExprDecl. 13372 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13373 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13374 ValueDecl *Field = nullptr; 13375 DeclRefExpr *CapturedExpr = nullptr; 13376 13377 public: 13378 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13379 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13380 13381 ExprResult TransformMemberExpr(MemberExpr *E) { 13382 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13383 E->getMemberDecl() == Field) { 13384 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13385 return CapturedExpr; 13386 } 13387 return BaseTransform::TransformMemberExpr(E); 13388 } 13389 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13390 }; 13391 } // namespace 13392 13393 template <typename T, typename U> 13394 static T filterLookupForUDReductionAndMapper( 13395 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13396 for (U &Set : Lookups) { 13397 for (auto *D : Set) { 13398 if (T Res = Gen(cast<ValueDecl>(D))) 13399 return Res; 13400 } 13401 } 13402 return T(); 13403 } 13404 13405 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13406 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13407 13408 for (auto RD : D->redecls()) { 13409 // Don't bother with extra checks if we already know this one isn't visible. 13410 if (RD == D) 13411 continue; 13412 13413 auto ND = cast<NamedDecl>(RD); 13414 if (LookupResult::isVisible(SemaRef, ND)) 13415 return ND; 13416 } 13417 13418 return nullptr; 13419 } 13420 13421 static void 13422 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13423 SourceLocation Loc, QualType Ty, 13424 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13425 // Find all of the associated namespaces and classes based on the 13426 // arguments we have. 13427 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13428 Sema::AssociatedClassSet AssociatedClasses; 13429 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13430 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13431 AssociatedClasses); 13432 13433 // C++ [basic.lookup.argdep]p3: 13434 // Let X be the lookup set produced by unqualified lookup (3.4.1) 13435 // and let Y be the lookup set produced by argument dependent 13436 // lookup (defined as follows). If X contains [...] then Y is 13437 // empty. Otherwise Y is the set of declarations found in the 13438 // namespaces associated with the argument types as described 13439 // below. The set of declarations found by the lookup of the name 13440 // is the union of X and Y. 13441 // 13442 // Here, we compute Y and add its members to the overloaded 13443 // candidate set. 13444 for (auto *NS : AssociatedNamespaces) { 13445 // When considering an associated namespace, the lookup is the 13446 // same as the lookup performed when the associated namespace is 13447 // used as a qualifier (3.4.3.2) except that: 13448 // 13449 // -- Any using-directives in the associated namespace are 13450 // ignored. 13451 // 13452 // -- Any namespace-scope friend functions declared in 13453 // associated classes are visible within their respective 13454 // namespaces even if they are not visible during an ordinary 13455 // lookup (11.4). 13456 DeclContext::lookup_result R = NS->lookup(Id.getName()); 13457 for (auto *D : R) { 13458 auto *Underlying = D; 13459 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13460 Underlying = USD->getTargetDecl(); 13461 13462 if (!isa<OMPDeclareReductionDecl>(Underlying) && 13463 !isa<OMPDeclareMapperDecl>(Underlying)) 13464 continue; 13465 13466 if (!SemaRef.isVisible(D)) { 13467 D = findAcceptableDecl(SemaRef, D); 13468 if (!D) 13469 continue; 13470 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13471 Underlying = USD->getTargetDecl(); 13472 } 13473 Lookups.emplace_back(); 13474 Lookups.back().addDecl(Underlying); 13475 } 13476 } 13477 } 13478 13479 static ExprResult 13480 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 13481 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 13482 const DeclarationNameInfo &ReductionId, QualType Ty, 13483 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 13484 if (ReductionIdScopeSpec.isInvalid()) 13485 return ExprError(); 13486 SmallVector<UnresolvedSet<8>, 4> Lookups; 13487 if (S) { 13488 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13489 Lookup.suppressDiagnostics(); 13490 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 13491 NamedDecl *D = Lookup.getRepresentativeDecl(); 13492 do { 13493 S = S->getParent(); 13494 } while (S && !S->isDeclScope(D)); 13495 if (S) 13496 S = S->getParent(); 13497 Lookups.emplace_back(); 13498 Lookups.back().append(Lookup.begin(), Lookup.end()); 13499 Lookup.clear(); 13500 } 13501 } else if (auto *ULE = 13502 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 13503 Lookups.push_back(UnresolvedSet<8>()); 13504 Decl *PrevD = nullptr; 13505 for (NamedDecl *D : ULE->decls()) { 13506 if (D == PrevD) 13507 Lookups.push_back(UnresolvedSet<8>()); 13508 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 13509 Lookups.back().addDecl(DRD); 13510 PrevD = D; 13511 } 13512 } 13513 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 13514 Ty->isInstantiationDependentType() || 13515 Ty->containsUnexpandedParameterPack() || 13516 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13517 return !D->isInvalidDecl() && 13518 (D->getType()->isDependentType() || 13519 D->getType()->isInstantiationDependentType() || 13520 D->getType()->containsUnexpandedParameterPack()); 13521 })) { 13522 UnresolvedSet<8> ResSet; 13523 for (const UnresolvedSet<8> &Set : Lookups) { 13524 if (Set.empty()) 13525 continue; 13526 ResSet.append(Set.begin(), Set.end()); 13527 // The last item marks the end of all declarations at the specified scope. 13528 ResSet.addDecl(Set[Set.size() - 1]); 13529 } 13530 return UnresolvedLookupExpr::Create( 13531 SemaRef.Context, /*NamingClass=*/nullptr, 13532 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 13533 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 13534 } 13535 // Lookup inside the classes. 13536 // C++ [over.match.oper]p3: 13537 // For a unary operator @ with an operand of a type whose 13538 // cv-unqualified version is T1, and for a binary operator @ with 13539 // a left operand of a type whose cv-unqualified version is T1 and 13540 // a right operand of a type whose cv-unqualified version is T2, 13541 // three sets of candidate functions, designated member 13542 // candidates, non-member candidates and built-in candidates, are 13543 // constructed as follows: 13544 // -- If T1 is a complete class type or a class currently being 13545 // defined, the set of member candidates is the result of the 13546 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13547 // the set of member candidates is empty. 13548 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13549 Lookup.suppressDiagnostics(); 13550 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13551 // Complete the type if it can be completed. 13552 // If the type is neither complete nor being defined, bail out now. 13553 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13554 TyRec->getDecl()->getDefinition()) { 13555 Lookup.clear(); 13556 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13557 if (Lookup.empty()) { 13558 Lookups.emplace_back(); 13559 Lookups.back().append(Lookup.begin(), Lookup.end()); 13560 } 13561 } 13562 } 13563 // Perform ADL. 13564 if (SemaRef.getLangOpts().CPlusPlus) 13565 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13566 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13567 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13568 if (!D->isInvalidDecl() && 13569 SemaRef.Context.hasSameType(D->getType(), Ty)) 13570 return D; 13571 return nullptr; 13572 })) 13573 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13574 VK_LValue, Loc); 13575 if (SemaRef.getLangOpts().CPlusPlus) { 13576 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13577 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13578 if (!D->isInvalidDecl() && 13579 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13580 !Ty.isMoreQualifiedThan(D->getType())) 13581 return D; 13582 return nullptr; 13583 })) { 13584 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13585 /*DetectVirtual=*/false); 13586 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13587 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13588 VD->getType().getUnqualifiedType()))) { 13589 if (SemaRef.CheckBaseClassAccess( 13590 Loc, VD->getType(), Ty, Paths.front(), 13591 /*DiagID=*/0) != Sema::AR_inaccessible) { 13592 SemaRef.BuildBasePathArray(Paths, BasePath); 13593 return SemaRef.BuildDeclRefExpr( 13594 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13595 } 13596 } 13597 } 13598 } 13599 } 13600 if (ReductionIdScopeSpec.isSet()) { 13601 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 13602 << Ty << Range; 13603 return ExprError(); 13604 } 13605 return ExprEmpty(); 13606 } 13607 13608 namespace { 13609 /// Data for the reduction-based clauses. 13610 struct ReductionData { 13611 /// List of original reduction items. 13612 SmallVector<Expr *, 8> Vars; 13613 /// List of private copies of the reduction items. 13614 SmallVector<Expr *, 8> Privates; 13615 /// LHS expressions for the reduction_op expressions. 13616 SmallVector<Expr *, 8> LHSs; 13617 /// RHS expressions for the reduction_op expressions. 13618 SmallVector<Expr *, 8> RHSs; 13619 /// Reduction operation expression. 13620 SmallVector<Expr *, 8> ReductionOps; 13621 /// Taskgroup descriptors for the corresponding reduction items in 13622 /// in_reduction clauses. 13623 SmallVector<Expr *, 8> TaskgroupDescriptors; 13624 /// List of captures for clause. 13625 SmallVector<Decl *, 4> ExprCaptures; 13626 /// List of postupdate expressions. 13627 SmallVector<Expr *, 4> ExprPostUpdates; 13628 ReductionData() = delete; 13629 /// Reserves required memory for the reduction data. 13630 ReductionData(unsigned Size) { 13631 Vars.reserve(Size); 13632 Privates.reserve(Size); 13633 LHSs.reserve(Size); 13634 RHSs.reserve(Size); 13635 ReductionOps.reserve(Size); 13636 TaskgroupDescriptors.reserve(Size); 13637 ExprCaptures.reserve(Size); 13638 ExprPostUpdates.reserve(Size); 13639 } 13640 /// Stores reduction item and reduction operation only (required for dependent 13641 /// reduction item). 13642 void push(Expr *Item, Expr *ReductionOp) { 13643 Vars.emplace_back(Item); 13644 Privates.emplace_back(nullptr); 13645 LHSs.emplace_back(nullptr); 13646 RHSs.emplace_back(nullptr); 13647 ReductionOps.emplace_back(ReductionOp); 13648 TaskgroupDescriptors.emplace_back(nullptr); 13649 } 13650 /// Stores reduction data. 13651 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13652 Expr *TaskgroupDescriptor) { 13653 Vars.emplace_back(Item); 13654 Privates.emplace_back(Private); 13655 LHSs.emplace_back(LHS); 13656 RHSs.emplace_back(RHS); 13657 ReductionOps.emplace_back(ReductionOp); 13658 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13659 } 13660 }; 13661 } // namespace 13662 13663 static bool checkOMPArraySectionConstantForReduction( 13664 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13665 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13666 const Expr *Length = OASE->getLength(); 13667 if (Length == nullptr) { 13668 // For array sections of the form [1:] or [:], we would need to analyze 13669 // the lower bound... 13670 if (OASE->getColonLoc().isValid()) 13671 return false; 13672 13673 // This is an array subscript which has implicit length 1! 13674 SingleElement = true; 13675 ArraySizes.push_back(llvm::APSInt::get(1)); 13676 } else { 13677 Expr::EvalResult Result; 13678 if (!Length->EvaluateAsInt(Result, Context)) 13679 return false; 13680 13681 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13682 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13683 ArraySizes.push_back(ConstantLengthValue); 13684 } 13685 13686 // Get the base of this array section and walk up from there. 13687 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13688 13689 // We require length = 1 for all array sections except the right-most to 13690 // guarantee that the memory region is contiguous and has no holes in it. 13691 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13692 Length = TempOASE->getLength(); 13693 if (Length == nullptr) { 13694 // For array sections of the form [1:] or [:], we would need to analyze 13695 // the lower bound... 13696 if (OASE->getColonLoc().isValid()) 13697 return false; 13698 13699 // This is an array subscript which has implicit length 1! 13700 ArraySizes.push_back(llvm::APSInt::get(1)); 13701 } else { 13702 Expr::EvalResult Result; 13703 if (!Length->EvaluateAsInt(Result, Context)) 13704 return false; 13705 13706 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13707 if (ConstantLengthValue.getSExtValue() != 1) 13708 return false; 13709 13710 ArraySizes.push_back(ConstantLengthValue); 13711 } 13712 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13713 } 13714 13715 // If we have a single element, we don't need to add the implicit lengths. 13716 if (!SingleElement) { 13717 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13718 // Has implicit length 1! 13719 ArraySizes.push_back(llvm::APSInt::get(1)); 13720 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13721 } 13722 } 13723 13724 // This array section can be privatized as a single value or as a constant 13725 // sized array. 13726 return true; 13727 } 13728 13729 static bool actOnOMPReductionKindClause( 13730 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13731 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13732 SourceLocation ColonLoc, SourceLocation EndLoc, 13733 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13734 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13735 DeclarationName DN = ReductionId.getName(); 13736 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13737 BinaryOperatorKind BOK = BO_Comma; 13738 13739 ASTContext &Context = S.Context; 13740 // OpenMP [2.14.3.6, reduction clause] 13741 // C 13742 // reduction-identifier is either an identifier or one of the following 13743 // operators: +, -, *, &, |, ^, && and || 13744 // C++ 13745 // reduction-identifier is either an id-expression or one of the following 13746 // operators: +, -, *, &, |, ^, && and || 13747 switch (OOK) { 13748 case OO_Plus: 13749 case OO_Minus: 13750 BOK = BO_Add; 13751 break; 13752 case OO_Star: 13753 BOK = BO_Mul; 13754 break; 13755 case OO_Amp: 13756 BOK = BO_And; 13757 break; 13758 case OO_Pipe: 13759 BOK = BO_Or; 13760 break; 13761 case OO_Caret: 13762 BOK = BO_Xor; 13763 break; 13764 case OO_AmpAmp: 13765 BOK = BO_LAnd; 13766 break; 13767 case OO_PipePipe: 13768 BOK = BO_LOr; 13769 break; 13770 case OO_New: 13771 case OO_Delete: 13772 case OO_Array_New: 13773 case OO_Array_Delete: 13774 case OO_Slash: 13775 case OO_Percent: 13776 case OO_Tilde: 13777 case OO_Exclaim: 13778 case OO_Equal: 13779 case OO_Less: 13780 case OO_Greater: 13781 case OO_LessEqual: 13782 case OO_GreaterEqual: 13783 case OO_PlusEqual: 13784 case OO_MinusEqual: 13785 case OO_StarEqual: 13786 case OO_SlashEqual: 13787 case OO_PercentEqual: 13788 case OO_CaretEqual: 13789 case OO_AmpEqual: 13790 case OO_PipeEqual: 13791 case OO_LessLess: 13792 case OO_GreaterGreater: 13793 case OO_LessLessEqual: 13794 case OO_GreaterGreaterEqual: 13795 case OO_EqualEqual: 13796 case OO_ExclaimEqual: 13797 case OO_Spaceship: 13798 case OO_PlusPlus: 13799 case OO_MinusMinus: 13800 case OO_Comma: 13801 case OO_ArrowStar: 13802 case OO_Arrow: 13803 case OO_Call: 13804 case OO_Subscript: 13805 case OO_Conditional: 13806 case OO_Coawait: 13807 case NUM_OVERLOADED_OPERATORS: 13808 llvm_unreachable("Unexpected reduction identifier"); 13809 case OO_None: 13810 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13811 if (II->isStr("max")) 13812 BOK = BO_GT; 13813 else if (II->isStr("min")) 13814 BOK = BO_LT; 13815 } 13816 break; 13817 } 13818 SourceRange ReductionIdRange; 13819 if (ReductionIdScopeSpec.isValid()) 13820 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13821 else 13822 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13823 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13824 13825 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13826 bool FirstIter = true; 13827 for (Expr *RefExpr : VarList) { 13828 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13829 // OpenMP [2.1, C/C++] 13830 // A list item is a variable or array section, subject to the restrictions 13831 // specified in Section 2.4 on page 42 and in each of the sections 13832 // describing clauses and directives for which a list appears. 13833 // OpenMP [2.14.3.3, Restrictions, p.1] 13834 // A variable that is part of another variable (as an array or 13835 // structure element) cannot appear in a private clause. 13836 if (!FirstIter && IR != ER) 13837 ++IR; 13838 FirstIter = false; 13839 SourceLocation ELoc; 13840 SourceRange ERange; 13841 Expr *SimpleRefExpr = RefExpr; 13842 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13843 /*AllowArraySection=*/true); 13844 if (Res.second) { 13845 // Try to find 'declare reduction' corresponding construct before using 13846 // builtin/overloaded operators. 13847 QualType Type = Context.DependentTy; 13848 CXXCastPath BasePath; 13849 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13850 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13851 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13852 Expr *ReductionOp = nullptr; 13853 if (S.CurContext->isDependentContext() && 13854 (DeclareReductionRef.isUnset() || 13855 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13856 ReductionOp = DeclareReductionRef.get(); 13857 // It will be analyzed later. 13858 RD.push(RefExpr, ReductionOp); 13859 } 13860 ValueDecl *D = Res.first; 13861 if (!D) 13862 continue; 13863 13864 Expr *TaskgroupDescriptor = nullptr; 13865 QualType Type; 13866 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13867 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13868 if (ASE) { 13869 Type = ASE->getType().getNonReferenceType(); 13870 } else if (OASE) { 13871 QualType BaseType = 13872 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13873 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13874 Type = ATy->getElementType(); 13875 else 13876 Type = BaseType->getPointeeType(); 13877 Type = Type.getNonReferenceType(); 13878 } else { 13879 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13880 } 13881 auto *VD = dyn_cast<VarDecl>(D); 13882 13883 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13884 // A variable that appears in a private clause must not have an incomplete 13885 // type or a reference type. 13886 if (S.RequireCompleteType(ELoc, D->getType(), 13887 diag::err_omp_reduction_incomplete_type)) 13888 continue; 13889 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13890 // A list item that appears in a reduction clause must not be 13891 // const-qualified. 13892 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13893 /*AcceptIfMutable*/ false, ASE || OASE)) 13894 continue; 13895 13896 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13897 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13898 // If a list-item is a reference type then it must bind to the same object 13899 // for all threads of the team. 13900 if (!ASE && !OASE) { 13901 if (VD) { 13902 VarDecl *VDDef = VD->getDefinition(); 13903 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13904 DSARefChecker Check(Stack); 13905 if (Check.Visit(VDDef->getInit())) { 13906 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13907 << getOpenMPClauseName(ClauseKind) << ERange; 13908 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13909 continue; 13910 } 13911 } 13912 } 13913 13914 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13915 // in a Construct] 13916 // Variables with the predetermined data-sharing attributes may not be 13917 // listed in data-sharing attributes clauses, except for the cases 13918 // listed below. For these exceptions only, listing a predetermined 13919 // variable in a data-sharing attribute clause is allowed and overrides 13920 // the variable's predetermined data-sharing attributes. 13921 // OpenMP [2.14.3.6, Restrictions, p.3] 13922 // Any number of reduction clauses can be specified on the directive, 13923 // but a list item can appear only once in the reduction clauses for that 13924 // directive. 13925 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13926 if (DVar.CKind == OMPC_reduction) { 13927 S.Diag(ELoc, diag::err_omp_once_referenced) 13928 << getOpenMPClauseName(ClauseKind); 13929 if (DVar.RefExpr) 13930 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13931 continue; 13932 } 13933 if (DVar.CKind != OMPC_unknown) { 13934 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13935 << getOpenMPClauseName(DVar.CKind) 13936 << getOpenMPClauseName(OMPC_reduction); 13937 reportOriginalDsa(S, Stack, D, DVar); 13938 continue; 13939 } 13940 13941 // OpenMP [2.14.3.6, Restrictions, p.1] 13942 // A list item that appears in a reduction clause of a worksharing 13943 // construct must be shared in the parallel regions to which any of the 13944 // worksharing regions arising from the worksharing construct bind. 13945 if (isOpenMPWorksharingDirective(CurrDir) && 13946 !isOpenMPParallelDirective(CurrDir) && 13947 !isOpenMPTeamsDirective(CurrDir)) { 13948 DVar = Stack->getImplicitDSA(D, true); 13949 if (DVar.CKind != OMPC_shared) { 13950 S.Diag(ELoc, diag::err_omp_required_access) 13951 << getOpenMPClauseName(OMPC_reduction) 13952 << getOpenMPClauseName(OMPC_shared); 13953 reportOriginalDsa(S, Stack, D, DVar); 13954 continue; 13955 } 13956 } 13957 } 13958 13959 // Try to find 'declare reduction' corresponding construct before using 13960 // builtin/overloaded operators. 13961 CXXCastPath BasePath; 13962 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13963 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13964 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13965 if (DeclareReductionRef.isInvalid()) 13966 continue; 13967 if (S.CurContext->isDependentContext() && 13968 (DeclareReductionRef.isUnset() || 13969 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13970 RD.push(RefExpr, DeclareReductionRef.get()); 13971 continue; 13972 } 13973 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13974 // Not allowed reduction identifier is found. 13975 S.Diag(ReductionId.getBeginLoc(), 13976 diag::err_omp_unknown_reduction_identifier) 13977 << Type << ReductionIdRange; 13978 continue; 13979 } 13980 13981 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13982 // The type of a list item that appears in a reduction clause must be valid 13983 // for the reduction-identifier. For a max or min reduction in C, the type 13984 // of the list item must be an allowed arithmetic data type: char, int, 13985 // float, double, or _Bool, possibly modified with long, short, signed, or 13986 // unsigned. For a max or min reduction in C++, the type of the list item 13987 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13988 // double, or bool, possibly modified with long, short, signed, or unsigned. 13989 if (DeclareReductionRef.isUnset()) { 13990 if ((BOK == BO_GT || BOK == BO_LT) && 13991 !(Type->isScalarType() || 13992 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13993 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13994 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13995 if (!ASE && !OASE) { 13996 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13997 VarDecl::DeclarationOnly; 13998 S.Diag(D->getLocation(), 13999 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14000 << D; 14001 } 14002 continue; 14003 } 14004 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14005 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14006 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14007 << getOpenMPClauseName(ClauseKind); 14008 if (!ASE && !OASE) { 14009 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14010 VarDecl::DeclarationOnly; 14011 S.Diag(D->getLocation(), 14012 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14013 << D; 14014 } 14015 continue; 14016 } 14017 } 14018 14019 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14020 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14021 D->hasAttrs() ? &D->getAttrs() : nullptr); 14022 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14023 D->hasAttrs() ? &D->getAttrs() : nullptr); 14024 QualType PrivateTy = Type; 14025 14026 // Try if we can determine constant lengths for all array sections and avoid 14027 // the VLA. 14028 bool ConstantLengthOASE = false; 14029 if (OASE) { 14030 bool SingleElement; 14031 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14032 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14033 Context, OASE, SingleElement, ArraySizes); 14034 14035 // If we don't have a single element, we must emit a constant array type. 14036 if (ConstantLengthOASE && !SingleElement) { 14037 for (llvm::APSInt &Size : ArraySizes) 14038 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14039 ArrayType::Normal, 14040 /*IndexTypeQuals=*/0); 14041 } 14042 } 14043 14044 if ((OASE && !ConstantLengthOASE) || 14045 (!OASE && !ASE && 14046 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14047 if (!Context.getTargetInfo().isVLASupported()) { 14048 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14049 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14050 S.Diag(ELoc, diag::note_vla_unsupported); 14051 } else { 14052 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14053 S.targetDiag(ELoc, diag::note_vla_unsupported); 14054 } 14055 continue; 14056 } 14057 // For arrays/array sections only: 14058 // Create pseudo array type for private copy. The size for this array will 14059 // be generated during codegen. 14060 // For array subscripts or single variables Private Ty is the same as Type 14061 // (type of the variable or single array element). 14062 PrivateTy = Context.getVariableArrayType( 14063 Type, 14064 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14065 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14066 } else if (!ASE && !OASE && 14067 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14068 PrivateTy = D->getType().getNonReferenceType(); 14069 } 14070 // Private copy. 14071 VarDecl *PrivateVD = 14072 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14073 D->hasAttrs() ? &D->getAttrs() : nullptr, 14074 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14075 // Add initializer for private variable. 14076 Expr *Init = nullptr; 14077 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14078 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14079 if (DeclareReductionRef.isUsable()) { 14080 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14081 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14082 if (DRD->getInitializer()) { 14083 Init = DRDRef; 14084 RHSVD->setInit(DRDRef); 14085 RHSVD->setInitStyle(VarDecl::CallInit); 14086 } 14087 } else { 14088 switch (BOK) { 14089 case BO_Add: 14090 case BO_Xor: 14091 case BO_Or: 14092 case BO_LOr: 14093 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14094 if (Type->isScalarType() || Type->isAnyComplexType()) 14095 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14096 break; 14097 case BO_Mul: 14098 case BO_LAnd: 14099 if (Type->isScalarType() || Type->isAnyComplexType()) { 14100 // '*' and '&&' reduction ops - initializer is '1'. 14101 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14102 } 14103 break; 14104 case BO_And: { 14105 // '&' reduction op - initializer is '~0'. 14106 QualType OrigType = Type; 14107 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14108 Type = ComplexTy->getElementType(); 14109 if (Type->isRealFloatingType()) { 14110 llvm::APFloat InitValue = 14111 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14112 /*isIEEE=*/true); 14113 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14114 Type, ELoc); 14115 } else if (Type->isScalarType()) { 14116 uint64_t Size = Context.getTypeSize(Type); 14117 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14118 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14119 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14120 } 14121 if (Init && OrigType->isAnyComplexType()) { 14122 // Init = 0xFFFF + 0xFFFFi; 14123 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14124 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14125 } 14126 Type = OrigType; 14127 break; 14128 } 14129 case BO_LT: 14130 case BO_GT: { 14131 // 'min' reduction op - initializer is 'Largest representable number in 14132 // the reduction list item type'. 14133 // 'max' reduction op - initializer is 'Least representable number in 14134 // the reduction list item type'. 14135 if (Type->isIntegerType() || Type->isPointerType()) { 14136 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14137 uint64_t Size = Context.getTypeSize(Type); 14138 QualType IntTy = 14139 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14140 llvm::APInt InitValue = 14141 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14142 : llvm::APInt::getMinValue(Size) 14143 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14144 : llvm::APInt::getMaxValue(Size); 14145 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14146 if (Type->isPointerType()) { 14147 // Cast to pointer type. 14148 ExprResult CastExpr = S.BuildCStyleCastExpr( 14149 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14150 if (CastExpr.isInvalid()) 14151 continue; 14152 Init = CastExpr.get(); 14153 } 14154 } else if (Type->isRealFloatingType()) { 14155 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14156 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14157 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14158 Type, ELoc); 14159 } 14160 break; 14161 } 14162 case BO_PtrMemD: 14163 case BO_PtrMemI: 14164 case BO_MulAssign: 14165 case BO_Div: 14166 case BO_Rem: 14167 case BO_Sub: 14168 case BO_Shl: 14169 case BO_Shr: 14170 case BO_LE: 14171 case BO_GE: 14172 case BO_EQ: 14173 case BO_NE: 14174 case BO_Cmp: 14175 case BO_AndAssign: 14176 case BO_XorAssign: 14177 case BO_OrAssign: 14178 case BO_Assign: 14179 case BO_AddAssign: 14180 case BO_SubAssign: 14181 case BO_DivAssign: 14182 case BO_RemAssign: 14183 case BO_ShlAssign: 14184 case BO_ShrAssign: 14185 case BO_Comma: 14186 llvm_unreachable("Unexpected reduction operation"); 14187 } 14188 } 14189 if (Init && DeclareReductionRef.isUnset()) 14190 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14191 else if (!Init) 14192 S.ActOnUninitializedDecl(RHSVD); 14193 if (RHSVD->isInvalidDecl()) 14194 continue; 14195 if (!RHSVD->hasInit() && 14196 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14197 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14198 << Type << ReductionIdRange; 14199 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14200 VarDecl::DeclarationOnly; 14201 S.Diag(D->getLocation(), 14202 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14203 << D; 14204 continue; 14205 } 14206 // Store initializer for single element in private copy. Will be used during 14207 // codegen. 14208 PrivateVD->setInit(RHSVD->getInit()); 14209 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14210 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14211 ExprResult ReductionOp; 14212 if (DeclareReductionRef.isUsable()) { 14213 QualType RedTy = DeclareReductionRef.get()->getType(); 14214 QualType PtrRedTy = Context.getPointerType(RedTy); 14215 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14216 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14217 if (!BasePath.empty()) { 14218 LHS = S.DefaultLvalueConversion(LHS.get()); 14219 RHS = S.DefaultLvalueConversion(RHS.get()); 14220 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14221 CK_UncheckedDerivedToBase, LHS.get(), 14222 &BasePath, LHS.get()->getValueKind()); 14223 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14224 CK_UncheckedDerivedToBase, RHS.get(), 14225 &BasePath, RHS.get()->getValueKind()); 14226 } 14227 FunctionProtoType::ExtProtoInfo EPI; 14228 QualType Params[] = {PtrRedTy, PtrRedTy}; 14229 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14230 auto *OVE = new (Context) OpaqueValueExpr( 14231 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14232 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14233 Expr *Args[] = {LHS.get(), RHS.get()}; 14234 ReductionOp = 14235 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14236 } else { 14237 ReductionOp = S.BuildBinOp( 14238 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14239 if (ReductionOp.isUsable()) { 14240 if (BOK != BO_LT && BOK != BO_GT) { 14241 ReductionOp = 14242 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14243 BO_Assign, LHSDRE, ReductionOp.get()); 14244 } else { 14245 auto *ConditionalOp = new (Context) 14246 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14247 Type, VK_LValue, OK_Ordinary); 14248 ReductionOp = 14249 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14250 BO_Assign, LHSDRE, ConditionalOp); 14251 } 14252 if (ReductionOp.isUsable()) 14253 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14254 /*DiscardedValue*/ false); 14255 } 14256 if (!ReductionOp.isUsable()) 14257 continue; 14258 } 14259 14260 // OpenMP [2.15.4.6, Restrictions, p.2] 14261 // A list item that appears in an in_reduction clause of a task construct 14262 // must appear in a task_reduction clause of a construct associated with a 14263 // taskgroup region that includes the participating task in its taskgroup 14264 // set. The construct associated with the innermost region that meets this 14265 // condition must specify the same reduction-identifier as the in_reduction 14266 // clause. 14267 if (ClauseKind == OMPC_in_reduction) { 14268 SourceRange ParentSR; 14269 BinaryOperatorKind ParentBOK; 14270 const Expr *ParentReductionOp; 14271 Expr *ParentBOKTD, *ParentReductionOpTD; 14272 DSAStackTy::DSAVarData ParentBOKDSA = 14273 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14274 ParentBOKTD); 14275 DSAStackTy::DSAVarData ParentReductionOpDSA = 14276 Stack->getTopMostTaskgroupReductionData( 14277 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14278 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14279 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14280 if (!IsParentBOK && !IsParentReductionOp) { 14281 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 14282 continue; 14283 } 14284 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14285 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 14286 IsParentReductionOp) { 14287 bool EmitError = true; 14288 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14289 llvm::FoldingSetNodeID RedId, ParentRedId; 14290 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14291 DeclareReductionRef.get()->Profile(RedId, Context, 14292 /*Canonical=*/true); 14293 EmitError = RedId != ParentRedId; 14294 } 14295 if (EmitError) { 14296 S.Diag(ReductionId.getBeginLoc(), 14297 diag::err_omp_reduction_identifier_mismatch) 14298 << ReductionIdRange << RefExpr->getSourceRange(); 14299 S.Diag(ParentSR.getBegin(), 14300 diag::note_omp_previous_reduction_identifier) 14301 << ParentSR 14302 << (IsParentBOK ? ParentBOKDSA.RefExpr 14303 : ParentReductionOpDSA.RefExpr) 14304 ->getSourceRange(); 14305 continue; 14306 } 14307 } 14308 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14309 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 14310 } 14311 14312 DeclRefExpr *Ref = nullptr; 14313 Expr *VarsExpr = RefExpr->IgnoreParens(); 14314 if (!VD && !S.CurContext->isDependentContext()) { 14315 if (ASE || OASE) { 14316 TransformExprToCaptures RebuildToCapture(S, D); 14317 VarsExpr = 14318 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14319 Ref = RebuildToCapture.getCapturedExpr(); 14320 } else { 14321 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14322 } 14323 if (!S.isOpenMPCapturedDecl(D)) { 14324 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14325 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14326 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14327 if (!RefRes.isUsable()) 14328 continue; 14329 ExprResult PostUpdateRes = 14330 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14331 RefRes.get()); 14332 if (!PostUpdateRes.isUsable()) 14333 continue; 14334 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14335 Stack->getCurrentDirective() == OMPD_taskgroup) { 14336 S.Diag(RefExpr->getExprLoc(), 14337 diag::err_omp_reduction_non_addressable_expression) 14338 << RefExpr->getSourceRange(); 14339 continue; 14340 } 14341 RD.ExprPostUpdates.emplace_back( 14342 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14343 } 14344 } 14345 } 14346 // All reduction items are still marked as reduction (to do not increase 14347 // code base size). 14348 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 14349 if (CurrDir == OMPD_taskgroup) { 14350 if (DeclareReductionRef.isUsable()) 14351 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14352 DeclareReductionRef.get()); 14353 else 14354 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14355 } 14356 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14357 TaskgroupDescriptor); 14358 } 14359 return RD.Vars.empty(); 14360 } 14361 14362 OMPClause *Sema::ActOnOpenMPReductionClause( 14363 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14364 SourceLocation ColonLoc, SourceLocation EndLoc, 14365 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14366 ArrayRef<Expr *> UnresolvedReductions) { 14367 ReductionData RD(VarList.size()); 14368 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14369 StartLoc, LParenLoc, ColonLoc, EndLoc, 14370 ReductionIdScopeSpec, ReductionId, 14371 UnresolvedReductions, RD)) 14372 return nullptr; 14373 14374 return OMPReductionClause::Create( 14375 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14376 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14377 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14378 buildPreInits(Context, RD.ExprCaptures), 14379 buildPostUpdate(*this, RD.ExprPostUpdates)); 14380 } 14381 14382 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14383 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14384 SourceLocation ColonLoc, SourceLocation EndLoc, 14385 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14386 ArrayRef<Expr *> UnresolvedReductions) { 14387 ReductionData RD(VarList.size()); 14388 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14389 StartLoc, LParenLoc, ColonLoc, EndLoc, 14390 ReductionIdScopeSpec, ReductionId, 14391 UnresolvedReductions, RD)) 14392 return nullptr; 14393 14394 return OMPTaskReductionClause::Create( 14395 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14396 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14397 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14398 buildPreInits(Context, RD.ExprCaptures), 14399 buildPostUpdate(*this, RD.ExprPostUpdates)); 14400 } 14401 14402 OMPClause *Sema::ActOnOpenMPInReductionClause( 14403 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14404 SourceLocation ColonLoc, SourceLocation EndLoc, 14405 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14406 ArrayRef<Expr *> UnresolvedReductions) { 14407 ReductionData RD(VarList.size()); 14408 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14409 StartLoc, LParenLoc, ColonLoc, EndLoc, 14410 ReductionIdScopeSpec, ReductionId, 14411 UnresolvedReductions, RD)) 14412 return nullptr; 14413 14414 return OMPInReductionClause::Create( 14415 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14416 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14417 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 14418 buildPreInits(Context, RD.ExprCaptures), 14419 buildPostUpdate(*this, RD.ExprPostUpdates)); 14420 } 14421 14422 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 14423 SourceLocation LinLoc) { 14424 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 14425 LinKind == OMPC_LINEAR_unknown) { 14426 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 14427 return true; 14428 } 14429 return false; 14430 } 14431 14432 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 14433 OpenMPLinearClauseKind LinKind, 14434 QualType Type) { 14435 const auto *VD = dyn_cast_or_null<VarDecl>(D); 14436 // A variable must not have an incomplete type or a reference type. 14437 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 14438 return true; 14439 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 14440 !Type->isReferenceType()) { 14441 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 14442 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 14443 return true; 14444 } 14445 Type = Type.getNonReferenceType(); 14446 14447 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14448 // A variable that is privatized must not have a const-qualified type 14449 // unless it is of class type with a mutable member. This restriction does 14450 // not apply to the firstprivate clause. 14451 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 14452 return true; 14453 14454 // A list item must be of integral or pointer type. 14455 Type = Type.getUnqualifiedType().getCanonicalType(); 14456 const auto *Ty = Type.getTypePtrOrNull(); 14457 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 14458 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 14459 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 14460 if (D) { 14461 bool IsDecl = 14462 !VD || 14463 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14464 Diag(D->getLocation(), 14465 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14466 << D; 14467 } 14468 return true; 14469 } 14470 return false; 14471 } 14472 14473 OMPClause *Sema::ActOnOpenMPLinearClause( 14474 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 14475 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 14476 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14477 SmallVector<Expr *, 8> Vars; 14478 SmallVector<Expr *, 8> Privates; 14479 SmallVector<Expr *, 8> Inits; 14480 SmallVector<Decl *, 4> ExprCaptures; 14481 SmallVector<Expr *, 4> ExprPostUpdates; 14482 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 14483 LinKind = OMPC_LINEAR_val; 14484 for (Expr *RefExpr : VarList) { 14485 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14486 SourceLocation ELoc; 14487 SourceRange ERange; 14488 Expr *SimpleRefExpr = RefExpr; 14489 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14490 if (Res.second) { 14491 // It will be analyzed later. 14492 Vars.push_back(RefExpr); 14493 Privates.push_back(nullptr); 14494 Inits.push_back(nullptr); 14495 } 14496 ValueDecl *D = Res.first; 14497 if (!D) 14498 continue; 14499 14500 QualType Type = D->getType(); 14501 auto *VD = dyn_cast<VarDecl>(D); 14502 14503 // OpenMP [2.14.3.7, linear clause] 14504 // A list-item cannot appear in more than one linear clause. 14505 // A list-item that appears in a linear clause cannot appear in any 14506 // other data-sharing attribute clause. 14507 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14508 if (DVar.RefExpr) { 14509 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14510 << getOpenMPClauseName(OMPC_linear); 14511 reportOriginalDsa(*this, DSAStack, D, DVar); 14512 continue; 14513 } 14514 14515 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 14516 continue; 14517 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14518 14519 // Build private copy of original var. 14520 VarDecl *Private = 14521 buildVarDecl(*this, ELoc, Type, D->getName(), 14522 D->hasAttrs() ? &D->getAttrs() : nullptr, 14523 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14524 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 14525 // Build var to save initial value. 14526 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 14527 Expr *InitExpr; 14528 DeclRefExpr *Ref = nullptr; 14529 if (!VD && !CurContext->isDependentContext()) { 14530 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14531 if (!isOpenMPCapturedDecl(D)) { 14532 ExprCaptures.push_back(Ref->getDecl()); 14533 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14534 ExprResult RefRes = DefaultLvalueConversion(Ref); 14535 if (!RefRes.isUsable()) 14536 continue; 14537 ExprResult PostUpdateRes = 14538 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14539 SimpleRefExpr, RefRes.get()); 14540 if (!PostUpdateRes.isUsable()) 14541 continue; 14542 ExprPostUpdates.push_back( 14543 IgnoredValueConversions(PostUpdateRes.get()).get()); 14544 } 14545 } 14546 } 14547 if (LinKind == OMPC_LINEAR_uval) 14548 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14549 else 14550 InitExpr = VD ? SimpleRefExpr : Ref; 14551 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14552 /*DirectInit=*/false); 14553 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14554 14555 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14556 Vars.push_back((VD || CurContext->isDependentContext()) 14557 ? RefExpr->IgnoreParens() 14558 : Ref); 14559 Privates.push_back(PrivateRef); 14560 Inits.push_back(InitRef); 14561 } 14562 14563 if (Vars.empty()) 14564 return nullptr; 14565 14566 Expr *StepExpr = Step; 14567 Expr *CalcStepExpr = nullptr; 14568 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14569 !Step->isInstantiationDependent() && 14570 !Step->containsUnexpandedParameterPack()) { 14571 SourceLocation StepLoc = Step->getBeginLoc(); 14572 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14573 if (Val.isInvalid()) 14574 return nullptr; 14575 StepExpr = Val.get(); 14576 14577 // Build var to save the step value. 14578 VarDecl *SaveVar = 14579 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14580 ExprResult SaveRef = 14581 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14582 ExprResult CalcStep = 14583 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14584 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14585 14586 // Warn about zero linear step (it would be probably better specified as 14587 // making corresponding variables 'const'). 14588 llvm::APSInt Result; 14589 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14590 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14591 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14592 << (Vars.size() > 1); 14593 if (!IsConstant && CalcStep.isUsable()) { 14594 // Calculate the step beforehand instead of doing this on each iteration. 14595 // (This is not used if the number of iterations may be kfold-ed). 14596 CalcStepExpr = CalcStep.get(); 14597 } 14598 } 14599 14600 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14601 ColonLoc, EndLoc, Vars, Privates, Inits, 14602 StepExpr, CalcStepExpr, 14603 buildPreInits(Context, ExprCaptures), 14604 buildPostUpdate(*this, ExprPostUpdates)); 14605 } 14606 14607 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14608 Expr *NumIterations, Sema &SemaRef, 14609 Scope *S, DSAStackTy *Stack) { 14610 // Walk the vars and build update/final expressions for the CodeGen. 14611 SmallVector<Expr *, 8> Updates; 14612 SmallVector<Expr *, 8> Finals; 14613 SmallVector<Expr *, 8> UsedExprs; 14614 Expr *Step = Clause.getStep(); 14615 Expr *CalcStep = Clause.getCalcStep(); 14616 // OpenMP [2.14.3.7, linear clause] 14617 // If linear-step is not specified it is assumed to be 1. 14618 if (!Step) 14619 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14620 else if (CalcStep) 14621 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14622 bool HasErrors = false; 14623 auto CurInit = Clause.inits().begin(); 14624 auto CurPrivate = Clause.privates().begin(); 14625 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14626 for (Expr *RefExpr : Clause.varlists()) { 14627 SourceLocation ELoc; 14628 SourceRange ERange; 14629 Expr *SimpleRefExpr = RefExpr; 14630 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14631 ValueDecl *D = Res.first; 14632 if (Res.second || !D) { 14633 Updates.push_back(nullptr); 14634 Finals.push_back(nullptr); 14635 HasErrors = true; 14636 continue; 14637 } 14638 auto &&Info = Stack->isLoopControlVariable(D); 14639 // OpenMP [2.15.11, distribute simd Construct] 14640 // A list item may not appear in a linear clause, unless it is the loop 14641 // iteration variable. 14642 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14643 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14644 SemaRef.Diag(ELoc, 14645 diag::err_omp_linear_distribute_var_non_loop_iteration); 14646 Updates.push_back(nullptr); 14647 Finals.push_back(nullptr); 14648 HasErrors = true; 14649 continue; 14650 } 14651 Expr *InitExpr = *CurInit; 14652 14653 // Build privatized reference to the current linear var. 14654 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14655 Expr *CapturedRef; 14656 if (LinKind == OMPC_LINEAR_uval) 14657 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14658 else 14659 CapturedRef = 14660 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14661 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14662 /*RefersToCapture=*/true); 14663 14664 // Build update: Var = InitExpr + IV * Step 14665 ExprResult Update; 14666 if (!Info.first) 14667 Update = buildCounterUpdate( 14668 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14669 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14670 else 14671 Update = *CurPrivate; 14672 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14673 /*DiscardedValue*/ false); 14674 14675 // Build final: Var = InitExpr + NumIterations * Step 14676 ExprResult Final; 14677 if (!Info.first) 14678 Final = 14679 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14680 InitExpr, NumIterations, Step, /*Subtract=*/false, 14681 /*IsNonRectangularLB=*/false); 14682 else 14683 Final = *CurPrivate; 14684 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14685 /*DiscardedValue*/ false); 14686 14687 if (!Update.isUsable() || !Final.isUsable()) { 14688 Updates.push_back(nullptr); 14689 Finals.push_back(nullptr); 14690 UsedExprs.push_back(nullptr); 14691 HasErrors = true; 14692 } else { 14693 Updates.push_back(Update.get()); 14694 Finals.push_back(Final.get()); 14695 if (!Info.first) 14696 UsedExprs.push_back(SimpleRefExpr); 14697 } 14698 ++CurInit; 14699 ++CurPrivate; 14700 } 14701 if (Expr *S = Clause.getStep()) 14702 UsedExprs.push_back(S); 14703 // Fill the remaining part with the nullptr. 14704 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14705 Clause.setUpdates(Updates); 14706 Clause.setFinals(Finals); 14707 Clause.setUsedExprs(UsedExprs); 14708 return HasErrors; 14709 } 14710 14711 OMPClause *Sema::ActOnOpenMPAlignedClause( 14712 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14713 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14714 SmallVector<Expr *, 8> Vars; 14715 for (Expr *RefExpr : VarList) { 14716 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14717 SourceLocation ELoc; 14718 SourceRange ERange; 14719 Expr *SimpleRefExpr = RefExpr; 14720 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14721 if (Res.second) { 14722 // It will be analyzed later. 14723 Vars.push_back(RefExpr); 14724 } 14725 ValueDecl *D = Res.first; 14726 if (!D) 14727 continue; 14728 14729 QualType QType = D->getType(); 14730 auto *VD = dyn_cast<VarDecl>(D); 14731 14732 // OpenMP [2.8.1, simd construct, Restrictions] 14733 // The type of list items appearing in the aligned clause must be 14734 // array, pointer, reference to array, or reference to pointer. 14735 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14736 const Type *Ty = QType.getTypePtrOrNull(); 14737 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14738 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14739 << QType << getLangOpts().CPlusPlus << ERange; 14740 bool IsDecl = 14741 !VD || 14742 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14743 Diag(D->getLocation(), 14744 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14745 << D; 14746 continue; 14747 } 14748 14749 // OpenMP [2.8.1, simd construct, Restrictions] 14750 // A list-item cannot appear in more than one aligned clause. 14751 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14752 Diag(ELoc, diag::err_omp_used_in_clause_twice) 14753 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 14754 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14755 << getOpenMPClauseName(OMPC_aligned); 14756 continue; 14757 } 14758 14759 DeclRefExpr *Ref = nullptr; 14760 if (!VD && isOpenMPCapturedDecl(D)) 14761 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14762 Vars.push_back(DefaultFunctionArrayConversion( 14763 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14764 .get()); 14765 } 14766 14767 // OpenMP [2.8.1, simd construct, Description] 14768 // The parameter of the aligned clause, alignment, must be a constant 14769 // positive integer expression. 14770 // If no optional parameter is specified, implementation-defined default 14771 // alignments for SIMD instructions on the target platforms are assumed. 14772 if (Alignment != nullptr) { 14773 ExprResult AlignResult = 14774 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14775 if (AlignResult.isInvalid()) 14776 return nullptr; 14777 Alignment = AlignResult.get(); 14778 } 14779 if (Vars.empty()) 14780 return nullptr; 14781 14782 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14783 EndLoc, Vars, Alignment); 14784 } 14785 14786 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14787 SourceLocation StartLoc, 14788 SourceLocation LParenLoc, 14789 SourceLocation EndLoc) { 14790 SmallVector<Expr *, 8> Vars; 14791 SmallVector<Expr *, 8> SrcExprs; 14792 SmallVector<Expr *, 8> DstExprs; 14793 SmallVector<Expr *, 8> AssignmentOps; 14794 for (Expr *RefExpr : VarList) { 14795 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14796 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14797 // It will be analyzed later. 14798 Vars.push_back(RefExpr); 14799 SrcExprs.push_back(nullptr); 14800 DstExprs.push_back(nullptr); 14801 AssignmentOps.push_back(nullptr); 14802 continue; 14803 } 14804 14805 SourceLocation ELoc = RefExpr->getExprLoc(); 14806 // OpenMP [2.1, C/C++] 14807 // A list item is a variable name. 14808 // OpenMP [2.14.4.1, Restrictions, p.1] 14809 // A list item that appears in a copyin clause must be threadprivate. 14810 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14811 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14812 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14813 << 0 << RefExpr->getSourceRange(); 14814 continue; 14815 } 14816 14817 Decl *D = DE->getDecl(); 14818 auto *VD = cast<VarDecl>(D); 14819 14820 QualType Type = VD->getType(); 14821 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14822 // It will be analyzed later. 14823 Vars.push_back(DE); 14824 SrcExprs.push_back(nullptr); 14825 DstExprs.push_back(nullptr); 14826 AssignmentOps.push_back(nullptr); 14827 continue; 14828 } 14829 14830 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14831 // A list item that appears in a copyin clause must be threadprivate. 14832 if (!DSAStack->isThreadPrivate(VD)) { 14833 Diag(ELoc, diag::err_omp_required_access) 14834 << getOpenMPClauseName(OMPC_copyin) 14835 << getOpenMPDirectiveName(OMPD_threadprivate); 14836 continue; 14837 } 14838 14839 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14840 // A variable of class type (or array thereof) that appears in a 14841 // copyin clause requires an accessible, unambiguous copy assignment 14842 // operator for the class type. 14843 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14844 VarDecl *SrcVD = 14845 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14846 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14847 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14848 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14849 VarDecl *DstVD = 14850 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14851 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14852 DeclRefExpr *PseudoDstExpr = 14853 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14854 // For arrays generate assignment operation for single element and replace 14855 // it by the original array element in CodeGen. 14856 ExprResult AssignmentOp = 14857 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14858 PseudoSrcExpr); 14859 if (AssignmentOp.isInvalid()) 14860 continue; 14861 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14862 /*DiscardedValue*/ false); 14863 if (AssignmentOp.isInvalid()) 14864 continue; 14865 14866 DSAStack->addDSA(VD, DE, OMPC_copyin); 14867 Vars.push_back(DE); 14868 SrcExprs.push_back(PseudoSrcExpr); 14869 DstExprs.push_back(PseudoDstExpr); 14870 AssignmentOps.push_back(AssignmentOp.get()); 14871 } 14872 14873 if (Vars.empty()) 14874 return nullptr; 14875 14876 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14877 SrcExprs, DstExprs, AssignmentOps); 14878 } 14879 14880 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14881 SourceLocation StartLoc, 14882 SourceLocation LParenLoc, 14883 SourceLocation EndLoc) { 14884 SmallVector<Expr *, 8> Vars; 14885 SmallVector<Expr *, 8> SrcExprs; 14886 SmallVector<Expr *, 8> DstExprs; 14887 SmallVector<Expr *, 8> AssignmentOps; 14888 for (Expr *RefExpr : VarList) { 14889 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14890 SourceLocation ELoc; 14891 SourceRange ERange; 14892 Expr *SimpleRefExpr = RefExpr; 14893 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14894 if (Res.second) { 14895 // It will be analyzed later. 14896 Vars.push_back(RefExpr); 14897 SrcExprs.push_back(nullptr); 14898 DstExprs.push_back(nullptr); 14899 AssignmentOps.push_back(nullptr); 14900 } 14901 ValueDecl *D = Res.first; 14902 if (!D) 14903 continue; 14904 14905 QualType Type = D->getType(); 14906 auto *VD = dyn_cast<VarDecl>(D); 14907 14908 // OpenMP [2.14.4.2, Restrictions, p.2] 14909 // A list item that appears in a copyprivate clause may not appear in a 14910 // private or firstprivate clause on the single construct. 14911 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14912 DSAStackTy::DSAVarData DVar = 14913 DSAStack->getTopDSA(D, /*FromParent=*/false); 14914 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14915 DVar.RefExpr) { 14916 Diag(ELoc, diag::err_omp_wrong_dsa) 14917 << getOpenMPClauseName(DVar.CKind) 14918 << getOpenMPClauseName(OMPC_copyprivate); 14919 reportOriginalDsa(*this, DSAStack, D, DVar); 14920 continue; 14921 } 14922 14923 // OpenMP [2.11.4.2, Restrictions, p.1] 14924 // All list items that appear in a copyprivate clause must be either 14925 // threadprivate or private in the enclosing context. 14926 if (DVar.CKind == OMPC_unknown) { 14927 DVar = DSAStack->getImplicitDSA(D, false); 14928 if (DVar.CKind == OMPC_shared) { 14929 Diag(ELoc, diag::err_omp_required_access) 14930 << getOpenMPClauseName(OMPC_copyprivate) 14931 << "threadprivate or private in the enclosing context"; 14932 reportOriginalDsa(*this, DSAStack, D, DVar); 14933 continue; 14934 } 14935 } 14936 } 14937 14938 // Variably modified types are not supported. 14939 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14940 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14941 << getOpenMPClauseName(OMPC_copyprivate) << Type 14942 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14943 bool IsDecl = 14944 !VD || 14945 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14946 Diag(D->getLocation(), 14947 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14948 << D; 14949 continue; 14950 } 14951 14952 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14953 // A variable of class type (or array thereof) that appears in a 14954 // copyin clause requires an accessible, unambiguous copy assignment 14955 // operator for the class type. 14956 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14957 .getUnqualifiedType(); 14958 VarDecl *SrcVD = 14959 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14960 D->hasAttrs() ? &D->getAttrs() : nullptr); 14961 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14962 VarDecl *DstVD = 14963 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14964 D->hasAttrs() ? &D->getAttrs() : nullptr); 14965 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14966 ExprResult AssignmentOp = BuildBinOp( 14967 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14968 if (AssignmentOp.isInvalid()) 14969 continue; 14970 AssignmentOp = 14971 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14972 if (AssignmentOp.isInvalid()) 14973 continue; 14974 14975 // No need to mark vars as copyprivate, they are already threadprivate or 14976 // implicitly private. 14977 assert(VD || isOpenMPCapturedDecl(D)); 14978 Vars.push_back( 14979 VD ? RefExpr->IgnoreParens() 14980 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14981 SrcExprs.push_back(PseudoSrcExpr); 14982 DstExprs.push_back(PseudoDstExpr); 14983 AssignmentOps.push_back(AssignmentOp.get()); 14984 } 14985 14986 if (Vars.empty()) 14987 return nullptr; 14988 14989 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14990 Vars, SrcExprs, DstExprs, AssignmentOps); 14991 } 14992 14993 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14994 SourceLocation StartLoc, 14995 SourceLocation LParenLoc, 14996 SourceLocation EndLoc) { 14997 if (VarList.empty()) 14998 return nullptr; 14999 15000 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15001 } 15002 15003 OMPClause * 15004 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 15005 SourceLocation DepLoc, SourceLocation ColonLoc, 15006 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15007 SourceLocation LParenLoc, SourceLocation EndLoc) { 15008 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15009 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15010 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15011 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15012 return nullptr; 15013 } 15014 if (DSAStack->getCurrentDirective() != OMPD_ordered && 15015 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15016 DepKind == OMPC_DEPEND_sink)) { 15017 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 15018 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15019 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 15020 /*Last=*/OMPC_DEPEND_unknown, Except) 15021 << getOpenMPClauseName(OMPC_depend); 15022 return nullptr; 15023 } 15024 SmallVector<Expr *, 8> Vars; 15025 DSAStackTy::OperatorOffsetTy OpsOffs; 15026 llvm::APSInt DepCounter(/*BitWidth=*/32); 15027 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15028 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15029 if (const Expr *OrderedCountExpr = 15030 DSAStack->getParentOrderedRegionParam().first) { 15031 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15032 TotalDepCount.setIsUnsigned(/*Val=*/true); 15033 } 15034 } 15035 for (Expr *RefExpr : VarList) { 15036 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15037 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15038 // It will be analyzed later. 15039 Vars.push_back(RefExpr); 15040 continue; 15041 } 15042 15043 SourceLocation ELoc = RefExpr->getExprLoc(); 15044 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15045 if (DepKind == OMPC_DEPEND_sink) { 15046 if (DSAStack->getParentOrderedRegionParam().first && 15047 DepCounter >= TotalDepCount) { 15048 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15049 continue; 15050 } 15051 ++DepCounter; 15052 // OpenMP [2.13.9, Summary] 15053 // depend(dependence-type : vec), where dependence-type is: 15054 // 'sink' and where vec is the iteration vector, which has the form: 15055 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15056 // where n is the value specified by the ordered clause in the loop 15057 // directive, xi denotes the loop iteration variable of the i-th nested 15058 // loop associated with the loop directive, and di is a constant 15059 // non-negative integer. 15060 if (CurContext->isDependentContext()) { 15061 // It will be analyzed later. 15062 Vars.push_back(RefExpr); 15063 continue; 15064 } 15065 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15066 OverloadedOperatorKind OOK = OO_None; 15067 SourceLocation OOLoc; 15068 Expr *LHS = SimpleExpr; 15069 Expr *RHS = nullptr; 15070 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15071 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15072 OOLoc = BO->getOperatorLoc(); 15073 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15074 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15075 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15076 OOK = OCE->getOperator(); 15077 OOLoc = OCE->getOperatorLoc(); 15078 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15079 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15080 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15081 OOK = MCE->getMethodDecl() 15082 ->getNameInfo() 15083 .getName() 15084 .getCXXOverloadedOperator(); 15085 OOLoc = MCE->getCallee()->getExprLoc(); 15086 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15087 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15088 } 15089 SourceLocation ELoc; 15090 SourceRange ERange; 15091 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15092 if (Res.second) { 15093 // It will be analyzed later. 15094 Vars.push_back(RefExpr); 15095 } 15096 ValueDecl *D = Res.first; 15097 if (!D) 15098 continue; 15099 15100 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15101 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15102 continue; 15103 } 15104 if (RHS) { 15105 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15106 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15107 if (RHSRes.isInvalid()) 15108 continue; 15109 } 15110 if (!CurContext->isDependentContext() && 15111 DSAStack->getParentOrderedRegionParam().first && 15112 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15113 const ValueDecl *VD = 15114 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15115 if (VD) 15116 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15117 << 1 << VD; 15118 else 15119 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15120 continue; 15121 } 15122 OpsOffs.emplace_back(RHS, OOK); 15123 } else { 15124 // OpenMP 5.0 [2.17.11, Restrictions] 15125 // List items used in depend clauses cannot be zero-length array sections. 15126 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15127 if (OASE) { 15128 const Expr *Length = OASE->getLength(); 15129 Expr::EvalResult Result; 15130 if (Length && !Length->isValueDependent() && 15131 Length->EvaluateAsInt(Result, Context) && 15132 Result.Val.getInt().isNullValue()) { 15133 Diag(ELoc, 15134 diag::err_omp_depend_zero_length_array_section_not_allowed) 15135 << SimpleExpr->getSourceRange(); 15136 continue; 15137 } 15138 } 15139 15140 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15141 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15142 (ASE && 15143 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 15144 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15145 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15146 << RefExpr->getSourceRange(); 15147 continue; 15148 } 15149 15150 ExprResult Res; 15151 { 15152 Sema::TentativeAnalysisScope Trap(*this); 15153 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15154 RefExpr->IgnoreParenImpCasts()); 15155 } 15156 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 15157 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15158 << RefExpr->getSourceRange(); 15159 continue; 15160 } 15161 } 15162 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15163 } 15164 15165 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15166 TotalDepCount > VarList.size() && 15167 DSAStack->getParentOrderedRegionParam().first && 15168 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15169 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15170 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15171 } 15172 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15173 Vars.empty()) 15174 return nullptr; 15175 15176 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15177 DepKind, DepLoc, ColonLoc, Vars, 15178 TotalDepCount.getZExtValue()); 15179 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15180 DSAStack->isParentOrderedRegion()) 15181 DSAStack->addDoacrossDependClause(C, OpsOffs); 15182 return C; 15183 } 15184 15185 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 15186 SourceLocation LParenLoc, 15187 SourceLocation EndLoc) { 15188 Expr *ValExpr = Device; 15189 Stmt *HelperValStmt = nullptr; 15190 15191 // OpenMP [2.9.1, Restrictions] 15192 // The device expression must evaluate to a non-negative integer value. 15193 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15194 /*StrictlyPositive=*/false)) 15195 return nullptr; 15196 15197 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15198 OpenMPDirectiveKind CaptureRegion = 15199 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15200 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15201 ValExpr = MakeFullExpr(ValExpr).get(); 15202 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15203 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15204 HelperValStmt = buildPreInits(Context, Captures); 15205 } 15206 15207 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 15208 StartLoc, LParenLoc, EndLoc); 15209 } 15210 15211 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15212 DSAStackTy *Stack, QualType QTy, 15213 bool FullCheck = true) { 15214 NamedDecl *ND; 15215 if (QTy->isIncompleteType(&ND)) { 15216 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15217 return false; 15218 } 15219 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15220 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15221 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15222 return true; 15223 } 15224 15225 /// Return true if it can be proven that the provided array expression 15226 /// (array section or array subscript) does NOT specify the whole size of the 15227 /// array whose base type is \a BaseQTy. 15228 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15229 const Expr *E, 15230 QualType BaseQTy) { 15231 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15232 15233 // If this is an array subscript, it refers to the whole size if the size of 15234 // the dimension is constant and equals 1. Also, an array section assumes the 15235 // format of an array subscript if no colon is used. 15236 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15237 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15238 return ATy->getSize().getSExtValue() != 1; 15239 // Size can't be evaluated statically. 15240 return false; 15241 } 15242 15243 assert(OASE && "Expecting array section if not an array subscript."); 15244 const Expr *LowerBound = OASE->getLowerBound(); 15245 const Expr *Length = OASE->getLength(); 15246 15247 // If there is a lower bound that does not evaluates to zero, we are not 15248 // covering the whole dimension. 15249 if (LowerBound) { 15250 Expr::EvalResult Result; 15251 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15252 return false; // Can't get the integer value as a constant. 15253 15254 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15255 if (ConstLowerBound.getSExtValue()) 15256 return true; 15257 } 15258 15259 // If we don't have a length we covering the whole dimension. 15260 if (!Length) 15261 return false; 15262 15263 // If the base is a pointer, we don't have a way to get the size of the 15264 // pointee. 15265 if (BaseQTy->isPointerType()) 15266 return false; 15267 15268 // We can only check if the length is the same as the size of the dimension 15269 // if we have a constant array. 15270 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 15271 if (!CATy) 15272 return false; 15273 15274 Expr::EvalResult Result; 15275 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15276 return false; // Can't get the integer value as a constant. 15277 15278 llvm::APSInt ConstLength = Result.Val.getInt(); 15279 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 15280 } 15281 15282 // Return true if it can be proven that the provided array expression (array 15283 // section or array subscript) does NOT specify a single element of the array 15284 // whose base type is \a BaseQTy. 15285 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 15286 const Expr *E, 15287 QualType BaseQTy) { 15288 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15289 15290 // An array subscript always refer to a single element. Also, an array section 15291 // assumes the format of an array subscript if no colon is used. 15292 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 15293 return false; 15294 15295 assert(OASE && "Expecting array section if not an array subscript."); 15296 const Expr *Length = OASE->getLength(); 15297 15298 // If we don't have a length we have to check if the array has unitary size 15299 // for this dimension. Also, we should always expect a length if the base type 15300 // is pointer. 15301 if (!Length) { 15302 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15303 return ATy->getSize().getSExtValue() != 1; 15304 // We cannot assume anything. 15305 return false; 15306 } 15307 15308 // Check if the length evaluates to 1. 15309 Expr::EvalResult Result; 15310 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15311 return false; // Can't get the integer value as a constant. 15312 15313 llvm::APSInt ConstLength = Result.Val.getInt(); 15314 return ConstLength.getSExtValue() != 1; 15315 } 15316 15317 // Return the expression of the base of the mappable expression or null if it 15318 // cannot be determined and do all the necessary checks to see if the expression 15319 // is valid as a standalone mappable expression. In the process, record all the 15320 // components of the expression. 15321 static const Expr *checkMapClauseExpressionBase( 15322 Sema &SemaRef, Expr *E, 15323 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 15324 OpenMPClauseKind CKind, bool NoDiagnose) { 15325 SourceLocation ELoc = E->getExprLoc(); 15326 SourceRange ERange = E->getSourceRange(); 15327 15328 // The base of elements of list in a map clause have to be either: 15329 // - a reference to variable or field. 15330 // - a member expression. 15331 // - an array expression. 15332 // 15333 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 15334 // reference to 'r'. 15335 // 15336 // If we have: 15337 // 15338 // struct SS { 15339 // Bla S; 15340 // foo() { 15341 // #pragma omp target map (S.Arr[:12]); 15342 // } 15343 // } 15344 // 15345 // We want to retrieve the member expression 'this->S'; 15346 15347 const Expr *RelevantExpr = nullptr; 15348 15349 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 15350 // If a list item is an array section, it must specify contiguous storage. 15351 // 15352 // For this restriction it is sufficient that we make sure only references 15353 // to variables or fields and array expressions, and that no array sections 15354 // exist except in the rightmost expression (unless they cover the whole 15355 // dimension of the array). E.g. these would be invalid: 15356 // 15357 // r.ArrS[3:5].Arr[6:7] 15358 // 15359 // r.ArrS[3:5].x 15360 // 15361 // but these would be valid: 15362 // r.ArrS[3].Arr[6:7] 15363 // 15364 // r.ArrS[3].x 15365 15366 bool AllowUnitySizeArraySection = true; 15367 bool AllowWholeSizeArraySection = true; 15368 15369 while (!RelevantExpr) { 15370 E = E->IgnoreParenImpCasts(); 15371 15372 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 15373 if (!isa<VarDecl>(CurE->getDecl())) 15374 return nullptr; 15375 15376 RelevantExpr = CurE; 15377 15378 // If we got a reference to a declaration, we should not expect any array 15379 // section before that. 15380 AllowUnitySizeArraySection = false; 15381 AllowWholeSizeArraySection = false; 15382 15383 // Record the component. 15384 CurComponents.emplace_back(CurE, CurE->getDecl()); 15385 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 15386 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 15387 15388 if (isa<CXXThisExpr>(BaseE)) 15389 // We found a base expression: this->Val. 15390 RelevantExpr = CurE; 15391 else 15392 E = BaseE; 15393 15394 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 15395 if (!NoDiagnose) { 15396 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 15397 << CurE->getSourceRange(); 15398 return nullptr; 15399 } 15400 if (RelevantExpr) 15401 return nullptr; 15402 continue; 15403 } 15404 15405 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 15406 15407 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 15408 // A bit-field cannot appear in a map clause. 15409 // 15410 if (FD->isBitField()) { 15411 if (!NoDiagnose) { 15412 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 15413 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 15414 return nullptr; 15415 } 15416 if (RelevantExpr) 15417 return nullptr; 15418 continue; 15419 } 15420 15421 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15422 // If the type of a list item is a reference to a type T then the type 15423 // will be considered to be T for all purposes of this clause. 15424 QualType CurType = BaseE->getType().getNonReferenceType(); 15425 15426 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 15427 // A list item cannot be a variable that is a member of a structure with 15428 // a union type. 15429 // 15430 if (CurType->isUnionType()) { 15431 if (!NoDiagnose) { 15432 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 15433 << CurE->getSourceRange(); 15434 return nullptr; 15435 } 15436 continue; 15437 } 15438 15439 // If we got a member expression, we should not expect any array section 15440 // before that: 15441 // 15442 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 15443 // If a list item is an element of a structure, only the rightmost symbol 15444 // of the variable reference can be an array section. 15445 // 15446 AllowUnitySizeArraySection = false; 15447 AllowWholeSizeArraySection = false; 15448 15449 // Record the component. 15450 CurComponents.emplace_back(CurE, FD); 15451 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 15452 E = CurE->getBase()->IgnoreParenImpCasts(); 15453 15454 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 15455 if (!NoDiagnose) { 15456 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15457 << 0 << CurE->getSourceRange(); 15458 return nullptr; 15459 } 15460 continue; 15461 } 15462 15463 // If we got an array subscript that express the whole dimension we 15464 // can have any array expressions before. If it only expressing part of 15465 // the dimension, we can only have unitary-size array expressions. 15466 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 15467 E->getType())) 15468 AllowWholeSizeArraySection = false; 15469 15470 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15471 Expr::EvalResult Result; 15472 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 15473 if (!Result.Val.getInt().isNullValue()) { 15474 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15475 diag::err_omp_invalid_map_this_expr); 15476 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15477 diag::note_omp_invalid_subscript_on_this_ptr_map); 15478 } 15479 } 15480 RelevantExpr = TE; 15481 } 15482 15483 // Record the component - we don't have any declaration associated. 15484 CurComponents.emplace_back(CurE, nullptr); 15485 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 15486 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 15487 E = CurE->getBase()->IgnoreParenImpCasts(); 15488 15489 QualType CurType = 15490 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15491 15492 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15493 // If the type of a list item is a reference to a type T then the type 15494 // will be considered to be T for all purposes of this clause. 15495 if (CurType->isReferenceType()) 15496 CurType = CurType->getPointeeType(); 15497 15498 bool IsPointer = CurType->isAnyPointerType(); 15499 15500 if (!IsPointer && !CurType->isArrayType()) { 15501 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15502 << 0 << CurE->getSourceRange(); 15503 return nullptr; 15504 } 15505 15506 bool NotWhole = 15507 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 15508 bool NotUnity = 15509 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 15510 15511 if (AllowWholeSizeArraySection) { 15512 // Any array section is currently allowed. Allowing a whole size array 15513 // section implies allowing a unity array section as well. 15514 // 15515 // If this array section refers to the whole dimension we can still 15516 // accept other array sections before this one, except if the base is a 15517 // pointer. Otherwise, only unitary sections are accepted. 15518 if (NotWhole || IsPointer) 15519 AllowWholeSizeArraySection = false; 15520 } else if (AllowUnitySizeArraySection && NotUnity) { 15521 // A unity or whole array section is not allowed and that is not 15522 // compatible with the properties of the current array section. 15523 SemaRef.Diag( 15524 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 15525 << CurE->getSourceRange(); 15526 return nullptr; 15527 } 15528 15529 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15530 Expr::EvalResult ResultR; 15531 Expr::EvalResult ResultL; 15532 if (CurE->getLength()->EvaluateAsInt(ResultR, 15533 SemaRef.getASTContext())) { 15534 if (!ResultR.Val.getInt().isOneValue()) { 15535 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15536 diag::err_omp_invalid_map_this_expr); 15537 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15538 diag::note_omp_invalid_length_on_this_ptr_mapping); 15539 } 15540 } 15541 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 15542 ResultL, SemaRef.getASTContext())) { 15543 if (!ResultL.Val.getInt().isNullValue()) { 15544 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15545 diag::err_omp_invalid_map_this_expr); 15546 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15547 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 15548 } 15549 } 15550 RelevantExpr = TE; 15551 } 15552 15553 // Record the component - we don't have any declaration associated. 15554 CurComponents.emplace_back(CurE, nullptr); 15555 } else { 15556 if (!NoDiagnose) { 15557 // If nothing else worked, this is not a valid map clause expression. 15558 SemaRef.Diag( 15559 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 15560 << ERange; 15561 } 15562 return nullptr; 15563 } 15564 } 15565 15566 return RelevantExpr; 15567 } 15568 15569 // Return true if expression E associated with value VD has conflicts with other 15570 // map information. 15571 static bool checkMapConflicts( 15572 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15573 bool CurrentRegionOnly, 15574 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15575 OpenMPClauseKind CKind) { 15576 assert(VD && E); 15577 SourceLocation ELoc = E->getExprLoc(); 15578 SourceRange ERange = E->getSourceRange(); 15579 15580 // In order to easily check the conflicts we need to match each component of 15581 // the expression under test with the components of the expressions that are 15582 // already in the stack. 15583 15584 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15585 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15586 "Map clause expression with unexpected base!"); 15587 15588 // Variables to help detecting enclosing problems in data environment nests. 15589 bool IsEnclosedByDataEnvironmentExpr = false; 15590 const Expr *EnclosingExpr = nullptr; 15591 15592 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15593 VD, CurrentRegionOnly, 15594 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15595 ERange, CKind, &EnclosingExpr, 15596 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15597 StackComponents, 15598 OpenMPClauseKind) { 15599 assert(!StackComponents.empty() && 15600 "Map clause expression with no components!"); 15601 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15602 "Map clause expression with unexpected base!"); 15603 (void)VD; 15604 15605 // The whole expression in the stack. 15606 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15607 15608 // Expressions must start from the same base. Here we detect at which 15609 // point both expressions diverge from each other and see if we can 15610 // detect if the memory referred to both expressions is contiguous and 15611 // do not overlap. 15612 auto CI = CurComponents.rbegin(); 15613 auto CE = CurComponents.rend(); 15614 auto SI = StackComponents.rbegin(); 15615 auto SE = StackComponents.rend(); 15616 for (; CI != CE && SI != SE; ++CI, ++SI) { 15617 15618 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15619 // At most one list item can be an array item derived from a given 15620 // variable in map clauses of the same construct. 15621 if (CurrentRegionOnly && 15622 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15623 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15624 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15625 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15626 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15627 diag::err_omp_multiple_array_items_in_map_clause) 15628 << CI->getAssociatedExpression()->getSourceRange(); 15629 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15630 diag::note_used_here) 15631 << SI->getAssociatedExpression()->getSourceRange(); 15632 return true; 15633 } 15634 15635 // Do both expressions have the same kind? 15636 if (CI->getAssociatedExpression()->getStmtClass() != 15637 SI->getAssociatedExpression()->getStmtClass()) 15638 break; 15639 15640 // Are we dealing with different variables/fields? 15641 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15642 break; 15643 } 15644 // Check if the extra components of the expressions in the enclosing 15645 // data environment are redundant for the current base declaration. 15646 // If they are, the maps completely overlap, which is legal. 15647 for (; SI != SE; ++SI) { 15648 QualType Type; 15649 if (const auto *ASE = 15650 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15651 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15652 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15653 SI->getAssociatedExpression())) { 15654 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15655 Type = 15656 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15657 } 15658 if (Type.isNull() || Type->isAnyPointerType() || 15659 checkArrayExpressionDoesNotReferToWholeSize( 15660 SemaRef, SI->getAssociatedExpression(), Type)) 15661 break; 15662 } 15663 15664 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15665 // List items of map clauses in the same construct must not share 15666 // original storage. 15667 // 15668 // If the expressions are exactly the same or one is a subset of the 15669 // other, it means they are sharing storage. 15670 if (CI == CE && SI == SE) { 15671 if (CurrentRegionOnly) { 15672 if (CKind == OMPC_map) { 15673 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15674 } else { 15675 assert(CKind == OMPC_to || CKind == OMPC_from); 15676 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15677 << ERange; 15678 } 15679 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15680 << RE->getSourceRange(); 15681 return true; 15682 } 15683 // If we find the same expression in the enclosing data environment, 15684 // that is legal. 15685 IsEnclosedByDataEnvironmentExpr = true; 15686 return false; 15687 } 15688 15689 QualType DerivedType = 15690 std::prev(CI)->getAssociatedDeclaration()->getType(); 15691 SourceLocation DerivedLoc = 15692 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15693 15694 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15695 // If the type of a list item is a reference to a type T then the type 15696 // will be considered to be T for all purposes of this clause. 15697 DerivedType = DerivedType.getNonReferenceType(); 15698 15699 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15700 // A variable for which the type is pointer and an array section 15701 // derived from that variable must not appear as list items of map 15702 // clauses of the same construct. 15703 // 15704 // Also, cover one of the cases in: 15705 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15706 // If any part of the original storage of a list item has corresponding 15707 // storage in the device data environment, all of the original storage 15708 // must have corresponding storage in the device data environment. 15709 // 15710 if (DerivedType->isAnyPointerType()) { 15711 if (CI == CE || SI == SE) { 15712 SemaRef.Diag( 15713 DerivedLoc, 15714 diag::err_omp_pointer_mapped_along_with_derived_section) 15715 << DerivedLoc; 15716 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15717 << RE->getSourceRange(); 15718 return true; 15719 } 15720 if (CI->getAssociatedExpression()->getStmtClass() != 15721 SI->getAssociatedExpression()->getStmtClass() || 15722 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15723 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15724 assert(CI != CE && SI != SE); 15725 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15726 << DerivedLoc; 15727 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15728 << RE->getSourceRange(); 15729 return true; 15730 } 15731 } 15732 15733 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15734 // List items of map clauses in the same construct must not share 15735 // original storage. 15736 // 15737 // An expression is a subset of the other. 15738 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15739 if (CKind == OMPC_map) { 15740 if (CI != CE || SI != SE) { 15741 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15742 // a pointer. 15743 auto Begin = 15744 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15745 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15746 auto It = Begin; 15747 while (It != End && !It->getAssociatedDeclaration()) 15748 std::advance(It, 1); 15749 assert(It != End && 15750 "Expected at least one component with the declaration."); 15751 if (It != Begin && It->getAssociatedDeclaration() 15752 ->getType() 15753 .getCanonicalType() 15754 ->isAnyPointerType()) { 15755 IsEnclosedByDataEnvironmentExpr = false; 15756 EnclosingExpr = nullptr; 15757 return false; 15758 } 15759 } 15760 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15761 } else { 15762 assert(CKind == OMPC_to || CKind == OMPC_from); 15763 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15764 << ERange; 15765 } 15766 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15767 << RE->getSourceRange(); 15768 return true; 15769 } 15770 15771 // The current expression uses the same base as other expression in the 15772 // data environment but does not contain it completely. 15773 if (!CurrentRegionOnly && SI != SE) 15774 EnclosingExpr = RE; 15775 15776 // The current expression is a subset of the expression in the data 15777 // environment. 15778 IsEnclosedByDataEnvironmentExpr |= 15779 (!CurrentRegionOnly && CI != CE && SI == SE); 15780 15781 return false; 15782 }); 15783 15784 if (CurrentRegionOnly) 15785 return FoundError; 15786 15787 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15788 // If any part of the original storage of a list item has corresponding 15789 // storage in the device data environment, all of the original storage must 15790 // have corresponding storage in the device data environment. 15791 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15792 // If a list item is an element of a structure, and a different element of 15793 // the structure has a corresponding list item in the device data environment 15794 // prior to a task encountering the construct associated with the map clause, 15795 // then the list item must also have a corresponding list item in the device 15796 // data environment prior to the task encountering the construct. 15797 // 15798 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15799 SemaRef.Diag(ELoc, 15800 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15801 << ERange; 15802 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15803 << EnclosingExpr->getSourceRange(); 15804 return true; 15805 } 15806 15807 return FoundError; 15808 } 15809 15810 // Look up the user-defined mapper given the mapper name and mapped type, and 15811 // build a reference to it. 15812 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15813 CXXScopeSpec &MapperIdScopeSpec, 15814 const DeclarationNameInfo &MapperId, 15815 QualType Type, 15816 Expr *UnresolvedMapper) { 15817 if (MapperIdScopeSpec.isInvalid()) 15818 return ExprError(); 15819 // Get the actual type for the array type. 15820 if (Type->isArrayType()) { 15821 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15822 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15823 } 15824 // Find all user-defined mappers with the given MapperId. 15825 SmallVector<UnresolvedSet<8>, 4> Lookups; 15826 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15827 Lookup.suppressDiagnostics(); 15828 if (S) { 15829 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15830 NamedDecl *D = Lookup.getRepresentativeDecl(); 15831 while (S && !S->isDeclScope(D)) 15832 S = S->getParent(); 15833 if (S) 15834 S = S->getParent(); 15835 Lookups.emplace_back(); 15836 Lookups.back().append(Lookup.begin(), Lookup.end()); 15837 Lookup.clear(); 15838 } 15839 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15840 // Extract the user-defined mappers with the given MapperId. 15841 Lookups.push_back(UnresolvedSet<8>()); 15842 for (NamedDecl *D : ULE->decls()) { 15843 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15844 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15845 Lookups.back().addDecl(DMD); 15846 } 15847 } 15848 // Defer the lookup for dependent types. The results will be passed through 15849 // UnresolvedMapper on instantiation. 15850 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15851 Type->isInstantiationDependentType() || 15852 Type->containsUnexpandedParameterPack() || 15853 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15854 return !D->isInvalidDecl() && 15855 (D->getType()->isDependentType() || 15856 D->getType()->isInstantiationDependentType() || 15857 D->getType()->containsUnexpandedParameterPack()); 15858 })) { 15859 UnresolvedSet<8> URS; 15860 for (const UnresolvedSet<8> &Set : Lookups) { 15861 if (Set.empty()) 15862 continue; 15863 URS.append(Set.begin(), Set.end()); 15864 } 15865 return UnresolvedLookupExpr::Create( 15866 SemaRef.Context, /*NamingClass=*/nullptr, 15867 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15868 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15869 } 15870 SourceLocation Loc = MapperId.getLoc(); 15871 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15872 // The type must be of struct, union or class type in C and C++ 15873 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15874 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15875 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15876 return ExprError(); 15877 } 15878 // Perform argument dependent lookup. 15879 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15880 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15881 // Return the first user-defined mapper with the desired type. 15882 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15883 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15884 if (!D->isInvalidDecl() && 15885 SemaRef.Context.hasSameType(D->getType(), Type)) 15886 return D; 15887 return nullptr; 15888 })) 15889 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15890 // Find the first user-defined mapper with a type derived from the desired 15891 // type. 15892 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15893 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15894 if (!D->isInvalidDecl() && 15895 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15896 !Type.isMoreQualifiedThan(D->getType())) 15897 return D; 15898 return nullptr; 15899 })) { 15900 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15901 /*DetectVirtual=*/false); 15902 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15903 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15904 VD->getType().getUnqualifiedType()))) { 15905 if (SemaRef.CheckBaseClassAccess( 15906 Loc, VD->getType(), Type, Paths.front(), 15907 /*DiagID=*/0) != Sema::AR_inaccessible) { 15908 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15909 } 15910 } 15911 } 15912 } 15913 // Report error if a mapper is specified, but cannot be found. 15914 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15915 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15916 << Type << MapperId.getName(); 15917 return ExprError(); 15918 } 15919 return ExprEmpty(); 15920 } 15921 15922 namespace { 15923 // Utility struct that gathers all the related lists associated with a mappable 15924 // expression. 15925 struct MappableVarListInfo { 15926 // The list of expressions. 15927 ArrayRef<Expr *> VarList; 15928 // The list of processed expressions. 15929 SmallVector<Expr *, 16> ProcessedVarList; 15930 // The mappble components for each expression. 15931 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15932 // The base declaration of the variable. 15933 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15934 // The reference to the user-defined mapper associated with every expression. 15935 SmallVector<Expr *, 16> UDMapperList; 15936 15937 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15938 // We have a list of components and base declarations for each entry in the 15939 // variable list. 15940 VarComponents.reserve(VarList.size()); 15941 VarBaseDeclarations.reserve(VarList.size()); 15942 } 15943 }; 15944 } 15945 15946 // Check the validity of the provided variable list for the provided clause kind 15947 // \a CKind. In the check process the valid expressions, mappable expression 15948 // components, variables, and user-defined mappers are extracted and used to 15949 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15950 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15951 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15952 static void checkMappableExpressionList( 15953 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15954 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15955 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15956 ArrayRef<Expr *> UnresolvedMappers, 15957 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15958 bool IsMapTypeImplicit = false) { 15959 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15960 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15961 "Unexpected clause kind with mappable expressions!"); 15962 15963 // If the identifier of user-defined mapper is not specified, it is "default". 15964 // We do not change the actual name in this clause to distinguish whether a 15965 // mapper is specified explicitly, i.e., it is not explicitly specified when 15966 // MapperId.getName() is empty. 15967 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15968 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15969 MapperId.setName(DeclNames.getIdentifier( 15970 &SemaRef.getASTContext().Idents.get("default"))); 15971 } 15972 15973 // Iterators to find the current unresolved mapper expression. 15974 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15975 bool UpdateUMIt = false; 15976 Expr *UnresolvedMapper = nullptr; 15977 15978 // Keep track of the mappable components and base declarations in this clause. 15979 // Each entry in the list is going to have a list of components associated. We 15980 // record each set of the components so that we can build the clause later on. 15981 // In the end we should have the same amount of declarations and component 15982 // lists. 15983 15984 for (Expr *RE : MVLI.VarList) { 15985 assert(RE && "Null expr in omp to/from/map clause"); 15986 SourceLocation ELoc = RE->getExprLoc(); 15987 15988 // Find the current unresolved mapper expression. 15989 if (UpdateUMIt && UMIt != UMEnd) { 15990 UMIt++; 15991 assert( 15992 UMIt != UMEnd && 15993 "Expect the size of UnresolvedMappers to match with that of VarList"); 15994 } 15995 UpdateUMIt = true; 15996 if (UMIt != UMEnd) 15997 UnresolvedMapper = *UMIt; 15998 15999 const Expr *VE = RE->IgnoreParenLValueCasts(); 16000 16001 if (VE->isValueDependent() || VE->isTypeDependent() || 16002 VE->isInstantiationDependent() || 16003 VE->containsUnexpandedParameterPack()) { 16004 // Try to find the associated user-defined mapper. 16005 ExprResult ER = buildUserDefinedMapperRef( 16006 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16007 VE->getType().getCanonicalType(), UnresolvedMapper); 16008 if (ER.isInvalid()) 16009 continue; 16010 MVLI.UDMapperList.push_back(ER.get()); 16011 // We can only analyze this information once the missing information is 16012 // resolved. 16013 MVLI.ProcessedVarList.push_back(RE); 16014 continue; 16015 } 16016 16017 Expr *SimpleExpr = RE->IgnoreParenCasts(); 16018 16019 if (!RE->IgnoreParenImpCasts()->isLValue()) { 16020 SemaRef.Diag(ELoc, 16021 diag::err_omp_expected_named_var_member_or_array_expression) 16022 << RE->getSourceRange(); 16023 continue; 16024 } 16025 16026 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 16027 ValueDecl *CurDeclaration = nullptr; 16028 16029 // Obtain the array or member expression bases if required. Also, fill the 16030 // components array with all the components identified in the process. 16031 const Expr *BE = checkMapClauseExpressionBase( 16032 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 16033 if (!BE) 16034 continue; 16035 16036 assert(!CurComponents.empty() && 16037 "Invalid mappable expression information."); 16038 16039 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 16040 // Add store "this" pointer to class in DSAStackTy for future checking 16041 DSAS->addMappedClassesQualTypes(TE->getType()); 16042 // Try to find the associated user-defined mapper. 16043 ExprResult ER = buildUserDefinedMapperRef( 16044 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16045 VE->getType().getCanonicalType(), UnresolvedMapper); 16046 if (ER.isInvalid()) 16047 continue; 16048 MVLI.UDMapperList.push_back(ER.get()); 16049 // Skip restriction checking for variable or field declarations 16050 MVLI.ProcessedVarList.push_back(RE); 16051 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16052 MVLI.VarComponents.back().append(CurComponents.begin(), 16053 CurComponents.end()); 16054 MVLI.VarBaseDeclarations.push_back(nullptr); 16055 continue; 16056 } 16057 16058 // For the following checks, we rely on the base declaration which is 16059 // expected to be associated with the last component. The declaration is 16060 // expected to be a variable or a field (if 'this' is being mapped). 16061 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 16062 assert(CurDeclaration && "Null decl on map clause."); 16063 assert( 16064 CurDeclaration->isCanonicalDecl() && 16065 "Expecting components to have associated only canonical declarations."); 16066 16067 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 16068 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 16069 16070 assert((VD || FD) && "Only variables or fields are expected here!"); 16071 (void)FD; 16072 16073 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 16074 // threadprivate variables cannot appear in a map clause. 16075 // OpenMP 4.5 [2.10.5, target update Construct] 16076 // threadprivate variables cannot appear in a from clause. 16077 if (VD && DSAS->isThreadPrivate(VD)) { 16078 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16079 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 16080 << getOpenMPClauseName(CKind); 16081 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 16082 continue; 16083 } 16084 16085 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16086 // A list item cannot appear in both a map clause and a data-sharing 16087 // attribute clause on the same construct. 16088 16089 // Check conflicts with other map clause expressions. We check the conflicts 16090 // with the current construct separately from the enclosing data 16091 // environment, because the restrictions are different. We only have to 16092 // check conflicts across regions for the map clauses. 16093 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16094 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 16095 break; 16096 if (CKind == OMPC_map && 16097 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16098 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 16099 break; 16100 16101 // OpenMP 4.5 [2.10.5, target update Construct] 16102 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16103 // If the type of a list item is a reference to a type T then the type will 16104 // be considered to be T for all purposes of this clause. 16105 auto I = llvm::find_if( 16106 CurComponents, 16107 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16108 return MC.getAssociatedDeclaration(); 16109 }); 16110 assert(I != CurComponents.end() && "Null decl on map clause."); 16111 QualType Type; 16112 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16113 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16114 if (ASE) { 16115 Type = ASE->getType().getNonReferenceType(); 16116 } else if (OASE) { 16117 QualType BaseType = 16118 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16119 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16120 Type = ATy->getElementType(); 16121 else 16122 Type = BaseType->getPointeeType(); 16123 Type = Type.getNonReferenceType(); 16124 } else { 16125 Type = VE->getType(); 16126 } 16127 16128 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 16129 // A list item in a to or from clause must have a mappable type. 16130 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16131 // A list item must have a mappable type. 16132 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 16133 DSAS, Type)) 16134 continue; 16135 16136 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 16137 16138 if (CKind == OMPC_map) { 16139 // target enter data 16140 // OpenMP [2.10.2, Restrictions, p. 99] 16141 // A map-type must be specified in all map clauses and must be either 16142 // to or alloc. 16143 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 16144 if (DKind == OMPD_target_enter_data && 16145 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 16146 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16147 << (IsMapTypeImplicit ? 1 : 0) 16148 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16149 << getOpenMPDirectiveName(DKind); 16150 continue; 16151 } 16152 16153 // target exit_data 16154 // OpenMP [2.10.3, Restrictions, p. 102] 16155 // A map-type must be specified in all map clauses and must be either 16156 // from, release, or delete. 16157 if (DKind == OMPD_target_exit_data && 16158 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 16159 MapType == OMPC_MAP_delete)) { 16160 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16161 << (IsMapTypeImplicit ? 1 : 0) 16162 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16163 << getOpenMPDirectiveName(DKind); 16164 continue; 16165 } 16166 16167 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 16168 // A list item cannot appear in both a map clause and a data-sharing 16169 // attribute clause on the same construct 16170 // 16171 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 16172 // A list item cannot appear in both a map clause and a data-sharing 16173 // attribute clause on the same construct unless the construct is a 16174 // combined construct. 16175 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 16176 isOpenMPTargetExecutionDirective(DKind)) || 16177 DKind == OMPD_target)) { 16178 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16179 if (isOpenMPPrivate(DVar.CKind)) { 16180 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16181 << getOpenMPClauseName(DVar.CKind) 16182 << getOpenMPClauseName(OMPC_map) 16183 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 16184 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 16185 continue; 16186 } 16187 } 16188 } 16189 16190 // Try to find the associated user-defined mapper. 16191 ExprResult ER = buildUserDefinedMapperRef( 16192 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16193 Type.getCanonicalType(), UnresolvedMapper); 16194 if (ER.isInvalid()) 16195 continue; 16196 MVLI.UDMapperList.push_back(ER.get()); 16197 16198 // Save the current expression. 16199 MVLI.ProcessedVarList.push_back(RE); 16200 16201 // Store the components in the stack so that they can be used to check 16202 // against other clauses later on. 16203 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 16204 /*WhereFoundClauseKind=*/OMPC_map); 16205 16206 // Save the components and declaration to create the clause. For purposes of 16207 // the clause creation, any component list that has has base 'this' uses 16208 // null as base declaration. 16209 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16210 MVLI.VarComponents.back().append(CurComponents.begin(), 16211 CurComponents.end()); 16212 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 16213 : CurDeclaration); 16214 } 16215 } 16216 16217 OMPClause *Sema::ActOnOpenMPMapClause( 16218 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 16219 ArrayRef<SourceLocation> MapTypeModifiersLoc, 16220 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 16221 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 16222 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 16223 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 16224 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 16225 OMPC_MAP_MODIFIER_unknown, 16226 OMPC_MAP_MODIFIER_unknown}; 16227 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 16228 16229 // Process map-type-modifiers, flag errors for duplicate modifiers. 16230 unsigned Count = 0; 16231 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 16232 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 16233 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 16234 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 16235 continue; 16236 } 16237 assert(Count < OMPMapClause::NumberOfModifiers && 16238 "Modifiers exceed the allowed number of map type modifiers"); 16239 Modifiers[Count] = MapTypeModifiers[I]; 16240 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 16241 ++Count; 16242 } 16243 16244 MappableVarListInfo MVLI(VarList); 16245 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 16246 MapperIdScopeSpec, MapperId, UnresolvedMappers, 16247 MapType, IsMapTypeImplicit); 16248 16249 // We need to produce a map clause even if we don't have variables so that 16250 // other diagnostics related with non-existing map clauses are accurate. 16251 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 16252 MVLI.VarBaseDeclarations, MVLI.VarComponents, 16253 MVLI.UDMapperList, Modifiers, ModifiersLoc, 16254 MapperIdScopeSpec.getWithLocInContext(Context), 16255 MapperId, MapType, IsMapTypeImplicit, MapLoc); 16256 } 16257 16258 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 16259 TypeResult ParsedType) { 16260 assert(ParsedType.isUsable()); 16261 16262 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 16263 if (ReductionType.isNull()) 16264 return QualType(); 16265 16266 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 16267 // A type name in a declare reduction directive cannot be a function type, an 16268 // array type, a reference type, or a type qualified with const, volatile or 16269 // restrict. 16270 if (ReductionType.hasQualifiers()) { 16271 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 16272 return QualType(); 16273 } 16274 16275 if (ReductionType->isFunctionType()) { 16276 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 16277 return QualType(); 16278 } 16279 if (ReductionType->isReferenceType()) { 16280 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 16281 return QualType(); 16282 } 16283 if (ReductionType->isArrayType()) { 16284 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 16285 return QualType(); 16286 } 16287 return ReductionType; 16288 } 16289 16290 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 16291 Scope *S, DeclContext *DC, DeclarationName Name, 16292 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 16293 AccessSpecifier AS, Decl *PrevDeclInScope) { 16294 SmallVector<Decl *, 8> Decls; 16295 Decls.reserve(ReductionTypes.size()); 16296 16297 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 16298 forRedeclarationInCurContext()); 16299 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 16300 // A reduction-identifier may not be re-declared in the current scope for the 16301 // same type or for a type that is compatible according to the base language 16302 // rules. 16303 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16304 OMPDeclareReductionDecl *PrevDRD = nullptr; 16305 bool InCompoundScope = true; 16306 if (S != nullptr) { 16307 // Find previous declaration with the same name not referenced in other 16308 // declarations. 16309 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16310 InCompoundScope = 16311 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16312 LookupName(Lookup, S); 16313 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16314 /*AllowInlineNamespace=*/false); 16315 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 16316 LookupResult::Filter Filter = Lookup.makeFilter(); 16317 while (Filter.hasNext()) { 16318 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 16319 if (InCompoundScope) { 16320 auto I = UsedAsPrevious.find(PrevDecl); 16321 if (I == UsedAsPrevious.end()) 16322 UsedAsPrevious[PrevDecl] = false; 16323 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 16324 UsedAsPrevious[D] = true; 16325 } 16326 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16327 PrevDecl->getLocation(); 16328 } 16329 Filter.done(); 16330 if (InCompoundScope) { 16331 for (const auto &PrevData : UsedAsPrevious) { 16332 if (!PrevData.second) { 16333 PrevDRD = PrevData.first; 16334 break; 16335 } 16336 } 16337 } 16338 } else if (PrevDeclInScope != nullptr) { 16339 auto *PrevDRDInScope = PrevDRD = 16340 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 16341 do { 16342 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 16343 PrevDRDInScope->getLocation(); 16344 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 16345 } while (PrevDRDInScope != nullptr); 16346 } 16347 for (const auto &TyData : ReductionTypes) { 16348 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 16349 bool Invalid = false; 16350 if (I != PreviousRedeclTypes.end()) { 16351 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 16352 << TyData.first; 16353 Diag(I->second, diag::note_previous_definition); 16354 Invalid = true; 16355 } 16356 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 16357 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 16358 Name, TyData.first, PrevDRD); 16359 DC->addDecl(DRD); 16360 DRD->setAccess(AS); 16361 Decls.push_back(DRD); 16362 if (Invalid) 16363 DRD->setInvalidDecl(); 16364 else 16365 PrevDRD = DRD; 16366 } 16367 16368 return DeclGroupPtrTy::make( 16369 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 16370 } 16371 16372 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 16373 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16374 16375 // Enter new function scope. 16376 PushFunctionScope(); 16377 setFunctionHasBranchProtectedScope(); 16378 getCurFunction()->setHasOMPDeclareReductionCombiner(); 16379 16380 if (S != nullptr) 16381 PushDeclContext(S, DRD); 16382 else 16383 CurContext = DRD; 16384 16385 PushExpressionEvaluationContext( 16386 ExpressionEvaluationContext::PotentiallyEvaluated); 16387 16388 QualType ReductionType = DRD->getType(); 16389 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 16390 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 16391 // uses semantics of argument handles by value, but it should be passed by 16392 // reference. C lang does not support references, so pass all parameters as 16393 // pointers. 16394 // Create 'T omp_in;' variable. 16395 VarDecl *OmpInParm = 16396 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 16397 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 16398 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 16399 // uses semantics of argument handles by value, but it should be passed by 16400 // reference. C lang does not support references, so pass all parameters as 16401 // pointers. 16402 // Create 'T omp_out;' variable. 16403 VarDecl *OmpOutParm = 16404 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 16405 if (S != nullptr) { 16406 PushOnScopeChains(OmpInParm, S); 16407 PushOnScopeChains(OmpOutParm, S); 16408 } else { 16409 DRD->addDecl(OmpInParm); 16410 DRD->addDecl(OmpOutParm); 16411 } 16412 Expr *InE = 16413 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 16414 Expr *OutE = 16415 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 16416 DRD->setCombinerData(InE, OutE); 16417 } 16418 16419 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 16420 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16421 DiscardCleanupsInEvaluationContext(); 16422 PopExpressionEvaluationContext(); 16423 16424 PopDeclContext(); 16425 PopFunctionScopeInfo(); 16426 16427 if (Combiner != nullptr) 16428 DRD->setCombiner(Combiner); 16429 else 16430 DRD->setInvalidDecl(); 16431 } 16432 16433 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 16434 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16435 16436 // Enter new function scope. 16437 PushFunctionScope(); 16438 setFunctionHasBranchProtectedScope(); 16439 16440 if (S != nullptr) 16441 PushDeclContext(S, DRD); 16442 else 16443 CurContext = DRD; 16444 16445 PushExpressionEvaluationContext( 16446 ExpressionEvaluationContext::PotentiallyEvaluated); 16447 16448 QualType ReductionType = DRD->getType(); 16449 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 16450 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 16451 // uses semantics of argument handles by value, but it should be passed by 16452 // reference. C lang does not support references, so pass all parameters as 16453 // pointers. 16454 // Create 'T omp_priv;' variable. 16455 VarDecl *OmpPrivParm = 16456 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 16457 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 16458 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 16459 // uses semantics of argument handles by value, but it should be passed by 16460 // reference. C lang does not support references, so pass all parameters as 16461 // pointers. 16462 // Create 'T omp_orig;' variable. 16463 VarDecl *OmpOrigParm = 16464 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 16465 if (S != nullptr) { 16466 PushOnScopeChains(OmpPrivParm, S); 16467 PushOnScopeChains(OmpOrigParm, S); 16468 } else { 16469 DRD->addDecl(OmpPrivParm); 16470 DRD->addDecl(OmpOrigParm); 16471 } 16472 Expr *OrigE = 16473 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 16474 Expr *PrivE = 16475 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 16476 DRD->setInitializerData(OrigE, PrivE); 16477 return OmpPrivParm; 16478 } 16479 16480 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 16481 VarDecl *OmpPrivParm) { 16482 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16483 DiscardCleanupsInEvaluationContext(); 16484 PopExpressionEvaluationContext(); 16485 16486 PopDeclContext(); 16487 PopFunctionScopeInfo(); 16488 16489 if (Initializer != nullptr) { 16490 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 16491 } else if (OmpPrivParm->hasInit()) { 16492 DRD->setInitializer(OmpPrivParm->getInit(), 16493 OmpPrivParm->isDirectInit() 16494 ? OMPDeclareReductionDecl::DirectInit 16495 : OMPDeclareReductionDecl::CopyInit); 16496 } else { 16497 DRD->setInvalidDecl(); 16498 } 16499 } 16500 16501 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 16502 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 16503 for (Decl *D : DeclReductions.get()) { 16504 if (IsValid) { 16505 if (S) 16506 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 16507 /*AddToContext=*/false); 16508 } else { 16509 D->setInvalidDecl(); 16510 } 16511 } 16512 return DeclReductions; 16513 } 16514 16515 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 16516 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 16517 QualType T = TInfo->getType(); 16518 if (D.isInvalidType()) 16519 return true; 16520 16521 if (getLangOpts().CPlusPlus) { 16522 // Check that there are no default arguments (C++ only). 16523 CheckExtraCXXDefaultArguments(D); 16524 } 16525 16526 return CreateParsedType(T, TInfo); 16527 } 16528 16529 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 16530 TypeResult ParsedType) { 16531 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 16532 16533 QualType MapperType = GetTypeFromParser(ParsedType.get()); 16534 assert(!MapperType.isNull() && "Expect valid mapper type"); 16535 16536 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16537 // The type must be of struct, union or class type in C and C++ 16538 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 16539 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 16540 return QualType(); 16541 } 16542 return MapperType; 16543 } 16544 16545 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 16546 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 16547 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 16548 Decl *PrevDeclInScope) { 16549 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 16550 forRedeclarationInCurContext()); 16551 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16552 // A mapper-identifier may not be redeclared in the current scope for the 16553 // same type or for a type that is compatible according to the base language 16554 // rules. 16555 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16556 OMPDeclareMapperDecl *PrevDMD = nullptr; 16557 bool InCompoundScope = true; 16558 if (S != nullptr) { 16559 // Find previous declaration with the same name not referenced in other 16560 // declarations. 16561 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16562 InCompoundScope = 16563 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16564 LookupName(Lookup, S); 16565 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16566 /*AllowInlineNamespace=*/false); 16567 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 16568 LookupResult::Filter Filter = Lookup.makeFilter(); 16569 while (Filter.hasNext()) { 16570 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 16571 if (InCompoundScope) { 16572 auto I = UsedAsPrevious.find(PrevDecl); 16573 if (I == UsedAsPrevious.end()) 16574 UsedAsPrevious[PrevDecl] = false; 16575 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16576 UsedAsPrevious[D] = true; 16577 } 16578 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16579 PrevDecl->getLocation(); 16580 } 16581 Filter.done(); 16582 if (InCompoundScope) { 16583 for (const auto &PrevData : UsedAsPrevious) { 16584 if (!PrevData.second) { 16585 PrevDMD = PrevData.first; 16586 break; 16587 } 16588 } 16589 } 16590 } else if (PrevDeclInScope) { 16591 auto *PrevDMDInScope = PrevDMD = 16592 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16593 do { 16594 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16595 PrevDMDInScope->getLocation(); 16596 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16597 } while (PrevDMDInScope != nullptr); 16598 } 16599 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16600 bool Invalid = false; 16601 if (I != PreviousRedeclTypes.end()) { 16602 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16603 << MapperType << Name; 16604 Diag(I->second, diag::note_previous_definition); 16605 Invalid = true; 16606 } 16607 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16608 MapperType, VN, PrevDMD); 16609 DC->addDecl(DMD); 16610 DMD->setAccess(AS); 16611 if (Invalid) 16612 DMD->setInvalidDecl(); 16613 16614 // Enter new function scope. 16615 PushFunctionScope(); 16616 setFunctionHasBranchProtectedScope(); 16617 16618 CurContext = DMD; 16619 16620 return DMD; 16621 } 16622 16623 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16624 Scope *S, 16625 QualType MapperType, 16626 SourceLocation StartLoc, 16627 DeclarationName VN) { 16628 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16629 if (S) 16630 PushOnScopeChains(VD, S); 16631 else 16632 DMD->addDecl(VD); 16633 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16634 DMD->setMapperVarRef(MapperVarRefExpr); 16635 } 16636 16637 Sema::DeclGroupPtrTy 16638 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16639 ArrayRef<OMPClause *> ClauseList) { 16640 PopDeclContext(); 16641 PopFunctionScopeInfo(); 16642 16643 if (D) { 16644 if (S) 16645 PushOnScopeChains(D, S, /*AddToContext=*/false); 16646 D->CreateClauses(Context, ClauseList); 16647 } 16648 16649 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16650 } 16651 16652 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16653 SourceLocation StartLoc, 16654 SourceLocation LParenLoc, 16655 SourceLocation EndLoc) { 16656 Expr *ValExpr = NumTeams; 16657 Stmt *HelperValStmt = nullptr; 16658 16659 // OpenMP [teams Constrcut, Restrictions] 16660 // The num_teams expression must evaluate to a positive integer value. 16661 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16662 /*StrictlyPositive=*/true)) 16663 return nullptr; 16664 16665 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16666 OpenMPDirectiveKind CaptureRegion = 16667 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 16668 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16669 ValExpr = MakeFullExpr(ValExpr).get(); 16670 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16671 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16672 HelperValStmt = buildPreInits(Context, Captures); 16673 } 16674 16675 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16676 StartLoc, LParenLoc, EndLoc); 16677 } 16678 16679 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16680 SourceLocation StartLoc, 16681 SourceLocation LParenLoc, 16682 SourceLocation EndLoc) { 16683 Expr *ValExpr = ThreadLimit; 16684 Stmt *HelperValStmt = nullptr; 16685 16686 // OpenMP [teams Constrcut, Restrictions] 16687 // The thread_limit expression must evaluate to a positive integer value. 16688 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16689 /*StrictlyPositive=*/true)) 16690 return nullptr; 16691 16692 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16693 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 16694 DKind, OMPC_thread_limit, LangOpts.OpenMP); 16695 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16696 ValExpr = MakeFullExpr(ValExpr).get(); 16697 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16698 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16699 HelperValStmt = buildPreInits(Context, Captures); 16700 } 16701 16702 return new (Context) OMPThreadLimitClause( 16703 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16704 } 16705 16706 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16707 SourceLocation StartLoc, 16708 SourceLocation LParenLoc, 16709 SourceLocation EndLoc) { 16710 Expr *ValExpr = Priority; 16711 Stmt *HelperValStmt = nullptr; 16712 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16713 16714 // OpenMP [2.9.1, task Constrcut] 16715 // The priority-value is a non-negative numerical scalar expression. 16716 if (!isNonNegativeIntegerValue( 16717 ValExpr, *this, OMPC_priority, 16718 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16719 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16720 return nullptr; 16721 16722 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16723 StartLoc, LParenLoc, EndLoc); 16724 } 16725 16726 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16727 SourceLocation StartLoc, 16728 SourceLocation LParenLoc, 16729 SourceLocation EndLoc) { 16730 Expr *ValExpr = Grainsize; 16731 Stmt *HelperValStmt = nullptr; 16732 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16733 16734 // OpenMP [2.9.2, taskloop Constrcut] 16735 // The parameter of the grainsize clause must be a positive integer 16736 // expression. 16737 if (!isNonNegativeIntegerValue( 16738 ValExpr, *this, OMPC_grainsize, 16739 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16740 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16741 return nullptr; 16742 16743 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16744 StartLoc, LParenLoc, EndLoc); 16745 } 16746 16747 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16748 SourceLocation StartLoc, 16749 SourceLocation LParenLoc, 16750 SourceLocation EndLoc) { 16751 Expr *ValExpr = NumTasks; 16752 Stmt *HelperValStmt = nullptr; 16753 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16754 16755 // OpenMP [2.9.2, taskloop Constrcut] 16756 // The parameter of the num_tasks clause must be a positive integer 16757 // expression. 16758 if (!isNonNegativeIntegerValue( 16759 ValExpr, *this, OMPC_num_tasks, 16760 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16761 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16762 return nullptr; 16763 16764 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16765 StartLoc, LParenLoc, EndLoc); 16766 } 16767 16768 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16769 SourceLocation LParenLoc, 16770 SourceLocation EndLoc) { 16771 // OpenMP [2.13.2, critical construct, Description] 16772 // ... where hint-expression is an integer constant expression that evaluates 16773 // to a valid lock hint. 16774 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16775 if (HintExpr.isInvalid()) 16776 return nullptr; 16777 return new (Context) 16778 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16779 } 16780 16781 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16782 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16783 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16784 SourceLocation EndLoc) { 16785 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16786 std::string Values; 16787 Values += "'"; 16788 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16789 Values += "'"; 16790 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16791 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16792 return nullptr; 16793 } 16794 Expr *ValExpr = ChunkSize; 16795 Stmt *HelperValStmt = nullptr; 16796 if (ChunkSize) { 16797 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16798 !ChunkSize->isInstantiationDependent() && 16799 !ChunkSize->containsUnexpandedParameterPack()) { 16800 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16801 ExprResult Val = 16802 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16803 if (Val.isInvalid()) 16804 return nullptr; 16805 16806 ValExpr = Val.get(); 16807 16808 // OpenMP [2.7.1, Restrictions] 16809 // chunk_size must be a loop invariant integer expression with a positive 16810 // value. 16811 llvm::APSInt Result; 16812 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16813 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16814 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16815 << "dist_schedule" << ChunkSize->getSourceRange(); 16816 return nullptr; 16817 } 16818 } else if (getOpenMPCaptureRegionForClause( 16819 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 16820 LangOpts.OpenMP) != OMPD_unknown && 16821 !CurContext->isDependentContext()) { 16822 ValExpr = MakeFullExpr(ValExpr).get(); 16823 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16824 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16825 HelperValStmt = buildPreInits(Context, Captures); 16826 } 16827 } 16828 } 16829 16830 return new (Context) 16831 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16832 Kind, ValExpr, HelperValStmt); 16833 } 16834 16835 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16836 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16837 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16838 SourceLocation KindLoc, SourceLocation EndLoc) { 16839 if (getLangOpts().OpenMP < 50) { 16840 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 16841 Kind != OMPC_DEFAULTMAP_scalar) { 16842 std::string Value; 16843 SourceLocation Loc; 16844 Value += "'"; 16845 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16846 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16847 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16848 Loc = MLoc; 16849 } else { 16850 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16851 OMPC_DEFAULTMAP_scalar); 16852 Loc = KindLoc; 16853 } 16854 Value += "'"; 16855 Diag(Loc, diag::err_omp_unexpected_clause_value) 16856 << Value << getOpenMPClauseName(OMPC_defaultmap); 16857 return nullptr; 16858 } 16859 } else { 16860 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 16861 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 16862 if (!isDefaultmapKind || !isDefaultmapModifier) { 16863 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 16864 "'firstprivate', 'none', 'default'"; 16865 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 16866 if (!isDefaultmapKind && isDefaultmapModifier) { 16867 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16868 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16869 } else if (isDefaultmapKind && !isDefaultmapModifier) { 16870 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16871 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16872 } else { 16873 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16874 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16875 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16876 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16877 } 16878 return nullptr; 16879 } 16880 16881 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 16882 // At most one defaultmap clause for each category can appear on the 16883 // directive. 16884 if (DSAStack->checkDefaultmapCategory(Kind)) { 16885 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 16886 return nullptr; 16887 } 16888 } 16889 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 16890 16891 return new (Context) 16892 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16893 } 16894 16895 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16896 DeclContext *CurLexicalContext = getCurLexicalContext(); 16897 if (!CurLexicalContext->isFileContext() && 16898 !CurLexicalContext->isExternCContext() && 16899 !CurLexicalContext->isExternCXXContext() && 16900 !isa<CXXRecordDecl>(CurLexicalContext) && 16901 !isa<ClassTemplateDecl>(CurLexicalContext) && 16902 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16903 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16904 Diag(Loc, diag::err_omp_region_not_file_context); 16905 return false; 16906 } 16907 ++DeclareTargetNestingLevel; 16908 return true; 16909 } 16910 16911 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16912 assert(DeclareTargetNestingLevel > 0 && 16913 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16914 --DeclareTargetNestingLevel; 16915 } 16916 16917 NamedDecl * 16918 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16919 const DeclarationNameInfo &Id, 16920 NamedDeclSetType &SameDirectiveDecls) { 16921 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16922 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16923 16924 if (Lookup.isAmbiguous()) 16925 return nullptr; 16926 Lookup.suppressDiagnostics(); 16927 16928 if (!Lookup.isSingleResult()) { 16929 VarOrFuncDeclFilterCCC CCC(*this); 16930 if (TypoCorrection Corrected = 16931 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16932 CTK_ErrorRecovery)) { 16933 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16934 << Id.getName()); 16935 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16936 return nullptr; 16937 } 16938 16939 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16940 return nullptr; 16941 } 16942 16943 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16944 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16945 !isa<FunctionTemplateDecl>(ND)) { 16946 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16947 return nullptr; 16948 } 16949 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16950 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16951 return ND; 16952 } 16953 16954 void Sema::ActOnOpenMPDeclareTargetName( 16955 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16956 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16957 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16958 isa<FunctionTemplateDecl>(ND)) && 16959 "Expected variable, function or function template."); 16960 16961 // Diagnose marking after use as it may lead to incorrect diagnosis and 16962 // codegen. 16963 if (LangOpts.OpenMP >= 50 && 16964 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16965 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16966 16967 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16968 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16969 if (DevTy.hasValue() && *DevTy != DT) { 16970 Diag(Loc, diag::err_omp_device_type_mismatch) 16971 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16972 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16973 return; 16974 } 16975 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16976 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16977 if (!Res) { 16978 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16979 SourceRange(Loc, Loc)); 16980 ND->addAttr(A); 16981 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16982 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16983 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16984 } else if (*Res != MT) { 16985 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16986 } 16987 } 16988 16989 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16990 Sema &SemaRef, Decl *D) { 16991 if (!D || !isa<VarDecl>(D)) 16992 return; 16993 auto *VD = cast<VarDecl>(D); 16994 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16995 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16996 if (SemaRef.LangOpts.OpenMP >= 50 && 16997 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16998 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16999 VD->hasGlobalStorage()) { 17000 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17001 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17002 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 17003 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 17004 // If a lambda declaration and definition appears between a 17005 // declare target directive and the matching end declare target 17006 // directive, all variables that are captured by the lambda 17007 // expression must also appear in a to clause. 17008 SemaRef.Diag(VD->getLocation(), 17009 diag::err_omp_lambda_capture_in_declare_target_not_to); 17010 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 17011 << VD << 0 << SR; 17012 return; 17013 } 17014 } 17015 if (MapTy.hasValue()) 17016 return; 17017 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 17018 SemaRef.Diag(SL, diag::note_used_here) << SR; 17019 } 17020 17021 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 17022 Sema &SemaRef, DSAStackTy *Stack, 17023 ValueDecl *VD) { 17024 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 17025 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 17026 /*FullCheck=*/false); 17027 } 17028 17029 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 17030 SourceLocation IdLoc) { 17031 if (!D || D->isInvalidDecl()) 17032 return; 17033 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 17034 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 17035 if (auto *VD = dyn_cast<VarDecl>(D)) { 17036 // Only global variables can be marked as declare target. 17037 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 17038 !VD->isStaticDataMember()) 17039 return; 17040 // 2.10.6: threadprivate variable cannot appear in a declare target 17041 // directive. 17042 if (DSAStack->isThreadPrivate(VD)) { 17043 Diag(SL, diag::err_omp_threadprivate_in_target); 17044 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 17045 return; 17046 } 17047 } 17048 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 17049 D = FTD->getTemplatedDecl(); 17050 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 17051 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17052 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 17053 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 17054 Diag(IdLoc, diag::err_omp_function_in_link_clause); 17055 Diag(FD->getLocation(), diag::note_defined_here) << FD; 17056 return; 17057 } 17058 // Mark the function as must be emitted for the device. 17059 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17060 OMPDeclareTargetDeclAttr::getDeviceType(FD); 17061 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 17062 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 17063 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 17064 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 17065 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 17066 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 17067 } 17068 if (auto *VD = dyn_cast<ValueDecl>(D)) { 17069 // Problem if any with var declared with incomplete type will be reported 17070 // as normal, so no need to check it here. 17071 if ((E || !VD->getType()->isIncompleteType()) && 17072 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 17073 return; 17074 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 17075 // Checking declaration inside declare target region. 17076 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 17077 isa<FunctionTemplateDecl>(D)) { 17078 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 17079 Context, OMPDeclareTargetDeclAttr::MT_To, 17080 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 17081 D->addAttr(A); 17082 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17083 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 17084 } 17085 return; 17086 } 17087 } 17088 if (!E) 17089 return; 17090 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 17091 } 17092 17093 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 17094 CXXScopeSpec &MapperIdScopeSpec, 17095 DeclarationNameInfo &MapperId, 17096 const OMPVarListLocTy &Locs, 17097 ArrayRef<Expr *> UnresolvedMappers) { 17098 MappableVarListInfo MVLI(VarList); 17099 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 17100 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17101 if (MVLI.ProcessedVarList.empty()) 17102 return nullptr; 17103 17104 return OMPToClause::Create( 17105 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17106 MVLI.VarComponents, MVLI.UDMapperList, 17107 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17108 } 17109 17110 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 17111 CXXScopeSpec &MapperIdScopeSpec, 17112 DeclarationNameInfo &MapperId, 17113 const OMPVarListLocTy &Locs, 17114 ArrayRef<Expr *> UnresolvedMappers) { 17115 MappableVarListInfo MVLI(VarList); 17116 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 17117 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17118 if (MVLI.ProcessedVarList.empty()) 17119 return nullptr; 17120 17121 return OMPFromClause::Create( 17122 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17123 MVLI.VarComponents, MVLI.UDMapperList, 17124 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17125 } 17126 17127 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 17128 const OMPVarListLocTy &Locs) { 17129 MappableVarListInfo MVLI(VarList); 17130 SmallVector<Expr *, 8> PrivateCopies; 17131 SmallVector<Expr *, 8> Inits; 17132 17133 for (Expr *RefExpr : VarList) { 17134 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 17135 SourceLocation ELoc; 17136 SourceRange ERange; 17137 Expr *SimpleRefExpr = RefExpr; 17138 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17139 if (Res.second) { 17140 // It will be analyzed later. 17141 MVLI.ProcessedVarList.push_back(RefExpr); 17142 PrivateCopies.push_back(nullptr); 17143 Inits.push_back(nullptr); 17144 } 17145 ValueDecl *D = Res.first; 17146 if (!D) 17147 continue; 17148 17149 QualType Type = D->getType(); 17150 Type = Type.getNonReferenceType().getUnqualifiedType(); 17151 17152 auto *VD = dyn_cast<VarDecl>(D); 17153 17154 // Item should be a pointer or reference to pointer. 17155 if (!Type->isPointerType()) { 17156 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 17157 << 0 << RefExpr->getSourceRange(); 17158 continue; 17159 } 17160 17161 // Build the private variable and the expression that refers to it. 17162 auto VDPrivate = 17163 buildVarDecl(*this, ELoc, Type, D->getName(), 17164 D->hasAttrs() ? &D->getAttrs() : nullptr, 17165 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17166 if (VDPrivate->isInvalidDecl()) 17167 continue; 17168 17169 CurContext->addDecl(VDPrivate); 17170 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17171 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17172 17173 // Add temporary variable to initialize the private copy of the pointer. 17174 VarDecl *VDInit = 17175 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 17176 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 17177 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 17178 AddInitializerToDecl(VDPrivate, 17179 DefaultLvalueConversion(VDInitRefExpr).get(), 17180 /*DirectInit=*/false); 17181 17182 // If required, build a capture to implement the privatization initialized 17183 // with the current list item value. 17184 DeclRefExpr *Ref = nullptr; 17185 if (!VD) 17186 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17187 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 17188 PrivateCopies.push_back(VDPrivateRefExpr); 17189 Inits.push_back(VDInitRefExpr); 17190 17191 // We need to add a data sharing attribute for this variable to make sure it 17192 // is correctly captured. A variable that shows up in a use_device_ptr has 17193 // similar properties of a first private variable. 17194 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17195 17196 // Create a mappable component for the list item. List items in this clause 17197 // only need a component. 17198 MVLI.VarBaseDeclarations.push_back(D); 17199 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17200 MVLI.VarComponents.back().push_back( 17201 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 17202 } 17203 17204 if (MVLI.ProcessedVarList.empty()) 17205 return nullptr; 17206 17207 return OMPUseDevicePtrClause::Create( 17208 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 17209 MVLI.VarBaseDeclarations, MVLI.VarComponents); 17210 } 17211 17212 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 17213 const OMPVarListLocTy &Locs) { 17214 MappableVarListInfo MVLI(VarList); 17215 for (Expr *RefExpr : VarList) { 17216 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 17217 SourceLocation ELoc; 17218 SourceRange ERange; 17219 Expr *SimpleRefExpr = RefExpr; 17220 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17221 if (Res.second) { 17222 // It will be analyzed later. 17223 MVLI.ProcessedVarList.push_back(RefExpr); 17224 } 17225 ValueDecl *D = Res.first; 17226 if (!D) 17227 continue; 17228 17229 QualType Type = D->getType(); 17230 // item should be a pointer or array or reference to pointer or array 17231 if (!Type.getNonReferenceType()->isPointerType() && 17232 !Type.getNonReferenceType()->isArrayType()) { 17233 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 17234 << 0 << RefExpr->getSourceRange(); 17235 continue; 17236 } 17237 17238 // Check if the declaration in the clause does not show up in any data 17239 // sharing attribute. 17240 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17241 if (isOpenMPPrivate(DVar.CKind)) { 17242 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17243 << getOpenMPClauseName(DVar.CKind) 17244 << getOpenMPClauseName(OMPC_is_device_ptr) 17245 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17246 reportOriginalDsa(*this, DSAStack, D, DVar); 17247 continue; 17248 } 17249 17250 const Expr *ConflictExpr; 17251 if (DSAStack->checkMappableExprComponentListsForDecl( 17252 D, /*CurrentRegionOnly=*/true, 17253 [&ConflictExpr]( 17254 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 17255 OpenMPClauseKind) -> bool { 17256 ConflictExpr = R.front().getAssociatedExpression(); 17257 return true; 17258 })) { 17259 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 17260 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 17261 << ConflictExpr->getSourceRange(); 17262 continue; 17263 } 17264 17265 // Store the components in the stack so that they can be used to check 17266 // against other clauses later on. 17267 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 17268 DSAStack->addMappableExpressionComponents( 17269 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 17270 17271 // Record the expression we've just processed. 17272 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 17273 17274 // Create a mappable component for the list item. List items in this clause 17275 // only need a component. We use a null declaration to signal fields in 17276 // 'this'. 17277 assert((isa<DeclRefExpr>(SimpleRefExpr) || 17278 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 17279 "Unexpected device pointer expression!"); 17280 MVLI.VarBaseDeclarations.push_back( 17281 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 17282 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17283 MVLI.VarComponents.back().push_back(MC); 17284 } 17285 17286 if (MVLI.ProcessedVarList.empty()) 17287 return nullptr; 17288 17289 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 17290 MVLI.VarBaseDeclarations, 17291 MVLI.VarComponents); 17292 } 17293 17294 OMPClause *Sema::ActOnOpenMPAllocateClause( 17295 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 17296 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 17297 if (Allocator) { 17298 // OpenMP [2.11.4 allocate Clause, Description] 17299 // allocator is an expression of omp_allocator_handle_t type. 17300 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 17301 return nullptr; 17302 17303 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 17304 if (AllocatorRes.isInvalid()) 17305 return nullptr; 17306 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 17307 DSAStack->getOMPAllocatorHandleT(), 17308 Sema::AA_Initializing, 17309 /*AllowExplicit=*/true); 17310 if (AllocatorRes.isInvalid()) 17311 return nullptr; 17312 Allocator = AllocatorRes.get(); 17313 } else { 17314 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 17315 // allocate clauses that appear on a target construct or on constructs in a 17316 // target region must specify an allocator expression unless a requires 17317 // directive with the dynamic_allocators clause is present in the same 17318 // compilation unit. 17319 if (LangOpts.OpenMPIsDevice && 17320 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 17321 targetDiag(StartLoc, diag::err_expected_allocator_expression); 17322 } 17323 // Analyze and build list of variables. 17324 SmallVector<Expr *, 8> Vars; 17325 for (Expr *RefExpr : VarList) { 17326 assert(RefExpr && "NULL expr in OpenMP private clause."); 17327 SourceLocation ELoc; 17328 SourceRange ERange; 17329 Expr *SimpleRefExpr = RefExpr; 17330 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17331 if (Res.second) { 17332 // It will be analyzed later. 17333 Vars.push_back(RefExpr); 17334 } 17335 ValueDecl *D = Res.first; 17336 if (!D) 17337 continue; 17338 17339 auto *VD = dyn_cast<VarDecl>(D); 17340 DeclRefExpr *Ref = nullptr; 17341 if (!VD && !CurContext->isDependentContext()) 17342 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17343 Vars.push_back((VD || CurContext->isDependentContext()) 17344 ? RefExpr->IgnoreParens() 17345 : Ref); 17346 } 17347 17348 if (Vars.empty()) 17349 return nullptr; 17350 17351 if (Allocator) 17352 DSAStack->addInnerAllocatorExpr(Allocator); 17353 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 17354 ColonLoc, EndLoc, Vars); 17355 } 17356 17357 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 17358 SourceLocation StartLoc, 17359 SourceLocation LParenLoc, 17360 SourceLocation EndLoc) { 17361 SmallVector<Expr *, 8> Vars; 17362 for (Expr *RefExpr : VarList) { 17363 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 17364 SourceLocation ELoc; 17365 SourceRange ERange; 17366 Expr *SimpleRefExpr = RefExpr; 17367 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17368 if (Res.second) 17369 // It will be analyzed later. 17370 Vars.push_back(RefExpr); 17371 ValueDecl *D = Res.first; 17372 if (!D) 17373 continue; 17374 17375 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 17376 // A list-item cannot appear in more than one nontemporal clause. 17377 if (const Expr *PrevRef = 17378 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 17379 Diag(ELoc, diag::err_omp_used_in_clause_twice) 17380 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 17381 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 17382 << getOpenMPClauseName(OMPC_nontemporal); 17383 continue; 17384 } 17385 17386 Vars.push_back(RefExpr); 17387 } 17388 17389 if (Vars.empty()) 17390 return nullptr; 17391 17392 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17393 Vars); 17394 } 17395